shithub: hell

ref: 078c23e447246952aae7eec077828256eea49966
dir: /templater.go/

View raw version
package main

import (
	"fmt"
	"os"
)

// Holds a stringer and its template key
type templateDefs struct {
	stringer fmt.Stringer
	key      string
}

// Renders line templates by turning keys into mapped stringers
type templateRenderer struct {
	tempdefs []*templateDefs
}

// returns a new template renderer loaded with standard format keys
func newStatusTemplateRenderer(sf *StatusFormatter) *templateRenderer {
	template := &templateRenderer{
		tempdefs: []*templateDefs{
			{key: "content", stringer: &statusContent{sf}},
			{key: "subject_or_content", stringer: &statusOrContent{sf}},
			{key: "media_descriptions", stringer: &mediaDescriptions{sf}},
			{key: "detail_line", stringer: &detailLine{sf}},
			{key: "username", stringer: &username{sf}},
			{key: "boostuser", stringer: &boostedusername{sf}},
			{key: "boostcontent", stringer: &boostContent{sf}},
			{key: "boosted_media_descriptions", stringer: &boostMediaDescriptions{sf}},
			{key: "notif_user", stringer: &notificationUser{sf}},
			{key: "notif_type", stringer: &notificationType{sf}},
			{key: "index", stringer: &indexString{sf}},
		},
	}
	// macro templates
	template.tempdefs = append(template.tempdefs, []*templateDefs{
		{key: "standard_status", stringer: &standardStatus{template, false}},
		{key: "standard_or_subject", stringer: &standardStatus{template, true}},
		{key: "standard_reblog", stringer: &standardReblog{template}},
		{key: "status_notif", stringer: &statusNotification{template}},
		{key: "other_notif", stringer: &otherNotification{template}},
	}...)
	return template
}

// Render a template into a string, hyphenated for user display
func (tr *templateRenderer) render(template string) (string, error) {
	template, _ = tr.renderRaw(template)
	template, long := hyphenate(template)
	if long {
		return template + "\n\n", nil
	}
	return template + "\n", nil
}

// Render a template string with no hyphenation
func (tr *templateRenderer) renderRaw(template string) (string, error) {
	expandMap := func(key string) string {
		for item := range tr.tempdefs {
			if key == tr.tempdefs[item].key {
				return tr.tempdefs[item].stringer.String()
			}
		}
		return fmt.Sprintf("[%%KEY_NOT_FOUND:%s]", key)
	}
	return os.Expand(template, expandMap), nil
}

// Renders a status line with username + content + media descriptions
type standardStatus struct {
	*templateRenderer
	hidespoilers bool
}

func (ss *standardStatus) String() string {
	if ss.hidespoilers {
		line, _ := ss.renderRaw("$index $username $subject_or_content $media_descriptions")
		return line
	}
	line, _ := ss.renderRaw("$index $username $content $media_descriptions")
	return line
}

// Renders a status line for a reblog
type standardReblog struct {
	*templateRenderer
}

func (ss *standardReblog) String() string {
	line, _ := ss.renderRaw("$username Reblogged $index $boostuser $boostcontent $boosted_media_descriptions")
	return line
}

// Renders a status notification line
type statusNotification struct {
	*templateRenderer
}

func (sn *statusNotification) String() string {
	line, _ := sn.renderRaw("$notif_type from $notif_user: $standard_status")
	return line
}

type otherNotification struct {
	*templateRenderer
}

func (on *otherNotification) String() string {
	line, _ := on.renderRaw("$notif_type from $notif_user")
	return line
}