package internal import ( htemplate "html/template" "net/url" "text/template" "tildegit.org/tjp/sliderule/gemini/gemtext" ) var Renderers = map[gemtext.LineType]string{ gemtext.LineTypeText: "textline", gemtext.LineTypeLink: "linkline", gemtext.LineTypeHeading1: "heading1line", gemtext.LineTypeHeading2: "heading2line", gemtext.LineTypeHeading3: "heading3line", gemtext.LineTypeQuote: "quoteline", } func AddAllTemplates(base *template.Template, additions *template.Template) (*template.Template, error) { if additions == nil { return base, nil } tmpl := base var err error for _, addition := range additions.Templates() { tmpl, err = tmpl.AddParseTree(addition.Name(), addition.Tree) if err != nil { return nil, err } } return tmpl, nil } func AddHTMLTemplates(base *htemplate.Template, additions *htemplate.Template) (*htemplate.Template, error) { if additions == nil { return base, nil } tmpl := base var err error for _, addition := range additions.Templates() { tmpl, err = tmpl.AddParseTree(addition.Name(), addition.Tree) if err != nil { return nil, err } } return tmpl, nil } func ValidateLinks(doc gemtext.Document) error { for _, line := range doc { if linkLine, ok := line.(gemtext.LinkLine); ok { _, err := url.Parse(linkLine.URL()) if err != nil { return err } } } return nil } type RenderItem struct { Template string Object any } func RenderItems(doc gemtext.Document) []RenderItem { out := make([]RenderItem, 0, len(doc)) out = append(out, RenderItem{ Template: "header", Object: doc, }) inUL := false ulStart := 0 inPF := false pfStart := 0 for i, line := range doc { switch line.Type() { case gemtext.LineTypeListItem: if !inUL { inUL = true ulStart = i } case gemtext.LineTypePreformatToggle: if inUL { inUL = false out = append(out, RenderItem{ Template: "listitemlines", Object: doc[ulStart:i], }) } if !inPF { inPF = true pfStart = i } else { inPF = false out = append(out, RenderItem{ Template: "preformattedtextlines", Object: doc[pfStart+1 : i], }) } case gemtext.LineTypePreformattedText: default: if inUL { inUL = false out = append(out, RenderItem{ Template: "listitemlines", Object: doc[ulStart:i], }) } if linkLine, ok := line.(gemtext.LinkLine); ok { line = validatedLinkLine{linkLine} } out = append(out, RenderItem{ Template: Renderers[line.Type()], Object: line, }) } } if inUL { out = append(out, RenderItem{ Template: "listitemlines", Object: doc[ulStart:], }) } out = append(out, RenderItem{ Template: "footer", Object: doc, }) return out } type validatedLinkLine struct { gemtext.LinkLine } func (vll validatedLinkLine) ValidatedURL() htemplate.URL { return htemplate.URL(vll.URL()) }