Skip to content

Commit

Permalink
impl <? optional and </ end tag
Browse files Browse the repository at this point in the history
  • Loading branch information
Peyton-Spencer committed Jan 25, 2025
1 parent e0a7a54 commit cf489c4
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 4 deletions.
11 changes: 11 additions & 0 deletions pkg/token/kind/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,14 @@ func (k Kind) String() string {
}
return "Unknown"
}

func (k Kind) IsTag() bool {
switch k {
case
Var,
OptionalBlock,
EndTag:
return true
}
return false
}
14 changes: 10 additions & 4 deletions pkg/token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,26 @@ func Tokenize(input []byte) (Slice, error) {
}
}

if ct.Kind == kind.Var && b == '>' {
if b == '>' && ct.Kind.IsTag() {
ct.End = i
tokens = append(tokens, ct)
ct = T{}
continue
}
if b == '<' && len(input) > i && input[i+1] == '!' {
if b == '<' && len(input) > i {
if ct.Kind != kind.Unset {
ct.End = i
tokens = append(tokens, ct)
}
ct.Kind = kind.Var
switch input[i+1] {
case '!':
ct.Kind = kind.Var
case '?':
ct.Kind = kind.OptionalBlock
case '/':
ct.Kind = kind.EndTag
}
ct.Start = i + 2

}

if b == '\n' {
Expand Down
126 changes: 126 additions & 0 deletions pkg/token/token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,129 @@ func TestCombined(t *testing.T) {
func joinLines(in ...[]byte) []byte {
return bytes.Join(in, []byte{'\n'})
}

func TestOptionalBlock(t *testing.T) {
testcases := []TestCase{
{
name: "simple optional block",
def: func() ([]byte, token.Slice, error) {
start := []byte("<?optional>")
text := []byte("some optional text")
end := []byte("</optional>")
input := bytes.Join([][]byte{start, text, end}, []byte{'\n'})
want := token.Slice{
{
Kind: kind.OptionalBlock,
Start: 2,
End: 10,
},
{
Kind: kind.Text,
Start: 11,
End: 31,
},
{
Kind: kind.EndTag,
Start: 33,
End: 41,
},
}
return input, want, nil
},
},
{
name: "optional block with variable",
def: func() ([]byte, token.Slice, error) {
start := []byte("<?block>")
text1 := []byte("Hello")
varStart := []byte("<!name>")
text2 := []byte(" how are you?")
end := []byte("</block>")
input := bytes.Join([][]byte{start, text1, varStart, text2, end}, []byte{' '})
want := token.Slice{
{
Kind: kind.OptionalBlock,
Start: 2,
End: 7,
},
{
Kind: kind.Text,
Start: 8,
End: 15,
},
{
Kind: kind.Var,
Start: 17,
End: 21,
},
{
Kind: kind.Text,
Start: 22,
End: 37,
},
{
Kind: kind.EndTag,
Start: 39,
End: 44,
},
}
return input, want, nil
},
},
{
name: "nested optional blocks",
def: func() ([]byte, token.Slice, error) {
outer := []byte("<?outer>")
text1 := []byte("start")
inner := []byte("<?inner>")
text2 := []byte("inner text")
innerEnd := []byte("</inner>")
text3 := []byte("end")
outerEnd := []byte("</outer>")
input := bytes.Join([][]byte{outer, text1, inner, text2, innerEnd, text3, outerEnd}, []byte{'\n'})
want := token.Slice{
{
Kind: kind.OptionalBlock,
Start: 2,
End: 7,
},
{
Kind: kind.Text,
Start: 8,
End: 15,
},
{
Kind: kind.OptionalBlock,
Start: 17,
End: 22,
},
{
Kind: kind.Text,
Start: 23,
End: 35,
},
{
Kind: kind.EndTag,
Start: 37,
End: 42,
},
{
Kind: kind.Text,
Start: 43,
End: 48,
},
{
Kind: kind.EndTag,
Start: 50,
End: 55,
},
}
return input, want, nil
},
},
}

for _, tc := range testcases {
tc.Run(t)
}
}

0 comments on commit cf489c4

Please sign in to comment.