diff options
| author | tjpcc <tjp@ctrl-c.club> | 2023-01-15 19:59:58 -0700 | 
|---|---|---|
| committer | tjpcc <tjp@ctrl-c.club> | 2023-01-15 19:59:58 -0700 | 
| commit | 4c2630752f7367fff491a6ba53303e9102da7da0 (patch) | |
| tree | 7819a03ddd08e9ee017e7245dfd58cde9f51857d /gemtext/mdconv | |
| parent | cec3718bdd089bcf58575740c5ae4f86b27226d1 (diff) | |
Completed markdown and HTML conversion.
Diffstat (limited to 'gemtext/mdconv')
| -rw-r--r-- | gemtext/mdconv/convert.go | 104 | ||||
| -rw-r--r-- | gemtext/mdconv/convert_test.go | 7 | 
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:]))  | 
