diff --git a/.version b/.version
index 32cab653c..509a53ab2 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-0.2.543
\ No newline at end of file
+0.2.544
\ No newline at end of file
diff --git a/generator/generator.go b/generator/generator.go
index b772c1257..fd05d3f31 100644
--- a/generator/generator.go
+++ b/generator/generator.go
@@ -402,7 +402,7 @@ func (g *generator) writeTemplate(nodeIdx int, t parser.HTMLTemplate) error {
return err
}
// Nodes.
- if err = g.writeNodes(indentLevel, stripWhitespace(t.Children)); err != nil {
+ if err = g.writeNodes(indentLevel, stripWhitespace(t.Children), nil); err != nil {
return err
}
// Return the buffer.
@@ -479,13 +479,16 @@ func stripLeadingAndTrailingWhitespace(nodes []parser.Node) []parser.Node {
return stripTrailingWhitespace(stripLeadingWhitespace(nodes))
}
-func (g *generator) writeNodes(indentLevel int, nodes []parser.Node) error {
+func (g *generator) writeNodes(indentLevel int, nodes []parser.Node, next parser.Node) error {
for i, curr := range nodes {
- var next parser.Node
+ var nextNode parser.Node
if i+1 < len(nodes) {
- next = nodes[i+1]
+ nextNode = nodes[i+1]
}
- if err := g.writeNode(indentLevel, curr, next); err != nil {
+ if nextNode == nil {
+ nextNode = next
+ }
+ if err := g.writeNode(indentLevel, curr, nextNode); err != nil {
return err
}
}
@@ -505,15 +508,15 @@ func (g *generator) writeNode(indentLevel int, current parser.Node, next parser.
case parser.RawElement:
err = g.writeRawElement(indentLevel, n)
case parser.ForExpression:
- err = g.writeForExpression(indentLevel, n)
+ err = g.writeForExpression(indentLevel, n, next)
case parser.CallTemplateExpression:
err = g.writeCallTemplateExpression(indentLevel, n)
case parser.TemplElementExpression:
err = g.writeTemplElementExpression(indentLevel, n)
case parser.IfExpression:
- err = g.writeIfExpression(indentLevel, n)
+ err = g.writeIfExpression(indentLevel, n, next)
case parser.SwitchExpression:
- err = g.writeSwitchExpression(indentLevel, n)
+ err = g.writeSwitchExpression(indentLevel, n, next)
case parser.StringExpression:
err = g.writeStringExpression(indentLevel, n.Expression)
case parser.Whitespace:
@@ -583,7 +586,7 @@ func (g *generator) writeDocType(indentLevel int, n parser.DocType) (err error)
return nil
}
-func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (err error) {
+func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression, nextNode parser.Node) (err error) {
var r parser.Range
// if
if _, err = g.w.WriteIndent(indentLevel, `if `); err != nil {
@@ -600,7 +603,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
}
{
indentLevel++
- if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Then)); err != nil {
+ if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Then), nextNode); err != nil {
return err
}
indentLevel--
@@ -621,7 +624,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
}
{
indentLevel++
- if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(elseIf.Then)); err != nil {
+ if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(elseIf.Then), nextNode); err != nil {
return err
}
indentLevel--
@@ -634,7 +637,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
}
{
indentLevel++
- if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Else)); err != nil {
+ if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Else), nextNode); err != nil {
return err
}
indentLevel--
@@ -647,7 +650,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
return nil
}
-func (g *generator) writeSwitchExpression(indentLevel int, n parser.SwitchExpression) (err error) {
+func (g *generator) writeSwitchExpression(indentLevel int, n parser.SwitchExpression, next parser.Node) (err error) {
var r parser.Range
// switch
if _, err = g.w.WriteIndent(indentLevel, `switch `); err != nil {
@@ -672,7 +675,7 @@ func (g *generator) writeSwitchExpression(indentLevel int, n parser.SwitchExpres
}
g.sourceMap.Add(c.Expression, r)
indentLevel++
- if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(c.Children)); err != nil {
+ if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(c.Children), next); err != nil {
return err
}
indentLevel--
@@ -712,7 +715,7 @@ func (g *generator) writeBlockTemplElementExpression(indentLevel int, n parser.T
if err := g.writeTemplBuffer(indentLevel); err != nil {
return err
}
- if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children)); err != nil {
+ if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children), nil); err != nil {
return err
}
// Return the buffer.
@@ -795,7 +798,7 @@ func (g *generator) writeCallTemplateExpression(indentLevel int, n parser.CallTe
return nil
}
-func (g *generator) writeForExpression(indentLevel int, n parser.ForExpression) (err error) {
+func (g *generator) writeForExpression(indentLevel int, n parser.ForExpression, next parser.Node) (err error) {
var r parser.Range
// for
if _, err = g.w.WriteIndent(indentLevel, `for `); err != nil {
@@ -812,7 +815,7 @@ func (g *generator) writeForExpression(indentLevel int, n parser.ForExpression)
}
// Children.
indentLevel++
- if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children)); err != nil {
+ if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children), next); err != nil {
return err
}
indentLevel--
@@ -909,7 +912,7 @@ func (g *generator) writeStandardElement(indentLevel int, n parser.Element) (err
}
}
// Children.
- if err = g.writeNodes(indentLevel, stripWhitespace(n.Children)); err != nil {
+ if err = g.writeNodes(indentLevel, stripWhitespace(n.Children), nil); err != nil {
return err
}
//
diff --git a/generator/test-whitespace-around-go-keywords/render_test.go b/generator/test-whitespace-around-go-keywords/render_test.go
new file mode 100644
index 000000000..0628fdf5a
--- /dev/null
+++ b/generator/test-whitespace-around-go-keywords/render_test.go
@@ -0,0 +1,78 @@
+package testwhitespacearoundgokeywords
+
+import (
+ "context"
+ "strings"
+ "testing"
+
+ "github.com/a-h/templ"
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestTextWhitespace(t *testing.T) {
+ for _, test := range []struct {
+ name string
+ input templ.Component
+ expected string
+ }{
+ {
+ name: "whitespace is consistent in a true evaluated if statement",
+ input: WhitespaceIsConsistentInIf(true, false),
+ expected: WhitespaceIsConsistentInTrueIfExpected,
+ },
+ {
+ name: "whitespace is consistent in a true evaluated else if statement",
+ input: WhitespaceIsConsistentInIf(false, true),
+ expected: WhitespaceIsConsistentInTrueElseIfExpected,
+ },
+ {
+ name: "whitespace is consistent in a true evaluated else statement",
+ input: WhitespaceIsConsistentInIf(false, false),
+ expected: WhitespaceIsConsistentInTrueElseExpected,
+ },
+ {
+ name: "whitespace is consistent in a false evaluated if statement",
+ input: WhitespaceIsConsistentInFalseIf(),
+ expected: WhitespaceIsConsistentInFalseIfExpected,
+ },
+ {
+ name: "whitespace is consistent in a switch statment with a true case",
+ input: WhitespaceIsConsistentInSwitch(1),
+ expected: WhitespaceIsConsistentInOneSwitchExpected,
+ },
+ {
+ name: "whitespace is consistent in a switch statment with a default case",
+ input: WhitespaceIsConsistentInSwitch(2),
+ expected: WhitespaceIsConsistentInDefaultSwitchExpected,
+ },
+ {
+ name: "whitespace is consistent in a switch statment with no default case and no true cases",
+ input: WhitespaceIsConsistentInSwitchNoDefault(),
+ expected: WhitespaceIsConsistentInSwitchNoDefaultExpected,
+ },
+ {
+ name: "whitespace is consistent in a for statment that runs 0 times",
+ input: WhitespaceIsConsistentInFor(0),
+ expected: WhitespaceIsConsistentInForZeroExpected,
+ },
+ {
+ name: "whitespace is consistent in a for statment that runs 1 times",
+ input: WhitespaceIsConsistentInFor(1),
+ expected: WhitespaceIsConsistentInForOneExpected,
+ },
+ {
+ name: "whitespace is consistent in a for statment that runs 3 times",
+ input: WhitespaceIsConsistentInFor(3),
+ expected: WhitespaceIsConsistentInForThreeExpected,
+ },
+ } {
+ w := new(strings.Builder)
+ err := test.input.Render(context.Background(), w)
+ if err != nil {
+ t.Errorf("failed to render: %v", err)
+ }
+ if diff := cmp.Diff(test.expected, w.String()); diff != "" {
+ t.Error(diff)
+ }
+ }
+}
diff --git a/generator/test-whitespace-around-go-keywords/template.templ b/generator/test-whitespace-around-go-keywords/template.templ
new file mode 100644
index 000000000..91e137667
--- /dev/null
+++ b/generator/test-whitespace-around-go-keywords/template.templ
@@ -0,0 +1,66 @@
+package testwhitespacearoundgokeywords
+
+import "fmt"
+
+templ WhitespaceIsConsistentInIf(firstIf, secondIf bool) {
+
+ if firstIf {
+
+ } else if secondIf {
+
+ } else {
+
+ }
+
+}
+
+const WhitespaceIsConsistentInTrueIfExpected = ` `
+const WhitespaceIsConsistentInTrueElseIfExpected = ` `
+const WhitespaceIsConsistentInTrueElseExpected = ` `
+
+templ WhitespaceIsConsistentInFalseIf() {
+
+ if false {
+
+ }
+
+}
+
+const WhitespaceIsConsistentInFalseIfExpected = ` `
+
+templ WhitespaceIsConsistentInSwitch(i int) {
+
+ switch i {
+ case 1:
+
+ default:
+
+ }
+
+}
+
+const WhitespaceIsConsistentInOneSwitchExpected = ` `
+const WhitespaceIsConsistentInDefaultSwitchExpected = ` `
+
+templ WhitespaceIsConsistentInSwitchNoDefault() {
+
+ switch false {
+ case true:
+
+ }
+
+}
+
+const WhitespaceIsConsistentInSwitchNoDefaultExpected = ` `
+
+templ WhitespaceIsConsistentInFor(i int) {
+
+ for j := 0; j < i; j++ {
+
+ }
+
+}
+
+const WhitespaceIsConsistentInForZeroExpected = ` `
+const WhitespaceIsConsistentInForOneExpected = ` `
+const WhitespaceIsConsistentInForThreeExpected = ` `
diff --git a/generator/test-whitespace-around-go-keywords/template_templ.go b/generator/test-whitespace-around-go-keywords/template_templ.go
new file mode 100644
index 000000000..5ce5d1075
--- /dev/null
+++ b/generator/test-whitespace-around-go-keywords/template_templ.go
@@ -0,0 +1,380 @@
+// Code generated by templ - DO NOT EDIT.
+
+package testwhitespacearoundgokeywords
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import "context"
+import "io"
+import "bytes"
+
+import "fmt"
+
+func WhitespaceIsConsistentInIf(firstIf, secondIf bool) templ.Component {
+ return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
+ if !templ_7745c5c3_IsBuffer {
+ templ_7745c5c3_Buffer = templ.GetBuffer()
+ defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if firstIf {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ } else if secondIf {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ } else {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if !templ_7745c5c3_IsBuffer {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
+ }
+ return templ_7745c5c3_Err
+ })
+}
+
+const WhitespaceIsConsistentInTrueIfExpected = ` `
+const WhitespaceIsConsistentInTrueElseIfExpected = ` `
+const WhitespaceIsConsistentInTrueElseExpected = ` `
+
+func WhitespaceIsConsistentInFalseIf() templ.Component {
+ return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
+ if !templ_7745c5c3_IsBuffer {
+ templ_7745c5c3_Buffer = templ.GetBuffer()
+ defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var7 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var7 == nil {
+ templ_7745c5c3_Var7 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if false {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if !templ_7745c5c3_IsBuffer {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
+ }
+ return templ_7745c5c3_Err
+ })
+}
+
+const WhitespaceIsConsistentInFalseIfExpected = ` `
+
+func WhitespaceIsConsistentInSwitch(i int) templ.Component {
+ return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
+ if !templ_7745c5c3_IsBuffer {
+ templ_7745c5c3_Buffer = templ.GetBuffer()
+ defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var11 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var11 == nil {
+ templ_7745c5c3_Var11 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ switch i {
+ case 1:
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ default:
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if !templ_7745c5c3_IsBuffer {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
+ }
+ return templ_7745c5c3_Err
+ })
+}
+
+const WhitespaceIsConsistentInOneSwitchExpected = ` `
+const WhitespaceIsConsistentInDefaultSwitchExpected = ` `
+
+func WhitespaceIsConsistentInSwitchNoDefault() templ.Component {
+ return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
+ if !templ_7745c5c3_IsBuffer {
+ templ_7745c5c3_Buffer = templ.GetBuffer()
+ defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var16 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var16 == nil {
+ templ_7745c5c3_Var16 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ switch false {
+ case true:
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if !templ_7745c5c3_IsBuffer {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
+ }
+ return templ_7745c5c3_Err
+ })
+}
+
+const WhitespaceIsConsistentInSwitchNoDefaultExpected = ` `
+
+func WhitespaceIsConsistentInFor(i int) templ.Component {
+ return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
+ if !templ_7745c5c3_IsBuffer {
+ templ_7745c5c3_Buffer = templ.GetBuffer()
+ defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var20 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var20 == nil {
+ templ_7745c5c3_Var20 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for j := 0; j < i; j++ {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if !templ_7745c5c3_IsBuffer {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
+ }
+ return templ_7745c5c3_Err
+ })
+}
+
+const WhitespaceIsConsistentInForZeroExpected = ` `
+const WhitespaceIsConsistentInForOneExpected = ` `
+const WhitespaceIsConsistentInForThreeExpected = ` `