summaryrefslogtreecommitdiff
path: root/gopher/gophermap/internal/templates.go
diff options
context:
space:
mode:
Diffstat (limited to 'gopher/gophermap/internal/templates.go')
-rw-r--r--gopher/gophermap/internal/templates.go153
1 files changed, 153 insertions, 0 deletions
diff --git a/gopher/gophermap/internal/templates.go b/gopher/gophermap/internal/templates.go
new file mode 100644
index 0000000..cc8ba14
--- /dev/null
+++ b/gopher/gophermap/internal/templates.go
@@ -0,0 +1,153 @@
+package internal
+
+import (
+ "bytes"
+ "text/template"
+ htemplate "html/template"
+ "strings"
+
+ "tildegit.org/tjp/sliderule/gopher"
+ "tildegit.org/tjp/sliderule/internal/types"
+)
+
+type renderItem struct {
+ Template string
+ Object any
+}
+
+type renderRef struct {
+ Type types.Status
+ Display string
+ Selector htemplate.URL
+ Hostname string
+ Port string
+}
+
+func simplifyLinks(items []renderItem, currentHost, currentPort string) {
+ for i, item := range items {
+ if item.Template != "link" && item.Template != "image" {
+ continue
+ }
+
+ m := item.Object.(renderRef)
+ if m.Hostname == currentHost && m.Port == currentPort {
+ m.Hostname = ""
+ m.Port = ""
+ m.Selector = htemplate.URL(strings.TrimPrefix(string(m.Selector), "URL:"))
+ items[i].Object = m
+ }
+ }
+}
+
+func AddOverrides(base *template.Template, overrides *template.Template) (*template.Template, error) {
+ if overrides == nil {
+ return base, nil
+ }
+
+ tmpl := base
+ var err error
+ for _, override := range overrides.Templates() {
+ tmpl, err = tmpl.AddParseTree(override.Name(), override.Tree)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return tmpl, nil
+}
+
+func AddHTMLOverrides(base *htemplate.Template, overrides *htemplate.Template) (*htemplate.Template, error) {
+ if overrides == nil {
+ return base, nil
+ }
+
+ tmpl := base
+ var err error
+ for _, override := range overrides.Templates() {
+ tmpl, err = tmpl.AddParseTree(override.Name(), override.Tree)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return tmpl, nil
+}
+
+func refItem(item gopher.MapItem) renderRef {
+ return renderRef{
+ Type: item.Type,
+ Display: item.Display,
+ Selector: htemplate.URL(item.Selector),
+ Hostname: item.Hostname,
+ Port: item.Port,
+ }
+}
+
+func RenderItems(doc gopher.MapDocument) []renderItem {
+ out := make([]renderItem, 0, len(doc))
+ out = append(out, renderItem{
+ Template: "header",
+ Object: doc,
+ })
+ inMsg := false
+ msg := &bytes.Buffer{}
+ var currentHost, currentPort string
+
+ for _, mapItem := range doc {
+ switch mapItem.Type {
+ case gopher.InfoMessageType:
+ if inMsg {
+ _, _ = msg.WriteString("\n")
+ } else {
+ msg.Reset()
+ }
+ _, _ = msg.WriteString(mapItem.Display)
+ inMsg = true
+
+ if currentHost == "" {
+ currentHost = mapItem.Hostname
+ }
+ if currentPort == "" {
+ currentPort = mapItem.Port
+ }
+ case gopher.GifFileType, gopher.ImageFileType, gopher.BitmapType, gopher.PngImageFileType:
+ if inMsg {
+ out = append(out, renderItem{
+ Template: "message",
+ Object: msg.String(),
+ })
+ inMsg = false
+ }
+ out = append(out, renderItem{
+ Template: "image",
+ Object: refItem(mapItem),
+ })
+ default:
+ if inMsg {
+ out = append(out, renderItem{
+ Template: "message",
+ Object: msg.String(),
+ })
+ inMsg = false
+ }
+ out = append(out, renderItem{
+ Template: "link",
+ Object: refItem(mapItem),
+ })
+ }
+ }
+
+ if inMsg {
+ out = append(out, renderItem{
+ Template: "message",
+ Object: msg.String(),
+ })
+ }
+
+ simplifyLinks(out, currentHost, currentPort)
+
+ return append(out, renderItem{
+ Template: "footer",
+ Object: doc,
+ })
+}