aboutsummaryrefslogtreecommitdiff
path: root/cgit/filters/html-transform.py
blob: e12ffdaf626522bb696c257f8f828bcf84014c7b (plain) (blame)
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
#!/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 name == "href" and is_absolute_url(value):
        if not 'target' in attr_map: attr_map['target'] = '_blank _parent'
        if not 'rel' in attr_map: attr_map['rel'] = 'noopener'

    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())