all repos — flounder @ 2799ede93e92daa87144e345d5b086aac4e8c037

A small site builder for the Gemini protocol

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}