summaryrefslogtreecommitdiff
path: root/ar/.config/qutebrowser/userscripts/code_select
blob: 8f7fc312719d64f338c18d285bb71f8de23266aa (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
#!/usr/bin/env python3

import os
import html
import re
import sys
import xml.etree.ElementTree as ET
try:
    import pyperclip
except ImportError:
    try:
        import pyclip as pyperclip
    except ImportError:
        PYPERCLIP = False
    else:
        PYPERCLIP = True
else:
    PYPERCLIP = True


def parse_text_content(element):
    # https://stackoverflow.com/a/35591507/15245191
    magic = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
                <!ENTITY nbsp ' '>
                ]>'''
    root = ET.fromstring(magic + element)
    text = ET.tostring(root, encoding="unicode", method="text")
    text = html.unescape(text)
    return text


def send_command_to_qute(command):
    with open(os.environ.get("QUTE_FIFO"), "w") as f:
        f.write(command)


def main():
    delimiter = sys.argv[1] if len(sys.argv) > 1 else ";"
    # For info on qute environment vairables, see
    # https://github.com/qutebrowser/qutebrowser/blob/master/doc/userscripts.asciidoc
    element = os.environ.get("QUTE_SELECTED_HTML")
    code_text = parse_text_content(element)
    re_remove_dollars = re.compile(r"^(\$ )", re.MULTILINE)
    code_text = re.sub(re_remove_dollars, '', code_text)
    if PYPERCLIP:
        pyperclip.copy(code_text)
        send_command_to_qute(
            "message-info 'copied to clipboard: {info}{suffix}'".format(
                info=code_text.splitlines()[0].replace("'", "\""),
                suffix="..." if len(code_text.splitlines()) > 1 else ""
            )
        )
    else:
        # Qute's yank command  won't copy accross multiple lines so we
        # compromise by placing lines on a single line seperated by the
        # specified delimiter
        code_text = re.sub("(\n)+", delimiter, code_text)
        code_text = code_text.replace("'", "\"")
        send_command_to_qute("yank inline '{code}'\n".format(code=code_text))


if __name__ == "__main__":
    main()