diff options
Diffstat (limited to 'gemtext/htmlconv/convert.go')
| -rw-r--r-- | gemtext/htmlconv/convert.go | 86 | 
1 files changed, 86 insertions, 0 deletions
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" }}<html><body>{{ end }} +{{ define "textline" }}{{ if ne .String "\n" }}<p>{{ . }}</p>{{ end }}{{ end }} +{{ define "linkline" -}} +	<p>=> <a href="{{ .ValidatedURL }}">{{ if eq .Label "" -}} +		{{ .URL }} +	{{- else -}} +		{{ .Label }} +	{{- end -}} +	</a></p> +{{- end }} +{{ define "preformattedtextlines" -}} +	<pre> +	{{- range . -}} +		{{ . }} +	{{- end -}} +	</pre> +{{- end }} +{{ define "heading1line" }}<h1>{{ .Body }}</h1>{{ end }} +{{ define "heading2line" }}<h2>{{ .Body }}</h2>{{ end }} +{{ define "heading3line" }}<h3>{{ .Body }}</h3>{{ end }} +{{ define "listitemlines" -}} +	<ul> +	{{- range . -}} +		<li>{{ .Body }}</li> +	{{- end -}} +	</ul> +{{- end }} +{{ define "quoteline" }}<blockquote>{{ .Body }}</blockquote>{{ end }} +{{ define "footer" }}</body></html>{{ end }} +`))  | 
