-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Description
I'd like to propose adding a new node to text/template similar to {{range pipeline}} named {{table pipeline}}. Inspired by Docker CLI's pseudo-function to format an array using text/tabwriter, this could be a generally useful way to format an array as columnar data using elastic tabstops.
As noted in cli/cli#3488 (comment), Docker CLI checks if the template starts with "table" and does some simple string pre-parsing. The inherent problem is that the template must start with "table", so you can't first scope a pipeline with {{with pipeline}}, for example. You can't really do this wthin a string either because you need to know where the table columns should end, and only parse tree nodes have {{end}}.
I propose (and interested in contributing) something like range that works on an array, but lets you delimit columns like so:
nodes := []struct{
Nodes []struct{
Id string
Name string
}
Description string
}{
// ...
}
template.Must(template.New("main").Parse(`{{table .Nodes}}{{.Id}}{{"\t"}}{{.Name}}{{end}}`)).Execute(os.Stdout, nodes)This would product output like:
123 Foo
4567 Bar
8 Baz
The {{end}} node would call Writer.Flush which should effectively set the final tabstops.
Ideally, it would be great to provide some control over tabwriter.NewWriter's arguments. Perhaps {{table}} could support variadic ...[]string arguments to set a few options, but columns can help support that on their own, like a user-defined pad function that prefixes or suffixes padding characters like "..", changing colors, etc. Another option might be to emit a header using the same tabstops so the headers align with the columns, much like Docker CLI does with their pseudo-function.