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
|
#!/usr/bin/env python3
# Rewrite image urls in about section
import sys
from html.parser import HTMLParser
import html
from urllib.parse import urljoin, urlparse
import re
def is_absolute_url(url):
if not url: return False
parsed = urlparse(url)
return bool(parsed.netloc or parsed.scheme)
def is_relative_path(url):
if not url: return False
return not url.startswith("/") and not is_absolute_url(url)
# def linkify(text, make_link):
# url_pattern = r'(?<!\S)(https?://\S+?)([.,!?;:]?(?=\s|$))'
# def replace(m):
# url, trail = m.group(1), m.group(2)
# return make_link(url) + trail
# return re.sub(url_pattern, replace, text)
class LinkRewriter(HTMLParser):
def __init__(self):
super().__init__(convert_charrefs=False)
self.output = []
def get_html(self):
return "".join(self.output)
def _build_tag(self, tag, attrs, self_closing = False):
new_tag = tag
attr_map = {}
for name, value in attrs:
if name in ("href", "src") and is_relative_path(value) and not value.startswith('#'):
if tag == 'a':
value = "../" + urljoin("tree/", value)
else:
value = "../" + urljoin("plain/", value)
attr_map[name] = value
# Open in new tab
if tag == 'a' and 'href' in attr_map and is_absolute_url(attr_map['href']):
if not 'target' in attr_map: attr_map['target'] = '_blank _parent'
if not 'rel' in attr_map: attr_map['rel'] = 'noopener'
# Image tag lazy loading
if tag == 'img':
attr_map['loading'] = 'lazy'
attr_map['decoding'] = 'async'
attr_str = ''.join(
f' {name}="{html.escape(value, quote=True)}"' if value is not None else f" {name}"
for name, value in attr_map.items()
)
return f"<{new_tag}{attr_str}{' /' if self_closing else ''}>"
def handle_starttag(self, tag, attrs):
self.output.append(self._build_tag(tag, attrs))
def handle_startendtag(self, tag, attrs):
self.output.append(self._build_tag(tag, attrs, self_closing=True))
def handle_endtag(self, tag):
self.output.append(f"</{tag}>")
def handle_data(self, data):
# data_with_links = linkify(data,
# lambda url: self._build_tag("a", [('href', url)]) + html.escape(url) + "</a>")
self.output.append(data)
def handle_entityref(self, name):
self.output.append(f"&{name};")
def handle_charref(self, name):
self.output.append(f"&#{name};")
def handle_comment(self, data):
self.output.append(f"<!--{data}-->")
html_in = sys.stdin.read()
parser = LinkRewriter()
parser.feed(html_in)
print(parser.get_html())
|