gmi2html.go (view raw)
1package main
2
3import (
4 "fmt"
5 "html"
6 "net/url"
7 "strings"
8
9 "git.sr.ht/~adnano/go-gemini"
10)
11
12type ConvertedGmiDoc struct {
13 Content string
14 Title string
15}
16
17func textToHTML(reqUrl *url.URL, text gemini.Text) ConvertedGmiDoc {
18 var b strings.Builder
19 var pre bool
20 var list bool
21 var title string
22 for _, l := range text {
23 if _, ok := l.(gemini.LineListItem); ok {
24 if !list {
25 list = true
26 fmt.Fprint(&b, "<ul>\n")
27 }
28 } else if list {
29 list = false
30 fmt.Fprint(&b, "</ul>\n")
31 }
32 switch l.(type) {
33 case gemini.LineLink:
34 link := l.(gemini.LineLink)
35 urlstring := html.EscapeString(link.URL)
36 // u = ctx.URL.ResolveReference(u) ?
37 u, err := url.Parse(urlstring)
38 if err != nil {
39 continue
40 }
41 if reqUrl != nil {
42 u = reqUrl.ResolveReference(u)
43 }
44 if u.Scheme == "gemini" || (reqUrl != nil && u.Scheme == "") {
45 if strings.HasSuffix(u.Host, c.Host) {
46 u.Scheme = ""
47 urlstring = html.EscapeString(u.String())
48 } else {
49 u.Path = fmt.Sprintf("/%s%s", u.Host, u.Path)
50 u.Scheme = ""
51 u.Host = "proxy." + c.Host
52 urlstring = html.EscapeString(u.String())
53 }
54 }
55 name := html.EscapeString(link.Name)
56 if name == "" {
57 name = urlstring
58 }
59 fmt.Fprintf(&b, "<p><a href='%s'>%s</a></p>\n", urlstring, name)
60 case gemini.LinePreformattingToggle:
61 pre = !pre
62 if pre {
63 altText := string(l.(gemini.LinePreformattingToggle))
64 if altText != "" {
65 altText = html.EscapeString(altText)
66 fmt.Fprintf(&b, "<pre title='%s'>\n", altText)
67 } else {
68 fmt.Fprint(&b, "<pre>\n")
69 }
70 } else {
71 fmt.Fprint(&b, "</pre>\n")
72 }
73 case gemini.LinePreformattedText:
74 text := string(l.(gemini.LinePreformattedText))
75 fmt.Fprintf(&b, "%s\n", html.EscapeString(text))
76 case gemini.LineHeading1:
77 text := string(l.(gemini.LineHeading1))
78 fmt.Fprintf(&b, "<h1>%s</h1>\n", html.EscapeString(text))
79 if title == "" {
80 title = text
81 } // TODO deal with repetition
82 case gemini.LineHeading2:
83 text := string(l.(gemini.LineHeading2))
84 fmt.Fprintf(&b, "<h2>%s</h2>\n", html.EscapeString(text))
85 if title == "" {
86 title = text
87 }
88 case gemini.LineHeading3:
89 text := string(l.(gemini.LineHeading3))
90 fmt.Fprintf(&b, "<h3>%s</h3>\n", html.EscapeString(text))
91 if title == "" {
92 title = text
93 }
94 case gemini.LineListItem:
95 text := string(l.(gemini.LineListItem))
96 fmt.Fprintf(&b, "<li>%s</li>\n", html.EscapeString(text))
97 case gemini.LineQuote:
98 text := string(l.(gemini.LineQuote))
99 fmt.Fprintf(&b, "<blockquote>%s</blockquote>\n", html.EscapeString(text))
100 case gemini.LineText:
101 text := string(l.(gemini.LineText))
102 if text == "" {
103 fmt.Fprint(&b, "<br>\n")
104 } else {
105 fmt.Fprintf(&b, "<p>%s</p>\n", html.EscapeString(text))
106 }
107 }
108 }
109 if pre {
110 fmt.Fprint(&b, "</pre>\n")
111 }
112 if list {
113 fmt.Fprint(&b, "</ul>\n")
114 }
115 return ConvertedGmiDoc{
116 b.String(),
117 title,
118 }
119}