2017-06-25 12:36:28 -04:00
|
|
|
//go:generate stringer -type=ChunkType
|
|
|
|
|
2017-06-26 09:36:52 -04:00
|
|
|
package chunks
|
2017-06-25 11:23:20 -04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"regexp"
|
|
|
|
)
|
|
|
|
|
2017-06-27 22:34:46 -04:00
|
|
|
var chunkMatcher = regexp.MustCompile(`{{\s*(.+?)\s*}}|{%\s*(\w+)(?:\s+((?:[^%]|%[^}])+?))?\s*%}`)
|
2017-06-25 11:23:20 -04:00
|
|
|
|
2017-06-26 12:41:41 -04:00
|
|
|
// Scan breaks a string into a sequence of Chunks.
|
2017-06-26 10:15:01 -04:00
|
|
|
func Scan(data string, pathname string) []Chunk {
|
2017-06-26 12:41:41 -04: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 11:23:20 -04:00
|
|
|
var (
|
|
|
|
sourceInfo = SourceInfo{pathname, 0}
|
|
|
|
out = make([]Chunk, 0)
|
|
|
|
p, pe = 0, len(data)
|
|
|
|
matches = chunkMatcher.FindAllStringSubmatchIndex(data, -1)
|
|
|
|
)
|
|
|
|
for _, m := range matches {
|
|
|
|
ts, te := m[0], m[1]
|
|
|
|
if p < ts {
|
2017-06-29 12:20:16 -04:00
|
|
|
out = append(out, Chunk{Type: TextChunkType, SourceInfo: sourceInfo, Source: data[p:ts]})
|
2017-06-25 11:23:20 -04:00
|
|
|
}
|
|
|
|
switch data[ts+1] {
|
|
|
|
case '{':
|
2017-06-29 12:20:16 -04:00
|
|
|
out = append(out, Chunk{
|
|
|
|
Type: ObjChunkType,
|
|
|
|
SourceInfo: sourceInfo,
|
|
|
|
Source: data[ts:te],
|
|
|
|
Parameters: data[m[2]:m[3]],
|
|
|
|
})
|
2017-06-25 11:23:20 -04:00
|
|
|
case '%':
|
2017-06-29 12:20:16 -04:00
|
|
|
c := Chunk{
|
|
|
|
Type: TagChunkType,
|
|
|
|
SourceInfo: sourceInfo,
|
|
|
|
Source: data[ts:te],
|
|
|
|
Name: data[m[4]:m[5]],
|
|
|
|
}
|
2017-06-25 11:23:20 -04:00
|
|
|
if m[6] > 0 {
|
2017-06-29 12:20:16 -04:00
|
|
|
c.Parameters = data[m[6]:m[7]]
|
2017-06-25 11:23:20 -04:00
|
|
|
}
|
2017-06-29 12:20:16 -04:00
|
|
|
out = append(out, c)
|
2017-06-25 11:23:20 -04:00
|
|
|
}
|
2017-06-25 17:26:14 -04:00
|
|
|
p = te
|
2017-06-25 11:23:20 -04:00
|
|
|
}
|
|
|
|
if p < pe {
|
2017-06-29 12:20:16 -04:00
|
|
|
out = append(out, Chunk{Type: TextChunkType, SourceInfo: sourceInfo, Source: data[p:]})
|
2017-06-25 11:23:20 -04:00
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|