1// Package printer implements printing of AST nodes to HCL format.
2package printer
3
4import (
5	"bytes"
6	"io"
7	"text/tabwriter"
8
9	"github.com/hashicorp/hcl/hcl/ast"
10	"github.com/hashicorp/hcl/hcl/parser"
11)
12
13var DefaultConfig = Config{
14	SpacesWidth: 2,
15}
16
17// A Config node controls the output of Fprint.
18type Config struct {
19	SpacesWidth int // if set, it will use spaces instead of tabs for alignment
20}
21
22func (c *Config) Fprint(output io.Writer, node ast.Node) error {
23	p := &printer{
24		cfg:                *c,
25		comments:           make([]*ast.CommentGroup, 0),
26		standaloneComments: make([]*ast.CommentGroup, 0),
27		// enableTrace:        true,
28	}
29
30	p.collectComments(node)
31
32	if _, err := output.Write(p.unindent(p.output(node))); err != nil {
33		return err
34	}
35
36	// flush tabwriter, if any
37	var err error
38	if tw, _ := output.(*tabwriter.Writer); tw != nil {
39		err = tw.Flush()
40	}
41
42	return err
43}
44
45// Fprint "pretty-prints" an HCL node to output
46// It calls Config.Fprint with default settings.
47func Fprint(output io.Writer, node ast.Node) error {
48	return DefaultConfig.Fprint(output, node)
49}
50
51// Format formats src HCL and returns the result.
52func Format(src []byte) ([]byte, error) {
53	node, err := parser.Parse(src)
54	if err != nil {
55		return nil, err
56	}
57
58	var buf bytes.Buffer
59	if err := DefaultConfig.Fprint(&buf, node); err != nil {
60		return nil, err
61	}
62
63	// Add trailing newline to result
64	buf.WriteString("\n")
65	return buf.Bytes(), nil
66}
67