gmi2html.go (view raw)
1package main
2
3import (
4 "fmt"
5 "html"
6 "mime"
7 neturl "net/url"
8 "path"
9 "strings"
10
11 "git.sr.ht/~adnano/go-gemini"
12)
13
14func textToHTML(text gemini.Text) string {
15 var b strings.Builder
16 var pre bool
17 var list bool
18 for _, l := range text {
19 if _, ok := l.(gemini.LineListItem); ok {
20 if !list {
21 list = true
22 fmt.Fprint(&b, "<ul>\n")
23 }
24 } else if list {
25 list = false
26 fmt.Fprint(&b, "</ul>\n")
27 }
28 switch l.(type) {
29 case gemini.LineLink:
30 link := l.(gemini.LineLink)
31 url := html.EscapeString(link.URL)
32 name := html.EscapeString(link.Name)
33 var internal bool
34 parsedUrl, err := neturl.Parse(url) // simpler way to do this?
35 if err == nil {
36 // only show images inline if they are relative links
37 internal = parsedUrl.Host == ""
38 }
39 if strings.HasPrefix(mime.TypeByExtension(path.Ext(url)), "image") && internal {
40 fmt.Fprintf(&b, "<img src='%s' alt='%s'>\n", url, name)
41 } else {
42 if name == "" {
43 name = url
44 }
45 fmt.Fprintf(&b, "<p><a href='%s'>%s</a></p>\n", url, name)
46 }
47 case gemini.LinePreformattingToggle:
48 pre = !pre
49 if pre {
50 altText := string(l.(gemini.LinePreformattingToggle))
51 if altText != "" {
52 altText = html.EscapeString(altText)
53 fmt.Fprintf(&b, "<pre title='%s'>\n", altText)
54 }
55 fmt.Fprint(&b, "<pre>\n")
56 } else {
57 fmt.Fprint(&b, "</pre>\n")
58 }
59 case gemini.LinePreformattedText:
60 text := string(l.(gemini.LinePreformattedText))
61 fmt.Fprintf(&b, "%s\n", html.EscapeString(text))
62 case gemini.LineHeading1:
63 text := string(l.(gemini.LineHeading1))
64 fmt.Fprintf(&b, "<h1>%s</h1>\n", html.EscapeString(text))
65 case gemini.LineHeading2:
66 text := string(l.(gemini.LineHeading2))
67 fmt.Fprintf(&b, "<h2>%s</h2>\n", html.EscapeString(text))
68 case gemini.LineHeading3:
69 text := string(l.(gemini.LineHeading3))
70 fmt.Fprintf(&b, "<h3>%s</h3>\n", html.EscapeString(text))
71 case gemini.LineListItem:
72 text := string(l.(gemini.LineListItem))
73 fmt.Fprintf(&b, "<li>%s</li>\n", html.EscapeString(text))
74 case gemini.LineQuote:
75 text := string(l.(gemini.LineQuote))
76 fmt.Fprintf(&b, "<blockquote>%s</blockquote>\n", html.EscapeString(text))
77 case gemini.LineText:
78 text := string(l.(gemini.LineText))
79 if text == "" {
80 fmt.Fprint(&b, "<br>\n")
81 } else {
82 fmt.Fprintf(&b, "<p>%s</p>\n", html.EscapeString(text))
83 }
84 }
85 }
86 if pre {
87 fmt.Fprint(&b, "</pre>\n")
88 }
89 if list {
90 fmt.Fprint(&b, "</ul>\n")
91 }
92 return b.String()
93}