diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-09-01 12:37:42 -0600 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-09-01 12:37:42 -0600 |
commit | a61bcdeb314d4e0e9f6e8915b92010895170e785 (patch) | |
tree | 29611d33a0e65f334c7238a7748244ab63ad0d5c /gopher/gophermap/internal/templates.go | |
parent | 2ce5be68acd3c66d4d135d7eb68b9ecd1563aa1d (diff) |
refactor gophermap template handling and add markdown conversion
Diffstat (limited to 'gopher/gophermap/internal/templates.go')
-rw-r--r-- | gopher/gophermap/internal/templates.go | 153 |
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, + }) +} |