diff options
author | Brian Picciano <me@mediocregopher.com> | 2024-10-31 17:14:10 +0100 |
---|---|---|
committer | Brian Picciano <me@mediocregopher.com> | 2024-10-31 17:14:10 +0100 |
commit | 246a99c28980e985bb4cff99042459bd5729cde1 (patch) | |
tree | f9ac2d531acc9edb7664f36317d9fafc52d20742 /http/handlers/templates/functions | |
parent | 695cd4c58fb146933ed02e61db8f553f7f9bf419 (diff) |
Move gemtext translation into its own package
Diffstat (limited to 'http/handlers/templates/functions')
-rw-r--r-- | http/handlers/templates/functions/gemtext.go | 120 |
1 files changed, 12 insertions, 108 deletions
diff --git a/http/handlers/templates/functions/gemtext.go b/http/handlers/templates/functions/gemtext.go index 179d558..68a10ca 100644 --- a/http/handlers/templates/functions/gemtext.go +++ b/http/handlers/templates/functions/gemtext.go @@ -1,9 +1,6 @@ package functions import ( - "bufio" - "bytes" - "errors" "fmt" "html" "io" @@ -11,6 +8,7 @@ import ( "strings" "text/template" + "dev.mediocregopher.com/mediocre-caddy-plugins.git/internal/gemtext" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" @@ -67,120 +65,26 @@ func sanitizeText(str string) string { return html.EscapeString(strings.TrimSpace(str)) } -type gemtextResult struct { - Title string - Body string -} - -func (g *Gemtext) funcGemtext(input any) (gemtextResult, error) { +func (g *Gemtext) funcGemtext(input any) (gemtext.HTML, error) { var ( - r = bufio.NewReader(strings.NewReader(caddy.ToString(input))) - w = new(bytes.Buffer) - title string - pft, list bool - writeErr error + r = strings.NewReader(caddy.ToString(input)) + translator gemtext.HTMLTranslator ) - write := func(fmtStr string, args ...any) { - if writeErr != nil { - return - } - fmt.Fprintf(w, fmtStr, args...) - } - -loop: - for { - if writeErr != nil { - return gemtextResult{}, fmt.Errorf("writing line: %w", writeErr) - } - - line, err := r.ReadString('\n') - - switch { - case errors.Is(err, io.EOF): - break loop - - case err != nil: - return gemtextResult{}, fmt.Errorf("reading next line: %w", err) - - case strings.HasPrefix(line, "```"): - if !pft { - write("<pre>\n") - pft = true - } else { - write("</pre>\n") - pft = false - } - continue - - case pft: - write(line) - continue - - case len(strings.TrimSpace(line)) == 0: - continue - } - - // list case is special, because it requires a prefix and suffix tag - if strings.HasPrefix(line, "*") { - if !list { - write("<ul>\n") + if g.GatewayURL != "" { + translator.RenderLink = func(w io.Writer, urlStr, label string) error { + if u, err := url.Parse(urlStr); err == nil && u.Scheme == "gemini" { + urlStr = g.GatewayURL + u.Host + u.Path } - write("<li>%s</li>\n", sanitizeText(line[1:])) - list = true - continue - } else if list { - write("</ul>\n") - list = false - } - switch { - case strings.HasPrefix(line, "=>"): - // TODO convert gemini:// links ? - var ( - line = strings.TrimSpace(line[2:]) - urlStr = line - label = urlStr + _, err := fmt.Fprintf( + w, "<p><a href=\"%s\">%s (proxied)</a></p>\n", urlStr, label, ) - - if i := strings.IndexAny(urlStr, " \t"); i > -1 { - urlStr, label = urlStr[:i], sanitizeText(urlStr[i:]) - } - - if g.GatewayURL != "" { - if u, err := url.Parse(urlStr); err == nil && u.Scheme == "gemini" { - urlStr = g.GatewayURL + u.Host + u.Path - } - } - - write("<p><a href=\"%s\">%s</a></p>\n", urlStr, label) - - case strings.HasPrefix(line, "###"): - write("<h3>%s</h3>\n", sanitizeText(line[3:])) - - case strings.HasPrefix(line, "##"): - write("<h2>%s</h2>\n", sanitizeText(line[2:])) - - case strings.HasPrefix(line, "#"): - line = sanitizeText(line[1:]) - if title == "" { - title = line - } - write("<h1>%s</h1>\n", line) - - case strings.HasPrefix(line, ">"): - write("<blockquote>%s</blockquote>\n", sanitizeText(line[1:])) - - default: - line = strings.TrimSpace(line) - write("<p>%s</p>\n", line) + return err } } - return gemtextResult{ - Title: title, - Body: w.String(), - }, nil + return translator.Translate(r) } // UnmarshalCaddyfile implements caddyfile.Unmarshaler. |