annotate vendor/github.com/eknkc/amber/parser/parser.go @ 66:787b5ee0289d draft

Use vendored modules Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Sun, 23 Jul 2023 13:18:53 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 package parser
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4 "bytes"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 "fmt"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 "io"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7 "io/ioutil"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 "net/http"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9 "path/filepath"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10 "strings"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13 type Parser struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 scanner *scanner
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15 filename string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16 fs http.FileSystem
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17 currenttoken *token
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 namedBlocks map[string]*NamedBlock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 parent *Parser
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20 result *Block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23 func newParser(rdr io.Reader) *Parser {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24 p := new(Parser)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25 p.scanner = newScanner(rdr)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 p.namedBlocks = make(map[string]*NamedBlock)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 return p
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 func StringParser(input string) (*Parser, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 return newParser(bytes.NewReader([]byte(input))), nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 func ByteParser(input []byte) (*Parser, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 return newParser(bytes.NewReader(input)), nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38 func (p *Parser) SetFilename(filename string) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 p.filename = filename
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 func (p *Parser) SetVirtualFilesystem(fs http.FileSystem) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 p.fs = fs
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 func FileParser(filename string) (*Parser, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 data, err := ioutil.ReadFile(filename)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50 return nil, err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 parser := newParser(bytes.NewReader(data))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 parser.filename = filename
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 return parser, nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58 func VirtualFileParser(filename string, fs http.FileSystem) (*Parser, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 file, err := fs.Open(filename)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 return nil, err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 data, err := ioutil.ReadAll(file)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 return nil, err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 parser := newParser(bytes.NewReader(data))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 parser.filename = filename
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 parser.fs = fs
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 return parser, nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 func (p *Parser) Parse() *Block {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 if p.result != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 return p.result
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80 defer func() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 if r := recover(); r != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82 if rs, ok := r.(string); ok && rs[:len("Amber Error")] == "Amber Error" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 panic(r)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 pos := p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88 if len(pos.Filename) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 panic(fmt.Sprintf("Amber Error in <%s>: %v - Line: %d, Column: %d, Length: %d", pos.Filename, r, pos.LineNum, pos.ColNum, pos.TokenLength))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91 panic(fmt.Sprintf("Amber Error: %v - Line: %d, Column: %d, Length: %d", r, pos.LineNum, pos.ColNum, pos.TokenLength))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 }()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 block := newBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 p.advance()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 if p.currenttoken == nil || p.currenttoken.Kind == tokEOF {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 if p.currenttoken.Kind == tokBlank {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105 p.advance()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 block.push(p.parse())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 if p.parent != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113 p.parent.Parse()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 for _, prev := range p.parent.namedBlocks {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 ours := p.namedBlocks[prev.Name]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118 if ours == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 // Put a copy of the named block into current context, so that sub-templates can use the block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120 p.namedBlocks[prev.Name] = prev
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 top := findTopmostParentWithNamedBlock(p, prev.Name)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 nb := top.namedBlocks[prev.Name]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 switch ours.Modifier {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 case NamedBlockAppend:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 for i := 0; i < len(ours.Children); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129 nb.push(ours.Children[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 case NamedBlockPrepend:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 for i := len(ours.Children) - 1; i >= 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133 nb.pushFront(ours.Children[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 nb.Children = ours.Children
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 block = p.parent.result
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143 p.result = block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 return block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147 func (p *Parser) pos() SourcePosition {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 pos := p.scanner.Pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149 pos.Filename = p.filename
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 return pos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153 func (p *Parser) parseRelativeFile(filename string) *Parser {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154 if len(p.filename) == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 panic("Unable to import or extend " + filename + " in a non filesystem based parser.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158 filename = filepath.Join(filepath.Dir(p.filename), filename)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160 if strings.IndexRune(filepath.Base(filename), '.') < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 filename = filename + ".amber"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 parser, err := FileParser(filename)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165 if err != nil && p.fs != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166 parser, err = VirtualFileParser(filename, p.fs)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169 panic("Unable to read " + filename + ", Error: " + string(err.Error()))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 return parser
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175 func (p *Parser) parse() Node {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176 switch p.currenttoken.Kind {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 case tokDoctype:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
178 return p.parseDoctype()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
179 case tokComment:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
180 return p.parseComment()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
181 case tokText:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
182 return p.parseText()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
183 case tokIf:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
184 return p.parseIf()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
185 case tokEach:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
186 return p.parseEach()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
187 case tokImport:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
188 return p.parseImport()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
189 case tokTag:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
190 return p.parseTag()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
191 case tokAssignment:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
192 return p.parseAssignment()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
193 case tokNamedBlock:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
194 return p.parseNamedBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
195 case tokExtends:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
196 return p.parseExtends()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
197 case tokIndent:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
198 return p.parseBlock(nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
199 case tokMixin:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
200 return p.parseMixin()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
201 case tokMixinCall:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
202 return p.parseMixinCall()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
203 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
204
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
205 panic(fmt.Sprintf("Unexpected token: %d", p.currenttoken.Kind))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
206 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
207
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
208 func (p *Parser) expect(typ rune) *token {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
209 if p.currenttoken.Kind != typ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
210 panic("Unexpected token!")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
211 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
212 curtok := p.currenttoken
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
213 p.advance()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
214 return curtok
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
215 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
216
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
217 func (p *Parser) advance() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
218 p.currenttoken = p.scanner.Next()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
219 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
220
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
221 func (p *Parser) parseExtends() *Block {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
222 if p.parent != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
223 panic("Unable to extend multiple parent templates.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
224 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
225
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
226 tok := p.expect(tokExtends)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
227 parser := p.parseRelativeFile(tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
228 parser.Parse()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
229 p.parent = parser
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
230 return newBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
231 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
232
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
233 func (p *Parser) parseBlock(parent Node) *Block {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
234 p.expect(tokIndent)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
235 block := newBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
236 block.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
237
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
238 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
239 if p.currenttoken == nil || p.currenttoken.Kind == tokEOF || p.currenttoken.Kind == tokOutdent {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
240 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
241 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
242
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
243 if p.currenttoken.Kind == tokBlank {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
244 p.advance()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
245 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
246 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
247
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
248 if p.currenttoken.Kind == tokId ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
249 p.currenttoken.Kind == tokClassName ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
250 p.currenttoken.Kind == tokAttribute {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
251
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
252 if tag, ok := parent.(*Tag); ok {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
253 attr := p.expect(p.currenttoken.Kind)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
254 cond := attr.Data["Condition"]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
255
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
256 switch attr.Kind {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
257 case tokId:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
258 tag.Attributes = append(tag.Attributes, Attribute{p.pos(), "id", attr.Value, true, cond})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
259 case tokClassName:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
260 tag.Attributes = append(tag.Attributes, Attribute{p.pos(), "class", attr.Value, true, cond})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
261 case tokAttribute:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
262 tag.Attributes = append(tag.Attributes, Attribute{p.pos(), attr.Value, attr.Data["Content"], attr.Data["Mode"] == "raw", cond})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
263 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
264
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
265 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
266 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
267 panic("Conditional attributes must be placed immediately within a parent tag.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
268 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
269 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
270
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
271 block.push(p.parse())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
272 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
273
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
274 p.expect(tokOutdent)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
275
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
276 return block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
277 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
278
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
279 func (p *Parser) parseIf() *Condition {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
280 tok := p.expect(tokIf)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
281 cnd := newCondition(tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
282 cnd.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
283
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
284 readmore:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
285 switch p.currenttoken.Kind {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
286 case tokIndent:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
287 cnd.Positive = p.parseBlock(cnd)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
288 goto readmore
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
289 case tokElse:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
290 p.expect(tokElse)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
291 if p.currenttoken.Kind == tokIf {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
292 cnd.Negative = newBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
293 cnd.Negative.push(p.parseIf())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
294 } else if p.currenttoken.Kind == tokIndent {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
295 cnd.Negative = p.parseBlock(cnd)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
296 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
297 panic("Unexpected token!")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
298 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
299 goto readmore
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
300 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
301
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
302 return cnd
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
303 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
304
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
305 func (p *Parser) parseEach() *Each {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
306 tok := p.expect(tokEach)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
307 ech := newEach(tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
308 ech.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
309 ech.X = tok.Data["X"]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
310 ech.Y = tok.Data["Y"]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
311
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
312 if p.currenttoken.Kind == tokIndent {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
313 ech.Block = p.parseBlock(ech)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
314 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
315
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
316 return ech
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
317 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
318
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
319 func (p *Parser) parseImport() *Block {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
320 tok := p.expect(tokImport)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
321 node := p.parseRelativeFile(tok.Value).Parse()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
322 node.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
323 return node
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
324 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
325
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
326 func (p *Parser) parseNamedBlock() *Block {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
327 tok := p.expect(tokNamedBlock)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
328
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
329 if p.namedBlocks[tok.Value] != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
330 panic("Multiple definitions of named blocks are not permitted. Block " + tok.Value + " has been re defined.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
331 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
332
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
333 block := newNamedBlock(tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
334 block.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
335
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
336 if tok.Data["Modifier"] == "append" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
337 block.Modifier = NamedBlockAppend
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
338 } else if tok.Data["Modifier"] == "prepend" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
339 block.Modifier = NamedBlockPrepend
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
340 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
341
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
342 if p.currenttoken.Kind == tokIndent {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
343 block.Block = *(p.parseBlock(nil))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
344 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
345
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
346 p.namedBlocks[block.Name] = block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
347
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
348 if block.Modifier == NamedBlockDefault {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
349 return &block.Block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
350 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
351
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
352 return newBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
353 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
354
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
355 func (p *Parser) parseDoctype() *Doctype {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
356 tok := p.expect(tokDoctype)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
357 node := newDoctype(tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
358 node.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
359 return node
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
360 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
361
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
362 func (p *Parser) parseComment() *Comment {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
363 tok := p.expect(tokComment)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
364 cmnt := newComment(tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
365 cmnt.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
366 cmnt.Silent = tok.Data["Mode"] == "silent"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
367
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
368 if p.currenttoken.Kind == tokIndent {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
369 cmnt.Block = p.parseBlock(cmnt)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
370 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
371
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
372 return cmnt
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
373 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
374
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
375 func (p *Parser) parseText() *Text {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
376 tok := p.expect(tokText)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
377 node := newText(tok.Value, tok.Data["Mode"] == "raw")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
378 node.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
379 return node
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
380 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
381
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
382 func (p *Parser) parseAssignment() *Assignment {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
383 tok := p.expect(tokAssignment)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
384 node := newAssignment(tok.Data["X"], tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
385 node.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
386 return node
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
387 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
388
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
389 func (p *Parser) parseTag() *Tag {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
390 tok := p.expect(tokTag)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
391 tag := newTag(tok.Value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
392 tag.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
393
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
394 ensureBlock := func() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
395 if tag.Block == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
396 tag.Block = newBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
397 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
398 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
399
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
400 readmore:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
401 switch p.currenttoken.Kind {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
402 case tokIndent:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
403 if tag.IsRawText() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
404 p.scanner.readRaw = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
405 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
406
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
407 block := p.parseBlock(tag)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
408 if tag.Block == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
409 tag.Block = block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
410 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
411 for _, c := range block.Children {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
412 tag.Block.push(c)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
413 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
414 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
415 case tokId:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
416 id := p.expect(tokId)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
417 if len(id.Data["Condition"]) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
418 panic("Conditional attributes must be placed in a block within a tag.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
419 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
420 tag.Attributes = append(tag.Attributes, Attribute{p.pos(), "id", id.Value, true, ""})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
421 goto readmore
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
422 case tokClassName:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
423 cls := p.expect(tokClassName)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
424 if len(cls.Data["Condition"]) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
425 panic("Conditional attributes must be placed in a block within a tag.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
426 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
427 tag.Attributes = append(tag.Attributes, Attribute{p.pos(), "class", cls.Value, true, ""})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
428 goto readmore
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
429 case tokAttribute:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
430 attr := p.expect(tokAttribute)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
431 if len(attr.Data["Condition"]) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
432 panic("Conditional attributes must be placed in a block within a tag.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
433 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
434 tag.Attributes = append(tag.Attributes, Attribute{p.pos(), attr.Value, attr.Data["Content"], attr.Data["Mode"] == "raw", ""})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
435 goto readmore
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
436 case tokText:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
437 if p.currenttoken.Data["Mode"] != "piped" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
438 ensureBlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
439 tag.Block.pushFront(p.parseText())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
440 goto readmore
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
441 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
442 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
443
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
444 return tag
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
445 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
446
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
447 func (p *Parser) parseMixin() *Mixin {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
448 tok := p.expect(tokMixin)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
449 mixin := newMixin(tok.Value, tok.Data["Args"])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
450 mixin.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
451
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
452 if p.currenttoken.Kind == tokIndent {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
453 mixin.Block = p.parseBlock(mixin)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
454 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
455
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
456 return mixin
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
457 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
458
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
459 func (p *Parser) parseMixinCall() *MixinCall {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
460 tok := p.expect(tokMixinCall)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
461 mixinCall := newMixinCall(tok.Value, tok.Data["Args"])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
462 mixinCall.SourcePosition = p.pos()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
463 return mixinCall
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
464 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
465
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
466 func findTopmostParentWithNamedBlock(p *Parser, name string) *Parser {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
467 top := p
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
468
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
469 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
470 if top.namedBlocks[name] == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
471 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
472 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
473 if top.parent == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
474 return top
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
475 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
476 if top.parent.namedBlocks[name] != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
477 top = top.parent
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
478 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
479 return top
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
480 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
481 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
482 }