From 4c2630752f7367fff491a6ba53303e9102da7da0 Mon Sep 17 00:00:00 2001 From: tjpcc Date: Sun, 15 Jan 2023 19:59:58 -0700 Subject: Completed markdown and HTML conversion. --- gemtext/htmlconv/convert.go | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 gemtext/htmlconv/convert.go (limited to 'gemtext/htmlconv/convert.go') diff --git a/gemtext/htmlconv/convert.go b/gemtext/htmlconv/convert.go new file mode 100644 index 0000000..c703211 --- /dev/null +++ b/gemtext/htmlconv/convert.go @@ -0,0 +1,86 @@ +package htmlconv + +import ( + "html/template" + "io" + + "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 an object which wraps +// a gemtext.LinkLine but also supports a ValidatedURL() method returning a +// string which html/template will always allow as href attributes. +// - "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 + } + + tmpl, err = internal.AddHTMLTemplates(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 nil +} + +var baseTmpl = template.Must(template.New("htmlconv").Parse(` +{{ define "header" }}{{ end }} +{{ define "textline" }}{{ if ne .String "\n" }}

{{ . }}

{{ end }}{{ end }} +{{ define "linkline" -}} +

=> {{ if eq .Label "" -}} + {{ .URL }} + {{- else -}} + {{ .Label }} + {{- end -}} +

+{{- end }} +{{ define "preformattedtextlines" -}} +
+	{{- range . -}}
+		{{ . }}
+	{{- end -}}
+	
+{{- end }} +{{ define "heading1line" }}

{{ .Body }}

{{ end }} +{{ define "heading2line" }}

{{ .Body }}

{{ end }} +{{ define "heading3line" }}

{{ .Body }}

{{ end }} +{{ define "listitemlines" -}} + +{{- end }} +{{ define "quoteline" }}
{{ .Body }}
{{ end }} +{{ define "footer" }}{{ end }} +`)) -- cgit v1.2.3