summaryrefslogtreecommitdiff
path: root/gopher/gophermap/htmlconv/convert.go
blob: 8fa2f5243d582baf6ba24d565e1f62a240e029cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package htmlconv

import (
	"html/template"
	"io"

	"tildegit.org/tjp/sliderule/gopher"
	"tildegit.org/tjp/sliderule/gopher/gophermap/internal"
)

// Convert writes html to a writer  from the provided gophermap document.
//
// Templates can be provided to override the output for different line types.
// The supported templates are:
//   - "header' is called before any lines and is passed the full document.
//   - "footer" is called after all lines and is passed the full document.
//   - "message" is called for every group of consecutive info-message lines. It is
//     passed a string of all the display components of the included lines, joined by
//     newline characters.
//   - "image" is called for all lines of any of the following types: GifFileType,
//     ImageFileType, BitmapType, PngImageFileType. It is passed the gopher.MapItem.
//   - "link" is called for all lines of any other type not yet mentioned, and is passed
//     the gopher.MapItem.
//
// There are already default implementations of each of these templates, so the "overrides"
// argument can be nil or include just a subset of the supported templates.
func Convert(wr io.Writer, doc gopher.MapDocument, overrides *template.Template) error {
	tmpl, err := baseTmpl.Clone()
	if err != nil {
		return err
	}

	tmpl, err = internal.AddHTMLOverrides(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" -}}
<!DOCTYPE html>
<html><body class="gophermap">
{{- end }}

{{ define "message" -}}
<pre class="gophermap">{{.}}
</pre>
{{- end }}

{{ define "link" -}}
<p class="gophermap"><a class="gophermap" {{ if .Hostname | and .Port }}href="gopher://{{.Hostname}}:{{.Port}}{{.Selector}}"{{ else }}href="{{.Selector}}"{{ end }}>{{.Display}}</a></p>
{{- end }}

{{ define "image" -}}
<p class="gophermap"><img class="gophermap" {{ if .Hostname | and .Port }}src="gopher://{{.Hostname}}:{{.Port}}{{.Selector}}"{{ else }}src="{{.Selector}}"{{ end }} alt="{{.Display}}"/></p>
{{- end }}

{{ define "footer" -}}
</body></html>
{{ end }}
`))