aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2023-09-11 01:28:54 +0200
committerThomas Voss <mail@thomasvoss.com> 2023-09-11 01:28:54 +0200
commit1e49191f5afab7fed8a3f162c9b7e672225c2fdc (patch)
tree91c794108d6296229974b10b207024f3e65edad4
parent340f5e45f3251a11830af844fd85f8934b90cf79 (diff)
Add the ‘>’ node modifier
-rw-r--r--formatter/formatter.go4
-rw-r--r--gsp.532
-rw-r--r--parser/parser.go58
3 files changed, 65 insertions, 29 deletions
diff --git a/formatter/formatter.go b/formatter/formatter.go
index 7c80b96..157b0ab 100644
--- a/formatter/formatter.go
+++ b/formatter/formatter.go
@@ -36,6 +36,10 @@ func PrintAst(ast parser.AstNode) {
printChildren(ast.Children)
fmt.Printf("</%s>", ast.Text)
}
+
+ if ast.Newline {
+ fmt.Print("\n")
+ }
case parser.Tagless:
printChildren(ast.Children)
}
diff --git a/gsp.5 b/gsp.5
index 87b1af8..c6678be 100644
--- a/gsp.5
+++ b/gsp.5
@@ -209,7 +209,7 @@ After
<foo><bar>Hello World</bar><baz>Hello World</baz></foo>
.Ed
.Pp
-The one exception to this use is when using embedded nodes.
+One exception to this use is when using embedded nodes.
If your literal text contains an embedded node, then whitespace around the node
is preserved:
.Bd -literal -offset indent
@@ -225,8 +225,8 @@ After
<foo>Hello <bar>there</bar> world!</foo>
.Ed
.Pp
-Therefore if you would like to remove the whitespace, you need to manually
-compact your document:
+Therefore if you would like to remove the whitespace when working with literal
+text, you need to manually compact your document:
.Bd -literal -offset indent
Before
@@ -239,6 +239,32 @@ After
<foo>Hello<bar>there</bar>world!</foo>
.Ed
+.Pp
+Sometimes it is also useful to have a newline between nodes, especially when
+working with
+.Sq code
+tags nested within a
+.Sq pre
+tag.
+To specify that you want a newline to be placed after a node, you can prefix the
+node name with a greater-than symbol
+.Pq Sq > :
+.Bd -literal -offset indent
+Before
+
+pre {
+ >code {-foo}
+ >code {-bar}
+ code {-baz}
+}
+.Ed
+.Bd -literal -offset indent
+After
+
+<pre><code>foo</code>
+<code>bar</code>
+<code>baz</code></pre>
+.Ed
.Sh SEE ALSO
.Xr gsp 1
.Pp
diff --git a/parser/parser.go b/parser/parser.go
index 4b9625d..f55a135 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -27,6 +27,7 @@ type AstNode struct {
Text string
Attrs []Attr
Children []AstNode
+ Newline bool
}
func ParseFile(file *os.File) (AstNode, error) {
@@ -54,64 +55,69 @@ func ParseFile(file *os.File) (AstNode, error) {
}
}
-func (reader *reader) parseNode() (AstNode, error) {
- if err := reader.skipSpaces(); err != nil {
- return AstNode{}, err
+func (reader *reader) parseNode() (node AstNode, err error) {
+ if err = reader.skipSpaces(); err != nil {
+ return
}
- if r, err := reader.peekRune(); err != nil {
- return AstNode{}, err
- } else if r == '-' {
+ r, err := reader.peekRune()
+ if err != nil {
+ return
+ }
+
+ switch r {
+ case '-':
return reader.parseText()
+ case '>':
+ node.Newline = true
+ if _, err = reader.readRune(); err != nil {
+ return
+ }
}
- node := AstNode{}
- if name, err := reader.parseNodeName(); err != nil {
- return AstNode{}, err
+ if node.Text, err = reader.parseNodeName(); err != nil {
+ return
} else {
node.Type = Normal
- node.Text = name
}
- if attrs, err := reader.parseAttrs(); err != nil {
- return AstNode{}, err
- } else {
- node.Attrs = attrs
+ if node.Attrs, err = reader.parseAttrs(); err != nil {
+ return
}
// The above call to reader.parseAttrs() guarantees that we have the ‘{’
// token.
- if _, err := reader.readRune(); err != nil {
- return AstNode{}, err
+ if _, err = reader.readRune(); err != nil {
+ return
}
loop:
for {
- if err := reader.skipSpaces(); err != nil {
- return AstNode{}, err
+ if err = reader.skipSpaces(); err != nil {
+ return
}
- if r, err := reader.peekRune(); err == io.EOF {
+ if r, err = reader.peekRune(); err == io.EOF {
return AstNode{}, eof{}
} else if err != nil {
- return AstNode{}, err
+ return
} else if r == '}' {
break loop
}
- if n, err := reader.parseNode(); err != nil {
- return AstNode{}, err
+ var n AstNode
+ if n, err = reader.parseNode(); err != nil {
+ return
} else {
node.Children = append(node.Children, n)
}
}
// The above loop guarantees that we have the ‘}’ token.
- if _, err := reader.readRune(); err != nil {
- return AstNode{}, err
+ if _, err = reader.readRune(); err != nil {
+ return
}
-
- return node, nil
+ return
}
func (reader *reader) parseNodeName() (string, error) {