From 643623dbecdc1ccb6f3ac77e4ebabdc6ca1d8d06 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sat, 2 Sep 2023 18:49:53 +0200 Subject: Genesis commit --- formatter/formatter.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 formatter/formatter.go (limited to 'formatter') diff --git a/formatter/formatter.go b/formatter/formatter.go new file mode 100644 index 0000000..96e19d1 --- /dev/null +++ b/formatter/formatter.go @@ -0,0 +1,104 @@ +package formatter + +import ( + "fmt" + "unicode" + + "git.thomasvoss.com/gsp/parser" +) + +var stringEscapes = map[rune]string{ + '"': """, + '&': "&", + '<': "<", +} + +func PrintHtml(ast parser.AstNode) { + if ast.Type == parser.Text { + fmt.Print(ast.Text) + return + } + + if ast.Type == parser.Normal { + fmt.Printf("<%s", ast.Text) + + // Classes are grouped together with ‘class="…"’, so we need + // special handling. + classes := []string{} + notClasses := []parser.Attr{} + + for _, a := range ast.Attrs { + if a.Key == "class" { + classes = append(classes, a.Value) + } else { + notClasses = append(notClasses, a) + } + } + + if len(classes) > 0 { + fmt.Printf(" class=\"%s", classes[0]) + for _, c := range classes[1:] { + fmt.Printf(" %s", c) + } + fmt.Print("\"") + } + + for _, a := range notClasses { + fmt.Printf(" %s", a.Key) + if a.Value == "" { + break + } + fmt.Print("=\"") + for _, r := range a.Value { + if v, ok := stringEscapes[r]; ok { + fmt.Print(v) + } else { + fmt.Printf("%c", r) + } + } + fmt.Print("\"") + } + + fmt.Print(">") + } + + if len(ast.Children) == 0 { + return + } + + for i, n := range ast.Children { + if n.Type == parser.Text { + if i == 0 { + n.Text = trimLeftSpaces(n.Text) + } + + if i == len(ast.Children)-1 { + n.Text = trimRightSpaces(n.Text) + } + } + + PrintHtml(n) + } + + if ast.Type == parser.Normal { + fmt.Printf("", ast.Text) + } +} + +func trimLeftSpaces(s string) string { + i := 0 + rs := []rune(s) + for i < len(s) && unicode.IsSpace(rs[i]) { + i++ + } + return string(rs[i:]) +} + +func trimRightSpaces(s string) string { + rs := []rune(s) + i := len(rs) - 1 + for i >= 0 && unicode.IsSpace(rs[i]) { + i-- + } + return string(rs[:i+1]) +} -- cgit v1.2.3