mirror of
https://github.com/danog/liquid.git
synced 2024-11-27 08:34:42 +01:00
Implement case (w/out else)
This commit is contained in:
parent
c433c0894e
commit
c5e7e6c277
50
tags/tags.go
50
tags/tags.go
@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/osteele/liquid/chunks"
|
||||
"github.com/osteele/liquid/generics"
|
||||
)
|
||||
|
||||
// DefineStandardTags defines the standard Liquid tags.
|
||||
@ -14,13 +15,13 @@ func DefineStandardTags() {
|
||||
// but it ignores any syntax specified here.
|
||||
loopTags := []string{"break", "continue", "cycle"}
|
||||
chunks.DefineControlTag("capture").Action(captureTag)
|
||||
chunks.DefineControlTag("case").Branch("when")
|
||||
chunks.DefineControlTag("case").Branch("when").Action(caseTag)
|
||||
chunks.DefineControlTag("comment")
|
||||
chunks.DefineControlTag("for").Governs(loopTags).Action(loopTag)
|
||||
chunks.DefineControlTag("if").Branch("else").Branch("elsif").Action(ifTagAction(true))
|
||||
chunks.DefineControlTag("if").Branch("else").Branch("elsif").Action(ifTag(true))
|
||||
chunks.DefineControlTag("raw")
|
||||
chunks.DefineControlTag("tablerow").Governs(loopTags)
|
||||
chunks.DefineControlTag("unless").SameSyntaxAs("if").Action(ifTagAction(false))
|
||||
chunks.DefineControlTag("unless").SameSyntaxAs("if").Action(ifTag(false))
|
||||
}
|
||||
|
||||
func captureTag(node chunks.ASTControlTag) func(io.Writer, chunks.Context) error {
|
||||
@ -36,10 +37,51 @@ func captureTag(node chunks.ASTControlTag) func(io.Writer, chunks.Context) error
|
||||
}
|
||||
}
|
||||
|
||||
func ifTagAction(polarity bool) func(chunks.ASTControlTag) func(io.Writer, chunks.Context) error {
|
||||
func caseTag(node chunks.ASTControlTag) func(io.Writer, chunks.Context) error {
|
||||
// TODO parse error on non-empty node.Body
|
||||
// TODO case can include an else
|
||||
expr, err := chunks.MakeExpressionValueFn(node.Args)
|
||||
// TODO change the API to let this return the error directly
|
||||
if err != nil {
|
||||
return func(io.Writer, chunks.Context) error { return err }
|
||||
}
|
||||
type branchRec struct {
|
||||
fn func(chunks.Context) (interface{}, error)
|
||||
node *chunks.ASTControlTag
|
||||
}
|
||||
cases := []branchRec{}
|
||||
for _, branch := range node.Branches {
|
||||
bfn, err := chunks.MakeExpressionValueFn(branch.Args)
|
||||
if err != nil {
|
||||
return func(io.Writer, chunks.Context) error { return err }
|
||||
}
|
||||
cases = append(cases, branchRec{bfn, branch})
|
||||
}
|
||||
return func(w io.Writer, ctx chunks.Context) error {
|
||||
value, err := expr(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, branch := range cases {
|
||||
b, err := branch.fn(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if generics.Equal(value, b) {
|
||||
return ctx.RenderASTSequence(w, branch.node.Body)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ifTag(polarity bool) func(chunks.ASTControlTag) func(io.Writer, chunks.Context) error {
|
||||
// TODO parse error if the order of branches is other than ifelse*else?
|
||||
// TODO parse the tests into a table evaluator -> []AST
|
||||
return func(node chunks.ASTControlTag) func(io.Writer, chunks.Context) error {
|
||||
expr, err := chunks.MakeExpressionValueFn(node.Args)
|
||||
if err != nil {
|
||||
// TODO allow these to return the error directly
|
||||
return func(io.Writer, chunks.Context) error { return err }
|
||||
}
|
||||
return func(w io.Writer, ctx chunks.Context) error {
|
||||
|
@ -18,42 +18,47 @@ var parseErrorTests = []struct{ in, expected string }{
|
||||
}
|
||||
|
||||
var tagTests = []struct{ in, expected string }{
|
||||
{"{%assign av = 1%}{{av}}", "1"},
|
||||
{"{%assign av = obj.a%}{{av}}", "1"},
|
||||
{`{%assign av = 1%}{{av}}`, "1"},
|
||||
{`{%assign av = obj.a%}{{av}}`, "1"},
|
||||
|
||||
// TODO test whether this requires matching interior tags
|
||||
{"{%comment%}{{a}}{%unknown%}{%endcomment%}", ""},
|
||||
{`{%comment%}{{a}}{%unknown%}{%endcomment%}`, ""},
|
||||
|
||||
{"{%capture x%}captured{%endcapture%}{{x}}", "captured"},
|
||||
{`{%capture x%}captured{%endcapture%}{{x}}`, "captured"},
|
||||
|
||||
{"{%for a in ar%}{{a}} {%endfor%}", "first second third "},
|
||||
{"{%for a in ar reversed%}{{a}} {%endfor%}", "third second first "},
|
||||
{`{%case 1%}{%when 1%}a{%when 2%}b{%endcase%}`, "a"},
|
||||
{`{%case 2%}{%when 1%}a{%when 2%}b{%endcase%}`, "b"},
|
||||
{`{%case 3%}{%when 1%}a{%when 2%}b{%endcase%}`, ""},
|
||||
// {`{%case 2%}{%when 1%}a{%else 2%}b{%endcase%}`, "captured"},
|
||||
|
||||
{"{%if true%}true{%endif%}", "true"},
|
||||
{"{%if false%}false{%endif%}", ""},
|
||||
{"{%if 0%}true{%endif%}", "true"},
|
||||
{"{%if 1%}true{%endif%}", "true"},
|
||||
{"{%if x%}true{%endif%}", "true"},
|
||||
{"{%if y%}true{%endif%}", ""},
|
||||
{"{%if true%}true{%endif%}", "true"},
|
||||
{"{%if false%}false{%endif%}", ""},
|
||||
{"{%if true%}true{%else%}false{%endif%}", "true"},
|
||||
{"{%if false%}false{%else%}true{%endif%}", "true"},
|
||||
{"{%if true%}0{%elsif true%}1{%else%}2{%endif%}", "0"},
|
||||
{"{%if false%}0{%elsif true%}1{%else%}2{%endif%}", "1"},
|
||||
{"{%if false%}0{%elsif false%}1{%else%}2{%endif%}", "2"},
|
||||
{`{%for a in ar%}{{a}} {%endfor%}`, "first second third "},
|
||||
{`{%for a in ar reversed%}{{a}} {%endfor%}`, "third second first "},
|
||||
|
||||
{`{%if true%}true{%endif%}`, "true"},
|
||||
{`{%if false%}false{%endif%}`, ""},
|
||||
{`{%if 0%}true{%endif%}`, "true"},
|
||||
{`{%if 1%}true{%endif%}`, "true"},
|
||||
{`{%if x%}true{%endif%}`, "true"},
|
||||
{`{%if y%}true{%endif%}`, ""},
|
||||
{`{%if true%}true{%endif%}`, "true"},
|
||||
{`{%if false%}false{%endif%}`, ""},
|
||||
{`{%if true%}true{%else%}false{%endif%}`, "true"},
|
||||
{`{%if false%}false{%else%}true{%endif%}`, "true"},
|
||||
{`{%if true%}0{%elsif true%}1{%else%}2{%endif%}`, "0"},
|
||||
{`{%if false%}0{%elsif true%}1{%else%}2{%endif%}`, "1"},
|
||||
{`{%if false%}0{%elsif false%}1{%else%}2{%endif%}`, "2"},
|
||||
|
||||
// TODO test whether this requires matching interior tags
|
||||
{"pre{%raw%}{{a}}{%unknown%}{%endraw%}post", "pre{{a}}{%unknown%}post"},
|
||||
{"pre{%raw%}{%if false%}anyway-{%endraw%}post", "pre{%if false%}anyway-post"},
|
||||
{`pre{%raw%}{{a}}{%unknown%}{%endraw%}post`, "pre{{a}}{%unknown%}post"},
|
||||
{`pre{%raw%}{%if false%}anyway-{%endraw%}post`, "pre{%if false%}anyway-post"},
|
||||
|
||||
{"{%unless true%}false{%endunless%}", ""},
|
||||
{"{%unless false%}true{%endunless%}", "true"},
|
||||
{"{%unless true%}false{%else%}true{%endunless%}", "true"},
|
||||
{"{%unless false%}true{%else%}false{%endunless%}", "true"},
|
||||
{"{%unless false%}0{%elsif true%}1{%else%}2{%endunless%}", "0"},
|
||||
{"{%unless true%}0{%elsif true%}1{%else%}2{%endunless%}", "1"},
|
||||
{"{%unless true%}0{%elsif false%}1{%else%}2{%endunless%}", "2"},
|
||||
{`{%unless true%}false{%endunless%}`, ""},
|
||||
{`{%unless false%}true{%endunless%}`, "true"},
|
||||
{`{%unless true%}false{%else%}true{%endunless%}`, "true"},
|
||||
{`{%unless false%}true{%else%}false{%endunless%}`, "true"},
|
||||
{`{%unless false%}0{%elsif true%}1{%else%}2{%endunless%}`, "0"},
|
||||
{`{%unless true%}0{%elsif true%}1{%else%}2{%endunless%}`, "1"},
|
||||
{`{%unless true%}0{%elsif false%}1{%else%}2{%endunless%}`, "2"},
|
||||
}
|
||||
|
||||
var tagTestContext = chunks.NewContext(map[string]interface{}{
|
||||
|
Loading…
Reference in New Issue
Block a user