Skip to content

Commit

Permalink
Add docs; remove unused UnimplementedError
Browse files Browse the repository at this point in the history
  • Loading branch information
osteele committed Jul 2, 2017
1 parent d6bc456 commit 983b9f5
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 15 deletions.
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -3,9 +3,11 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/osteele/liquid)](https://goreportcard.com/report/github.com/osteele/liquid)
[![GoDoc](https://godoc.org/github.com/osteele/liquid?status.svg)](http://godoc.org/github.com/osteele/liquid)

`liquid` is a pure Go implementation of [Shopify Liquid templates](https://shopify.github.io/liquid), for use in [gojekyll](https://github.com/osteele/gojekyll).
> "Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp." – Philip Greenspun
It supports a functional API for defining tags and filters. On the one hand, this isn't idiomatic Go. On the other hand, this made it possibly to quickly implement a boatload of Liquid and Jekyll filters that would otherwise have been onerous. The jury is still out…
`liquid` ports [Shopify Liquid templates](https://shopify.github.io/liquid) to Go. It was developed for use in [gojekyll](https://github.com/osteele/gojekyll).

`liquid` provides a functional API for defining tags and filters. See examples [here](https://github.com/osteele/liquid/blob/master/filters/filters.go), [here](https://github.com/osteele/gojekyll/blob/master/filters/filters.go), and [here](https://github.com/osteele/gojekyll/blob/master/tags/tags.go). On the one hand, this isn't idiomatic Go. On the other hand, this made it possible to implement a boatload of Liquid and Jekyll filters without an onerous amount of boilerplate – in some cases, simply by passing a reference to a function from the standard library.

<!-- TOC -->

Expand Down
4 changes: 4 additions & 0 deletions chunks/context.go
Expand Up @@ -10,16 +10,19 @@ type Context struct {
settings Settings
}

// Settings holds configuration information for parsing and rendering.
type Settings struct {
ExpressionSettings expressions.Settings
tags map[string]TagDefinition
controlTags map[string]*controlTagDefinition
}

// AddFilter adds a filter to settings.
func (s Settings) AddFilter(name string, fn interface{}) {
s.ExpressionSettings.AddFilter(name, fn)
}

// NewSettings creates a new Settings.
func NewSettings() Settings {
s := Settings{
expressions.NewSettings(),
Expand All @@ -41,6 +44,7 @@ func NewContext(scope map[string]interface{}, s Settings) Context {
return Context{vars, s}
}

// Clone makes a copy of a context, with copied bindings.
func (c Context) Clone() Context {
bindings := map[string]interface{}{}
for k, v := range c.bindings {
Expand Down
1 change: 1 addition & 0 deletions chunks/parser.go
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/osteele/liquid/expressions"
)

// Parse parses a source template. It returns an AST root, that can be evaluated.
func (s Settings) Parse(source string) (ASTNode, error) {
tokens := Scan(source, "")
return s.parseChunks(tokens)
Expand Down
3 changes: 3 additions & 0 deletions expressions/context.go
Expand Up @@ -12,14 +12,17 @@ type context struct {
Settings
}

// Settings holds configuration information for expression interpretation.
type Settings struct {
filters *filterDictionary
}

// NewSettings creates a new Settings.
func NewSettings() Settings {
return Settings{newFilterDictionary()}
}

// AddFilter adds a filter function to settings.
func (s Settings) AddFilter(name string, fn interface{}) {
s.filters.addFilter(name, fn)
}
Expand Down
2 changes: 0 additions & 2 deletions expressions/expressions.go
Expand Up @@ -44,8 +44,6 @@ func (e expression) Evaluate(ctx Context) (out interface{}, err error) {
err = e
case InterpreterError:
err = e
case UnimplementedError:
err = e
case UndefinedFilter:
err = e
default:
Expand Down
9 changes: 1 addition & 8 deletions expressions/parser.go
Expand Up @@ -17,25 +17,18 @@ type loopModifiers struct {
Reversed bool
}

// ParseError represents a parse error.
type ParseError string

func (e ParseError) Error() string { return string(e) }

type UnimplementedError string

func (e UnimplementedError) Error() string {
return fmt.Sprintf("unimplemented %s", string(e))
}

// Parse parses an expression string into an Expression.
func Parse(source string) (expr Expression, err error) {
defer func() {
if r := recover(); r != nil {
switch e := r.(type) {
case ParseError:
err = e
case UnimplementedError:
err = e
case UndefinedFilter:
err = e
default:
Expand Down
3 changes: 0 additions & 3 deletions interface.go
Expand Up @@ -54,9 +54,6 @@ type Context interface {
Bindings() map[string]interface{}
}

// Renderer is the type of a function that is evaluated within a context and writes to output.
// type Renderer func(io.Writer, chunks.Context) error

// TagDefinition is the type of a function that parses the argument string "args" from a tag "{% tagname args %}",
// and returns a renderer.
type TagDefinition func(io.Writer, chunks.RenderContext) error

0 comments on commit 983b9f5

Please sign in to comment.