File: template.go

package info (click to toggle)
golang-github-alecaivazis-survey 2.3.6%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-backports
  • size: 636 kB
  • sloc: makefile: 12
file content (91 lines) | stat: -rw-r--r-- 2,497 bytes parent folder | download
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package core

import (
	"bytes"
	"sync"
	"text/template"

	"github.com/mgutz/ansi"
)

// DisableColor can be used to make testing reliable
var DisableColor = false

var TemplateFuncsWithColor = map[string]interface{}{
	// Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
	"color": ansi.ColorCode,
}

var TemplateFuncsNoColor = map[string]interface{}{
	// Templates without Color formatting. For layout/ testing.
	"color": func(color string) string {
		return ""
	},
}

//RunTemplate returns two formatted strings given a template and
//the data it requires. The first string returned is generated for
//user-facing output and may or may not contain ANSI escape codes
//for colored output. The second string does not contain escape codes
//and can be used by the renderer for layout purposes.
func RunTemplate(tmpl string, data interface{}) (string, string, error) {
	tPair, err := GetTemplatePair(tmpl)
	if err != nil {
		return "", "", err
	}
	userBuf := bytes.NewBufferString("")
	err = tPair[0].Execute(userBuf, data)
	if err != nil {
		return "", "", err
	}
	layoutBuf := bytes.NewBufferString("")
	err = tPair[1].Execute(layoutBuf, data)
	if err != nil {
		return userBuf.String(), "", err
	}
	return userBuf.String(), layoutBuf.String(), err
}

var (
	memoizedGetTemplate = map[string][2]*template.Template{}

	memoMutex = &sync.RWMutex{}
)

//GetTemplatePair returns a pair of compiled templates where the
//first template is generated for user-facing output and the
//second is generated for use by the renderer. The second
//template does not contain any color escape codes, whereas
//the first template may or may not depending on DisableColor.
func GetTemplatePair(tmpl string) ([2]*template.Template, error) {
	memoMutex.RLock()
	if t, ok := memoizedGetTemplate[tmpl]; ok {
		memoMutex.RUnlock()
		return t, nil
	}
	memoMutex.RUnlock()

	templatePair := [2]*template.Template{nil, nil}

	templateNoColor, err := template.New("prompt").Funcs(TemplateFuncsNoColor).Parse(tmpl)
	if err != nil {
		return [2]*template.Template{}, err
	}

	templatePair[1] = templateNoColor

	if DisableColor {
		templatePair[0] = templatePair[1]
	} else {
		templateWithColor, err := template.New("prompt").Funcs(TemplateFuncsWithColor).Parse(tmpl)
		templatePair[0] = templateWithColor
		if err != nil {
			return [2]*template.Template{}, err
		}
	}

	memoMutex.Lock()
	memoizedGetTemplate[tmpl] = templatePair
	memoMutex.Unlock()
	return templatePair, nil
}