func ElseIfFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { condition, err := p.ReadConditionGroup() if err != nil { return nil, err } p.SkipPastTag() return &ElseIf{NewCommon(), condition}, nil }
func WhenFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { condition, err := p.ReadPartialCondition() if err != nil { return nil, err } p.SkipPastTag() return &When{NewCommon(), condition}, nil }
func CaseFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { value, err := p.ReadValue() if err != nil { return nil, err } p.SkipPastTag() return &Case{value, make([]CaseSibling, 0, 5)}, nil }
func UnlessFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { condition, err := p.ReadConditionGroup() if err != nil { return nil, err } p.SkipPastTag() condition.Inverse() return &Unless{NewCommon(), condition, nil}, nil }
func newTag(p *core.Parser, config *core.Configuration) (core.Tag, error) { p.ForwardBy(2) // skip the {% name := p.ReadName() factory, ok := Tags[name] if ok == false { return nil, nil //return nil, p.Error(fmt.Sprintf("unknown tag %q", name)) } return factory(p, config) }
func IfFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { condition, err := p.ReadConditionGroup() if err != nil { return nil, err } i := &If{ NewCommon(), condition, make([]IfSibling, 0, 3), } i.conditions = append(i.conditions, i) p.SkipPastTag() return i, nil }
func newOutput(p *core.Parser) (core.Code, error) { p.ForwardBy(2) // skip the {{ value, err := p.ReadValue() if err != nil || value == nil { return nil, err } filters, err := p.ReadFilters() if err != nil { return nil, err } p.SkipPastOutput() return &Output{value, filters}, nil }
func extractTokens(parser *core.Parser, container core.Tag, config *core.Configuration) error { stack := []core.Tag{container} preserveWhiteSpace := config.GetPreserveWhitespace() for parser.HasMore() { pre, markupType := parser.ToMarkup(preserveWhiteSpace) if len(pre) > 0 { container.AddCode(newLiteral(pre)) } if markupType == core.OutputMarkup { code, err := newOutput(parser) if err != nil { return err } if code != nil { container.AddCode(code) } } else if markupType == core.TagMarkup { tag, err := newTag(parser, config) if err != nil { return err } switch tag.Type() { case core.ContainerTag, core.LoopTag: container.AddCode(tag) container = tag stack = append(stack, container) case core.EndTag: l := len(stack) - 1 container = stack[l] if tag.Name() != container.Name() { return parser.Error(fmt.Sprintf("end tag \"end%s\" cannot terminate %q", tag.Name(), container.Name())) } stack = stack[0:l] container = stack[l-1] parser.SkipPastTag() case core.SiblingTag: if err := stack[len(stack)-1].AddSibling(tag); err != nil { return err } container = tag case core.StandaloneTag: container.AddCode(tag) } } else { break } } return nil }
// Creates an assign tag func CaptureFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { name := p.ReadName() if len(name) == 0 { return nil, p.Error("Invalid assignment, variable not found. ") } p.SkipPastTag() return &Capture{name, NewCommon()}, nil }
// Special handling to just quickly skip over it all func HighlightFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { openTags := 1 for { _, markupType := p.ToMarkup(false) if markupType == core.TagMarkup { p.ForwardBy(2) // skip {% if name := p.ReadName(); name == "highlight" { openTags++ } else if name == "endhighlight" { openTags-- if openTags == 0 { p.SkipPastTag() break } } } else if markupType == core.OutputMarkup { p.SkipPastTag() } else { break } } return highlight, nil }
// Creates an include tag func IncludeFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { value, err := p.ReadValue() if err != nil { return nil, err } if value == nil { return nil, p.Error("Invalid include value") } p.SkipPastTag() return &Include{value, config.GetIncludeHandler()}, nil }
func ElseFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { p.SkipPastTag() return &Else{NewCommon(), new(core.TrueCondition)}, nil }
// Creates an assign tag func AssignFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { name := p.ReadName() if len(name) == 0 { return nil, p.Error("Invalid variable name in assign tag") } if p.SkipUntil('=') != '=' { return nil, p.Error("Invalid assign, missing '=' ") } p.Forward() value, err := p.ReadValue() if err != nil { return nil, err } filters, err := p.ReadFilters() if err != nil { return nil, err } p.SkipPastTag() return &Assign{name, value, filters}, nil }
// Creates a break tag func BreakFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { p.SkipPastTag() return breakTag, nil }
// Creates a continue tag func ContinueFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { p.SkipPastTag() return continueTag, nil }
// Special handling to just quickly skip over it all func RawFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { p.SkipPastTag() start := p.Position end := start for { _, markupType := p.ToMarkup(false) if markupType == core.TagMarkup { //tentative end is before the start of the endraw tag end = p.Position p.ForwardBy(2) // skip {% if name := p.ReadName(); name == "endraw" { p.SkipPastTag() break } } else if markupType == core.OutputMarkup { p.ForwardBy(2) // skip it } else { break } } return &Raw{p.Data[start:end]}, nil }
func ForFactory(p *core.Parser, config *core.Configuration) (core.Tag, error) { name := p.ReadName() if len(name) == 0 { return nil, p.Error("Invalid variable name in for tag") } if p.SkipSpaces() != 'i' || p.Left() < 3 || p.Data[p.Position+1] != 'n' || !core.IsTokenEnd(p.Data[p.Position+2]) { return nil, p.Error("Expecting keyword 'in' after variable name in for tag") } p.ForwardBy(2) value, err := p.ReadValue() if err != nil { return nil, err } f := &For{ Common: NewCommon(), name: name, keyName: name + "[0]", valueName: name + "[1]", value: value, } for { name := p.ReadName() if name == "" { break } if name == "limit" { if p.SkipUntil(':') != ':' { return nil, p.Error("Expecting ':' after limit in for tag") } p.Forward() limit, err := p.ReadValue() if err != nil { return nil, err } f.limit = limit } else if name == "offset" { if p.SkipUntil(':') != ':' { return nil, p.Error("Expecting ':' after offset in for tag") } p.Forward() offset, err := p.ReadValue() if err != nil { return nil, err } f.offset = offset } else if name == "reverse" { f.reverse = true } else { return nil, p.Error(fmt.Sprint("%q is an inknown modifier in for tag", name)) } } p.SkipPastTag() return f, nil }