summaryrefslogtreecommitdiff
path: root/misc/userscripts/readability-js
blob: 310d1c081ae2c1998a1ac1c8bb170ea9a61476be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env node
//
// # Description
//
// Summarize the current page in a new tab, by processing it with the standalone readability
// library used for Firefox Reader View.
//
// # Prerequisites
//
//   - Setting NODE_PATH might be required to point qutebrowser to your global node libraries:
//     export NODE_PATH=$NODE_PATH:$(npm root -g)
//   - Mozilla's readability library (npm install -g @mozilla/readability)
//   - jsdom (npm install -g jsdom)
//   - qutejs (npm install -g qutejs)
//
// # Usage
//
// :spawn --userscript readability-js
//
// One may wish to define an easy to type command alias in qutebrowser's configuration file:
// c.aliases = {"readability" : "spawn --userscript readability-js", ...}

const { Readability } = require('@mozilla/readability');
const qute = require('qutejs');
const JSDOM = require('jsdom').JSDOM;
const fs = require('fs');
const path = require('path');
const util = require('util');

const HEADER = `
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1, text/html, charset=UTF-8" http-equiv="Content-Type">
    </meta>
    <title>%s</title>
    <style type="text/css">
        body {
            margin: 30px auto;
            max-width: 650px;
            line-height: 1.4;
            padding: 0 10px;
        }
        h1, h2, h3 {
            line-height: 1.2;
        }
        img {
            max-width:100%;
            height:auto;
        }
        p > img:only-child,
        p > a:only-child > img:only-child,
        .wp-caption img,
        figure img {
            display: block;
        }
        table,
        th,
        td {
            border: 1px solid grey;
            border-collapse: collapse;
            padding: 6px;
            vertical-align: top;
        }
        table {
            margin: 5px;
        }
        pre {
            padding: 16px;
            overflow: auto;
            line-height: 1.45;
            background-color: #dddddd;
        }
        code { 
            padding: .2em .4em;
            margin: 0;
            background-color: #dddddd;
        }
        blockquote {
            border-inline-start: 2px solid grey !important;
            padding: 0;
            padding-inline-start: 16px;
            margin-inline-start: 24px;
            border-radius: 5px;
        }
    </style>
    <!-- This icon is licensed under the Mozilla Public License 2.0 (available at: https://www.mozilla.org/en-US/MPL/2.0/).
    The original icon can be found here: https://dxr.mozilla.org/mozilla-central/source/browser/themes/shared/reader/readerMode.svg -->
    <link rel="shortcut icon" href="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjRweCIgaGVpZ2h0PSI2NHB4IiB2ZXJzaW9uPSIxLjEiI
    HZpZXdCb3g9IjAgMCA2NCA2NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgZmlsbD0iI2ZmZiI+CjxwYXRoIGQ9Im01MiAwaC00
    MGMtNC40MiAwLTggMy41OC04IDh2NDhjMCA0LjQyIDMuNTggOCA4IDhoNDBjNC40MiAwIDgtMy41OCA4LTh2LTQ4YzAtNC40Mi0zLjU4LTgtOC04em0wIDU
    yYzAgMi4yMS0xLjc5IDQtNCA0aC0zMmMtMi4yMSAwLTQtMS43OS00LTR2LTQwYzAtMi4yMSAxLjc5LTQgNC00aDMyYzIuMjEgMCA0IDEuNzkgNCA0em0tMT
    AtMzZoLTIwYy0xLjExIDAtMiAwLjg5NS0yIDJzMC44OTUgMiAyIDJoMjBjMS4xMSAwIDItMC44OTUgMi0ycy0wLjg5NS0yLTItMnptMCA4aC0yMGMtMS4xM
    SAwLTIgMC44OTUtMiAyczAuODk1IDIgMiAyaDIwYzEuMTEgMCAyLTAuODk1IDItMnMtMC44OTUtMi0yLTJ6bTAgOGgtMjBjLTEuMTEgMC0yIDAuODk1LTIg
    MnMwLjg5NSAyIDIgMmgyMGMxLjExIDAgMi0wLjg5NSAyLTJzLTAuODk1LTItMi0yem0tMTIgOGgtOGMtMS4xMSAwLTIgMC44OTUtMiAyczAuODk1IDIgMiA
    yaDhjMS4xMSAwIDItMC44OTUgMi0ycy0wLjg5NS0yLTItMnoiIGZpbGw9IiNmZmYiLz4KPC9nPgo8L3N2Zz4K"/>
</head>`;
const scriptsDir = path.join(process.env.QUTE_DATA_DIR, 'userscripts');
const tmpFile = path.join(scriptsDir, '/readability.html');

if (!fs.existsSync(scriptsDir)) {
    fs.mkdirSync(scriptsDir);
}

let getDOM, domOpts, target;
// When hinting, use the selected hint instead of the current page
if (process.env.QUTE_MODE === 'hints') {
    getDOM = JSDOM.fromURL;
    target = process.env.QUTE_URL;
}
else {
    getDOM = JSDOM.fromFile;
    domOpts = {url: process.env.QUTE_URL, contentType: "text/html; charset=utf-8"};
    target = process.env.QUTE_HTML;
}

getDOM(target, domOpts).then(dom => {
    let reader = new Readability(dom.window.document);
    let article = reader.parse();
    let content = util.format(HEADER, article.title) + article.content;

    fs.writeFile(tmpFile, content, (err) => {
        if (err) {
            qute.messageError([`"${err}"`])
            return 1;
        }
        // Success
        qute.open(['-t', '-r', tmpFile]);
    })
});