mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-25 22:00:58 +02:00
@@ -210,7 +210,6 @@ func (t *Tree) recover(errp *error) {
|
||||
panic(e)
|
||||
}
|
||||
if t != nil {
|
||||
t.lex.drain()
|
||||
t.stopParse()
|
||||
}
|
||||
*errp = e.(error)
|
||||
@@ -224,8 +223,6 @@ func (t *Tree) startParse(funcs []map[string]any, lex *lexer, treeSet map[string
|
||||
t.vars = []string{"$"}
|
||||
t.funcs = funcs
|
||||
t.treeSet = treeSet
|
||||
lex.breakOK = !t.hasFunction("break")
|
||||
lex.continueOK = !t.hasFunction("continue")
|
||||
}
|
||||
|
||||
// stopParse terminates parsing.
|
||||
@@ -243,8 +240,13 @@ func (t *Tree) stopParse() {
|
||||
func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]any) (tree *Tree, err error) {
|
||||
defer t.recover(&err)
|
||||
t.ParseName = t.Name
|
||||
emitComment := t.Mode&ParseComments != 0
|
||||
t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim, emitComment), treeSet)
|
||||
lexer := lex(t.Name, text, leftDelim, rightDelim)
|
||||
lexer.options = lexOptions{
|
||||
emitComment: t.Mode&ParseComments != 0,
|
||||
breakOK: !t.hasFunction("break"),
|
||||
continueOK: !t.hasFunction("continue"),
|
||||
}
|
||||
t.startParse(funcs, lexer, treeSet)
|
||||
t.text = text
|
||||
t.parse()
|
||||
t.add()
|
||||
@@ -341,7 +343,9 @@ func (t *Tree) parseDefinition() {
|
||||
}
|
||||
|
||||
// itemList:
|
||||
//
|
||||
// textOrAction*
|
||||
//
|
||||
// Terminates at {{end}} or {{else}}, returned separately.
|
||||
func (t *Tree) itemList() (list *ListNode, next Node) {
|
||||
list = t.newList(t.peekNonSpace().pos)
|
||||
@@ -358,6 +362,7 @@ func (t *Tree) itemList() (list *ListNode, next Node) {
|
||||
}
|
||||
|
||||
// textOrAction:
|
||||
//
|
||||
// text | comment | action
|
||||
func (t *Tree) textOrAction() Node {
|
||||
switch token := t.nextNonSpace(); token.typ {
|
||||
@@ -380,8 +385,10 @@ func (t *Tree) clearActionLine() {
|
||||
}
|
||||
|
||||
// Action:
|
||||
//
|
||||
// control
|
||||
// command ("|" command)*
|
||||
//
|
||||
// Left delim is past. Now get actions.
|
||||
// First word could be a keyword such as range.
|
||||
func (t *Tree) action() (n Node) {
|
||||
@@ -412,7 +419,9 @@ func (t *Tree) action() (n Node) {
|
||||
}
|
||||
|
||||
// Break:
|
||||
//
|
||||
// {{break}}
|
||||
//
|
||||
// Break keyword is past.
|
||||
func (t *Tree) breakControl(pos Pos, line int) Node {
|
||||
if token := t.nextNonSpace(); token.typ != itemRightDelim {
|
||||
@@ -425,7 +434,9 @@ func (t *Tree) breakControl(pos Pos, line int) Node {
|
||||
}
|
||||
|
||||
// Continue:
|
||||
//
|
||||
// {{continue}}
|
||||
//
|
||||
// Continue keyword is past.
|
||||
func (t *Tree) continueControl(pos Pos, line int) Node {
|
||||
if token := t.nextNonSpace(); token.typ != itemRightDelim {
|
||||
@@ -438,6 +449,7 @@ func (t *Tree) continueControl(pos Pos, line int) Node {
|
||||
}
|
||||
|
||||
// Pipeline:
|
||||
//
|
||||
// declarations? command ('|' command)*
|
||||
func (t *Tree) pipeline(context string, end itemType) (pipe *PipeNode) {
|
||||
token := t.peekNonSpace()
|
||||
@@ -549,16 +561,20 @@ func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int
|
||||
}
|
||||
|
||||
// If:
|
||||
//
|
||||
// {{if pipeline}} itemList {{end}}
|
||||
// {{if pipeline}} itemList {{else}} itemList {{end}}
|
||||
//
|
||||
// If keyword is past.
|
||||
func (t *Tree) ifControl() Node {
|
||||
return t.newIf(t.parseControl(true, "if"))
|
||||
}
|
||||
|
||||
// Range:
|
||||
//
|
||||
// {{range pipeline}} itemList {{end}}
|
||||
// {{range pipeline}} itemList {{else}} itemList {{end}}
|
||||
//
|
||||
// Range keyword is past.
|
||||
func (t *Tree) rangeControl() Node {
|
||||
r := t.newRange(t.parseControl(false, "range"))
|
||||
@@ -566,22 +582,28 @@ func (t *Tree) rangeControl() Node {
|
||||
}
|
||||
|
||||
// With:
|
||||
//
|
||||
// {{with pipeline}} itemList {{end}}
|
||||
// {{with pipeline}} itemList {{else}} itemList {{end}}
|
||||
//
|
||||
// If keyword is past.
|
||||
func (t *Tree) withControl() Node {
|
||||
return t.newWith(t.parseControl(false, "with"))
|
||||
}
|
||||
|
||||
// End:
|
||||
//
|
||||
// {{end}}
|
||||
//
|
||||
// End keyword is past.
|
||||
func (t *Tree) endControl() Node {
|
||||
return t.newEnd(t.expect(itemRightDelim, "end").pos)
|
||||
}
|
||||
|
||||
// Else:
|
||||
//
|
||||
// {{else}}
|
||||
//
|
||||
// Else keyword is past.
|
||||
func (t *Tree) elseControl() Node {
|
||||
// Special case for "else if".
|
||||
@@ -595,7 +617,9 @@ func (t *Tree) elseControl() Node {
|
||||
}
|
||||
|
||||
// Block:
|
||||
//
|
||||
// {{block stringValue pipeline}}
|
||||
//
|
||||
// Block keyword is past.
|
||||
// The name must be something that can evaluate to a string.
|
||||
// The pipeline is mandatory.
|
||||
@@ -623,7 +647,9 @@ func (t *Tree) blockControl() Node {
|
||||
}
|
||||
|
||||
// Template:
|
||||
//
|
||||
// {{template stringValue pipeline}}
|
||||
//
|
||||
// Template keyword is past. The name must be something that can evaluate
|
||||
// to a string.
|
||||
func (t *Tree) templateControl() Node {
|
||||
@@ -654,7 +680,9 @@ func (t *Tree) parseTemplateName(token item, context string) (name string) {
|
||||
}
|
||||
|
||||
// command:
|
||||
//
|
||||
// operand (space operand)*
|
||||
//
|
||||
// space-separated arguments up to a pipeline character or right delimiter.
|
||||
// we consume the pipe character but leave the right delim to terminate the action.
|
||||
func (t *Tree) command() *CommandNode {
|
||||
@@ -684,7 +712,9 @@ func (t *Tree) command() *CommandNode {
|
||||
}
|
||||
|
||||
// operand:
|
||||
//
|
||||
// term .Field*
|
||||
//
|
||||
// An operand is a space-separated component of a command,
|
||||
// a term possibly followed by field accesses.
|
||||
// A nil return means the next item is not an operand.
|
||||
@@ -718,12 +748,14 @@ func (t *Tree) operand() Node {
|
||||
}
|
||||
|
||||
// term:
|
||||
//
|
||||
// literal (number, string, nil, boolean)
|
||||
// function (identifier)
|
||||
// .
|
||||
// .Field
|
||||
// $
|
||||
// '(' pipeline ')'
|
||||
//
|
||||
// A term is a simple "expression".
|
||||
// A nil return means the next item is not a term.
|
||||
func (t *Tree) term() Node {
|
||||
|
Reference in New Issue
Block a user