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
|
import itertools
import htmlgenerator as h
from blog import meta, pretty, gemtext
def html_template(*content, page_title=None):
title = [h.A(meta.TITLE, href=f"{meta.SCHEMA}://{meta.HOST}")]
if page_title:
title += f" - {page_title}"
title = h.BaseElement(*title)
links = list(itertools.chain(*[(h.A(text, href=href), ", ") for text, href in meta.LINKS]))
links += h.BaseElement(f" {meta.EMAIL_TEXT}")
return pretty.pretty_html(h.render(
h.HTML(
h.HEAD(
h.TITLE(meta.TITLE + (f" - {page_title}" if page_title else "")),
h.LINK(rel="alternate", type="application/rss+xml", title=meta.TITLE, href=f"{meta.SCHEMA}://{meta.HOST}/feed/"),
),
h.BODY(
h.H1(title),
h.H2(meta.SUBTITLE),
h.P(*links),
*content,
),
doctype="html",
),
{},
))
def gemini_to_html(parsed):
i = 0
result = []
while i < len(parsed):
gem_element = parsed[i]
if isinstance(gem_element, gemtext.Header):
header = [h.H1, h.H2, h.H3, h.H4, h.H5, h.H6][gem_element.level - 1]
result.append(header(gem_element.text))
i = i + 1
continue
if isinstance(gem_element, gemtext.List):
result.append(h.UL(*[h.LI(i.text) for i in gem_element.items]))
i = i + 1
continue
if isinstance(gem_element, gemtext.Link):
url = gem_element.url
if url.startswith("gemini://"):
if url.startswith("gemini://alex.corcoles.net/"):
url = url.replace("gemini://alex.corcoles.net/", f"{meta.SCHEMA}://{meta.HOST}/")
else:
url = url.replace("gemini://", "https://portal.mozz.us/gemini/")
result.append(h.P(h.A(gem_element.text or gem_element.url, href=url)))
i = i + 1
continue
if gem_element == gemtext.Line(""):
i = i + 1
continue
if isinstance(gem_element, gemtext.BlockQuote):
content = []
for line in gem_element.lines:
if line.text:
content.append(line.text)
content.append(h.BR())
result.append(h.BLOCKQUOTE(*content))
i = i + 1
continue
if isinstance(gem_element, gemtext.Line):
paragraph = [gem_element.text]
i = i + 1
while i < len(parsed):
gem_element = parsed[i]
if isinstance(gem_element, gemtext.Line) and gem_element.text != "":
paragraph.append(h.BR())
paragraph.append(gem_element.text)
i = i + 1
else:
break
result.append(h.P(*paragraph))
continue
if isinstance(gem_element, gemtext.Pre):
result.append(h.PRE(gem_element.content))
i = i + 1
continue
assert False, f"unknown element {gem_element}"
return result
|