diff --git a/README.md b/README.md index dbaced1..b82b266 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Gojekyll uses these libraries: | [gopkg.in/alecthomas/kingpin.v2](https://github.com/alecthomas/kingpin) | Alec Thomas | command line and flag parser | | [gopkg.in/yaml.v2](https://github.com/go-yaml) | Canonical | YAML support | -In addition to being totally and obviously inspired by the Jekyll Ruby implementation, Jekyll's solid documentation was indispensible. The [Jekyll docs](https://jekyllrb.com/docs/home/) were always open in at least one tab. +In addition to being totally and obviously inspired by the Jekyll Ruby implementation, Jekyll's solid documentation was indispensible. Many of the filter test cases are taken directly from the Jekyll documentation, and the [Jekyll docs](https://jekyllrb.com/docs/home/) were always open in at least one tab. The gopher image in the test directory is from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Gophercolor.jpg). It is used under the [Creative Commons Attribution-Share Alike 3.0 Unported license](https://creativecommons.org/licenses/by-sa/3.0/deed.en). diff --git a/liquid/tags.go b/liquid/tags.go index 6ea7814..b534af5 100644 --- a/liquid/tags.go +++ b/liquid/tags.go @@ -10,55 +10,59 @@ import ( ) func (e *Wrapper) addJekyllTags() { - e.engine.DefineTag("link", func(filename string) (func(io.Writer, chunks.Context) error, error) { - return func(w io.Writer, _ chunks.Context) error { - url, found := e.linkHandler(filename) - if !found { - return fmt.Errorf("missing link filename: %s", filename) - } - _, err := w.Write([]byte(url)) - return err - }, nil - }) - e.engine.DefineTag("include", func(line string) (func(io.Writer, chunks.Context) error, error) { - // TODO string escapes - includeLinePattern := regexp.MustCompile(`^\S+(?:\s+\S+=("[^"]+"|'[^']'|[^'"\s]+))*$`) - includeParamPattern := regexp.MustCompile(`\b(\S+)=("[^"]+"|'[^']'|[^'"\s]+)(?:\s|$)`) - if !includeLinePattern.MatchString(line) { - return nil, fmt.Errorf("parse error in include tag parameters") - } - filename := strings.Fields(line)[0] - type paramSpec struct { - value string - eval bool - } - params := map[string]paramSpec{} - for _, m := range includeParamPattern.FindAllStringSubmatch(line, -1) { - k, v, eval := m[1], m[2], true - if strings.HasPrefix(v, `'`) || strings.HasPrefix(v, `"`) { - v, eval = v[1:len(v)-1], false - } - params[k] = paramSpec{v, eval} - } - return func(w io.Writer, ctx chunks.Context) error { - include := map[string]interface{}{} - for k, v := range params { - if v.eval { - value, err := ctx.EvaluateString(v.value) - if err != nil { - return err - } - include[k] = value - } else { - include[k] = v.value - } - } - bindings := map[string]interface{}{} - for k, v := range ctx.GetVariableMap() { - bindings[k] = v - } - bindings["include"] = include - return e.includeTagHandler(filename, w, bindings) - }, nil - }) + e.engine.DefineTag("link", e.linkTag) + e.engine.DefineTag("include", e.includeTag) +} + +func (e *Wrapper) linkTag(filename string) (func(io.Writer, chunks.Context) error, error) { + return func(w io.Writer, _ chunks.Context) error { + url, found := e.linkHandler(filename) + if !found { + return fmt.Errorf("missing link filename: %s", filename) + } + _, err := w.Write([]byte(url)) + return err + }, nil +} + +func (e *Wrapper) includeTag(line string) (func(io.Writer, chunks.Context) error, error) { + // TODO string escapes + includeLinePattern := regexp.MustCompile(`^\S+(?:\s+\S+=("[^"]+"|'[^']'|[^'"\s]+))*$`) + includeParamPattern := regexp.MustCompile(`\b(\S+)=("[^"]+"|'[^']'|[^'"\s]+)(?:\s|$)`) + if !includeLinePattern.MatchString(line) { + return nil, fmt.Errorf("parse error in include tag parameters") + } + filename := strings.Fields(line)[0] + type paramSpec struct { + value string + eval bool + } + params := map[string]paramSpec{} + for _, m := range includeParamPattern.FindAllStringSubmatch(line, -1) { + k, v, eval := m[1], m[2], true + if strings.HasPrefix(v, `'`) || strings.HasPrefix(v, `"`) { + v, eval = v[1:len(v)-1], false + } + params[k] = paramSpec{v, eval} + } + return func(w io.Writer, ctx chunks.Context) error { + include := map[string]interface{}{} + for k, v := range params { + if v.eval { + value, err := ctx.EvaluateString(v.value) + if err != nil { + return err + } + include[k] = value + } else { + include[k] = v.value + } + } + bindings := map[string]interface{}{} + for k, v := range ctx.GetVariableMap() { + bindings[k] = v + } + bindings["include"] = include + return e.includeTagHandler(filename, w, bindings) + }, nil }