1
0
mirror of https://github.com/danog/liquid.git synced 2024-11-30 10:08:58 +01:00
liquid/parser/scanner.go

53 lines
1.2 KiB
Go
Raw Normal View History

2017-07-07 11:41:37 +02:00
package parser
2017-06-25 17:23:20 +02:00
import (
"regexp"
2017-06-30 14:42:11 +02:00
"strings"
2017-06-25 17:23:20 +02:00
)
2017-07-09 17:18:35 +02:00
var tokenMatcher = regexp.MustCompile(`{{\s*(.+?)\s*}}|{%\s*(\w+)(?:\s+((?:[^%]|%[^}])+?))?\s*%}`)
2017-06-25 17:23:20 +02:00
2017-07-09 17:18:35 +02:00
// Scan breaks a string into a sequence of Tokens.
func Scan(data string, si SourceLoc) []Token {
2017-06-26 18:41:41 +02:00
// TODO error on unterminated {{ and {%
// TODO probably an error when a tag contains a {{ or {%, at least outside of a string
2017-06-25 17:23:20 +02:00
var (
2017-06-30 14:42:11 +02:00
p, pe = 0, len(data)
2017-07-09 17:18:35 +02:00
out = make([]Token, 0)
2017-06-25 17:23:20 +02:00
)
2017-07-09 17:18:35 +02:00
for _, m := range tokenMatcher.FindAllStringSubmatchIndex(data, -1) {
2017-06-25 17:23:20 +02:00
ts, te := m[0], m[1]
if p < ts {
2017-07-10 17:49:14 +02:00
out = append(out, Token{Type: TextTokenType, SourceLoc: si, Source: data[p:ts]})
si.LineNo += strings.Count(data[p:ts], "\n")
2017-06-25 17:23:20 +02:00
}
2017-06-30 14:42:11 +02:00
source := data[ts:te]
2017-06-25 17:23:20 +02:00
switch data[ts+1] {
case '{':
2017-07-09 17:18:35 +02:00
out = append(out, Token{
Type: ObjTokenType,
2017-07-10 17:49:14 +02:00
SourceLoc: si,
Source: source,
Args: data[m[2]:m[3]],
2017-06-29 18:20:16 +02:00
})
2017-06-25 17:23:20 +02:00
case '%':
2017-07-09 17:18:35 +02:00
c := Token{
Type: TagTokenType,
2017-07-10 17:49:14 +02:00
SourceLoc: si,
Source: source,
Name: data[m[4]:m[5]],
2017-06-29 18:20:16 +02:00
}
2017-06-25 17:23:20 +02:00
if m[6] > 0 {
2017-06-30 23:33:36 +02:00
c.Args = data[m[6]:m[7]]
2017-06-25 17:23:20 +02:00
}
2017-06-29 18:20:16 +02:00
out = append(out, c)
2017-06-25 17:23:20 +02:00
}
2017-07-10 17:49:14 +02:00
si.LineNo += strings.Count(source, "\n")
2017-06-25 23:26:14 +02:00
p = te
2017-06-25 17:23:20 +02:00
}
if p < pe {
2017-07-10 17:49:14 +02:00
out = append(out, Token{Type: TextTokenType, SourceLoc: si, Source: data[p:]})
2017-06-25 17:23:20 +02:00
}
return out
}