summaryrefslogtreecommitdiff
path: root/gemtext/mdconv
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-01-15 19:59:58 -0700
committertjpcc <tjp@ctrl-c.club>2023-01-15 19:59:58 -0700
commit4c2630752f7367fff491a6ba53303e9102da7da0 (patch)
tree7819a03ddd08e9ee017e7245dfd58cde9f51857d /gemtext/mdconv
parentcec3718bdd089bcf58575740c5ae4f86b27226d1 (diff)
Completed markdown and HTML conversion.
Diffstat (limited to 'gemtext/mdconv')
-rw-r--r--gemtext/mdconv/convert.go104
-rw-r--r--gemtext/mdconv/convert_test.go7
2 files changed, 55 insertions, 56 deletions
diff --git a/gemtext/mdconv/convert.go b/gemtext/mdconv/convert.go
index 0c92f9f..9371d92 100644
--- a/gemtext/mdconv/convert.go
+++ b/gemtext/mdconv/convert.go
@@ -1,72 +1,72 @@
package mdconv
import (
- "fmt"
"io"
"text/template"
"tildegit.org/tjp/gus/gemtext"
+ "tildegit.org/tjp/gus/gemtext/internal"
)
+// Convert writes markdown to a writer from the provided gemtext document.
+//
+// Templates can be provided to override the output for different line types.
+// The templates supported are:
+// - "header" is called before any lines and is passed the full Document.
+// - "footer" is called after the lines and is passed the full Document.
+// - "textline" is called once per line of text and is passed a gemtext.TextLine.
+// - "linkline" is called once per link line and is passed a gemtext.LinkLine.
+// - "preformattedtextlines" is called once for a block of preformatted text and is
+// passed a slice of gemtext.PreformattedTextLines.
+// - "heading1line" is called once per h1 line and is passed a gemtext.Heading1Line.
+// - "heading2line" is called once per h2 line and is passed a gemtext.Heading2Line.
+// - "heading3line" is called once per h3 line and is passed a gemtext.Heading3Line.
+// - "listitemlines" is called once for a block of contiguous list item lines and
+// is passed a slice of gemtext.ListItemLines.
+// - "quoteline" is passed once per blockquote line and is passed a gemtext.QuoteLine.
+//
+// There exist default implementations of each of these templates, so the "overrides"
+// argument can be nil.
func Convert(wr io.Writer, doc gemtext.Document, overrides *template.Template) error {
+ if err := internal.ValidateLinks(doc); err != nil {
+ return err
+ }
+
tmpl, err := baseTmpl.Clone()
if err != nil {
return err
}
- if overrides != nil {
- for _, override := range overrides.Templates() {
- tmpl, err = tmpl.AddParseTree(override.Name(), override.Tree)
- if err != nil {
- return err
- }
+ tmpl, err = internal.AddAllTemplates(tmpl, overrides)
+ if err != nil {
+ return err
+ }
+
+ for _, item := range internal.RenderItems(doc) {
+ if err := tmpl.ExecuteTemplate(wr, item.Template, item.Object); err != nil {
+ return err
}
}
- return tmpl.ExecuteTemplate(wr, "mdconv", doc)
+ return nil
}
-var baseTmpl = template.Must(template.New("mdconv").Parse(fmt.Sprintf((`
-{{block "header" .}}{{end -}}
-{{range . -}}
-{{if .Type | eq %d}}{{block "textline" . -}}
- {{. -}}
-{{end -}}
-{{else if .Type | eq %d}}{{block "linkline" . -}}
- => [{{if eq .Label ""}}{{.URL}}{{else}}{{.Label}}{{end}}]({{.URL}})
-{{end -}}
-{{else if .Type | eq %d}}{{block "preformattoggleline" . -}}
- ` + "```" + `
-{{end -}}
-{{else if .Type | eq %d}}{{block "preformattedtextline" . -}}
- {{. -}}
-{{end -}}
-{{else if .Type | eq %d}}{{block "heading1line" . -}}
- # {{.Body}}
-{{end -}}
-{{else if .Type | eq %d}}{{block "heading2line" . -}}
- ## {{.Body}}
-{{end -}}
-{{else if .Type | eq %d}}{{block "heading3line" . -}}
- ### {{.Body}}
-{{end -}}
-{{else if .Type | eq %d}}{{block "listitemline" . -}}
- * {{.Body}}
-{{end -}}
-{{else if .Type | eq %d}}{{block "quoteline" . -}}
- > {{.Body}}
-{{end -}}
-{{end -}}
-{{end -}}
-{{block "footer" .}}{{end -}}
-`)[1:],
- gemtext.LineTypeText,
- gemtext.LineTypeLink,
- gemtext.LineTypePreformatToggle,
- gemtext.LineTypePreformattedText,
- gemtext.LineTypeHeading1,
- gemtext.LineTypeHeading2,
- gemtext.LineTypeHeading3,
- gemtext.LineTypeListItem,
- gemtext.LineTypeQuote,
-)))
+var baseTmpl = template.Must(template.New("mdconv").Parse(`
+{{ define "header" }}{{ end }}
+{{ define "textline" }}{{ . }}{{ end }}
+{{ define "linkline" -}}
+ => [{{ if eq .Label "" }}{{ .URL }}{{ else }}{{ .Label }}{{ end }}]({{ .URL }})
+{{ end }}
+{{ define "preformattedtextlines" }}` + "```\n" + `{{ range . }}{{ . }}{{ end }}` + "```\n" + `{{ end }}
+{{ define "heading1line" }}# {{ .Body }}
+{{ end }}
+{{ define "heading2line" }}## {{ .Body }}
+{{ end }}
+{{ define "heading3line" }}### {{ .Body }}
+{{ end }}
+{{ define "listitemlines" }}{{ range . }}* {{ .Body }}
+{{ end }}{{ end }}
+{{ define "quoteline" }}> {{ .Body }}
+{{ end }}
+{{ define "footer" }}{{ end }}
+`))
diff --git a/gemtext/mdconv/convert_test.go b/gemtext/mdconv/convert_test.go
index 6cde08b..010ddce 100644
--- a/gemtext/mdconv/convert_test.go
+++ b/gemtext/mdconv/convert_test.go
@@ -78,17 +78,16 @@ text:
> quote: this is a quote
> quote: -tjp
text:
-`[1:] + "pftoggle: ```\npf: doc := gemtext.Parse(req.Body)\npftoggle: ```\n"
+`[1:] + "```\npf: doc := gemtext.Parse(req.Body)\n```\n"
overrides := template.Must(template.New("overrides").Parse((`
{{define "textline"}}text: {{.}}{{end}}
{{define "linkline"}}=> link: [{{if eq .Label ""}}{{.URL}}{{else}}{{.Label}}{{end}}]({{.URL}})` + "\n" + `{{end}}
- {{define "preformattoggleline"}}pftoggle: ` + "```\n" + `{{end}}
- {{define "preformattedtextline"}}pf: {{.}}{{end}}
+ {{define "preformattedtextlines"}}` + "```\n" + `{{range . }}pf: {{.}}{{end}}` + "```\n" + `{{end}}
{{define "heading1line"}}# h1: {{.Body}}` + "\n" + `{{end}}
{{define "heading2line"}}## h2: {{.Body}}` + "\n" + `{{end}}
{{define "heading3line"}}### h3: {{.Body}}` + "\n" + `{{end}}
- {{define "listitemline"}}* li: {{.Body}}` + "\n" + `{{end}}
+ {{define "listitemlines"}}{{range .}}* li: {{.Body}}` + "\n" + `{{end}}{{end}}
{{define "quoteline"}}> quote: {{.Body}}` + "\n" + `{{end}}
`)[1:]))