1
0
mirror of https://github.com/danog/liquid.git synced 2024-11-27 06:44:42 +01:00
liquid/chunks/scanner.go
2017-06-30 17:33:36 -04:00

56 lines
1.3 KiB
Go

//go:generate stringer -type=ChunkType
package chunks
import (
"regexp"
"strings"
)
var chunkMatcher = regexp.MustCompile(`{{\s*(.+?)\s*}}|{%\s*(\w+)(?:\s+((?:[^%]|%[^}])+?))?\s*%}`)
// Scan breaks a string into a sequence of Chunks.
func Scan(data string, pathname string) []Chunk {
// TODO error on unterminated {{ and {%
// TODO probably an error when a tag contains a {{ or {%, at least outside of a string
var (
p, pe = 0, len(data)
si = SourceInfo{pathname, 1}
out = make([]Chunk, 0)
)
for _, m := range chunkMatcher.FindAllStringSubmatchIndex(data, -1) {
ts, te := m[0], m[1]
if p < ts {
out = append(out, Chunk{Type: TextChunkType, SourceInfo: si, Source: data[p:ts]})
si.lineNo += strings.Count(data[p:ts], "\n")
}
source := data[ts:te]
switch data[ts+1] {
case '{':
out = append(out, Chunk{
Type: ObjChunkType,
SourceInfo: si,
Source: source,
Args: data[m[2]:m[3]],
})
case '%':
c := Chunk{
Type: TagChunkType,
SourceInfo: si,
Source: source,
Name: data[m[4]:m[5]],
}
if m[6] > 0 {
c.Args = data[m[6]:m[7]]
}
out = append(out, c)
}
si.lineNo += strings.Count(source, "\n")
p = te
}
if p < pe {
out = append(out, Chunk{Type: TextChunkType, SourceInfo: si, Source: data[p:]})
}
return out
}