printer/templateprinter.go
author Mikael Berthe <mikael@lilotux.net>
Thu, 22 Sep 2022 16:32:45 +0200
changeset 261 270cc4dda0c5
parent 239 605a00e9d1ab
child 265 05c40b36d3b2
permissions -rw-r--r--
Change version to 2.4.0-dev
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// Copyright © 2017 Mikael Berthe <mikael@lilotux.net>
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
//
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
// Licensed under the MIT license.
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
// Please see the LICENSE file is this directory.
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
package printer
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
import (
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
	"encoding/json"
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
	"fmt"
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
	"io"
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
	"os"
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
	"reflect"
93
1cef5da83488 Add template functions trim and wrap
Mikael Berthe <mikael@lilotux.net>
parents: 90
diff changeset
    14
	"strings"
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
	"text/template"
120
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
    16
	"time"
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
124
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
    18
	"github.com/kr/text"
50
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
    19
	"github.com/mattn/go-isatty"
40
ad148f60dc87 TemplatePrinter: Handle InstanceStatus lists
Mikael Berthe <mikael@lilotux.net>
parents: 14
diff changeset
    20
239
605a00e9d1ab Switch to Go modules (and bump Go version requirement)
Mikael Berthe <mikael@lilotux.net>
parents: 194
diff changeset
    21
	"github.com/McKael/madon/v2"
49
d6b4e3b7c6c6 Add ANSI color support to templates (function "color")
Mikael Berthe <mikael@lilotux.net>
parents: 41
diff changeset
    22
	"github.com/McKael/madonctl/printer/colors"
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
51
300ac09051a7 Add ability to force colors: option --color=auto|on|off
Mikael Berthe <mikael@lilotux.net>
parents: 50
diff changeset
    25
// disableColors can be set to true to disable the color template function
300ac09051a7 Add ability to force colors: option --color=auto|on|off
Mikael Berthe <mikael@lilotux.net>
parents: 50
diff changeset
    26
var disableColors bool
50
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
    27
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
// TemplatePrinter represents a Template printer
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
type TemplatePrinter struct {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	rawTemplate string
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
	template    *template.Template
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
// NewPrinterTemplate returns a Template ResourcePrinter
83
57afac822019 Use a map for ResourcePrinter options
Mikael Berthe <mikael@lilotux.net>
parents: 51
diff changeset
    35
// For TemplatePrinter, the options parameter contains the template string.
89
3758bb5f0979 ResourcePrinter (templates): Use options to pass color_mode
Mikael Berthe <mikael@lilotux.net>
parents: 85
diff changeset
    36
// The "color_mode" option defines the color behaviour: it can be
3758bb5f0979 ResourcePrinter (templates): Use options to pass color_mode
Mikael Berthe <mikael@lilotux.net>
parents: 85
diff changeset
    37
// "auto" (default), "on" (forced), "off" (disabled).
83
57afac822019 Use a map for ResourcePrinter options
Mikael Berthe <mikael@lilotux.net>
parents: 51
diff changeset
    38
func NewPrinterTemplate(options Options) (*TemplatePrinter, error) {
57afac822019 Use a map for ResourcePrinter options
Mikael Berthe <mikael@lilotux.net>
parents: 51
diff changeset
    39
	tmpl := options["template"]
85
a4464c0b0c36 Add theme support
Mikael Berthe <mikael@lilotux.net>
parents: 83
diff changeset
    40
	if tmpl == "" {
a4464c0b0c36 Add theme support
Mikael Berthe <mikael@lilotux.net>
parents: 83
diff changeset
    41
		return nil, fmt.Errorf("empty template")
a4464c0b0c36 Add theme support
Mikael Berthe <mikael@lilotux.net>
parents: 83
diff changeset
    42
	}
41
909c3ddd83f6 Add fromunix filter to templates (converts date from UNIX timestamp)
Mikael Berthe <mikael@lilotux.net>
parents: 40
diff changeset
    43
	t, err := template.New("output").Funcs(template.FuncMap{
909c3ddd83f6 Add fromunix filter to templates (converts date from UNIX timestamp)
Mikael Berthe <mikael@lilotux.net>
parents: 40
diff changeset
    44
		"fromhtml": html2string,
120
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
    45
		"fromunix": unix2time,
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
    46
		"tolocal":  dateToLocal,
50
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
    47
		"color":    ansiColor,
93
1cef5da83488 Add template functions trim and wrap
Mikael Berthe <mikael@lilotux.net>
parents: 90
diff changeset
    48
		"trim":     strings.TrimSpace,
1cef5da83488 Add template functions trim and wrap
Mikael Berthe <mikael@lilotux.net>
parents: 90
diff changeset
    49
		"wrap":     wrap,
41
909c3ddd83f6 Add fromunix filter to templates (converts date from UNIX timestamp)
Mikael Berthe <mikael@lilotux.net>
parents: 40
diff changeset
    50
	}).Parse(tmpl)
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
	if err != nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
		return nil, err
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
	}
50
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
    54
51
300ac09051a7 Add ability to force colors: option --color=auto|on|off
Mikael Berthe <mikael@lilotux.net>
parents: 50
diff changeset
    55
	// Update disableColors.
300ac09051a7 Add ability to force colors: option --color=auto|on|off
Mikael Berthe <mikael@lilotux.net>
parents: 50
diff changeset
    56
	// In auto-mode, check if stdout is a TTY.
89
3758bb5f0979 ResourcePrinter (templates): Use options to pass color_mode
Mikael Berthe <mikael@lilotux.net>
parents: 85
diff changeset
    57
	colorMode := options["color_mode"]
3758bb5f0979 ResourcePrinter (templates): Use options to pass color_mode
Mikael Berthe <mikael@lilotux.net>
parents: 85
diff changeset
    58
	if colorMode == "off" || (colorMode != "on" && !isatty.IsTerminal(os.Stdout.Fd())) {
51
300ac09051a7 Add ability to force colors: option --color=auto|on|off
Mikael Berthe <mikael@lilotux.net>
parents: 50
diff changeset
    59
		disableColors = true
50
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
    60
	}
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
    61
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
	return &TemplatePrinter{
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
		rawTemplate: tmpl,
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
		template:    t,
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
	}, nil
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
// PrintObj sends the object as text to the writer
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
// If the writer w is nil, standard output will be used.
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
func (p *TemplatePrinter) PrintObj(obj interface{}, w io.Writer, tmpl string) error {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
	if w == nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
		w = os.Stdout
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
	if p.template == nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
		return fmt.Errorf("template not built")
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
	switch ot := obj.(type) { // I wish I knew a better way...
193
4a1e3b57fd0f Themes & Templates: Add new types
Mikael Berthe <mikael@lilotux.net>
parents: 124
diff changeset
    80
	case []madon.Account, []madon.Application, []madon.Attachment,
4a1e3b57fd0f Themes & Templates: Add new types
Mikael Berthe <mikael@lilotux.net>
parents: 124
diff changeset
    81
		[]madon.Card, []madon.Client, []madon.Context, []madon.Emoji,
4a1e3b57fd0f Themes & Templates: Add new types
Mikael Berthe <mikael@lilotux.net>
parents: 124
diff changeset
    82
		[]madon.Instance, []madon.List, []madon.Mention,
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
		[]madon.Notification, []madon.Relationship, []madon.Report,
193
4a1e3b57fd0f Themes & Templates: Add new types
Mikael Berthe <mikael@lilotux.net>
parents: 124
diff changeset
    84
		[]madon.Results, []madon.Status, []madon.StreamEvent,
194
660233815ca8 Printers: Remove previous instance statistics
Mikael Berthe <mikael@lilotux.net>
parents: 193
diff changeset
    85
		[]madon.Tag, []string:
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
		return p.templateForeach(ot, w)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
	return p.templatePrintSingleObj(obj, w)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
func (p *TemplatePrinter) templatePrintSingleObj(obj interface{}, w io.Writer) error {
90
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
    93
	if s, ok := obj.(string); ok {
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
    94
		// obj is a simple string
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
    95
		if err := p.safeExecute(w, s); err != nil {
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
    96
			return fmt.Errorf("error executing template %q: %v", p.rawTemplate, err)
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
    97
		}
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
    98
		return nil
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
    99
	}
b1da6dc9f689 TemplatePrinter: Add support for string objects
Mikael Berthe <mikael@lilotux.net>
parents: 89
diff changeset
   100
0
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
	// This code comes from Kubernetes.
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
	data, err := json.Marshal(obj)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
	if err != nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
		return err
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	out := map[string]interface{}{}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	if err := json.Unmarshal(data, &out); err != nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
		return err
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
	if err = p.safeExecute(w, out); err != nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
		return fmt.Errorf("error executing template %q: %v", p.rawTemplate, err)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	return nil
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
// safeExecute tries to execute the template, but catches panics and returns an error
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
// should the template engine panic.
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
// This code comes from Kubernetes.
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
func (p *TemplatePrinter) safeExecute(w io.Writer, obj interface{}) error {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	var panicErr error
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
	// Sorry for the double anonymous function. There's probably a clever way
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
	// to do this that has the defer'd func setting the value to be returned, but
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
	// that would be even less obvious.
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
	retErr := func() error {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
		defer func() {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
			if x := recover(); x != nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
				panicErr = fmt.Errorf("caught panic: %+v", x)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
			}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
		}()
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
		return p.template.Execute(w, obj)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
	}()
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
	if panicErr != nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
		return panicErr
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
	return retErr
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
func (p *TemplatePrinter) templateForeach(ol interface{}, w io.Writer) error {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
	switch reflect.TypeOf(ol).Kind() {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	case reflect.Slice:
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
		s := reflect.ValueOf(ol)
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
		for i := 0; i < s.Len(); i++ {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
			o := s.Index(i).Interface()
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
			if err := p.templatePrintSingleObj(o, w); err != nil {
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
				return err
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
			}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
		}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
	}
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
	return nil
5abace724584 Initial public release
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
}
50
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
   152
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
   153
func ansiColor(desc string) (string, error) {
51
300ac09051a7 Add ability to force colors: option --color=auto|on|off
Mikael Berthe <mikael@lilotux.net>
parents: 50
diff changeset
   154
	if disableColors {
50
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
   155
		return "", nil
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
   156
	}
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
   157
	return colors.ANSICodeString(desc)
c6adf9d9e996 Disable ANSI sequences when stdout is not a TTY
Mikael Berthe <mikael@lilotux.net>
parents: 49
diff changeset
   158
}
93
1cef5da83488 Add template functions trim and wrap
Mikael Berthe <mikael@lilotux.net>
parents: 90
diff changeset
   159
120
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   160
// Parse datetime string from RFC3339 (default format in templates because
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   161
// of implicit conversion to string) and return a local time.
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   162
func dateToLocal(s string) (time.Time, error) {
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   163
	t, err := time.Parse(time.RFC3339, s)
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   164
	if err != nil {
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   165
		return t, err
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   166
	}
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   167
	return t.Local(), err
54b6f2a4098b Add template command tolocal; update templates and documentation
Mikael Berthe <mikael@lilotux.net>
parents: 93
diff changeset
   168
}
124
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   169
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   170
// Wrap text with indent prefix
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   171
func wrap(indent string, lineLength int, txt string) string {
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   172
	width := lineLength - len(indent)
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   173
	if width < 10 {
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   174
		width = 10
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   175
	}
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   176
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   177
	lines := strings.SplitAfter(txt, "\n")
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   178
	var out []string
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   179
	for _, l := range lines {
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   180
		l = strings.TrimLeft(l, " ")
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   181
		out = append(out, text.Indent(text.Wrap(l, width), indent))
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   182
	}
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   183
	return strings.Join(out, "\n")
20d514540f37 Improve text wrapping
Mikael Berthe <mikael@lilotux.net>
parents: 120
diff changeset
   184
}