2015-10-16 20:22:28 +00:00
|
|
|
package printer
|
2015-10-03 00:30:57 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"text/tabwriter"
|
|
|
|
|
2015-10-24 21:04:31 +00:00
|
|
|
"github.com/fatih/hcl/ast"
|
2015-10-03 00:30:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type printer struct {
|
2015-10-24 22:23:50 +00:00
|
|
|
out []byte // raw printer result
|
2015-10-24 21:04:31 +00:00
|
|
|
cfg Config
|
|
|
|
node ast.Node
|
2015-10-03 00:30:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *printer) output() []byte {
|
|
|
|
fmt.Println("STARTING OUTPUT")
|
2015-10-24 22:23:50 +00:00
|
|
|
return p.printNode(p.node)
|
2015-10-03 00:30:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// A Mode value is a set of flags (or 0). They control printing.
|
|
|
|
type Mode uint
|
|
|
|
|
|
|
|
const (
|
|
|
|
RawFormat Mode = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored
|
|
|
|
TabIndent // use tabs for indentation independent of UseSpaces
|
|
|
|
UseSpaces // use spaces instead of tabs for alignment
|
|
|
|
)
|
|
|
|
|
|
|
|
// A Config node controls the output of Fprint.
|
|
|
|
type Config struct {
|
|
|
|
Mode Mode // default: 0
|
2015-10-24 22:23:50 +00:00
|
|
|
Tabwidth int // default: 4
|
2015-10-03 00:30:57 +00:00
|
|
|
Indent int // default: 0 (all code is indented at least by this much)
|
|
|
|
}
|
|
|
|
|
2015-10-24 21:04:31 +00:00
|
|
|
func (c *Config) fprint(output io.Writer, node ast.Node) error {
|
2015-10-03 00:30:57 +00:00
|
|
|
p := &printer{
|
2015-10-24 21:04:31 +00:00
|
|
|
cfg: *c,
|
|
|
|
node: node,
|
2015-10-03 00:30:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(arslan): implement this
|
|
|
|
// redirect output through a trimmer to eliminate trailing whitespace
|
|
|
|
// (Input to a tabwriter must be untrimmed since trailing tabs provide
|
|
|
|
// formatting information. The tabwriter could provide trimming
|
|
|
|
// functionality but no tabwriter is used when RawFormat is set.)
|
|
|
|
// output = &trimmer{output: output}
|
|
|
|
|
|
|
|
// redirect output through a tabwriter if necessary
|
|
|
|
if c.Mode&RawFormat == 0 {
|
|
|
|
minwidth := c.Tabwidth
|
|
|
|
|
|
|
|
padchar := byte('\t')
|
|
|
|
if c.Mode&UseSpaces != 0 {
|
|
|
|
padchar = ' '
|
|
|
|
}
|
|
|
|
|
|
|
|
twmode := tabwriter.DiscardEmptyColumns
|
|
|
|
if c.Mode&TabIndent != 0 {
|
|
|
|
minwidth = 0
|
|
|
|
twmode |= tabwriter.TabIndent
|
|
|
|
}
|
|
|
|
|
|
|
|
output = tabwriter.NewWriter(output, minwidth, c.Tabwidth, 1, padchar, twmode)
|
|
|
|
}
|
|
|
|
|
|
|
|
// write printer result via tabwriter/trimmer to output
|
|
|
|
if _, err := output.Write(p.output()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// flush tabwriter, if any
|
|
|
|
var err error
|
|
|
|
if tw, _ := output.(*tabwriter.Writer); tw != nil {
|
|
|
|
err = tw.Flush()
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2015-10-24 21:04:31 +00:00
|
|
|
func (c *Config) Fprint(output io.Writer, node ast.Node) error {
|
|
|
|
return c.fprint(output, node)
|
2015-10-03 00:30:57 +00:00
|
|
|
}
|
|
|
|
|
2015-10-24 21:04:31 +00:00
|
|
|
// Fprint "pretty-prints" an HCL node to output
|
2015-10-03 00:30:57 +00:00
|
|
|
// It calls Config.Fprint with default settings.
|
2015-10-24 21:04:31 +00:00
|
|
|
func Fprint(output io.Writer, node ast.Node) error {
|
2015-10-24 22:23:50 +00:00
|
|
|
return (&Config{Tabwidth: 4}).Fprint(output, node)
|
2015-10-03 00:30:57 +00:00
|
|
|
}
|