all repos — htmlformat @ 314e0256b2b643fbd8acbea6c722fceecc102050

Go package and CLI tool used to format HTML

feat: skip formatting scripts (#3) * feat: skip formatting scripts * chore: fix up after PR

Adrian Hesketh
commit

314e0256b2b643fbd8acbea6c722fceecc102050

parent

1244374b2562d411222e82377bf11c1b84ea532d

5 files changed, 30 insertions(+), 67 deletions(-)

changed files
A .gitignore
@@ -0,0 +1,1 @@
+coverage.out
M format.goformat.go
@@ -36,70 +36,13 @@
// Nodes formats a slice of HTML nodes. func Nodes(w io.Writer, nodes []*html.Node) (err error) { for _, node := range nodes { - if err = printNode(w, node, 0); err != nil { + if err = printNode(w, node, false, 0); err != nil { return } } return } -// The <pre> tag indicates that the text within it should always be formatted -// as is. See https://github.com/ericchiang/pup/issues/33 -func printPre(w io.Writer, n *html.Node) (err error) { - switch n.Type { - case html.TextNode: - s := n.Data - if _, err = fmt.Fprint(w, s); err != nil { - return - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - if err = printPre(w, c); err != nil { - return - } - } - case html.ElementNode: - if _, err = fmt.Fprintf(w, "<%s", n.Data); err != nil { - return - } - for _, a := range n.Attr { - val := html.EscapeString(a.Val) - if _, err = fmt.Fprintf(w, ` %s="%s"`, a.Key, val); err != nil { - return - } - } - if _, err = fmt.Fprint(w, ">"); err != nil { - return - } - if !isVoidElement(n) { - for c := n.FirstChild; c != nil; c = c.NextSibling { - if err = printPre(w, c); err != nil { - return - } - } - if _, err = fmt.Fprintf(w, "</%s>", n.Data); err != nil { - return - } - } - case html.CommentNode: - data := n.Data - if _, err = fmt.Fprintf(w, "<!--%s-->\n", data); err != nil { - return - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - if err = printPre(w, c); err != nil { - return - } - } - case html.DoctypeNode, html.DocumentNode: - for c := n.FirstChild; c != nil; c = c.NextSibling { - if err = printPre(w, c); err != nil { - return - } - } - } - return -} - // Is this node a tag with no end tag such as <meta> or <br>? // http://www.w3.org/TR/html-markup/syntax.html#syntax-elements func isVoidElement(n *html.Node) bool {
@@ -136,9 +79,15 @@ func hasSingleTextChild(n *html.Node) bool {
return n != nil && n.FirstChild != nil && n.FirstChild == n.LastChild && n.FirstChild.Type == html.TextNode } -func printNode(w io.Writer, n *html.Node, level int) (err error) { +func printNode(w io.Writer, n *html.Node, pre bool, level int) (err error) { switch n.Type { case html.TextNode: + if pre { + if _, err = fmt.Fprint(w, n.Data); err != nil { + return + } + return nil + } s := n.Data s = strings.TrimSpace(s) if s != "" {
@@ -201,7 +150,7 @@ return
} } if !isVoidElement(n) { - if err = printChildren(w, n, level+1); err != nil { + if err = printChildren(w, n, isPreFormatted(n.Data), level+1); err != nil { return } if isSpecialContentElement(n) || !hasSingleTextChild(n) {
@@ -227,21 +176,25 @@ }
if _, err = fmt.Fprintf(w, "<!--%s-->\n", n.Data); err != nil { return } - if err = printChildren(w, n, level); err != nil { + if err = printChildren(w, n, false, level); err != nil { return } case html.DoctypeNode, html.DocumentNode: - if err = printChildren(w, n, level); err != nil { + if err = printChildren(w, n, false, level); err != nil { return } } return } -func printChildren(w io.Writer, n *html.Node, level int) (err error) { +func isPreFormatted(s string) bool { + return s == "pre" || s == "script" || s == "style" +} + +func printChildren(w io.Writer, n *html.Node, pre bool, level int) (err error) { child := n.FirstChild for child != nil { - if err = printNode(w, child, level); err != nil { + if err = printNode(w, child, pre, level); err != nil { return } child = child.NextSibling
M format_test.goformat_test.go
@@ -53,6 +53,15 @@ input: `test 123`,
expected: `test 123` + "\n", }, { + name: "script tags are not formatted", + input: `<script> + var x = 1; +</script>`, + expected: `<script> + var x = 1; +</script>` + "\n", + }, + { name: "phrasing content element children are kept on the same line, including punctuation", input: `<ul><li><a href="http://example.com">Test</a>.</li></ul>`, expected: `<ul>
M go.modgo.mod
@@ -2,6 +2,6 @@ module github.com/a-h/htmlformat
go 1.20 -require golang.org/x/net v0.17.0 +require golang.org/x/net v0.34.0 require github.com/google/go-cmp v0.6.0
M go.sumgo.sum
@@ -1,4 +1,4 @@
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=