-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmd_file.go
58 lines (47 loc) · 1.59 KB
/
md_file.go
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
package mdfile
import (
"bytes"
"errors"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/hcl/v2/hclwrite"
"gopkg.in/russross/blackfriday.v2"
)
type MdFile interface {
FmtHclCodeInMd() ([]byte, error)
}
type impleMdFile struct {
md *[]byte
filename string
}
func NewMdFile(md *[]byte, filename string) MdFile {
return &impleMdFile{md: md, filename: filename}
}
// FmtHclCodeInMd formats HCL code in Markdown.
// returns error if code has syntax error.
func (i impleMdFile) FmtHclCodeInMd() ([]byte, error) {
var synerr error
n := blackfriday.New(blackfriday.WithExtensions(blackfriday.FencedCode)).Parse(*i.md)
n.Walk(i.hclFmtWalkerFunc(&synerr))
if synerr != nil {
return nil, synerr
}
return *i.md, nil
}
func (i impleMdFile) isHclCodeBlock(node *blackfriday.Node) bool {
return node.Type == blackfriday.CodeBlock && (string(node.CodeBlockData.Info) == "hcl" || string(node.CodeBlockData.Info) == "hcl-terraform")
}
func (i impleMdFile) hclFmtWalkerFunc(synerr *error) blackfriday.NodeVisitor {
return func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
if i.isHclCodeBlock(node) {
_, syntaxDiags := hclsyntax.ParseConfig(node.Literal, i.filename, hcl.Pos{Line: 1, Column: 1})
if syntaxDiags.HasErrors() {
*synerr = errors.New("[tffmtmd] failed to format hcl source code. Please check syntax")
return blackfriday.Terminate
}
result := hclwrite.Format(node.Literal)
*i.md = bytes.ReplaceAll(*i.md, bytes.TrimRight(node.Literal, "\n"), bytes.TrimRight(result, "\n"))
}
return blackfriday.GoToNext
}
}