diff --git a/build/RELEASE.md b/build/RELEASE.md
index d5783ae..638f70f 100644
--- a/build/RELEASE.md
+++ b/build/RELEASE.md
@@ -1,9 +1,4 @@
NEUERUNGEN:
-- Cached Collection Webrequests
-- recursive Collections
-- Datei basierte Collections
-- markdown-Filter `s=SYNTAX_HIGHLIGHT_SHEMA` Parameter
-- image_process nutzt alle CPU-Kerne
-- GZIP/Brotli Vor-Komprimierung der Inhalte und Assets
-- Code neu organisiert
\ No newline at end of file
+- pongo2 v4
+- natives brotli Package ohne cgo
diff --git a/build/VERSION b/build/VERSION
index 867e524..cb174d5 100644
--- a/build/VERSION
+++ b/build/VERSION
@@ -1 +1 @@
-1.2.0
\ No newline at end of file
+1.2.1
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 27698b8..45d846b 100644
--- a/go.mod
+++ b/go.mod
@@ -10,8 +10,9 @@ require (
github.com/ddliu/motto v0.3.1
github.com/disintegration/imaging v1.6.2
github.com/extemporalgenome/slug v0.0.0-20150414033109-0320c85e32e0
- github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3
+ github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect
github.com/flosch/pongo2-addons v0.0.0-20210526150811-f969446c5b72
+ github.com/flosch/pongo2/v4 v4.0.2
github.com/gosuri/uilive v0.0.4 // indirect
github.com/gosuri/uiprogress v0.0.1
github.com/imdario/mergo v0.3.12
@@ -25,5 +26,6 @@ require (
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
golang.org/x/text v0.3.7 // indirect
+ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0
)
diff --git a/go.sum b/go.sum
index 209ce00..549f1e6 100644
--- a/go.sum
+++ b/go.sum
@@ -46,6 +46,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -59,7 +61,6 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
@@ -114,8 +115,9 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
diff --git a/pkg/filter/custom.go b/pkg/filter/custom.go
index 64a750b..f18c905 100644
--- a/pkg/filter/custom.go
+++ b/pkg/filter/custom.go
@@ -8,7 +8,7 @@ import (
"gitbase.de/apairon/mark2web/pkg/logger"
"gitbase.de/apairon/mark2web/pkg/mark2web"
"github.com/ddliu/motto"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
_ "github.com/robertkrimen/otto/underscore"
)
diff --git a/pkg/filter/dump.go b/pkg/filter/dump.go
index 9c7c04c..84e22d6 100644
--- a/pkg/filter/dump.go
+++ b/pkg/filter/dump.go
@@ -2,7 +2,7 @@ package filter
import (
"github.com/davecgh/go-spew/spew"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
// DumpFilter is a pongo2 filter, which returns a spew.Dump of the input
diff --git a/pkg/filter/dump_test.go b/pkg/filter/dump_test.go
index 4925345..96f688b 100644
--- a/pkg/filter/dump_test.go
+++ b/pkg/filter/dump_test.go
@@ -5,7 +5,7 @@ import (
"github.com/davecgh/go-spew/spew"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/pkg/filter/image_process.go b/pkg/filter/image_process.go
index 1fac500..a8fca90 100644
--- a/pkg/filter/image_process.go
+++ b/pkg/filter/image_process.go
@@ -20,7 +20,7 @@ import (
"gitbase.de/apairon/mark2web/pkg/mark2web"
"gitbase.de/apairon/mark2web/pkg/webrequest"
"github.com/disintegration/imaging"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
func parseImageParams(str string) (*mark2web.ImagingConfig, error) {
@@ -211,9 +211,9 @@ func ImageProcessFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *
}
} else {
out, err := os.Create(imgTarget)
+ logger.Eexit(err, "filter:image_resize, could not create image file '%s'", imgTarget)
defer out.Close()
- logger.Eexit(err, "filter:image_resize, could not create image file '%s'", imgTarget)
switch p.Format {
case "jpeg", "jpg":
var jpegOpt *jpeg.Options
diff --git a/pkg/filter/image_process_test.go b/pkg/filter/image_process_test.go
index 633a128..b95c8ca 100644
--- a/pkg/filter/image_process_test.go
+++ b/pkg/filter/image_process_test.go
@@ -7,7 +7,7 @@ import (
"gitbase.de/apairon/mark2web/pkg/jobm"
"gitbase.de/apairon/mark2web/pkg/mark2web"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/pkg/filter/init.go b/pkg/filter/init.go
index 659b09a..fcac8a2 100644
--- a/pkg/filter/init.go
+++ b/pkg/filter/init.go
@@ -1,18 +1,18 @@
package filter
import (
- "github.com/flosch/pongo2"
_ "github.com/flosch/pongo2-addons"
+ "github.com/flosch/pongo2/v4"
)
func init() {
err := pongo2.ReplaceFilter("markdown", MarkdownFilter)
+ // if err != nil {
+ // err = pongo2.RegisterFilter("markdown", MarkdownFilter)
if err != nil {
- err = pongo2.RegisterFilter("markdown", MarkdownFilter)
- if err != nil {
- panic(err)
- }
+ panic(err)
}
+ // }
newFilters := map[string]pongo2.FilterFunction{
"image_process": ImageProcessFilter,
diff --git a/pkg/filter/json.go b/pkg/filter/json.go
index d231115..05ae384 100644
--- a/pkg/filter/json.go
+++ b/pkg/filter/json.go
@@ -4,7 +4,7 @@ import (
"encoding/json"
"strings"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
// JSONFilter is a pongo2 filter, which returns a json string of the input
diff --git a/pkg/filter/json_test.go b/pkg/filter/json_test.go
index 2d1bcbe..6dcbc90 100644
--- a/pkg/filter/json_test.go
+++ b/pkg/filter/json_test.go
@@ -4,7 +4,7 @@ import (
"math"
"testing"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/pkg/filter/markdown.go b/pkg/filter/markdown.go
index c8e2a08..b9ba3b6 100644
--- a/pkg/filter/markdown.go
+++ b/pkg/filter/markdown.go
@@ -5,7 +5,7 @@ import (
"strings"
"gitbase.de/apairon/mark2web/pkg/helper"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
// MarkdownFilter is a pongo2 filter, which converts markdown to html
diff --git a/pkg/filter/markdown_test.go b/pkg/filter/markdown_test.go
index 5158886..a3a1431 100644
--- a/pkg/filter/markdown_test.go
+++ b/pkg/filter/markdown_test.go
@@ -3,7 +3,7 @@ package filter
import (
"testing"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/pkg/filter/relative_path.go b/pkg/filter/relative_path.go
index 1a85bda..598ee11 100644
--- a/pkg/filter/relative_path.go
+++ b/pkg/filter/relative_path.go
@@ -2,7 +2,7 @@ package filter
import (
"gitbase.de/apairon/mark2web/pkg/mark2web"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
// RelativePathFilter returns the relative path to navpoint based on current nav
diff --git a/pkg/filter/relative_path_test.go b/pkg/filter/relative_path_test.go
index c61cd4e..fde982c 100644
--- a/pkg/filter/relative_path_test.go
+++ b/pkg/filter/relative_path_test.go
@@ -5,7 +5,7 @@ import (
"gitbase.de/apairon/mark2web/pkg/mark2web"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/pkg/mark2web/collection.go b/pkg/mark2web/collection.go
index 28224ee..90c7c14 100644
--- a/pkg/mark2web/collection.go
+++ b/pkg/mark2web/collection.go
@@ -10,7 +10,7 @@ import (
"gitbase.de/apairon/mark2web/pkg/logger"
"gitbase.de/apairon/mark2web/pkg/webrequest"
"github.com/davecgh/go-spew/spew"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
type colCacheEntry struct {
diff --git a/pkg/mark2web/content.go b/pkg/mark2web/content.go
index 37f841b..434bc53 100644
--- a/pkg/mark2web/content.go
+++ b/pkg/mark2web/content.go
@@ -12,7 +12,7 @@ import (
"gitbase.de/apairon/mark2web/pkg/helper"
"gitbase.de/apairon/mark2web/pkg/logger"
"github.com/davecgh/go-spew/spew"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
cpy "github.com/otiai10/copy"
"gopkg.in/yaml.v2"
)
@@ -72,7 +72,7 @@ func (node *TreeNode) processMarkdownWithHeader(md []byte, errorRef string) (*Pa
newConfig := new(PathConfig)
- headerRegex := regexp.MustCompile(`(?s)^---(.*?)\r?\n\r?---\r?\\n\r?`)
+ headerRegex := regexp.MustCompile("(?s)^---(.*?)\\r?\\n\\r?---\\r?\\n\\r?")
yamlData := headerRegex.Find(md)
if string(yamlData) != "" {
// replace tabs
@@ -95,7 +95,7 @@ func (node *TreeNode) processMarkdownWithHeader(md []byte, errorRef string) (*Pa
}
// use --- for splitting document in markdown parts
- regex := regexp.MustCompile(`\r?\n\r?---\r?\n\r?`)
+ regex := regexp.MustCompile("\\r?\\n\\r?---\\r?\\n\\r?")
inputParts := regex.Split(string(md), -1)
htmlParts := make([]*pongo2.Value, 0)
diff --git a/pkg/mark2web/context.go b/pkg/mark2web/context.go
index 4a12deb..64a1a1b 100644
--- a/pkg/mark2web/context.go
+++ b/pkg/mark2web/context.go
@@ -13,7 +13,7 @@ import (
"gitbase.de/apairon/mark2web/pkg/progress"
"github.com/davecgh/go-spew/spew"
"github.com/extemporalgenome/slug"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
"gopkg.in/yaml.v2"
)
diff --git a/pkg/mark2web/context_fn.go b/pkg/mark2web/context_fn.go
index a55ae77..f467591 100644
--- a/pkg/mark2web/context_fn.go
+++ b/pkg/mark2web/context_fn.go
@@ -2,7 +2,7 @@ package mark2web
import (
"gitbase.de/apairon/mark2web/pkg/webrequest"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
// RequestFn will make a web request and returns map[string]interface form pongo2
diff --git a/pkg/mark2web/render.go b/pkg/mark2web/render.go
index ec3cebe..de0edc5 100644
--- a/pkg/mark2web/render.go
+++ b/pkg/mark2web/render.go
@@ -3,7 +3,7 @@ package mark2web
import (
"log"
- "github.com/flosch/pongo2"
+ "github.com/flosch/pongo2/v4"
)
var templateCache = make(map[string]*pongo2.Template)
diff --git a/tmp/build-errors.log b/tmp/build-errors.log
index 05e5985..571fc8e 100644
--- a/tmp/build-errors.log
+++ b/tmp/build-errors.log
@@ -1 +1 @@
-exit status 1
\ No newline at end of file
+exit status 1exit status 1exit status 1
\ No newline at end of file
diff --git a/tmp/main b/tmp/main
index b42fd32..1d348cd 100755
Binary files a/tmp/main and b/tmp/main differ
diff --git a/vendor/github.com/flosch/pongo2/.gitattributes b/vendor/github.com/flosch/pongo2/.gitattributes
deleted file mode 100644
index fcadb2c..0000000
--- a/vendor/github.com/flosch/pongo2/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-* text eol=lf
diff --git a/vendor/github.com/flosch/pongo2/.gitignore b/vendor/github.com/flosch/pongo2/.gitignore
deleted file mode 100644
index 1346be5..0000000
--- a/vendor/github.com/flosch/pongo2/.gitignore
+++ /dev/null
@@ -1,41 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-.idea
-.vscode
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-
-.project
-EBNF.txt
-test1.tpl
-pongo2_internal_test.go
-tpl-error.out
-/count.out
-/cover.out
-*.swp
-*.iml
-/cpu.out
-/mem.out
-/pongo2.test
-*.error
-/profile
-/coverage.out
-/pongo2_internal_test.ignore
diff --git a/vendor/github.com/flosch/pongo2/.travis.yml b/vendor/github.com/flosch/pongo2/.travis.yml
deleted file mode 100644
index e39e5d0..0000000
--- a/vendor/github.com/flosch/pongo2/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: go
-os:
- - linux
- - osx
-go:
- - 1.12
-script:
- - go test -v
diff --git a/vendor/github.com/flosch/pongo2/AUTHORS b/vendor/github.com/flosch/pongo2/AUTHORS
deleted file mode 100644
index 601697c..0000000
--- a/vendor/github.com/flosch/pongo2/AUTHORS
+++ /dev/null
@@ -1,11 +0,0 @@
-Main author and maintainer of pongo2:
-
-* Florian Schlachter
-
-Contributors (in no specific order):
-
-* @romanoaugusto88
-* @vitalbh
-* @blaubaer
-
-Feel free to add yourself to the list or to modify your entry if you did a contribution.
diff --git a/vendor/github.com/flosch/pongo2/LICENSE b/vendor/github.com/flosch/pongo2/LICENSE
deleted file mode 100644
index e876f86..0000000
--- a/vendor/github.com/flosch/pongo2/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013-2014 Florian Schlachter
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/flosch/pongo2/README.md b/vendor/github.com/flosch/pongo2/README.md
deleted file mode 100644
index e59694e..0000000
--- a/vendor/github.com/flosch/pongo2/README.md
+++ /dev/null
@@ -1,167 +0,0 @@
-# [pongo](https://en.wikipedia.org/wiki/Pongo_%28genus%29)2
-
-[![PkgGoDev](https://pkg.go.dev/badge/flosch/pongo2)](https://pkg.go.dev/flosch/pongo2)
-[![Build Status](https://travis-ci.org/flosch/pongo2.svg?branch=master)](https://travis-ci.org/flosch/pongo2)
-
-pongo2 is a Django-syntax like templating-language.
-
-Install/update using `go get` (no dependencies required by pongo2):
-
-```sh
-go get -u github.com/flosch/pongo2
-```
-
-Please use the [issue tracker](https://github.com/flosch/pongo2/issues) if you're encountering any problems with pongo2 or if you need help with implementing tags or filters ([create a ticket!](https://github.com/flosch/pongo2/issues/new)).
-
-## First impression of a template
-
-```django
-
-
- Our admins and users
-
- {# This is a short example to give you a quick overview of pongo2's syntax. #}
- {% macro user_details(user, is_admin=false) %}
-
-
-
- = 40) || (user.karma > calc_avg_karma(userlist)+5) %} class="karma-good"{%
- endif %}>
-
-
- {{ user }}
-
-
-
-
This user registered {{ user.register_date|naturaltime }}.
-
-
-
The user's biography:
-
- {{ user.biography|markdown|truncatewords_html:15 }}
- read more
-
-
- {% if is_admin %}
-
This user is an admin!
- {% endif %}
-
- {% endmacro %}
-
-
-
-
- Our admins
- {% for admin in adminlist %} {{ user_details(admin, true) }} {% endfor %}
-
- Our members
- {% for user in userlist %} {{ user_details(user) }} {% endfor %}
-
-
-```
-
-## Features
-
-- Syntax- and feature-set-compatible with [Django 1.7](https://django.readthedocs.io/en/1.7.x/topics/templates.html)
-- [Advanced C-like expressions](https://github.com/flosch/pongo2/blob/master/template_tests/expressions.tpl).
-- [Complex function calls within expressions](https://github.com/flosch/pongo2/blob/master/template_tests/function_calls_wrapper.tpl).
-- [Easy API to create new filters and tags](http://godoc.org/github.com/flosch/pongo2#RegisterFilter) ([including parsing arguments](http://godoc.org/github.com/flosch/pongo2#Parser))
-- Additional features:
- - Macros including importing macros from other files (see [template_tests/macro.tpl](https://github.com/flosch/pongo2/blob/master/template_tests/macro.tpl))
- - [Template sandboxing](https://godoc.org/github.com/flosch/pongo2#TemplateSet) ([directory patterns](http://golang.org/pkg/path/filepath/#Match), banned tags/filters)
-
-## Caveats
-
-### Filters
-
-- **date** / **time**: The `date` and `time` filter are taking the Golang specific time- and date-format (not Django's one) currently. [Take a look on the format here](http://golang.org/pkg/time/#Time.Format).
-- **stringformat**: `stringformat` does **not** take Python's string format syntax as a parameter, instead it takes Go's. Essentially `{{ 3.14|stringformat:"pi is %.2f" }}` is `fmt.Sprintf("pi is %.2f", 3.14)`.
-- **escape** / **force_escape**: Unlike Django's behaviour, the `escape`-filter is applied immediately. Therefore there is no need for a `force_escape`-filter yet.
-
-### Tags
-
-- **for**: All the `forloop` fields (like `forloop.counter`) are written with a capital letter at the beginning. For example, the `counter` can be accessed by `forloop.Counter` and the parentloop by `forloop.Parentloop`.
-- **now**: takes Go's time format (see **date** and **time**-filter).
-
-### Misc
-
-- **not in-operator**: You can check whether a map/struct/string contains a key/field/substring by using the in-operator (or the negation of it):
- `{% if key in map %}Key is in map{% else %}Key not in map{% endif %}` or `{% if !(key in map) %}Key is NOT in map{% else %}Key is in map{% endif %}`.
-
-## Add-ons, libraries and helpers
-
-### Official
-
-- [pongo2-addons](https://github.com/flosch/pongo2-addons) - Official additional filters/tags for pongo2 (for example a **markdown**-filter). They are in their own repository because they're relying on 3rd-party-libraries.
-
-### 3rd-party
-
-- [beego-pongo2](https://github.com/oal/beego-pongo2) - A tiny little helper for using Pongo2 with [Beego](https://github.com/astaxie/beego).
-- [beego-pongo2.v2](https://github.com/ipfans/beego-pongo2.v2) - Same as `beego-pongo2`, but for pongo2 v2.
-- [macaron-pongo2](https://github.com/macaron-contrib/pongo2) - pongo2 support for [Macaron](https://github.com/Unknwon/macaron), a modular web framework.
-- [ginpongo2](https://github.com/ngerakines/ginpongo2) - middleware for [gin](github.com/gin-gonic/gin) to use pongo2 templates
-- [Build'n support for Iris' template engine](https://github.com/kataras/iris)
-- [pongo2gin](https://gitlab.com/go-box/pongo2gin) - alternative renderer for [gin](github.com/gin-gonic/gin) to use pongo2 templates
-- [pongo2-trans](https://github.com/digitalcrab/pongo2trans) - `trans`-tag implementation for internationalization
-- [tpongo2](https://github.com/tango-contrib/tpongo2) - pongo2 support for [Tango](https://github.com/lunny/tango), a micro-kernel & pluggable web framework.
-- [p2cli](https://github.com/wrouesnel/p2cli) - command line templating utility based on pongo2
-
-Please add your project to this list and send me a pull request when you've developed something nice for pongo2.
-
-## Who's using pongo2
-
-[I'm compiling a list of pongo2 users](https://github.com/flosch/pongo2/issues/241). Add your project or company!
-
-## API-usage examples
-
-Please see the documentation for a full list of provided API methods.
-
-### A tiny example (template string)
-
-```go
-// Compile the template first (i. e. creating the AST)
-tpl, err := pongo2.FromString("Hello {{ name|capfirst }}!")
-if err != nil {
- panic(err)
-}
-// Now you can render the template with the given
-// pongo2.Context how often you want to.
-out, err := tpl.Execute(pongo2.Context{"name": "florian"})
-if err != nil {
- panic(err)
-}
-fmt.Println(out) // Output: Hello Florian!
-```
-
-## Example server-usage (template file)
-
-```go
-package main
-
-import (
- "github.com/flosch/pongo2"
- "net/http"
-)
-
-// Pre-compiling the templates at application startup using the
-// little Must()-helper function (Must() will panic if FromFile()
-// or FromString() will return with an error - that's it).
-// It's faster to pre-compile it anywhere at startup and only
-// execute the template later.
-var tplExample = pongo2.Must(pongo2.FromFile("example.html"))
-
-func examplePage(w http.ResponseWriter, r *http.Request) {
- // Execute the template per HTTP request
- err := tplExample.ExecuteWriter(pongo2.Context{"query": r.FormValue("query")}, w)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- }
-}
-
-func main() {
- http.HandleFunc("/", examplePage)
- http.ListenAndServe(":8080", nil)
-}
-```
diff --git a/vendor/github.com/flosch/pongo2/context.go b/vendor/github.com/flosch/pongo2/context.go
deleted file mode 100644
index dbc5e3e..0000000
--- a/vendor/github.com/flosch/pongo2/context.go
+++ /dev/null
@@ -1,137 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "regexp"
-
- "errors"
-)
-
-var reIdentifiers = regexp.MustCompile("^[a-zA-Z0-9_]+$")
-
-var autoescape = true
-
-func SetAutoescape(newValue bool) {
- autoescape = newValue
-}
-
-// A Context type provides constants, variables, instances or functions to a template.
-//
-// pongo2 automatically provides meta-information or functions through the "pongo2"-key.
-// Currently, context["pongo2"] contains the following keys:
-// 1. version: returns the version string
-//
-// Template examples for accessing items from your context:
-// {{ myconstant }}
-// {{ myfunc("test", 42) }}
-// {{ user.name }}
-// {{ pongo2.version }}
-type Context map[string]interface{}
-
-func (c Context) checkForValidIdentifiers() *Error {
- for k, v := range c {
- if !reIdentifiers.MatchString(k) {
- return &Error{
- Sender: "checkForValidIdentifiers",
- OrigError: fmt.Errorf("context-key '%s' (value: '%+v') is not a valid identifier", k, v),
- }
- }
- }
- return nil
-}
-
-// Update updates this context with the key/value-pairs from another context.
-func (c Context) Update(other Context) Context {
- for k, v := range other {
- c[k] = v
- }
- return c
-}
-
-// ExecutionContext contains all data important for the current rendering state.
-//
-// If you're writing a custom tag, your tag's Execute()-function will
-// have access to the ExecutionContext. This struct stores anything
-// about the current rendering process's Context including
-// the Context provided by the user (field Public).
-// You can safely use the Private context to provide data to the user's
-// template (like a 'forloop'-information). The Shared-context is used
-// to share data between tags. All ExecutionContexts share this context.
-//
-// Please be careful when accessing the Public data.
-// PLEASE DO NOT MODIFY THE PUBLIC CONTEXT (read-only).
-//
-// To create your own execution context within tags, use the
-// NewChildExecutionContext(parent) function.
-type ExecutionContext struct {
- template *Template
-
- Autoescape bool
- Public Context
- Private Context
- Shared Context
-}
-
-var pongo2MetaContext = Context{
- "version": Version,
-}
-
-func newExecutionContext(tpl *Template, ctx Context) *ExecutionContext {
- privateCtx := make(Context)
-
- // Make the pongo2-related funcs/vars available to the context
- privateCtx["pongo2"] = pongo2MetaContext
-
- return &ExecutionContext{
- template: tpl,
-
- Public: ctx,
- Private: privateCtx,
- Autoescape: autoescape,
- }
-}
-
-func NewChildExecutionContext(parent *ExecutionContext) *ExecutionContext {
- newctx := &ExecutionContext{
- template: parent.template,
-
- Public: parent.Public,
- Private: make(Context),
- Autoescape: parent.Autoescape,
- }
- newctx.Shared = parent.Shared
-
- // Copy all existing private items
- newctx.Private.Update(parent.Private)
-
- return newctx
-}
-
-func (ctx *ExecutionContext) Error(msg string, token *Token) *Error {
- return ctx.OrigError(errors.New(msg), token)
-}
-
-func (ctx *ExecutionContext) OrigError(err error, token *Token) *Error {
- filename := ctx.template.name
- var line, col int
- if token != nil {
- // No tokens available
- // TODO: Add location (from where?)
- filename = token.Filename
- line = token.Line
- col = token.Col
- }
- return &Error{
- Template: ctx.template,
- Filename: filename,
- Line: line,
- Column: col,
- Token: token,
- Sender: "execution",
- OrigError: err,
- }
-}
-
-func (ctx *ExecutionContext) Logf(format string, args ...interface{}) {
- ctx.template.set.logf(format, args...)
-}
diff --git a/vendor/github.com/flosch/pongo2/doc.go b/vendor/github.com/flosch/pongo2/doc.go
deleted file mode 100644
index 5a23e2b..0000000
--- a/vendor/github.com/flosch/pongo2/doc.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// A Django-syntax like template-engine
-//
-// Blog posts about pongo2 (including introduction and migration):
-// https://www.florian-schlachter.de/?tag=pongo2
-//
-// Complete documentation on the template language:
-// https://docs.djangoproject.com/en/dev/topics/templates/
-//
-// Try out pongo2 live in the pongo2 playground:
-// https://www.florian-schlachter.de/pongo2/
-//
-// Make sure to read README.md in the repository as well.
-//
-// A tiny example with template strings:
-//
-// (Snippet on playground: https://www.florian-schlachter.de/pongo2/?id=1206546277)
-//
-// // Compile the template first (i. e. creating the AST)
-// tpl, err := pongo2.FromString("Hello {{ name|capfirst }}!")
-// if err != nil {
-// panic(err)
-// }
-// // Now you can render the template with the given
-// // pongo2.Context how often you want to.
-// out, err := tpl.Execute(pongo2.Context{"name": "fred"})
-// if err != nil {
-// panic(err)
-// }
-// fmt.Println(out) // Output: Hello Fred!
-//
-package pongo2
diff --git a/vendor/github.com/flosch/pongo2/error.go b/vendor/github.com/flosch/pongo2/error.go
deleted file mode 100644
index 8aec8c1..0000000
--- a/vendor/github.com/flosch/pongo2/error.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package pongo2
-
-import (
- "bufio"
- "fmt"
- "os"
-)
-
-// The Error type is being used to address an error during lexing, parsing or
-// execution. If you want to return an error object (for example in your own
-// tag or filter) fill this object with as much information as you have.
-// Make sure "Sender" is always given (if you're returning an error within
-// a filter, make Sender equals 'filter:yourfilter'; same goes for tags: 'tag:mytag').
-// It's okay if you only fill in ErrorMsg if you don't have any other details at hand.
-type Error struct {
- Template *Template
- Filename string
- Line int
- Column int
- Token *Token
- Sender string
- OrigError error
-}
-
-func (e *Error) updateFromTokenIfNeeded(template *Template, t *Token) *Error {
- if e.Template == nil {
- e.Template = template
- }
-
- if e.Token == nil {
- e.Token = t
- if e.Line <= 0 {
- e.Line = t.Line
- e.Column = t.Col
- }
- }
-
- return e
-}
-
-// Returns a nice formatted error string.
-func (e *Error) Error() string {
- s := "[Error"
- if e.Sender != "" {
- s += " (where: " + e.Sender + ")"
- }
- if e.Filename != "" {
- s += " in " + e.Filename
- }
- if e.Line > 0 {
- s += fmt.Sprintf(" | Line %d Col %d", e.Line, e.Column)
- if e.Token != nil {
- s += fmt.Sprintf(" near '%s'", e.Token.Val)
- }
- }
- s += "] "
- s += e.OrigError.Error()
- return s
-}
-
-// RawLine returns the affected line from the original template, if available.
-func (e *Error) RawLine() (line string, available bool, outErr error) {
- if e.Line <= 0 || e.Filename == "" {
- return "", false, nil
- }
-
- filename := e.Filename
- if e.Template != nil {
- filename = e.Template.set.resolveFilename(e.Template, e.Filename)
- }
- file, err := os.Open(filename)
- if err != nil {
- return "", false, err
- }
- defer func() {
- err := file.Close()
- if err != nil && outErr == nil {
- outErr = err
- }
- }()
-
- scanner := bufio.NewScanner(file)
- l := 0
- for scanner.Scan() {
- l++
- if l == e.Line {
- return scanner.Text(), true, nil
- }
- }
- return "", false, nil
-}
diff --git a/vendor/github.com/flosch/pongo2/filters.go b/vendor/github.com/flosch/pongo2/filters.go
deleted file mode 100644
index 8d4c89e..0000000
--- a/vendor/github.com/flosch/pongo2/filters.go
+++ /dev/null
@@ -1,141 +0,0 @@
-package pongo2
-
-import (
- "fmt"
-)
-
-// FilterFunction is the type filter functions must fulfil
-type FilterFunction func(in *Value, param *Value) (out *Value, err *Error)
-
-var filters map[string]FilterFunction
-
-func init() {
- filters = make(map[string]FilterFunction)
-}
-
-// FilterExists returns true if the given filter is already registered
-func FilterExists(name string) bool {
- _, existing := filters[name]
- return existing
-}
-
-// RegisterFilter registers a new filter. If there's already a filter with the same
-// name, RegisterFilter will panic. You usually want to call this
-// function in the filter's init() function:
-// http://golang.org/doc/effective_go.html#init
-//
-// See http://www.florian-schlachter.de/post/pongo2/ for more about
-// writing filters and tags.
-func RegisterFilter(name string, fn FilterFunction) error {
- if FilterExists(name) {
- return fmt.Errorf("filter with name '%s' is already registered", name)
- }
- filters[name] = fn
- return nil
-}
-
-// ReplaceFilter replaces an already registered filter with a new implementation. Use this
-// function with caution since it allows you to change existing filter behaviour.
-func ReplaceFilter(name string, fn FilterFunction) error {
- if !FilterExists(name) {
- return fmt.Errorf("filter with name '%s' does not exist (therefore cannot be overridden)", name)
- }
- filters[name] = fn
- return nil
-}
-
-// MustApplyFilter behaves like ApplyFilter, but panics on an error.
-func MustApplyFilter(name string, value *Value, param *Value) *Value {
- val, err := ApplyFilter(name, value, param)
- if err != nil {
- panic(err)
- }
- return val
-}
-
-// ApplyFilter applies a filter to a given value using the given parameters.
-// Returns a *pongo2.Value or an error.
-func ApplyFilter(name string, value *Value, param *Value) (*Value, *Error) {
- fn, existing := filters[name]
- if !existing {
- return nil, &Error{
- Sender: "applyfilter",
- OrigError: fmt.Errorf("Filter with name '%s' not found.", name),
- }
- }
-
- // Make sure param is a *Value
- if param == nil {
- param = AsValue(nil)
- }
-
- return fn(value, param)
-}
-
-type filterCall struct {
- token *Token
-
- name string
- parameter IEvaluator
-
- filterFunc FilterFunction
-}
-
-func (fc *filterCall) Execute(v *Value, ctx *ExecutionContext) (*Value, *Error) {
- var param *Value
- var err *Error
-
- if fc.parameter != nil {
- param, err = fc.parameter.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- } else {
- param = AsValue(nil)
- }
-
- filteredValue, err := fc.filterFunc(v, param)
- if err != nil {
- return nil, err.updateFromTokenIfNeeded(ctx.template, fc.token)
- }
- return filteredValue, nil
-}
-
-// Filter = IDENT | IDENT ":" FilterArg | IDENT "|" Filter
-func (p *Parser) parseFilter() (*filterCall, *Error) {
- identToken := p.MatchType(TokenIdentifier)
-
- // Check filter ident
- if identToken == nil {
- return nil, p.Error("Filter name must be an identifier.", nil)
- }
-
- filter := &filterCall{
- token: identToken,
- name: identToken.Val,
- }
-
- // Get the appropriate filter function and bind it
- filterFn, exists := filters[identToken.Val]
- if !exists {
- return nil, p.Error(fmt.Sprintf("Filter '%s' does not exist.", identToken.Val), identToken)
- }
-
- filter.filterFunc = filterFn
-
- // Check for filter-argument (2 tokens needed: ':' ARG)
- if p.Match(TokenSymbol, ":") != nil {
- if p.Peek(TokenSymbol, "}}") != nil {
- return nil, p.Error("Filter parameter required after ':'.", nil)
- }
-
- // Get filter argument expression
- v, err := p.parseVariableOrLiteral()
- if err != nil {
- return nil, err
- }
- filter.parameter = v
- }
-
- return filter, nil
-}
diff --git a/vendor/github.com/flosch/pongo2/filters_builtin.go b/vendor/github.com/flosch/pongo2/filters_builtin.go
deleted file mode 100644
index c0ec616..0000000
--- a/vendor/github.com/flosch/pongo2/filters_builtin.go
+++ /dev/null
@@ -1,927 +0,0 @@
-package pongo2
-
-/* Filters that are provided through github.com/flosch/pongo2-addons:
- ------------------------------------------------------------------
-
- filesizeformat
- slugify
- timesince
- timeuntil
-
- Filters that won't be added:
- ----------------------------
-
- get_static_prefix (reason: web-framework specific)
- pprint (reason: python-specific)
- static (reason: web-framework specific)
-
- Reconsideration (not implemented yet):
- --------------------------------------
-
- force_escape (reason: not yet needed since this is the behaviour of pongo2's escape filter)
- safeseq (reason: same reason as `force_escape`)
- unordered_list (python-specific; not sure whether needed or not)
- dictsort (python-specific; maybe one could add a filter to sort a list of structs by a specific field name)
- dictsortreversed (see dictsort)
-*/
-
-import (
- "bytes"
- "fmt"
- "math/rand"
- "net/url"
- "regexp"
- "strconv"
- "strings"
- "time"
- "unicode/utf8"
-
- "errors"
-)
-
-func init() {
- rand.Seed(time.Now().Unix())
-
- RegisterFilter("escape", filterEscape)
- RegisterFilter("safe", filterSafe)
- RegisterFilter("escapejs", filterEscapejs)
-
- RegisterFilter("add", filterAdd)
- RegisterFilter("addslashes", filterAddslashes)
- RegisterFilter("capfirst", filterCapfirst)
- RegisterFilter("center", filterCenter)
- RegisterFilter("cut", filterCut)
- RegisterFilter("date", filterDate)
- RegisterFilter("default", filterDefault)
- RegisterFilter("default_if_none", filterDefaultIfNone)
- RegisterFilter("divisibleby", filterDivisibleby)
- RegisterFilter("first", filterFirst)
- RegisterFilter("floatformat", filterFloatformat)
- RegisterFilter("get_digit", filterGetdigit)
- RegisterFilter("iriencode", filterIriencode)
- RegisterFilter("join", filterJoin)
- RegisterFilter("last", filterLast)
- RegisterFilter("length", filterLength)
- RegisterFilter("length_is", filterLengthis)
- RegisterFilter("linebreaks", filterLinebreaks)
- RegisterFilter("linebreaksbr", filterLinebreaksbr)
- RegisterFilter("linenumbers", filterLinenumbers)
- RegisterFilter("ljust", filterLjust)
- RegisterFilter("lower", filterLower)
- RegisterFilter("make_list", filterMakelist)
- RegisterFilter("phone2numeric", filterPhone2numeric)
- RegisterFilter("pluralize", filterPluralize)
- RegisterFilter("random", filterRandom)
- RegisterFilter("removetags", filterRemovetags)
- RegisterFilter("rjust", filterRjust)
- RegisterFilter("slice", filterSlice)
- RegisterFilter("split", filterSplit)
- RegisterFilter("stringformat", filterStringformat)
- RegisterFilter("striptags", filterStriptags)
- RegisterFilter("time", filterDate) // time uses filterDate (same golang-format)
- RegisterFilter("title", filterTitle)
- RegisterFilter("truncatechars", filterTruncatechars)
- RegisterFilter("truncatechars_html", filterTruncatecharsHTML)
- RegisterFilter("truncatewords", filterTruncatewords)
- RegisterFilter("truncatewords_html", filterTruncatewordsHTML)
- RegisterFilter("upper", filterUpper)
- RegisterFilter("urlencode", filterUrlencode)
- RegisterFilter("urlize", filterUrlize)
- RegisterFilter("urlizetrunc", filterUrlizetrunc)
- RegisterFilter("wordcount", filterWordcount)
- RegisterFilter("wordwrap", filterWordwrap)
- RegisterFilter("yesno", filterYesno)
-
- RegisterFilter("float", filterFloat) // pongo-specific
- RegisterFilter("integer", filterInteger) // pongo-specific
-}
-
-func filterTruncatecharsHelper(s string, newLen int) string {
- runes := []rune(s)
- if newLen < len(runes) {
- if newLen >= 3 {
- return fmt.Sprintf("%s...", string(runes[:newLen-3]))
- }
- // Not enough space for the ellipsis
- return string(runes[:newLen])
- }
- return string(runes)
-}
-
-func filterTruncateHTMLHelper(value string, newOutput *bytes.Buffer, cond func() bool, fn func(c rune, s int, idx int) int, finalize func()) {
- vLen := len(value)
- var tagStack []string
- idx := 0
-
- for idx < vLen && !cond() {
- c, s := utf8.DecodeRuneInString(value[idx:])
- if c == utf8.RuneError {
- idx += s
- continue
- }
-
- if c == '<' {
- newOutput.WriteRune(c)
- idx += s // consume "<"
-
- if idx+1 < vLen {
- if value[idx] == '/' {
- // Close tag
-
- newOutput.WriteString("/")
-
- tag := ""
- idx++ // consume "/"
-
- for idx < vLen {
- c2, size2 := utf8.DecodeRuneInString(value[idx:])
- if c2 == utf8.RuneError {
- idx += size2
- continue
- }
-
- // End of tag found
- if c2 == '>' {
- idx++ // consume ">"
- break
- }
- tag += string(c2)
- idx += size2
- }
-
- if len(tagStack) > 0 {
- // Ideally, the close tag is TOP of tag stack
- // In malformed HTML, it must not be, so iterate through the stack and remove the tag
- for i := len(tagStack) - 1; i >= 0; i-- {
- if tagStack[i] == tag {
- // Found the tag
- tagStack[i] = tagStack[len(tagStack)-1]
- tagStack = tagStack[:len(tagStack)-1]
- break
- }
- }
- }
-
- newOutput.WriteString(tag)
- newOutput.WriteString(">")
- } else {
- // Open tag
-
- tag := ""
-
- params := false
- for idx < vLen {
- c2, size2 := utf8.DecodeRuneInString(value[idx:])
- if c2 == utf8.RuneError {
- idx += size2
- continue
- }
-
- newOutput.WriteRune(c2)
-
- // End of tag found
- if c2 == '>' {
- idx++ // consume ">"
- break
- }
-
- if !params {
- if c2 == ' ' {
- params = true
- } else {
- tag += string(c2)
- }
- }
-
- idx += size2
- }
-
- // Add tag to stack
- tagStack = append(tagStack, tag)
- }
- }
- } else {
- idx = fn(c, s, idx)
- }
- }
-
- finalize()
-
- for i := len(tagStack) - 1; i >= 0; i-- {
- tag := tagStack[i]
- // Close everything from the regular tag stack
- newOutput.WriteString(fmt.Sprintf("%s>", tag))
- }
-}
-
-func filterTruncatechars(in *Value, param *Value) (*Value, *Error) {
- s := in.String()
- newLen := param.Integer()
- return AsValue(filterTruncatecharsHelper(s, newLen)), nil
-}
-
-func filterTruncatecharsHTML(in *Value, param *Value) (*Value, *Error) {
- value := in.String()
- newLen := max(param.Integer()-3, 0)
-
- newOutput := bytes.NewBuffer(nil)
-
- textcounter := 0
-
- filterTruncateHTMLHelper(value, newOutput, func() bool {
- return textcounter >= newLen
- }, func(c rune, s int, idx int) int {
- textcounter++
- newOutput.WriteRune(c)
-
- return idx + s
- }, func() {
- if textcounter >= newLen && textcounter < len(value) {
- newOutput.WriteString("...")
- }
- })
-
- return AsSafeValue(newOutput.String()), nil
-}
-
-func filterTruncatewords(in *Value, param *Value) (*Value, *Error) {
- words := strings.Fields(in.String())
- n := param.Integer()
- if n <= 0 {
- return AsValue(""), nil
- }
- nlen := min(len(words), n)
- out := make([]string, 0, nlen)
- for i := 0; i < nlen; i++ {
- out = append(out, words[i])
- }
-
- if n < len(words) {
- out = append(out, "...")
- }
-
- return AsValue(strings.Join(out, " ")), nil
-}
-
-func filterTruncatewordsHTML(in *Value, param *Value) (*Value, *Error) {
- value := in.String()
- newLen := max(param.Integer(), 0)
-
- newOutput := bytes.NewBuffer(nil)
-
- wordcounter := 0
-
- filterTruncateHTMLHelper(value, newOutput, func() bool {
- return wordcounter >= newLen
- }, func(_ rune, _ int, idx int) int {
- // Get next word
- wordFound := false
-
- for idx < len(value) {
- c2, size2 := utf8.DecodeRuneInString(value[idx:])
- if c2 == utf8.RuneError {
- idx += size2
- continue
- }
-
- if c2 == '<' {
- // HTML tag start, don't consume it
- return idx
- }
-
- newOutput.WriteRune(c2)
- idx += size2
-
- if c2 == ' ' || c2 == '.' || c2 == ',' || c2 == ';' {
- // Word ends here, stop capturing it now
- break
- } else {
- wordFound = true
- }
- }
-
- if wordFound {
- wordcounter++
- }
-
- return idx
- }, func() {
- if wordcounter >= newLen {
- newOutput.WriteString("...")
- }
- })
-
- return AsSafeValue(newOutput.String()), nil
-}
-
-func filterEscape(in *Value, param *Value) (*Value, *Error) {
- output := strings.Replace(in.String(), "&", "&", -1)
- output = strings.Replace(output, ">", ">", -1)
- output = strings.Replace(output, "<", "<", -1)
- output = strings.Replace(output, "\"", """, -1)
- output = strings.Replace(output, "'", "'", -1)
- return AsValue(output), nil
-}
-
-func filterSafe(in *Value, param *Value) (*Value, *Error) {
- return in, nil // nothing to do here, just to keep track of the safe application
-}
-
-func filterEscapejs(in *Value, param *Value) (*Value, *Error) {
- sin := in.String()
-
- var b bytes.Buffer
-
- idx := 0
- for idx < len(sin) {
- c, size := utf8.DecodeRuneInString(sin[idx:])
- if c == utf8.RuneError {
- idx += size
- continue
- }
-
- if c == '\\' {
- // Escape seq?
- if idx+1 < len(sin) {
- switch sin[idx+1] {
- case 'r':
- b.WriteString(fmt.Sprintf(`\u%04X`, '\r'))
- idx += 2
- continue
- case 'n':
- b.WriteString(fmt.Sprintf(`\u%04X`, '\n'))
- idx += 2
- continue
- /*case '\'':
- b.WriteString(fmt.Sprintf(`\u%04X`, '\''))
- idx += 2
- continue
- case '"':
- b.WriteString(fmt.Sprintf(`\u%04X`, '"'))
- idx += 2
- continue*/
- }
- }
- }
-
- if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == ' ' || c == '/' {
- b.WriteRune(c)
- } else {
- b.WriteString(fmt.Sprintf(`\u%04X`, c))
- }
-
- idx += size
- }
-
- return AsValue(b.String()), nil
-}
-
-func filterAdd(in *Value, param *Value) (*Value, *Error) {
- if in.IsNumber() && param.IsNumber() {
- if in.IsFloat() || param.IsFloat() {
- return AsValue(in.Float() + param.Float()), nil
- }
- return AsValue(in.Integer() + param.Integer()), nil
- }
- // If in/param is not a number, we're relying on the
- // Value's String() conversion and just add them both together
- return AsValue(in.String() + param.String()), nil
-}
-
-func filterAddslashes(in *Value, param *Value) (*Value, *Error) {
- output := strings.Replace(in.String(), "\\", "\\\\", -1)
- output = strings.Replace(output, "\"", "\\\"", -1)
- output = strings.Replace(output, "'", "\\'", -1)
- return AsValue(output), nil
-}
-
-func filterCut(in *Value, param *Value) (*Value, *Error) {
- return AsValue(strings.Replace(in.String(), param.String(), "", -1)), nil
-}
-
-func filterLength(in *Value, param *Value) (*Value, *Error) {
- return AsValue(in.Len()), nil
-}
-
-func filterLengthis(in *Value, param *Value) (*Value, *Error) {
- return AsValue(in.Len() == param.Integer()), nil
-}
-
-func filterDefault(in *Value, param *Value) (*Value, *Error) {
- if !in.IsTrue() {
- return param, nil
- }
- return in, nil
-}
-
-func filterDefaultIfNone(in *Value, param *Value) (*Value, *Error) {
- if in.IsNil() {
- return param, nil
- }
- return in, nil
-}
-
-func filterDivisibleby(in *Value, param *Value) (*Value, *Error) {
- if param.Integer() == 0 {
- return AsValue(false), nil
- }
- return AsValue(in.Integer()%param.Integer() == 0), nil
-}
-
-func filterFirst(in *Value, param *Value) (*Value, *Error) {
- if in.CanSlice() && in.Len() > 0 {
- return in.Index(0), nil
- }
- return AsValue(""), nil
-}
-
-func filterFloatformat(in *Value, param *Value) (*Value, *Error) {
- val := in.Float()
-
- decimals := -1
- if !param.IsNil() {
- // Any argument provided?
- decimals = param.Integer()
- }
-
- // if the argument is not a number (e. g. empty), the default
- // behaviour is trim the result
- trim := !param.IsNumber()
-
- if decimals <= 0 {
- // argument is negative or zero, so we
- // want the output being trimmed
- decimals = -decimals
- trim = true
- }
-
- if trim {
- // Remove zeroes
- if float64(int(val)) == val {
- return AsValue(in.Integer()), nil
- }
- }
-
- return AsValue(strconv.FormatFloat(val, 'f', decimals, 64)), nil
-}
-
-func filterGetdigit(in *Value, param *Value) (*Value, *Error) {
- i := param.Integer()
- l := len(in.String()) // do NOT use in.Len() here!
- if i <= 0 || i > l {
- return in, nil
- }
- return AsValue(in.String()[l-i] - 48), nil
-}
-
-const filterIRIChars = "/#%[]=:;$&()+,!?*@'~"
-
-func filterIriencode(in *Value, param *Value) (*Value, *Error) {
- var b bytes.Buffer
-
- sin := in.String()
- for _, r := range sin {
- if strings.IndexRune(filterIRIChars, r) >= 0 {
- b.WriteRune(r)
- } else {
- b.WriteString(url.QueryEscape(string(r)))
- }
- }
-
- return AsValue(b.String()), nil
-}
-
-func filterJoin(in *Value, param *Value) (*Value, *Error) {
- if !in.CanSlice() {
- return in, nil
- }
- sep := param.String()
- sl := make([]string, 0, in.Len())
- for i := 0; i < in.Len(); i++ {
- sl = append(sl, in.Index(i).String())
- }
- return AsValue(strings.Join(sl, sep)), nil
-}
-
-func filterLast(in *Value, param *Value) (*Value, *Error) {
- if in.CanSlice() && in.Len() > 0 {
- return in.Index(in.Len() - 1), nil
- }
- return AsValue(""), nil
-}
-
-func filterUpper(in *Value, param *Value) (*Value, *Error) {
- return AsValue(strings.ToUpper(in.String())), nil
-}
-
-func filterLower(in *Value, param *Value) (*Value, *Error) {
- return AsValue(strings.ToLower(in.String())), nil
-}
-
-func filterMakelist(in *Value, param *Value) (*Value, *Error) {
- s := in.String()
- result := make([]string, 0, len(s))
- for _, c := range s {
- result = append(result, string(c))
- }
- return AsValue(result), nil
-}
-
-func filterCapfirst(in *Value, param *Value) (*Value, *Error) {
- if in.Len() <= 0 {
- return AsValue(""), nil
- }
- t := in.String()
- r, size := utf8.DecodeRuneInString(t)
- return AsValue(strings.ToUpper(string(r)) + t[size:]), nil
-}
-
-func filterCenter(in *Value, param *Value) (*Value, *Error) {
- width := param.Integer()
- slen := in.Len()
- if width <= slen {
- return in, nil
- }
-
- spaces := width - slen
- left := spaces/2 + spaces%2
- right := spaces / 2
-
- return AsValue(fmt.Sprintf("%s%s%s", strings.Repeat(" ", left),
- in.String(), strings.Repeat(" ", right))), nil
-}
-
-func filterDate(in *Value, param *Value) (*Value, *Error) {
- t, isTime := in.Interface().(time.Time)
- if !isTime {
- return nil, &Error{
- Sender: "filter:date",
- OrigError: errors.New("filter input argument must be of type 'time.Time'"),
- }
- }
- return AsValue(t.Format(param.String())), nil
-}
-
-func filterFloat(in *Value, param *Value) (*Value, *Error) {
- return AsValue(in.Float()), nil
-}
-
-func filterInteger(in *Value, param *Value) (*Value, *Error) {
- return AsValue(in.Integer()), nil
-}
-
-func filterLinebreaks(in *Value, param *Value) (*Value, *Error) {
- if in.Len() == 0 {
- return in, nil
- }
-
- var b bytes.Buffer
-
- // Newline =
- // Double newline = ...
- lines := strings.Split(in.String(), "\n")
- lenlines := len(lines)
-
- opened := false
-
- for idx, line := range lines {
-
- if !opened {
- b.WriteString("")
- opened = true
- }
-
- b.WriteString(line)
-
- if idx < lenlines-1 && strings.TrimSpace(lines[idx]) != "" {
- // We've not reached the end
- if strings.TrimSpace(lines[idx+1]) == "" {
- // Next line is empty
- if opened {
- b.WriteString("
")
- opened = false
- }
- } else {
- b.WriteString("
")
- }
- }
- }
-
- if opened {
- b.WriteString("
")
- }
-
- return AsValue(b.String()), nil
-}
-
-func filterSplit(in *Value, param *Value) (*Value, *Error) {
- chunks := strings.Split(in.String(), param.String())
-
- return AsValue(chunks), nil
-}
-
-func filterLinebreaksbr(in *Value, param *Value) (*Value, *Error) {
- return AsValue(strings.Replace(in.String(), "\n", "
", -1)), nil
-}
-
-func filterLinenumbers(in *Value, param *Value) (*Value, *Error) {
- lines := strings.Split(in.String(), "\n")
- output := make([]string, 0, len(lines))
- for idx, line := range lines {
- output = append(output, fmt.Sprintf("%d. %s", idx+1, line))
- }
- return AsValue(strings.Join(output, "\n")), nil
-}
-
-func filterLjust(in *Value, param *Value) (*Value, *Error) {
- times := param.Integer() - in.Len()
- if times < 0 {
- times = 0
- }
- return AsValue(fmt.Sprintf("%s%s", in.String(), strings.Repeat(" ", times))), nil
-}
-
-func filterUrlencode(in *Value, param *Value) (*Value, *Error) {
- return AsValue(url.QueryEscape(in.String())), nil
-}
-
-// TODO: This regexp could do some work
-var filterUrlizeURLRegexp = regexp.MustCompile(`((((http|https)://)|www\.|((^|[ ])[0-9A-Za-z_\-]+(\.com|\.net|\.org|\.info|\.biz|\.de))))(?U:.*)([ ]+|$)`)
-var filterUrlizeEmailRegexp = regexp.MustCompile(`(\w+@\w+\.\w{2,4})`)
-
-func filterUrlizeHelper(input string, autoescape bool, trunc int) (string, error) {
- var soutErr error
- sout := filterUrlizeURLRegexp.ReplaceAllStringFunc(input, func(raw_url string) string {
- var prefix string
- var suffix string
- if strings.HasPrefix(raw_url, " ") {
- prefix = " "
- }
- if strings.HasSuffix(raw_url, " ") {
- suffix = " "
- }
-
- raw_url = strings.TrimSpace(raw_url)
-
- t, err := ApplyFilter("iriencode", AsValue(raw_url), nil)
- if err != nil {
- soutErr = err
- return ""
- }
- url := t.String()
-
- if !strings.HasPrefix(url, "http") {
- url = fmt.Sprintf("http://%s", url)
- }
-
- title := raw_url
-
- if trunc > 3 && len(title) > trunc {
- title = fmt.Sprintf("%s...", title[:trunc-3])
- }
-
- if autoescape {
- t, err := ApplyFilter("escape", AsValue(title), nil)
- if err != nil {
- soutErr = err
- return ""
- }
- title = t.String()
- }
-
- return fmt.Sprintf(`%s%s%s`, prefix, url, title, suffix)
- })
- if soutErr != nil {
- return "", soutErr
- }
-
- sout = filterUrlizeEmailRegexp.ReplaceAllStringFunc(sout, func(mail string) string {
- title := mail
-
- if trunc > 3 && len(title) > trunc {
- title = fmt.Sprintf("%s...", title[:trunc-3])
- }
-
- return fmt.Sprintf(`%s`, mail, title)
- })
-
- return sout, nil
-}
-
-func filterUrlize(in *Value, param *Value) (*Value, *Error) {
- autoescape := true
- if param.IsBool() {
- autoescape = param.Bool()
- }
-
- s, err := filterUrlizeHelper(in.String(), autoescape, -1)
- if err != nil {
-
- }
-
- return AsValue(s), nil
-}
-
-func filterUrlizetrunc(in *Value, param *Value) (*Value, *Error) {
- s, err := filterUrlizeHelper(in.String(), true, param.Integer())
- if err != nil {
- return nil, &Error{
- Sender: "filter:urlizetrunc",
- OrigError: errors.New("you cannot pass more than 2 arguments to filter 'pluralize'"),
- }
- }
- return AsValue(s), nil
-}
-
-func filterStringformat(in *Value, param *Value) (*Value, *Error) {
- return AsValue(fmt.Sprintf(param.String(), in.Interface())), nil
-}
-
-var reStriptags = regexp.MustCompile("<[^>]*?>")
-
-func filterStriptags(in *Value, param *Value) (*Value, *Error) {
- s := in.String()
-
- // Strip all tags
- s = reStriptags.ReplaceAllString(s, "")
-
- return AsValue(strings.TrimSpace(s)), nil
-}
-
-// https://en.wikipedia.org/wiki/Phoneword
-var filterPhone2numericMap = map[string]string{
- "a": "2", "b": "2", "c": "2", "d": "3", "e": "3", "f": "3", "g": "4", "h": "4", "i": "4", "j": "5", "k": "5",
- "l": "5", "m": "6", "n": "6", "o": "6", "p": "7", "q": "7", "r": "7", "s": "7", "t": "8", "u": "8", "v": "8",
- "w": "9", "x": "9", "y": "9", "z": "9",
-}
-
-func filterPhone2numeric(in *Value, param *Value) (*Value, *Error) {
- sin := in.String()
- for k, v := range filterPhone2numericMap {
- sin = strings.Replace(sin, k, v, -1)
- sin = strings.Replace(sin, strings.ToUpper(k), v, -1)
- }
- return AsValue(sin), nil
-}
-
-func filterPluralize(in *Value, param *Value) (*Value, *Error) {
- if in.IsNumber() {
- // Works only on numbers
- if param.Len() > 0 {
- endings := strings.Split(param.String(), ",")
- if len(endings) > 2 {
- return nil, &Error{
- Sender: "filter:pluralize",
- OrigError: errors.New("you cannot pass more than 2 arguments to filter 'pluralize'"),
- }
- }
- if len(endings) == 1 {
- // 1 argument
- if in.Integer() != 1 {
- return AsValue(endings[0]), nil
- }
- } else {
- if in.Integer() != 1 {
- // 2 arguments
- return AsValue(endings[1]), nil
- }
- return AsValue(endings[0]), nil
- }
- } else {
- if in.Integer() != 1 {
- // return default 's'
- return AsValue("s"), nil
- }
- }
-
- return AsValue(""), nil
- }
- return nil, &Error{
- Sender: "filter:pluralize",
- OrigError: errors.New("filter 'pluralize' does only work on numbers"),
- }
-}
-
-func filterRandom(in *Value, param *Value) (*Value, *Error) {
- if !in.CanSlice() || in.Len() <= 0 {
- return in, nil
- }
- i := rand.Intn(in.Len())
- return in.Index(i), nil
-}
-
-func filterRemovetags(in *Value, param *Value) (*Value, *Error) {
- s := in.String()
- tags := strings.Split(param.String(), ",")
-
- // Strip only specific tags
- for _, tag := range tags {
- re := regexp.MustCompile(fmt.Sprintf("?%s/?>", tag))
- s = re.ReplaceAllString(s, "")
- }
-
- return AsValue(strings.TrimSpace(s)), nil
-}
-
-func filterRjust(in *Value, param *Value) (*Value, *Error) {
- return AsValue(fmt.Sprintf(fmt.Sprintf("%%%ds", param.Integer()), in.String())), nil
-}
-
-func filterSlice(in *Value, param *Value) (*Value, *Error) {
- comp := strings.Split(param.String(), ":")
- if len(comp) != 2 {
- return nil, &Error{
- Sender: "filter:slice",
- OrigError: errors.New("Slice string must have the format 'from:to' [from/to can be omitted, but the ':' is required]"),
- }
- }
-
- if !in.CanSlice() {
- return in, nil
- }
-
- from := AsValue(comp[0]).Integer()
- to := in.Len()
-
- if from > to {
- from = to
- }
-
- vto := AsValue(comp[1]).Integer()
- if vto >= from && vto <= in.Len() {
- to = vto
- }
-
- return in.Slice(from, to), nil
-}
-
-func filterTitle(in *Value, param *Value) (*Value, *Error) {
- if !in.IsString() {
- return AsValue(""), nil
- }
- return AsValue(strings.Title(strings.ToLower(in.String()))), nil
-}
-
-func filterWordcount(in *Value, param *Value) (*Value, *Error) {
- return AsValue(len(strings.Fields(in.String()))), nil
-}
-
-func filterWordwrap(in *Value, param *Value) (*Value, *Error) {
- words := strings.Fields(in.String())
- wordsLen := len(words)
- wrapAt := param.Integer()
- if wrapAt <= 0 {
- return in, nil
- }
-
- linecount := wordsLen/wrapAt + wordsLen%wrapAt
- lines := make([]string, 0, linecount)
- for i := 0; i < linecount; i++ {
- lines = append(lines, strings.Join(words[wrapAt*i:min(wrapAt*(i+1), wordsLen)], " "))
- }
- return AsValue(strings.Join(lines, "\n")), nil
-}
-
-func filterYesno(in *Value, param *Value) (*Value, *Error) {
- choices := map[int]string{
- 0: "yes",
- 1: "no",
- 2: "maybe",
- }
- paramString := param.String()
- customChoices := strings.Split(paramString, ",")
- if len(paramString) > 0 {
- if len(customChoices) > 3 {
- return nil, &Error{
- Sender: "filter:yesno",
- OrigError: fmt.Errorf("You cannot pass more than 3 options to the 'yesno'-filter (got: '%s').", paramString),
- }
- }
- if len(customChoices) < 2 {
- return nil, &Error{
- Sender: "filter:yesno",
- OrigError: fmt.Errorf("You must pass either no or at least 2 arguments to the 'yesno'-filter (got: '%s').", paramString),
- }
- }
-
- // Map to the options now
- choices[0] = customChoices[0]
- choices[1] = customChoices[1]
- if len(customChoices) == 3 {
- choices[2] = customChoices[2]
- }
- }
-
- // maybe
- if in.IsNil() {
- return AsValue(choices[2]), nil
- }
-
- // yes
- if in.IsTrue() {
- return AsValue(choices[0]), nil
- }
-
- // no
- return AsValue(choices[1]), nil
-}
diff --git a/vendor/github.com/flosch/pongo2/go.mod b/vendor/github.com/flosch/pongo2/go.mod
deleted file mode 100644
index c9b5531..0000000
--- a/vendor/github.com/flosch/pongo2/go.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-module github.com/flosch/pongo2
-
-go 1.14
-
-require (
- github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
- gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b
-)
diff --git a/vendor/github.com/flosch/pongo2/go.sum b/vendor/github.com/flosch/pongo2/go.sum
deleted file mode 100644
index ee71e85..0000000
--- a/vendor/github.com/flosch/pongo2/go.sum
+++ /dev/null
@@ -1,7 +0,0 @@
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
-gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/vendor/github.com/flosch/pongo2/helpers.go b/vendor/github.com/flosch/pongo2/helpers.go
deleted file mode 100644
index 880dbc0..0000000
--- a/vendor/github.com/flosch/pongo2/helpers.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package pongo2
-
-func max(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
-
-func min(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
diff --git a/vendor/github.com/flosch/pongo2/lexer.go b/vendor/github.com/flosch/pongo2/lexer.go
deleted file mode 100644
index f189798..0000000
--- a/vendor/github.com/flosch/pongo2/lexer.go
+++ /dev/null
@@ -1,432 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "strings"
- "unicode/utf8"
-
- "errors"
-)
-
-const (
- TokenError = iota
- EOF
-
- TokenHTML
-
- TokenKeyword
- TokenIdentifier
- TokenString
- TokenNumber
- TokenSymbol
-)
-
-var (
- tokenSpaceChars = " \n\r\t"
- tokenIdentifierChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
- tokenIdentifierCharsWithDigits = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789"
- tokenDigits = "0123456789"
-
- // Available symbols in pongo2 (within filters/tag)
- TokenSymbols = []string{
- // 3-Char symbols
- "{{-", "-}}", "{%-", "-%}",
-
- // 2-Char symbols
- "==", ">=", "<=", "&&", "||", "{{", "}}", "{%", "%}", "!=", "<>",
-
- // 1-Char symbol
- "(", ")", "+", "-", "*", "<", ">", "/", "^", ",", ".", "!", "|", ":", "=", "%",
- }
-
- // Available keywords in pongo2
- TokenKeywords = []string{"in", "and", "or", "not", "true", "false", "as", "export"}
-)
-
-type TokenType int
-type Token struct {
- Filename string
- Typ TokenType
- Val string
- Line int
- Col int
- TrimWhitespaces bool
-}
-
-type lexerStateFn func() lexerStateFn
-type lexer struct {
- name string
- input string
- start int // start pos of the item
- pos int // current pos
- width int // width of last rune
- tokens []*Token
- errored bool
- startline int
- startcol int
- line int
- col int
-
- inVerbatim bool
- verbatimName string
-}
-
-func (t *Token) String() string {
- val := t.Val
- if len(val) > 1000 {
- val = fmt.Sprintf("%s...%s", val[:10], val[len(val)-5:])
- }
-
- typ := ""
- switch t.Typ {
- case TokenHTML:
- typ = "HTML"
- case TokenError:
- typ = "Error"
- case TokenIdentifier:
- typ = "Identifier"
- case TokenKeyword:
- typ = "Keyword"
- case TokenNumber:
- typ = "Number"
- case TokenString:
- typ = "String"
- case TokenSymbol:
- typ = "Symbol"
- default:
- typ = "Unknown"
- }
-
- return fmt.Sprintf("",
- typ, t.Typ, val, t.Line, t.Col, t.TrimWhitespaces)
-}
-
-func lex(name string, input string) ([]*Token, *Error) {
- l := &lexer{
- name: name,
- input: input,
- tokens: make([]*Token, 0, 100),
- line: 1,
- col: 1,
- startline: 1,
- startcol: 1,
- }
- l.run()
- if l.errored {
- errtoken := l.tokens[len(l.tokens)-1]
- return nil, &Error{
- Filename: name,
- Line: errtoken.Line,
- Column: errtoken.Col,
- Sender: "lexer",
- OrigError: errors.New(errtoken.Val),
- }
- }
- return l.tokens, nil
-}
-
-func (l *lexer) value() string {
- return l.input[l.start:l.pos]
-}
-
-func (l *lexer) length() int {
- return l.pos - l.start
-}
-
-func (l *lexer) emit(t TokenType) {
- tok := &Token{
- Filename: l.name,
- Typ: t,
- Val: l.value(),
- Line: l.startline,
- Col: l.startcol,
- }
-
- if t == TokenString {
- // Escape sequence \" in strings
- tok.Val = strings.Replace(tok.Val, `\"`, `"`, -1)
- tok.Val = strings.Replace(tok.Val, `\\`, `\`, -1)
- }
-
- if t == TokenSymbol && len(tok.Val) == 3 && (strings.HasSuffix(tok.Val, "-") || strings.HasPrefix(tok.Val, "-")) {
- tok.TrimWhitespaces = true
- tok.Val = strings.Replace(tok.Val, "-", "", -1)
- }
-
- l.tokens = append(l.tokens, tok)
- l.start = l.pos
- l.startline = l.line
- l.startcol = l.col
-}
-
-func (l *lexer) next() rune {
- if l.pos >= len(l.input) {
- l.width = 0
- return EOF
- }
- r, w := utf8.DecodeRuneInString(l.input[l.pos:])
- l.width = w
- l.pos += l.width
- l.col += l.width
- return r
-}
-
-func (l *lexer) backup() {
- l.pos -= l.width
- l.col -= l.width
-}
-
-func (l *lexer) peek() rune {
- r := l.next()
- l.backup()
- return r
-}
-
-func (l *lexer) ignore() {
- l.start = l.pos
- l.startline = l.line
- l.startcol = l.col
-}
-
-func (l *lexer) accept(what string) bool {
- if strings.IndexRune(what, l.next()) >= 0 {
- return true
- }
- l.backup()
- return false
-}
-
-func (l *lexer) acceptRun(what string) {
- for strings.IndexRune(what, l.next()) >= 0 {
- }
- l.backup()
-}
-
-func (l *lexer) errorf(format string, args ...interface{}) lexerStateFn {
- t := &Token{
- Filename: l.name,
- Typ: TokenError,
- Val: fmt.Sprintf(format, args...),
- Line: l.startline,
- Col: l.startcol,
- }
- l.tokens = append(l.tokens, t)
- l.errored = true
- l.startline = l.line
- l.startcol = l.col
- return nil
-}
-
-func (l *lexer) eof() bool {
- return l.start >= len(l.input)-1
-}
-
-func (l *lexer) run() {
- for {
- // TODO: Support verbatim tag names
- // https://docs.djangoproject.com/en/dev/ref/templates/builtins/#verbatim
- if l.inVerbatim {
- name := l.verbatimName
- if name != "" {
- name += " "
- }
- if strings.HasPrefix(l.input[l.pos:], fmt.Sprintf("{%% endverbatim %s%%}", name)) { // end verbatim
- if l.pos > l.start {
- l.emit(TokenHTML)
- }
- w := len("{% endverbatim %}")
- l.pos += w
- l.col += w
- l.ignore()
- l.inVerbatim = false
- }
- } else if strings.HasPrefix(l.input[l.pos:], "{% verbatim %}") { // tag
- if l.pos > l.start {
- l.emit(TokenHTML)
- }
- l.inVerbatim = true
- w := len("{% verbatim %}")
- l.pos += w
- l.col += w
- l.ignore()
- }
-
- if !l.inVerbatim {
- // Ignore single-line comments {# ... #}
- if strings.HasPrefix(l.input[l.pos:], "{#") {
- if l.pos > l.start {
- l.emit(TokenHTML)
- }
-
- l.pos += 2 // pass '{#'
- l.col += 2
-
- for {
- switch l.peek() {
- case EOF:
- l.errorf("Single-line comment not closed.")
- return
- case '\n':
- l.errorf("Newline not permitted in a single-line comment.")
- return
- }
-
- if strings.HasPrefix(l.input[l.pos:], "#}") {
- l.pos += 2 // pass '#}'
- l.col += 2
- break
- }
-
- l.next()
- }
- l.ignore() // ignore whole comment
-
- // Comment skipped
- continue // next token
- }
-
- if strings.HasPrefix(l.input[l.pos:], "{{") || // variable
- strings.HasPrefix(l.input[l.pos:], "{%") { // tag
- if l.pos > l.start {
- l.emit(TokenHTML)
- }
- l.tokenize()
- if l.errored {
- return
- }
- continue
- }
- }
-
- switch l.peek() {
- case '\n':
- l.line++
- l.col = 0
- }
- if l.next() == EOF {
- break
- }
- }
-
- if l.pos > l.start {
- l.emit(TokenHTML)
- }
-
- if l.inVerbatim {
- l.errorf("verbatim-tag not closed, got EOF.")
- }
-}
-
-func (l *lexer) tokenize() {
- for state := l.stateCode; state != nil; {
- state = state()
- }
-}
-
-func (l *lexer) stateCode() lexerStateFn {
-outer_loop:
- for {
- switch {
- case l.accept(tokenSpaceChars):
- if l.value() == "\n" {
- return l.errorf("Newline not allowed within tag/variable.")
- }
- l.ignore()
- continue
- case l.accept(tokenIdentifierChars):
- return l.stateIdentifier
- case l.accept(tokenDigits):
- return l.stateNumber
- case l.accept(`"'`):
- return l.stateString
- }
-
- // Check for symbol
- for _, sym := range TokenSymbols {
- if strings.HasPrefix(l.input[l.start:], sym) {
- l.pos += len(sym)
- l.col += l.length()
- l.emit(TokenSymbol)
-
- if sym == "%}" || sym == "-%}" || sym == "}}" || sym == "-}}" {
- // Tag/variable end, return after emit
- return nil
- }
-
- continue outer_loop
- }
- }
-
- break
- }
-
- // Normal shut down
- return nil
-}
-
-func (l *lexer) stateIdentifier() lexerStateFn {
- l.acceptRun(tokenIdentifierChars)
- l.acceptRun(tokenIdentifierCharsWithDigits)
- for _, kw := range TokenKeywords {
- if kw == l.value() {
- l.emit(TokenKeyword)
- return l.stateCode
- }
- }
- l.emit(TokenIdentifier)
- return l.stateCode
-}
-
-func (l *lexer) stateNumber() lexerStateFn {
- l.acceptRun(tokenDigits)
- if l.accept(tokenIdentifierCharsWithDigits) {
- // This seems to be an identifier starting with a number.
- // See https://github.com/flosch/pongo2/issues/151
- return l.stateIdentifier()
- }
- /*
- Maybe context-sensitive number lexing?
- * comments.0.Text // first comment
- * usercomments.1.0 // second user, first comment
- * if (score >= 8.5) // 8.5 as a number
-
- if l.peek() == '.' {
- l.accept(".")
- if !l.accept(tokenDigits) {
- return l.errorf("Malformed number.")
- }
- l.acceptRun(tokenDigits)
- }
- */
- l.emit(TokenNumber)
- return l.stateCode
-}
-
-func (l *lexer) stateString() lexerStateFn {
- quotationMark := l.value()
- l.ignore()
- l.startcol-- // we're starting the position at the first "
- for !l.accept(quotationMark) {
- switch l.next() {
- case '\\':
- // escape sequence
- switch l.peek() {
- case '"', '\\':
- l.next()
- default:
- return l.errorf("Unknown escape sequence: \\%c", l.peek())
- }
- case EOF:
- return l.errorf("Unexpected EOF, string not closed.")
- case '\n':
- return l.errorf("Newline in string is not allowed.")
- }
- }
- l.backup()
- l.emit(TokenString)
-
- l.next()
- l.ignore()
-
- return l.stateCode
-}
diff --git a/vendor/github.com/flosch/pongo2/nodes.go b/vendor/github.com/flosch/pongo2/nodes.go
deleted file mode 100644
index 5b039cd..0000000
--- a/vendor/github.com/flosch/pongo2/nodes.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package pongo2
-
-// The root document
-type nodeDocument struct {
- Nodes []INode
-}
-
-func (doc *nodeDocument) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- for _, n := range doc.Nodes {
- err := n.Execute(ctx, writer)
- if err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/flosch/pongo2/nodes_html.go b/vendor/github.com/flosch/pongo2/nodes_html.go
deleted file mode 100644
index b980a3a..0000000
--- a/vendor/github.com/flosch/pongo2/nodes_html.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package pongo2
-
-import (
- "strings"
-)
-
-type nodeHTML struct {
- token *Token
- trimLeft bool
- trimRight bool
-}
-
-func (n *nodeHTML) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- res := n.token.Val
- if n.trimLeft {
- res = strings.TrimLeft(res, tokenSpaceChars)
- }
- if n.trimRight {
- res = strings.TrimRight(res, tokenSpaceChars)
- }
- writer.WriteString(res)
- return nil
-}
diff --git a/vendor/github.com/flosch/pongo2/nodes_wrapper.go b/vendor/github.com/flosch/pongo2/nodes_wrapper.go
deleted file mode 100644
index d1bcb8d..0000000
--- a/vendor/github.com/flosch/pongo2/nodes_wrapper.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package pongo2
-
-type NodeWrapper struct {
- Endtag string
- nodes []INode
-}
-
-func (wrapper *NodeWrapper) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- for _, n := range wrapper.nodes {
- err := n.Execute(ctx, writer)
- if err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/flosch/pongo2/options.go b/vendor/github.com/flosch/pongo2/options.go
deleted file mode 100644
index 9c39e46..0000000
--- a/vendor/github.com/flosch/pongo2/options.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package pongo2
-
-// Options allow you to change the behavior of template-engine.
-// You can change the options before calling the Execute method.
-type Options struct {
- // If this is set to true the first newline after a block is removed (block, not variable tag!). Defaults to false.
- TrimBlocks bool
-
- // If this is set to true leading spaces and tabs are stripped from the start of a line to a block. Defaults to false
- LStripBlocks bool
-}
-
-func newOptions() *Options {
- return &Options{
- TrimBlocks: false,
- LStripBlocks: false,
- }
-}
-
-// Update updates this options from another options.
-func (opt *Options) Update(other *Options) *Options {
- opt.TrimBlocks = other.TrimBlocks
- opt.LStripBlocks = other.LStripBlocks
-
- return opt
-}
diff --git a/vendor/github.com/flosch/pongo2/parser.go b/vendor/github.com/flosch/pongo2/parser.go
deleted file mode 100644
index 19553f1..0000000
--- a/vendor/github.com/flosch/pongo2/parser.go
+++ /dev/null
@@ -1,309 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "strings"
-
- "errors"
-)
-
-type INode interface {
- Execute(*ExecutionContext, TemplateWriter) *Error
-}
-
-type IEvaluator interface {
- INode
- GetPositionToken() *Token
- Evaluate(*ExecutionContext) (*Value, *Error)
- FilterApplied(name string) bool
-}
-
-// The parser provides you a comprehensive and easy tool to
-// work with the template document and arguments provided by
-// the user for your custom tag.
-//
-// The parser works on a token list which will be provided by pongo2.
-// A token is a unit you can work with. Tokens are either of type identifier,
-// string, number, keyword, HTML or symbol.
-//
-// (See Token's documentation for more about tokens)
-type Parser struct {
- name string
- idx int
- tokens []*Token
- lastToken *Token
-
- // if the parser parses a template document, here will be
- // a reference to it (needed to access the template through Tags)
- template *Template
-}
-
-// Creates a new parser to parse tokens.
-// Used inside pongo2 to parse documents and to provide an easy-to-use
-// parser for tag authors
-func newParser(name string, tokens []*Token, template *Template) *Parser {
- p := &Parser{
- name: name,
- tokens: tokens,
- template: template,
- }
- if len(tokens) > 0 {
- p.lastToken = tokens[len(tokens)-1]
- }
- return p
-}
-
-// Consume one token. It will be gone forever.
-func (p *Parser) Consume() {
- p.ConsumeN(1)
-}
-
-// Consume N tokens. They will be gone forever.
-func (p *Parser) ConsumeN(count int) {
- p.idx += count
-}
-
-// Returns the current token.
-func (p *Parser) Current() *Token {
- return p.Get(p.idx)
-}
-
-// Returns the CURRENT token if the given type matches.
-// Consumes this token on success.
-func (p *Parser) MatchType(typ TokenType) *Token {
- if t := p.PeekType(typ); t != nil {
- p.Consume()
- return t
- }
- return nil
-}
-
-// Returns the CURRENT token if the given type AND value matches.
-// Consumes this token on success.
-func (p *Parser) Match(typ TokenType, val string) *Token {
- if t := p.Peek(typ, val); t != nil {
- p.Consume()
- return t
- }
- return nil
-}
-
-// Returns the CURRENT token if the given type AND *one* of
-// the given values matches.
-// Consumes this token on success.
-func (p *Parser) MatchOne(typ TokenType, vals ...string) *Token {
- for _, val := range vals {
- if t := p.Peek(typ, val); t != nil {
- p.Consume()
- return t
- }
- }
- return nil
-}
-
-// Returns the CURRENT token if the given type matches.
-// It DOES NOT consume the token.
-func (p *Parser) PeekType(typ TokenType) *Token {
- return p.PeekTypeN(0, typ)
-}
-
-// Returns the CURRENT token if the given type AND value matches.
-// It DOES NOT consume the token.
-func (p *Parser) Peek(typ TokenType, val string) *Token {
- return p.PeekN(0, typ, val)
-}
-
-// Returns the CURRENT token if the given type AND *one* of
-// the given values matches.
-// It DOES NOT consume the token.
-func (p *Parser) PeekOne(typ TokenType, vals ...string) *Token {
- for _, v := range vals {
- t := p.PeekN(0, typ, v)
- if t != nil {
- return t
- }
- }
- return nil
-}
-
-// Returns the tokens[current position + shift] token if the
-// given type AND value matches for that token.
-// DOES NOT consume the token.
-func (p *Parser) PeekN(shift int, typ TokenType, val string) *Token {
- t := p.Get(p.idx + shift)
- if t != nil {
- if t.Typ == typ && t.Val == val {
- return t
- }
- }
- return nil
-}
-
-// Returns the tokens[current position + shift] token if the given type matches.
-// DOES NOT consume the token for that token.
-func (p *Parser) PeekTypeN(shift int, typ TokenType) *Token {
- t := p.Get(p.idx + shift)
- if t != nil {
- if t.Typ == typ {
- return t
- }
- }
- return nil
-}
-
-// Returns the UNCONSUMED token count.
-func (p *Parser) Remaining() int {
- return len(p.tokens) - p.idx
-}
-
-// Returns the total token count.
-func (p *Parser) Count() int {
- return len(p.tokens)
-}
-
-// Returns tokens[i] or NIL (if i >= len(tokens))
-func (p *Parser) Get(i int) *Token {
- if i < len(p.tokens) && i >= 0 {
- return p.tokens[i]
- }
- return nil
-}
-
-// Returns tokens[current-position + shift] or NIL
-// (if (current-position + i) >= len(tokens))
-func (p *Parser) GetR(shift int) *Token {
- i := p.idx + shift
- return p.Get(i)
-}
-
-// Error produces a nice error message and returns an error-object.
-// The 'token'-argument is optional. If provided, it will take
-// the token's position information. If not provided, it will
-// automatically use the CURRENT token's position information.
-func (p *Parser) Error(msg string, token *Token) *Error {
- if token == nil {
- // Set current token
- token = p.Current()
- if token == nil {
- // Set to last token
- if len(p.tokens) > 0 {
- token = p.tokens[len(p.tokens)-1]
- }
- }
- }
- var line, col int
- if token != nil {
- line = token.Line
- col = token.Col
- }
- return &Error{
- Template: p.template,
- Filename: p.name,
- Sender: "parser",
- Line: line,
- Column: col,
- Token: token,
- OrigError: errors.New(msg),
- }
-}
-
-// Wraps all nodes between starting tag and "{% endtag %}" and provides
-// one simple interface to execute the wrapped nodes.
-// It returns a parser to process provided arguments to the tag.
-func (p *Parser) WrapUntilTag(names ...string) (*NodeWrapper, *Parser, *Error) {
- wrapper := &NodeWrapper{}
-
- var tagArgs []*Token
-
- for p.Remaining() > 0 {
- // New tag, check whether we have to stop wrapping here
- if p.Peek(TokenSymbol, "{%") != nil {
- tagIdent := p.PeekTypeN(1, TokenIdentifier)
-
- if tagIdent != nil {
- // We've found a (!) end-tag
-
- found := false
- for _, n := range names {
- if tagIdent.Val == n {
- found = true
- break
- }
- }
-
- // We only process the tag if we've found an end tag
- if found {
- // Okay, endtag found.
- p.ConsumeN(2) // '{%' tagname
-
- for {
- if p.Match(TokenSymbol, "%}") != nil {
- // Okay, end the wrapping here
- wrapper.Endtag = tagIdent.Val
- return wrapper, newParser(p.template.name, tagArgs, p.template), nil
- }
- t := p.Current()
- p.Consume()
- if t == nil {
- return nil, nil, p.Error("Unexpected EOF.", p.lastToken)
- }
- tagArgs = append(tagArgs, t)
- }
- }
- }
-
- }
-
- // Otherwise process next element to be wrapped
- node, err := p.parseDocElement()
- if err != nil {
- return nil, nil, err
- }
- wrapper.nodes = append(wrapper.nodes, node)
- }
-
- return nil, nil, p.Error(fmt.Sprintf("Unexpected EOF, expected tag %s.", strings.Join(names, " or ")),
- p.lastToken)
-}
-
-// Skips all nodes between starting tag and "{% endtag %}"
-func (p *Parser) SkipUntilTag(names ...string) *Error {
- for p.Remaining() > 0 {
- // New tag, check whether we have to stop wrapping here
- if p.Peek(TokenSymbol, "{%") != nil {
- tagIdent := p.PeekTypeN(1, TokenIdentifier)
-
- if tagIdent != nil {
- // We've found a (!) end-tag
-
- found := false
- for _, n := range names {
- if tagIdent.Val == n {
- found = true
- break
- }
- }
-
- // We only process the tag if we've found an end tag
- if found {
- // Okay, endtag found.
- p.ConsumeN(2) // '{%' tagname
-
- for {
- if p.Match(TokenSymbol, "%}") != nil {
- // Done skipping, exit.
- return nil
- }
- }
- }
- }
- }
- t := p.Current()
- p.Consume()
- if t == nil {
- return p.Error("Unexpected EOF.", p.lastToken)
- }
- }
-
- return p.Error(fmt.Sprintf("Unexpected EOF, expected tag %s.", strings.Join(names, " or ")), p.lastToken)
-}
diff --git a/vendor/github.com/flosch/pongo2/parser_document.go b/vendor/github.com/flosch/pongo2/parser_document.go
deleted file mode 100644
index e3ac2c8..0000000
--- a/vendor/github.com/flosch/pongo2/parser_document.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package pongo2
-
-// Doc = { ( Filter | Tag | HTML ) }
-func (p *Parser) parseDocElement() (INode, *Error) {
- t := p.Current()
-
- switch t.Typ {
- case TokenHTML:
- n := &nodeHTML{token: t}
- left := p.PeekTypeN(-1, TokenSymbol)
- right := p.PeekTypeN(1, TokenSymbol)
- n.trimLeft = left != nil && left.TrimWhitespaces
- n.trimRight = right != nil && right.TrimWhitespaces
- p.Consume() // consume HTML element
- return n, nil
- case TokenSymbol:
- switch t.Val {
- case "{{":
- // parse variable
- variable, err := p.parseVariableElement()
- if err != nil {
- return nil, err
- }
- return variable, nil
- case "{%":
- // parse tag
- tag, err := p.parseTagElement()
- if err != nil {
- return nil, err
- }
- return tag, nil
- }
- }
- return nil, p.Error("Unexpected token (only HTML/tags/filters in templates allowed)", t)
-}
-
-func (tpl *Template) parse() *Error {
- tpl.parser = newParser(tpl.name, tpl.tokens, tpl)
- doc, err := tpl.parser.parseDocument()
- if err != nil {
- return err
- }
- tpl.root = doc
- return nil
-}
-
-func (p *Parser) parseDocument() (*nodeDocument, *Error) {
- doc := &nodeDocument{}
-
- for p.Remaining() > 0 {
- node, err := p.parseDocElement()
- if err != nil {
- return nil, err
- }
- doc.Nodes = append(doc.Nodes, node)
- }
-
- return doc, nil
-}
diff --git a/vendor/github.com/flosch/pongo2/parser_expression.go b/vendor/github.com/flosch/pongo2/parser_expression.go
deleted file mode 100644
index 215b0af..0000000
--- a/vendor/github.com/flosch/pongo2/parser_expression.go
+++ /dev/null
@@ -1,517 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "math"
-)
-
-type Expression struct {
- // TODO: Add location token?
- expr1 IEvaluator
- expr2 IEvaluator
- opToken *Token
-}
-
-type relationalExpression struct {
- // TODO: Add location token?
- expr1 IEvaluator
- expr2 IEvaluator
- opToken *Token
-}
-
-type simpleExpression struct {
- negate bool
- negativeSign bool
- term1 IEvaluator
- term2 IEvaluator
- opToken *Token
-}
-
-type term struct {
- // TODO: Add location token?
- factor1 IEvaluator
- factor2 IEvaluator
- opToken *Token
-}
-
-type power struct {
- // TODO: Add location token?
- power1 IEvaluator
- power2 IEvaluator
-}
-
-func (expr *Expression) FilterApplied(name string) bool {
- return expr.expr1.FilterApplied(name) && (expr.expr2 == nil ||
- (expr.expr2 != nil && expr.expr2.FilterApplied(name)))
-}
-
-func (expr *relationalExpression) FilterApplied(name string) bool {
- return expr.expr1.FilterApplied(name) && (expr.expr2 == nil ||
- (expr.expr2 != nil && expr.expr2.FilterApplied(name)))
-}
-
-func (expr *simpleExpression) FilterApplied(name string) bool {
- return expr.term1.FilterApplied(name) && (expr.term2 == nil ||
- (expr.term2 != nil && expr.term2.FilterApplied(name)))
-}
-
-func (expr *term) FilterApplied(name string) bool {
- return expr.factor1.FilterApplied(name) && (expr.factor2 == nil ||
- (expr.factor2 != nil && expr.factor2.FilterApplied(name)))
-}
-
-func (expr *power) FilterApplied(name string) bool {
- return expr.power1.FilterApplied(name) && (expr.power2 == nil ||
- (expr.power2 != nil && expr.power2.FilterApplied(name)))
-}
-
-func (expr *Expression) GetPositionToken() *Token {
- return expr.expr1.GetPositionToken()
-}
-
-func (expr *relationalExpression) GetPositionToken() *Token {
- return expr.expr1.GetPositionToken()
-}
-
-func (expr *simpleExpression) GetPositionToken() *Token {
- return expr.term1.GetPositionToken()
-}
-
-func (expr *term) GetPositionToken() *Token {
- return expr.factor1.GetPositionToken()
-}
-
-func (expr *power) GetPositionToken() *Token {
- return expr.power1.GetPositionToken()
-}
-
-func (expr *Expression) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := expr.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (expr *relationalExpression) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := expr.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (expr *simpleExpression) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := expr.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (expr *term) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := expr.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (expr *power) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := expr.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (expr *Expression) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- v1, err := expr.expr1.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- if expr.expr2 != nil {
- switch expr.opToken.Val {
- case "and", "&&":
- if !v1.IsTrue() {
- return AsValue(false), nil
- } else {
- v2, err := expr.expr2.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- return AsValue(v2.IsTrue()), nil
- }
- case "or", "||":
- if v1.IsTrue() {
- return AsValue(true), nil
- } else {
- v2, err := expr.expr2.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- return AsValue(v2.IsTrue()), nil
- }
- default:
- return nil, ctx.Error(fmt.Sprintf("unimplemented: %s", expr.opToken.Val), expr.opToken)
- }
- } else {
- return v1, nil
- }
-}
-
-func (expr *relationalExpression) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- v1, err := expr.expr1.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- if expr.expr2 != nil {
- v2, err := expr.expr2.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- switch expr.opToken.Val {
- case "<=":
- if v1.IsFloat() || v2.IsFloat() {
- return AsValue(v1.Float() <= v2.Float()), nil
- }
- if v1.IsTime() && v2.IsTime() {
- tm1, tm2 := v1.Time(), v2.Time()
- return AsValue(tm1.Before(tm2) || tm1.Equal(tm2)), nil
- }
- return AsValue(v1.Integer() <= v2.Integer()), nil
- case ">=":
- if v1.IsFloat() || v2.IsFloat() {
- return AsValue(v1.Float() >= v2.Float()), nil
- }
- if v1.IsTime() && v2.IsTime() {
- tm1, tm2 := v1.Time(), v2.Time()
- return AsValue(tm1.After(tm2) || tm1.Equal(tm2)), nil
- }
- return AsValue(v1.Integer() >= v2.Integer()), nil
- case "==":
- return AsValue(v1.EqualValueTo(v2)), nil
- case ">":
- if v1.IsFloat() || v2.IsFloat() {
- return AsValue(v1.Float() > v2.Float()), nil
- }
- if v1.IsTime() && v2.IsTime() {
- return AsValue(v1.Time().After(v2.Time())), nil
- }
- return AsValue(v1.Integer() > v2.Integer()), nil
- case "<":
- if v1.IsFloat() || v2.IsFloat() {
- return AsValue(v1.Float() < v2.Float()), nil
- }
- if v1.IsTime() && v2.IsTime() {
- return AsValue(v1.Time().Before(v2.Time())), nil
- }
- return AsValue(v1.Integer() < v2.Integer()), nil
- case "!=", "<>":
- return AsValue(!v1.EqualValueTo(v2)), nil
- case "in":
- return AsValue(v2.Contains(v1)), nil
- default:
- return nil, ctx.Error(fmt.Sprintf("unimplemented: %s", expr.opToken.Val), expr.opToken)
- }
- } else {
- return v1, nil
- }
-}
-
-func (expr *simpleExpression) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- t1, err := expr.term1.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- result := t1
-
- if expr.negate {
- result = result.Negate()
- }
-
- if expr.negativeSign {
- if result.IsNumber() {
- switch {
- case result.IsFloat():
- result = AsValue(-1 * result.Float())
- case result.IsInteger():
- result = AsValue(-1 * result.Integer())
- default:
- return nil, ctx.Error("Operation between a number and a non-(float/integer) is not possible", nil)
- }
- } else {
- return nil, ctx.Error("Negative sign on a non-number expression", expr.GetPositionToken())
- }
- }
-
- if expr.term2 != nil {
- t2, err := expr.term2.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- switch expr.opToken.Val {
- case "+":
- if result.IsFloat() || t2.IsFloat() {
- // Result will be a float
- return AsValue(result.Float() + t2.Float()), nil
- }
- // Result will be an integer
- return AsValue(result.Integer() + t2.Integer()), nil
- case "-":
- if result.IsFloat() || t2.IsFloat() {
- // Result will be a float
- return AsValue(result.Float() - t2.Float()), nil
- }
- // Result will be an integer
- return AsValue(result.Integer() - t2.Integer()), nil
- default:
- return nil, ctx.Error("Unimplemented", expr.GetPositionToken())
- }
- }
-
- return result, nil
-}
-
-func (expr *term) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- f1, err := expr.factor1.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- if expr.factor2 != nil {
- f2, err := expr.factor2.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- switch expr.opToken.Val {
- case "*":
- if f1.IsFloat() || f2.IsFloat() {
- // Result will be float
- return AsValue(f1.Float() * f2.Float()), nil
- }
- // Result will be int
- return AsValue(f1.Integer() * f2.Integer()), nil
- case "/":
- if f1.IsFloat() || f2.IsFloat() {
- // Result will be float
- return AsValue(f1.Float() / f2.Float()), nil
- }
- // Result will be int
- return AsValue(f1.Integer() / f2.Integer()), nil
- case "%":
- // Result will be int
- return AsValue(f1.Integer() % f2.Integer()), nil
- default:
- return nil, ctx.Error("unimplemented", expr.opToken)
- }
- } else {
- return f1, nil
- }
-}
-
-func (expr *power) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- p1, err := expr.power1.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- if expr.power2 != nil {
- p2, err := expr.power2.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
- return AsValue(math.Pow(p1.Float(), p2.Float())), nil
- }
- return p1, nil
-}
-
-func (p *Parser) parseFactor() (IEvaluator, *Error) {
- if p.Match(TokenSymbol, "(") != nil {
- expr, err := p.ParseExpression()
- if err != nil {
- return nil, err
- }
- if p.Match(TokenSymbol, ")") == nil {
- return nil, p.Error("Closing bracket expected after expression", nil)
- }
- return expr, nil
- }
-
- return p.parseVariableOrLiteralWithFilter()
-}
-
-func (p *Parser) parsePower() (IEvaluator, *Error) {
- pw := new(power)
-
- power1, err := p.parseFactor()
- if err != nil {
- return nil, err
- }
- pw.power1 = power1
-
- if p.Match(TokenSymbol, "^") != nil {
- power2, err := p.parsePower()
- if err != nil {
- return nil, err
- }
- pw.power2 = power2
- }
-
- if pw.power2 == nil {
- // Shortcut for faster evaluation
- return pw.power1, nil
- }
-
- return pw, nil
-}
-
-func (p *Parser) parseTerm() (IEvaluator, *Error) {
- returnTerm := new(term)
-
- factor1, err := p.parsePower()
- if err != nil {
- return nil, err
- }
- returnTerm.factor1 = factor1
-
- for p.PeekOne(TokenSymbol, "*", "/", "%") != nil {
- if returnTerm.opToken != nil {
- // Create new sub-term
- returnTerm = &term{
- factor1: returnTerm,
- }
- }
-
- op := p.Current()
- p.Consume()
-
- factor2, err := p.parsePower()
- if err != nil {
- return nil, err
- }
-
- returnTerm.opToken = op
- returnTerm.factor2 = factor2
- }
-
- if returnTerm.opToken == nil {
- // Shortcut for faster evaluation
- return returnTerm.factor1, nil
- }
-
- return returnTerm, nil
-}
-
-func (p *Parser) parseSimpleExpression() (IEvaluator, *Error) {
- expr := new(simpleExpression)
-
- if sign := p.MatchOne(TokenSymbol, "+", "-"); sign != nil {
- if sign.Val == "-" {
- expr.negativeSign = true
- }
- }
-
- if p.Match(TokenSymbol, "!") != nil || p.Match(TokenKeyword, "not") != nil {
- expr.negate = true
- }
-
- term1, err := p.parseTerm()
- if err != nil {
- return nil, err
- }
- expr.term1 = term1
-
- for p.PeekOne(TokenSymbol, "+", "-") != nil {
- if expr.opToken != nil {
- // New sub expr
- expr = &simpleExpression{
- term1: expr,
- }
- }
-
- op := p.Current()
- p.Consume()
-
- term2, err := p.parseTerm()
- if err != nil {
- return nil, err
- }
-
- expr.term2 = term2
- expr.opToken = op
- }
-
- if expr.negate == false && expr.negativeSign == false && expr.term2 == nil {
- // Shortcut for faster evaluation
- return expr.term1, nil
- }
-
- return expr, nil
-}
-
-func (p *Parser) parseRelationalExpression() (IEvaluator, *Error) {
- expr1, err := p.parseSimpleExpression()
- if err != nil {
- return nil, err
- }
-
- expr := &relationalExpression{
- expr1: expr1,
- }
-
- if t := p.MatchOne(TokenSymbol, "==", "<=", ">=", "!=", "<>", ">", "<"); t != nil {
- expr2, err := p.parseRelationalExpression()
- if err != nil {
- return nil, err
- }
- expr.opToken = t
- expr.expr2 = expr2
- } else if t := p.MatchOne(TokenKeyword, "in"); t != nil {
- expr2, err := p.parseSimpleExpression()
- if err != nil {
- return nil, err
- }
- expr.opToken = t
- expr.expr2 = expr2
- }
-
- if expr.expr2 == nil {
- // Shortcut for faster evaluation
- return expr.expr1, nil
- }
-
- return expr, nil
-}
-
-func (p *Parser) ParseExpression() (IEvaluator, *Error) {
- rexpr1, err := p.parseRelationalExpression()
- if err != nil {
- return nil, err
- }
-
- exp := &Expression{
- expr1: rexpr1,
- }
-
- if p.PeekOne(TokenSymbol, "&&", "||") != nil || p.PeekOne(TokenKeyword, "and", "or") != nil {
- op := p.Current()
- p.Consume()
- expr2, err := p.ParseExpression()
- if err != nil {
- return nil, err
- }
- exp.expr2 = expr2
- exp.opToken = op
- }
-
- if exp.expr2 == nil {
- // Shortcut for faster evaluation
- return exp.expr1, nil
- }
-
- return exp, nil
-}
diff --git a/vendor/github.com/flosch/pongo2/pongo2.go b/vendor/github.com/flosch/pongo2/pongo2.go
deleted file mode 100644
index eda3aa0..0000000
--- a/vendor/github.com/flosch/pongo2/pongo2.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package pongo2
-
-// Version string
-const Version = "dev"
-
-// Must panics, if a Template couldn't successfully parsed. This is how you
-// would use it:
-// var baseTemplate = pongo2.Must(pongo2.FromFile("templates/base.html"))
-func Must(tpl *Template, err error) *Template {
- if err != nil {
- panic(err)
- }
- return tpl
-}
diff --git a/vendor/github.com/flosch/pongo2/tags.go b/vendor/github.com/flosch/pongo2/tags.go
deleted file mode 100644
index 710ee25..0000000
--- a/vendor/github.com/flosch/pongo2/tags.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package pongo2
-
-/* Incomplete:
- -----------
-
- verbatim (only the "name" argument is missing for verbatim)
-
- Reconsideration:
- ----------------
-
- debug (reason: not sure what to output yet)
- regroup / Grouping on other properties (reason: maybe too python-specific; not sure how useful this would be in Go)
-
- Following built-in tags wont be added:
- --------------------------------------
-
- csrf_token (reason: web-framework specific)
- load (reason: python-specific)
- url (reason: web-framework specific)
-*/
-
-import (
- "fmt"
-)
-
-type INodeTag interface {
- INode
-}
-
-// This is the function signature of the tag's parser you will have
-// to implement in order to create a new tag.
-//
-// 'doc' is providing access to the whole document while 'arguments'
-// is providing access to the user's arguments to the tag:
-//
-// {% your_tag_name some "arguments" 123 %}
-//
-// start_token will be the *Token with the tag's name in it (here: your_tag_name).
-//
-// Please see the Parser documentation on how to use the parser.
-// See RegisterTag()'s documentation for more information about
-// writing a tag as well.
-type TagParser func(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error)
-
-type tag struct {
- name string
- parser TagParser
-}
-
-var tags map[string]*tag
-
-func init() {
- tags = make(map[string]*tag)
-}
-
-// Registers a new tag. You usually want to call this
-// function in the tag's init() function:
-// http://golang.org/doc/effective_go.html#init
-//
-// See http://www.florian-schlachter.de/post/pongo2/ for more about
-// writing filters and tags.
-func RegisterTag(name string, parserFn TagParser) error {
- _, existing := tags[name]
- if existing {
- return fmt.Errorf("tag with name '%s' is already registered", name)
- }
- tags[name] = &tag{
- name: name,
- parser: parserFn,
- }
- return nil
-}
-
-// Replaces an already registered tag with a new implementation. Use this
-// function with caution since it allows you to change existing tag behaviour.
-func ReplaceTag(name string, parserFn TagParser) error {
- _, existing := tags[name]
- if !existing {
- return fmt.Errorf("tag with name '%s' does not exist (therefore cannot be overridden)", name)
- }
- tags[name] = &tag{
- name: name,
- parser: parserFn,
- }
- return nil
-}
-
-// Tag = "{%" IDENT ARGS "%}"
-func (p *Parser) parseTagElement() (INodeTag, *Error) {
- p.Consume() // consume "{%"
- tokenName := p.MatchType(TokenIdentifier)
-
- // Check for identifier
- if tokenName == nil {
- return nil, p.Error("Tag name must be an identifier.", nil)
- }
-
- // Check for the existing tag
- tag, exists := tags[tokenName.Val]
- if !exists {
- // Does not exists
- return nil, p.Error(fmt.Sprintf("Tag '%s' not found (or beginning tag not provided)", tokenName.Val), tokenName)
- }
-
- // Check sandbox tag restriction
- if _, isBanned := p.template.set.bannedTags[tokenName.Val]; isBanned {
- return nil, p.Error(fmt.Sprintf("Usage of tag '%s' is not allowed (sandbox restriction active).", tokenName.Val), tokenName)
- }
-
- var argsToken []*Token
- for p.Peek(TokenSymbol, "%}") == nil && p.Remaining() > 0 {
- // Add token to args
- argsToken = append(argsToken, p.Current())
- p.Consume() // next token
- }
-
- // EOF?
- if p.Remaining() == 0 {
- return nil, p.Error("Unexpectedly reached EOF, no tag end found.", p.lastToken)
- }
-
- p.Match(TokenSymbol, "%}")
-
- argParser := newParser(p.name, argsToken, p.template)
- if len(argsToken) == 0 {
- // This is done to have nice EOF error messages
- argParser.lastToken = tokenName
- }
-
- p.template.level++
- defer func() { p.template.level-- }()
- return tag.parser(p, tokenName, argParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_autoescape.go b/vendor/github.com/flosch/pongo2/tags_autoescape.go
deleted file mode 100644
index 590a1db..0000000
--- a/vendor/github.com/flosch/pongo2/tags_autoescape.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package pongo2
-
-type tagAutoescapeNode struct {
- wrapper *NodeWrapper
- autoescape bool
-}
-
-func (node *tagAutoescapeNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- old := ctx.Autoescape
- ctx.Autoescape = node.autoescape
-
- err := node.wrapper.Execute(ctx, writer)
- if err != nil {
- return err
- }
-
- ctx.Autoescape = old
-
- return nil
-}
-
-func tagAutoescapeParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- autoescapeNode := &tagAutoescapeNode{}
-
- wrapper, _, err := doc.WrapUntilTag("endautoescape")
- if err != nil {
- return nil, err
- }
- autoescapeNode.wrapper = wrapper
-
- modeToken := arguments.MatchType(TokenIdentifier)
- if modeToken == nil {
- return nil, arguments.Error("A mode is required for autoescape-tag.", nil)
- }
- if modeToken.Val == "on" {
- autoescapeNode.autoescape = true
- } else if modeToken.Val == "off" {
- autoescapeNode.autoescape = false
- } else {
- return nil, arguments.Error("Only 'on' or 'off' is valid as an autoescape-mode.", nil)
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed autoescape-tag arguments.", nil)
- }
-
- return autoescapeNode, nil
-}
-
-func init() {
- RegisterTag("autoescape", tagAutoescapeParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_block.go b/vendor/github.com/flosch/pongo2/tags_block.go
deleted file mode 100644
index 86145f3..0000000
--- a/vendor/github.com/flosch/pongo2/tags_block.go
+++ /dev/null
@@ -1,129 +0,0 @@
-package pongo2
-
-import (
- "bytes"
- "fmt"
-)
-
-type tagBlockNode struct {
- name string
-}
-
-func (node *tagBlockNode) getBlockWrappers(tpl *Template) []*NodeWrapper {
- nodeWrappers := make([]*NodeWrapper, 0)
- var t *NodeWrapper
-
- for tpl != nil {
- t = tpl.blocks[node.name]
- if t != nil {
- nodeWrappers = append(nodeWrappers, t)
- }
- tpl = tpl.child
- }
-
- return nodeWrappers
-}
-
-func (node *tagBlockNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- tpl := ctx.template
- if tpl == nil {
- panic("internal error: tpl == nil")
- }
-
- // Determine the block to execute
- blockWrappers := node.getBlockWrappers(tpl)
- lenBlockWrappers := len(blockWrappers)
-
- if lenBlockWrappers == 0 {
- return ctx.Error("internal error: len(block_wrappers) == 0 in tagBlockNode.Execute()", nil)
- }
-
- blockWrapper := blockWrappers[lenBlockWrappers-1]
- ctx.Private["block"] = tagBlockInformation{
- ctx: ctx,
- wrappers: blockWrappers[0 : lenBlockWrappers-1],
- }
- err := blockWrapper.Execute(ctx, writer)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-type tagBlockInformation struct {
- ctx *ExecutionContext
- wrappers []*NodeWrapper
-}
-
-func (t tagBlockInformation) Super() string {
- lenWrappers := len(t.wrappers)
-
- if lenWrappers == 0 {
- return ""
- }
-
- superCtx := NewChildExecutionContext(t.ctx)
- superCtx.Private["block"] = tagBlockInformation{
- ctx: t.ctx,
- wrappers: t.wrappers[0 : lenWrappers-1],
- }
-
- blockWrapper := t.wrappers[lenWrappers-1]
- buf := bytes.NewBufferString("")
- err := blockWrapper.Execute(superCtx, &templateWriter{buf})
- if err != nil {
- return ""
- }
- return buf.String()
-}
-
-func tagBlockParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- if arguments.Count() == 0 {
- return nil, arguments.Error("Tag 'block' requires an identifier.", nil)
- }
-
- nameToken := arguments.MatchType(TokenIdentifier)
- if nameToken == nil {
- return nil, arguments.Error("First argument for tag 'block' must be an identifier.", nil)
- }
-
- if arguments.Remaining() != 0 {
- return nil, arguments.Error("Tag 'block' takes exactly 1 argument (an identifier).", nil)
- }
-
- wrapper, endtagargs, err := doc.WrapUntilTag("endblock")
- if err != nil {
- return nil, err
- }
- if endtagargs.Remaining() > 0 {
- endtagnameToken := endtagargs.MatchType(TokenIdentifier)
- if endtagnameToken != nil {
- if endtagnameToken.Val != nameToken.Val {
- return nil, endtagargs.Error(fmt.Sprintf("Name for 'endblock' must equal to 'block'-tag's name ('%s' != '%s').",
- nameToken.Val, endtagnameToken.Val), nil)
- }
- }
-
- if endtagnameToken == nil || endtagargs.Remaining() > 0 {
- return nil, endtagargs.Error("Either no or only one argument (identifier) allowed for 'endblock'.", nil)
- }
- }
-
- tpl := doc.template
- if tpl == nil {
- panic("internal error: tpl == nil")
- }
- _, hasBlock := tpl.blocks[nameToken.Val]
- if !hasBlock {
- tpl.blocks[nameToken.Val] = wrapper
- } else {
- return nil, arguments.Error(fmt.Sprintf("Block named '%s' already defined", nameToken.Val), nil)
- }
-
- return &tagBlockNode{name: nameToken.Val}, nil
-}
-
-func init() {
- RegisterTag("block", tagBlockParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_comment.go b/vendor/github.com/flosch/pongo2/tags_comment.go
deleted file mode 100644
index 56a02ed..0000000
--- a/vendor/github.com/flosch/pongo2/tags_comment.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package pongo2
-
-type tagCommentNode struct{}
-
-func (node *tagCommentNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- return nil
-}
-
-func tagCommentParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- commentNode := &tagCommentNode{}
-
- // TODO: Process the endtag's arguments (see django 'comment'-tag documentation)
- err := doc.SkipUntilTag("endcomment")
- if err != nil {
- return nil, err
- }
-
- if arguments.Count() != 0 {
- return nil, arguments.Error("Tag 'comment' does not take any argument.", nil)
- }
-
- return commentNode, nil
-}
-
-func init() {
- RegisterTag("comment", tagCommentParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_cycle.go b/vendor/github.com/flosch/pongo2/tags_cycle.go
deleted file mode 100644
index ffbd254..0000000
--- a/vendor/github.com/flosch/pongo2/tags_cycle.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package pongo2
-
-type tagCycleValue struct {
- node *tagCycleNode
- value *Value
-}
-
-type tagCycleNode struct {
- position *Token
- args []IEvaluator
- idx int
- asName string
- silent bool
-}
-
-func (cv *tagCycleValue) String() string {
- return cv.value.String()
-}
-
-func (node *tagCycleNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- item := node.args[node.idx%len(node.args)]
- node.idx++
-
- val, err := item.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- if t, ok := val.Interface().(*tagCycleValue); ok {
- // {% cycle "test1" "test2"
- // {% cycle cycleitem %}
-
- // Update the cycle value with next value
- item := t.node.args[t.node.idx%len(t.node.args)]
- t.node.idx++
-
- val, err := item.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- t.value = val
-
- if !t.node.silent {
- writer.WriteString(val.String())
- }
- } else {
- // Regular call
-
- cycleValue := &tagCycleValue{
- node: node,
- value: val,
- }
-
- if node.asName != "" {
- ctx.Private[node.asName] = cycleValue
- }
- if !node.silent {
- writer.WriteString(val.String())
- }
- }
-
- return nil
-}
-
-// HINT: We're not supporting the old comma-separated list of expressions argument-style
-func tagCycleParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- cycleNode := &tagCycleNode{
- position: start,
- }
-
- for arguments.Remaining() > 0 {
- node, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- cycleNode.args = append(cycleNode.args, node)
-
- if arguments.MatchOne(TokenKeyword, "as") != nil {
- // as
-
- nameToken := arguments.MatchType(TokenIdentifier)
- if nameToken == nil {
- return nil, arguments.Error("Name (identifier) expected after 'as'.", nil)
- }
- cycleNode.asName = nameToken.Val
-
- if arguments.MatchOne(TokenIdentifier, "silent") != nil {
- cycleNode.silent = true
- }
-
- // Now we're finished
- break
- }
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed cycle-tag.", nil)
- }
-
- return cycleNode, nil
-}
-
-func init() {
- RegisterTag("cycle", tagCycleParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_extends.go b/vendor/github.com/flosch/pongo2/tags_extends.go
deleted file mode 100644
index 5771020..0000000
--- a/vendor/github.com/flosch/pongo2/tags_extends.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package pongo2
-
-type tagExtendsNode struct {
- filename string
-}
-
-func (node *tagExtendsNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- return nil
-}
-
-func tagExtendsParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- extendsNode := &tagExtendsNode{}
-
- if doc.template.level > 1 {
- return nil, arguments.Error("The 'extends' tag can only defined on root level.", start)
- }
-
- if doc.template.parent != nil {
- // Already one parent
- return nil, arguments.Error("This template has already one parent.", start)
- }
-
- if filenameToken := arguments.MatchType(TokenString); filenameToken != nil {
- // prepared, static template
-
- // Get parent's filename
- parentFilename := doc.template.set.resolveFilename(doc.template, filenameToken.Val)
-
- // Parse the parent
- parentTemplate, err := doc.template.set.FromFile(parentFilename)
- if err != nil {
- return nil, err.(*Error)
- }
-
- // Keep track of things
- parentTemplate.child = doc.template
- doc.template.parent = parentTemplate
- extendsNode.filename = parentFilename
- } else {
- return nil, arguments.Error("Tag 'extends' requires a template filename as string.", nil)
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Tag 'extends' does only take 1 argument.", nil)
- }
-
- return extendsNode, nil
-}
-
-func init() {
- RegisterTag("extends", tagExtendsParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_filter.go b/vendor/github.com/flosch/pongo2/tags_filter.go
deleted file mode 100644
index b38fd92..0000000
--- a/vendor/github.com/flosch/pongo2/tags_filter.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package pongo2
-
-import (
- "bytes"
-)
-
-type nodeFilterCall struct {
- name string
- paramExpr IEvaluator
-}
-
-type tagFilterNode struct {
- position *Token
- bodyWrapper *NodeWrapper
- filterChain []*nodeFilterCall
-}
-
-func (node *tagFilterNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- temp := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB size
-
- err := node.bodyWrapper.Execute(ctx, temp)
- if err != nil {
- return err
- }
-
- value := AsValue(temp.String())
-
- for _, call := range node.filterChain {
- var param *Value
- if call.paramExpr != nil {
- param, err = call.paramExpr.Evaluate(ctx)
- if err != nil {
- return err
- }
- } else {
- param = AsValue(nil)
- }
- value, err = ApplyFilter(call.name, value, param)
- if err != nil {
- return ctx.Error(err.Error(), node.position)
- }
- }
-
- writer.WriteString(value.String())
-
- return nil
-}
-
-func tagFilterParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- filterNode := &tagFilterNode{
- position: start,
- }
-
- wrapper, _, err := doc.WrapUntilTag("endfilter")
- if err != nil {
- return nil, err
- }
- filterNode.bodyWrapper = wrapper
-
- for arguments.Remaining() > 0 {
- filterCall := &nodeFilterCall{}
-
- nameToken := arguments.MatchType(TokenIdentifier)
- if nameToken == nil {
- return nil, arguments.Error("Expected a filter name (identifier).", nil)
- }
- filterCall.name = nameToken.Val
-
- if arguments.MatchOne(TokenSymbol, ":") != nil {
- // Filter parameter
- // NOTICE: we can't use ParseExpression() here, because it would parse the next filter "|..." as well in the argument list
- expr, err := arguments.parseVariableOrLiteral()
- if err != nil {
- return nil, err
- }
- filterCall.paramExpr = expr
- }
-
- filterNode.filterChain = append(filterNode.filterChain, filterCall)
-
- if arguments.MatchOne(TokenSymbol, "|") == nil {
- break
- }
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed filter-tag arguments.", nil)
- }
-
- return filterNode, nil
-}
-
-func init() {
- RegisterTag("filter", tagFilterParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_firstof.go b/vendor/github.com/flosch/pongo2/tags_firstof.go
deleted file mode 100644
index 5b2888e..0000000
--- a/vendor/github.com/flosch/pongo2/tags_firstof.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package pongo2
-
-type tagFirstofNode struct {
- position *Token
- args []IEvaluator
-}
-
-func (node *tagFirstofNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- for _, arg := range node.args {
- val, err := arg.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- if val.IsTrue() {
- if ctx.Autoescape && !arg.FilterApplied("safe") {
- val, err = ApplyFilter("escape", val, nil)
- if err != nil {
- return err
- }
- }
-
- writer.WriteString(val.String())
- return nil
- }
- }
-
- return nil
-}
-
-func tagFirstofParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- firstofNode := &tagFirstofNode{
- position: start,
- }
-
- for arguments.Remaining() > 0 {
- node, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- firstofNode.args = append(firstofNode.args, node)
- }
-
- return firstofNode, nil
-}
-
-func init() {
- RegisterTag("firstof", tagFirstofParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_for.go b/vendor/github.com/flosch/pongo2/tags_for.go
deleted file mode 100644
index 5b0b555..0000000
--- a/vendor/github.com/flosch/pongo2/tags_for.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package pongo2
-
-type tagForNode struct {
- key string
- value string // only for maps: for key, value in map
- objectEvaluator IEvaluator
- reversed bool
- sorted bool
-
- bodyWrapper *NodeWrapper
- emptyWrapper *NodeWrapper
-}
-
-type tagForLoopInformation struct {
- Counter int
- Counter0 int
- Revcounter int
- Revcounter0 int
- First bool
- Last bool
- Parentloop *tagForLoopInformation
-}
-
-func (node *tagForNode) Execute(ctx *ExecutionContext, writer TemplateWriter) (forError *Error) {
- // Backup forloop (as parentloop in public context), key-name and value-name
- forCtx := NewChildExecutionContext(ctx)
- parentloop := forCtx.Private["forloop"]
-
- // Create loop struct
- loopInfo := &tagForLoopInformation{
- First: true,
- }
-
- // Is it a loop in a loop?
- if parentloop != nil {
- loopInfo.Parentloop = parentloop.(*tagForLoopInformation)
- }
-
- // Register loopInfo in public context
- forCtx.Private["forloop"] = loopInfo
-
- obj, err := node.objectEvaluator.Evaluate(forCtx)
- if err != nil {
- return err
- }
-
- obj.IterateOrder(func(idx, count int, key, value *Value) bool {
- // There's something to iterate over (correct type and at least 1 item)
-
- // Update loop infos and public context
- forCtx.Private[node.key] = key
- if value != nil {
- forCtx.Private[node.value] = value
- }
- loopInfo.Counter = idx + 1
- loopInfo.Counter0 = idx
- if idx == 1 {
- loopInfo.First = false
- }
- if idx+1 == count {
- loopInfo.Last = true
- }
- loopInfo.Revcounter = count - idx // TODO: Not sure about this, have to look it up
- loopInfo.Revcounter0 = count - (idx + 1) // TODO: Not sure about this, have to look it up
-
- // Render elements with updated context
- err := node.bodyWrapper.Execute(forCtx, writer)
- if err != nil {
- forError = err
- return false
- }
- return true
- }, func() {
- // Nothing to iterate over (maybe wrong type or no items)
- if node.emptyWrapper != nil {
- err := node.emptyWrapper.Execute(forCtx, writer)
- if err != nil {
- forError = err
- }
- }
- }, node.reversed, node.sorted)
-
- return forError
-}
-
-func tagForParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- forNode := &tagForNode{}
-
- // Arguments parsing
- var valueToken *Token
- keyToken := arguments.MatchType(TokenIdentifier)
- if keyToken == nil {
- return nil, arguments.Error("Expected an key identifier as first argument for 'for'-tag", nil)
- }
-
- if arguments.Match(TokenSymbol, ",") != nil {
- // Value name is provided
- valueToken = arguments.MatchType(TokenIdentifier)
- if valueToken == nil {
- return nil, arguments.Error("Value name must be an identifier.", nil)
- }
- }
-
- if arguments.Match(TokenKeyword, "in") == nil {
- return nil, arguments.Error("Expected keyword 'in'.", nil)
- }
-
- objectEvaluator, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- forNode.objectEvaluator = objectEvaluator
- forNode.key = keyToken.Val
- if valueToken != nil {
- forNode.value = valueToken.Val
- }
-
- if arguments.MatchOne(TokenIdentifier, "reversed") != nil {
- forNode.reversed = true
- }
-
- if arguments.MatchOne(TokenIdentifier, "sorted") != nil {
- forNode.sorted = true
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed for-loop arguments.", nil)
- }
-
- // Body wrapping
- wrapper, endargs, err := doc.WrapUntilTag("empty", "endfor")
- if err != nil {
- return nil, err
- }
- forNode.bodyWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
-
- if wrapper.Endtag == "empty" {
- // if there's an else in the if-statement, we need the else-Block as well
- wrapper, endargs, err = doc.WrapUntilTag("endfor")
- if err != nil {
- return nil, err
- }
- forNode.emptyWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
- }
-
- return forNode, nil
-}
-
-func init() {
- RegisterTag("for", tagForParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_if.go b/vendor/github.com/flosch/pongo2/tags_if.go
deleted file mode 100644
index 3eeaf3b..0000000
--- a/vendor/github.com/flosch/pongo2/tags_if.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package pongo2
-
-type tagIfNode struct {
- conditions []IEvaluator
- wrappers []*NodeWrapper
-}
-
-func (node *tagIfNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- for i, condition := range node.conditions {
- result, err := condition.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- if result.IsTrue() {
- return node.wrappers[i].Execute(ctx, writer)
- }
- // Last condition?
- if len(node.conditions) == i+1 && len(node.wrappers) > i+1 {
- return node.wrappers[i+1].Execute(ctx, writer)
- }
- }
- return nil
-}
-
-func tagIfParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- ifNode := &tagIfNode{}
-
- // Parse first and main IF condition
- condition, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- ifNode.conditions = append(ifNode.conditions, condition)
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("If-condition is malformed.", nil)
- }
-
- // Check the rest
- for {
- wrapper, tagArgs, err := doc.WrapUntilTag("elif", "else", "endif")
- if err != nil {
- return nil, err
- }
- ifNode.wrappers = append(ifNode.wrappers, wrapper)
-
- if wrapper.Endtag == "elif" {
- // elif can take a condition
- condition, err = tagArgs.ParseExpression()
- if err != nil {
- return nil, err
- }
- ifNode.conditions = append(ifNode.conditions, condition)
-
- if tagArgs.Remaining() > 0 {
- return nil, tagArgs.Error("Elif-condition is malformed.", nil)
- }
- } else {
- if tagArgs.Count() > 0 {
- // else/endif can't take any conditions
- return nil, tagArgs.Error("Arguments not allowed here.", nil)
- }
- }
-
- if wrapper.Endtag == "endif" {
- break
- }
- }
-
- return ifNode, nil
-}
-
-func init() {
- RegisterTag("if", tagIfParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_ifchanged.go b/vendor/github.com/flosch/pongo2/tags_ifchanged.go
deleted file mode 100644
index 45296a0..0000000
--- a/vendor/github.com/flosch/pongo2/tags_ifchanged.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package pongo2
-
-import (
- "bytes"
-)
-
-type tagIfchangedNode struct {
- watchedExpr []IEvaluator
- lastValues []*Value
- lastContent []byte
- thenWrapper *NodeWrapper
- elseWrapper *NodeWrapper
-}
-
-func (node *tagIfchangedNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- if len(node.watchedExpr) == 0 {
- // Check against own rendered body
-
- buf := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB
- err := node.thenWrapper.Execute(ctx, buf)
- if err != nil {
- return err
- }
-
- bufBytes := buf.Bytes()
- if !bytes.Equal(node.lastContent, bufBytes) {
- // Rendered content changed, output it
- writer.Write(bufBytes)
- node.lastContent = bufBytes
- }
- } else {
- nowValues := make([]*Value, 0, len(node.watchedExpr))
- for _, expr := range node.watchedExpr {
- val, err := expr.Evaluate(ctx)
- if err != nil {
- return err
- }
- nowValues = append(nowValues, val)
- }
-
- // Compare old to new values now
- changed := len(node.lastValues) == 0
-
- for idx, oldVal := range node.lastValues {
- if !oldVal.EqualValueTo(nowValues[idx]) {
- changed = true
- break // we can stop here because ONE value changed
- }
- }
-
- node.lastValues = nowValues
-
- if changed {
- // Render thenWrapper
- err := node.thenWrapper.Execute(ctx, writer)
- if err != nil {
- return err
- }
- } else {
- // Render elseWrapper
- err := node.elseWrapper.Execute(ctx, writer)
- if err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-func tagIfchangedParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- ifchangedNode := &tagIfchangedNode{}
-
- for arguments.Remaining() > 0 {
- // Parse condition
- expr, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- ifchangedNode.watchedExpr = append(ifchangedNode.watchedExpr, expr)
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Ifchanged-arguments are malformed.", nil)
- }
-
- // Wrap then/else-blocks
- wrapper, endargs, err := doc.WrapUntilTag("else", "endifchanged")
- if err != nil {
- return nil, err
- }
- ifchangedNode.thenWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
-
- if wrapper.Endtag == "else" {
- // if there's an else in the if-statement, we need the else-Block as well
- wrapper, endargs, err = doc.WrapUntilTag("endifchanged")
- if err != nil {
- return nil, err
- }
- ifchangedNode.elseWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
- }
-
- return ifchangedNode, nil
-}
-
-func init() {
- RegisterTag("ifchanged", tagIfchangedParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_ifequal.go b/vendor/github.com/flosch/pongo2/tags_ifequal.go
deleted file mode 100644
index 103f1c7..0000000
--- a/vendor/github.com/flosch/pongo2/tags_ifequal.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package pongo2
-
-type tagIfEqualNode struct {
- var1, var2 IEvaluator
- thenWrapper *NodeWrapper
- elseWrapper *NodeWrapper
-}
-
-func (node *tagIfEqualNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- r1, err := node.var1.Evaluate(ctx)
- if err != nil {
- return err
- }
- r2, err := node.var2.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- result := r1.EqualValueTo(r2)
-
- if result {
- return node.thenWrapper.Execute(ctx, writer)
- }
- if node.elseWrapper != nil {
- return node.elseWrapper.Execute(ctx, writer)
- }
- return nil
-}
-
-func tagIfEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- ifequalNode := &tagIfEqualNode{}
-
- // Parse two expressions
- var1, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- var2, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- ifequalNode.var1 = var1
- ifequalNode.var2 = var2
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("ifequal only takes 2 arguments.", nil)
- }
-
- // Wrap then/else-blocks
- wrapper, endargs, err := doc.WrapUntilTag("else", "endifequal")
- if err != nil {
- return nil, err
- }
- ifequalNode.thenWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
-
- if wrapper.Endtag == "else" {
- // if there's an else in the if-statement, we need the else-Block as well
- wrapper, endargs, err = doc.WrapUntilTag("endifequal")
- if err != nil {
- return nil, err
- }
- ifequalNode.elseWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
- }
-
- return ifequalNode, nil
-}
-
-func init() {
- RegisterTag("ifequal", tagIfEqualParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_ifnotequal.go b/vendor/github.com/flosch/pongo2/tags_ifnotequal.go
deleted file mode 100644
index 0d287d3..0000000
--- a/vendor/github.com/flosch/pongo2/tags_ifnotequal.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package pongo2
-
-type tagIfNotEqualNode struct {
- var1, var2 IEvaluator
- thenWrapper *NodeWrapper
- elseWrapper *NodeWrapper
-}
-
-func (node *tagIfNotEqualNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- r1, err := node.var1.Evaluate(ctx)
- if err != nil {
- return err
- }
- r2, err := node.var2.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- result := !r1.EqualValueTo(r2)
-
- if result {
- return node.thenWrapper.Execute(ctx, writer)
- }
- if node.elseWrapper != nil {
- return node.elseWrapper.Execute(ctx, writer)
- }
- return nil
-}
-
-func tagIfNotEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- ifnotequalNode := &tagIfNotEqualNode{}
-
- // Parse two expressions
- var1, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- var2, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- ifnotequalNode.var1 = var1
- ifnotequalNode.var2 = var2
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("ifequal only takes 2 arguments.", nil)
- }
-
- // Wrap then/else-blocks
- wrapper, endargs, err := doc.WrapUntilTag("else", "endifnotequal")
- if err != nil {
- return nil, err
- }
- ifnotequalNode.thenWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
-
- if wrapper.Endtag == "else" {
- // if there's an else in the if-statement, we need the else-Block as well
- wrapper, endargs, err = doc.WrapUntilTag("endifnotequal")
- if err != nil {
- return nil, err
- }
- ifnotequalNode.elseWrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
- }
-
- return ifnotequalNode, nil
-}
-
-func init() {
- RegisterTag("ifnotequal", tagIfNotEqualParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_import.go b/vendor/github.com/flosch/pongo2/tags_import.go
deleted file mode 100644
index 7e0d6a0..0000000
--- a/vendor/github.com/flosch/pongo2/tags_import.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package pongo2
-
-import (
- "fmt"
-)
-
-type tagImportNode struct {
- position *Token
- filename string
- macros map[string]*tagMacroNode // alias/name -> macro instance
-}
-
-func (node *tagImportNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- for name, macro := range node.macros {
- func(name string, macro *tagMacroNode) {
- ctx.Private[name] = func(args ...*Value) *Value {
- return macro.call(ctx, args...)
- }
- }(name, macro)
- }
- return nil
-}
-
-func tagImportParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- importNode := &tagImportNode{
- position: start,
- macros: make(map[string]*tagMacroNode),
- }
-
- filenameToken := arguments.MatchType(TokenString)
- if filenameToken == nil {
- return nil, arguments.Error("Import-tag needs a filename as string.", nil)
- }
-
- importNode.filename = doc.template.set.resolveFilename(doc.template, filenameToken.Val)
-
- if arguments.Remaining() == 0 {
- return nil, arguments.Error("You must at least specify one macro to import.", nil)
- }
-
- // Compile the given template
- tpl, err := doc.template.set.FromFile(importNode.filename)
- if err != nil {
- return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, start)
- }
-
- for arguments.Remaining() > 0 {
- macroNameToken := arguments.MatchType(TokenIdentifier)
- if macroNameToken == nil {
- return nil, arguments.Error("Expected macro name (identifier).", nil)
- }
-
- asName := macroNameToken.Val
- if arguments.Match(TokenKeyword, "as") != nil {
- aliasToken := arguments.MatchType(TokenIdentifier)
- if aliasToken == nil {
- return nil, arguments.Error("Expected macro alias name (identifier).", nil)
- }
- asName = aliasToken.Val
- }
-
- macroInstance, has := tpl.exportedMacros[macroNameToken.Val]
- if !has {
- return nil, arguments.Error(fmt.Sprintf("Macro '%s' not found (or not exported) in '%s'.", macroNameToken.Val,
- importNode.filename), macroNameToken)
- }
-
- importNode.macros[asName] = macroInstance
-
- if arguments.Remaining() == 0 {
- break
- }
-
- if arguments.Match(TokenSymbol, ",") == nil {
- return nil, arguments.Error("Expected ','.", nil)
- }
- }
-
- return importNode, nil
-}
-
-func init() {
- RegisterTag("import", tagImportParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_include.go b/vendor/github.com/flosch/pongo2/tags_include.go
deleted file mode 100644
index 6d619fd..0000000
--- a/vendor/github.com/flosch/pongo2/tags_include.go
+++ /dev/null
@@ -1,146 +0,0 @@
-package pongo2
-
-type tagIncludeNode struct {
- tpl *Template
- filenameEvaluator IEvaluator
- lazy bool
- only bool
- filename string
- withPairs map[string]IEvaluator
- ifExists bool
-}
-
-func (node *tagIncludeNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- // Building the context for the template
- includeCtx := make(Context)
-
- // Fill the context with all data from the parent
- if !node.only {
- includeCtx.Update(ctx.Public)
- includeCtx.Update(ctx.Private)
- }
-
- // Put all custom with-pairs into the context
- for key, value := range node.withPairs {
- val, err := value.Evaluate(ctx)
- if err != nil {
- return err
- }
- includeCtx[key] = val
- }
-
- // Execute the template
- if node.lazy {
- // Evaluate the filename
- filename, err := node.filenameEvaluator.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- if filename.String() == "" {
- return ctx.Error("Filename for 'include'-tag evaluated to an empty string.", nil)
- }
-
- // Get include-filename
- includedFilename := ctx.template.set.resolveFilename(ctx.template, filename.String())
-
- includedTpl, err2 := ctx.template.set.FromFile(includedFilename)
- if err2 != nil {
- // if this is ReadFile error, and "if_exists" flag is enabled
- if node.ifExists && err2.(*Error).Sender == "fromfile" {
- return nil
- }
- return err2.(*Error)
- }
- err2 = includedTpl.ExecuteWriter(includeCtx, writer)
- if err2 != nil {
- return err2.(*Error)
- }
- return nil
- }
- // Template is already parsed with static filename
- err := node.tpl.ExecuteWriter(includeCtx, writer)
- if err != nil {
- return err.(*Error)
- }
- return nil
-}
-
-type tagIncludeEmptyNode struct{}
-
-func (node *tagIncludeEmptyNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- return nil
-}
-
-func tagIncludeParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- includeNode := &tagIncludeNode{
- withPairs: make(map[string]IEvaluator),
- }
-
- if filenameToken := arguments.MatchType(TokenString); filenameToken != nil {
- // prepared, static template
-
- // "if_exists" flag
- ifExists := arguments.Match(TokenIdentifier, "if_exists") != nil
-
- // Get include-filename
- includedFilename := doc.template.set.resolveFilename(doc.template, filenameToken.Val)
-
- // Parse the parent
- includeNode.filename = includedFilename
- includedTpl, err := doc.template.set.FromFile(includedFilename)
- if err != nil {
- // if this is ReadFile error, and "if_exists" token presents we should create and empty node
- if err.(*Error).Sender == "fromfile" && ifExists {
- return &tagIncludeEmptyNode{}, nil
- }
- return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, filenameToken)
- }
- includeNode.tpl = includedTpl
- } else {
- // No String, then the user wants to use lazy-evaluation (slower, but possible)
- filenameEvaluator, err := arguments.ParseExpression()
- if err != nil {
- return nil, err.updateFromTokenIfNeeded(doc.template, filenameToken)
- }
- includeNode.filenameEvaluator = filenameEvaluator
- includeNode.lazy = true
- includeNode.ifExists = arguments.Match(TokenIdentifier, "if_exists") != nil // "if_exists" flag
- }
-
- // After having parsed the filename we're gonna parse the with+only options
- if arguments.Match(TokenIdentifier, "with") != nil {
- for arguments.Remaining() > 0 {
- // We have at least one key=expr pair (because of starting "with")
- keyToken := arguments.MatchType(TokenIdentifier)
- if keyToken == nil {
- return nil, arguments.Error("Expected an identifier", nil)
- }
- if arguments.Match(TokenSymbol, "=") == nil {
- return nil, arguments.Error("Expected '='.", nil)
- }
- valueExpr, err := arguments.ParseExpression()
- if err != nil {
- return nil, err.updateFromTokenIfNeeded(doc.template, keyToken)
- }
-
- includeNode.withPairs[keyToken.Val] = valueExpr
-
- // Only?
- if arguments.Match(TokenIdentifier, "only") != nil {
- includeNode.only = true
- break // stop parsing arguments because it's the last option
- }
- }
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed 'include'-tag arguments.", nil)
- }
-
- return includeNode, nil
-}
-
-func init() {
- RegisterTag("include", tagIncludeParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_lorem.go b/vendor/github.com/flosch/pongo2/tags_lorem.go
deleted file mode 100644
index 7794f6c..0000000
--- a/vendor/github.com/flosch/pongo2/tags_lorem.go
+++ /dev/null
@@ -1,132 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "math/rand"
- "strings"
- "time"
-)
-
-var (
- tagLoremParagraphs = strings.Split(tagLoremText, "\n")
- tagLoremWords = strings.Fields(tagLoremText)
-)
-
-type tagLoremNode struct {
- position *Token
- count int // number of paragraphs
- method string // w = words, p = HTML paragraphs, b = plain-text (default is b)
- random bool // does not use the default paragraph "Lorem ipsum dolor sit amet, ..."
-}
-
-func (node *tagLoremNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- switch node.method {
- case "b":
- if node.random {
- for i := 0; i < node.count; i++ {
- if i > 0 {
- writer.WriteString("\n")
- }
- par := tagLoremParagraphs[rand.Intn(len(tagLoremParagraphs))]
- writer.WriteString(par)
- }
- } else {
- for i := 0; i < node.count; i++ {
- if i > 0 {
- writer.WriteString("\n")
- }
- par := tagLoremParagraphs[i%len(tagLoremParagraphs)]
- writer.WriteString(par)
- }
- }
- case "w":
- if node.random {
- for i := 0; i < node.count; i++ {
- if i > 0 {
- writer.WriteString(" ")
- }
- word := tagLoremWords[rand.Intn(len(tagLoremWords))]
- writer.WriteString(word)
- }
- } else {
- for i := 0; i < node.count; i++ {
- if i > 0 {
- writer.WriteString(" ")
- }
- word := tagLoremWords[i%len(tagLoremWords)]
- writer.WriteString(word)
- }
- }
- case "p":
- if node.random {
- for i := 0; i < node.count; i++ {
- if i > 0 {
- writer.WriteString("\n")
- }
- writer.WriteString("")
- par := tagLoremParagraphs[rand.Intn(len(tagLoremParagraphs))]
- writer.WriteString(par)
- writer.WriteString("
")
- }
- } else {
- for i := 0; i < node.count; i++ {
- if i > 0 {
- writer.WriteString("\n")
- }
- writer.WriteString("")
- par := tagLoremParagraphs[i%len(tagLoremParagraphs)]
- writer.WriteString(par)
- writer.WriteString("
")
-
- }
- }
- default:
- return ctx.OrigError(fmt.Errorf("unsupported method: %s", node.method), nil)
- }
-
- return nil
-}
-
-func tagLoremParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- loremNode := &tagLoremNode{
- position: start,
- count: 1,
- method: "b",
- }
-
- if countToken := arguments.MatchType(TokenNumber); countToken != nil {
- loremNode.count = AsValue(countToken.Val).Integer()
- }
-
- if methodToken := arguments.MatchType(TokenIdentifier); methodToken != nil {
- if methodToken.Val != "w" && methodToken.Val != "p" && methodToken.Val != "b" {
- return nil, arguments.Error("lorem-method must be either 'w', 'p' or 'b'.", nil)
- }
-
- loremNode.method = methodToken.Val
- }
-
- if arguments.MatchOne(TokenIdentifier, "random") != nil {
- loremNode.random = true
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed lorem-tag arguments.", nil)
- }
-
- return loremNode, nil
-}
-
-func init() {
- rand.Seed(time.Now().Unix())
-
- RegisterTag("lorem", tagLoremParser)
-}
-
-const tagLoremText = `Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
-Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
-Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
-Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
-Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
-At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.
-Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.`
diff --git a/vendor/github.com/flosch/pongo2/tags_macro.go b/vendor/github.com/flosch/pongo2/tags_macro.go
deleted file mode 100644
index dd3e0bf..0000000
--- a/vendor/github.com/flosch/pongo2/tags_macro.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package pongo2
-
-import (
- "bytes"
- "fmt"
-)
-
-type tagMacroNode struct {
- position *Token
- name string
- argsOrder []string
- args map[string]IEvaluator
- exported bool
-
- wrapper *NodeWrapper
-}
-
-func (node *tagMacroNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- ctx.Private[node.name] = func(args ...*Value) *Value {
- return node.call(ctx, args...)
- }
-
- return nil
-}
-
-func (node *tagMacroNode) call(ctx *ExecutionContext, args ...*Value) *Value {
- argsCtx := make(Context)
-
- for k, v := range node.args {
- if v == nil {
- // User did not provided a default value
- argsCtx[k] = nil
- } else {
- // Evaluate the default value
- valueExpr, err := v.Evaluate(ctx)
- if err != nil {
- ctx.Logf(err.Error())
- return AsSafeValue(err.Error())
- }
-
- argsCtx[k] = valueExpr
- }
- }
-
- if len(args) > len(node.argsOrder) {
- // Too many arguments, we're ignoring them and just logging into debug mode.
- err := ctx.Error(fmt.Sprintf("Macro '%s' called with too many arguments (%d instead of %d).",
- node.name, len(args), len(node.argsOrder)), nil).updateFromTokenIfNeeded(ctx.template, node.position)
-
- ctx.Logf(err.Error()) // TODO: This is a workaround, because the error is not returned yet to the Execution()-methods
- return AsSafeValue(err.Error())
- }
-
- // Make a context for the macro execution
- macroCtx := NewChildExecutionContext(ctx)
-
- // Register all arguments in the private context
- macroCtx.Private.Update(argsCtx)
-
- for idx, argValue := range args {
- macroCtx.Private[node.argsOrder[idx]] = argValue.Interface()
- }
-
- var b bytes.Buffer
- err := node.wrapper.Execute(macroCtx, &b)
- if err != nil {
- return AsSafeValue(err.updateFromTokenIfNeeded(ctx.template, node.position).Error())
- }
-
- return AsSafeValue(b.String())
-}
-
-func tagMacroParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- macroNode := &tagMacroNode{
- position: start,
- args: make(map[string]IEvaluator),
- }
-
- nameToken := arguments.MatchType(TokenIdentifier)
- if nameToken == nil {
- return nil, arguments.Error("Macro-tag needs at least an identifier as name.", nil)
- }
- macroNode.name = nameToken.Val
-
- if arguments.MatchOne(TokenSymbol, "(") == nil {
- return nil, arguments.Error("Expected '('.", nil)
- }
-
- for arguments.Match(TokenSymbol, ")") == nil {
- argNameToken := arguments.MatchType(TokenIdentifier)
- if argNameToken == nil {
- return nil, arguments.Error("Expected argument name as identifier.", nil)
- }
- macroNode.argsOrder = append(macroNode.argsOrder, argNameToken.Val)
-
- if arguments.Match(TokenSymbol, "=") != nil {
- // Default expression follows
- argDefaultExpr, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- macroNode.args[argNameToken.Val] = argDefaultExpr
- } else {
- // No default expression
- macroNode.args[argNameToken.Val] = nil
- }
-
- if arguments.Match(TokenSymbol, ")") != nil {
- break
- }
- if arguments.Match(TokenSymbol, ",") == nil {
- return nil, arguments.Error("Expected ',' or ')'.", nil)
- }
- }
-
- if arguments.Match(TokenKeyword, "export") != nil {
- macroNode.exported = true
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed macro-tag.", nil)
- }
-
- // Body wrapping
- wrapper, endargs, err := doc.WrapUntilTag("endmacro")
- if err != nil {
- return nil, err
- }
- macroNode.wrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
-
- if macroNode.exported {
- // Now register the macro if it wants to be exported
- _, has := doc.template.exportedMacros[macroNode.name]
- if has {
- return nil, doc.Error(fmt.Sprintf("another macro with name '%s' already exported", macroNode.name), start)
- }
- doc.template.exportedMacros[macroNode.name] = macroNode
- }
-
- return macroNode, nil
-}
-
-func init() {
- RegisterTag("macro", tagMacroParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_now.go b/vendor/github.com/flosch/pongo2/tags_now.go
deleted file mode 100644
index d9fa4a3..0000000
--- a/vendor/github.com/flosch/pongo2/tags_now.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package pongo2
-
-import (
- "time"
-)
-
-type tagNowNode struct {
- position *Token
- format string
- fake bool
-}
-
-func (node *tagNowNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- var t time.Time
- if node.fake {
- t = time.Date(2014, time.February, 05, 18, 31, 45, 00, time.UTC)
- } else {
- t = time.Now()
- }
-
- writer.WriteString(t.Format(node.format))
-
- return nil
-}
-
-func tagNowParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- nowNode := &tagNowNode{
- position: start,
- }
-
- formatToken := arguments.MatchType(TokenString)
- if formatToken == nil {
- return nil, arguments.Error("Expected a format string.", nil)
- }
- nowNode.format = formatToken.Val
-
- if arguments.MatchOne(TokenIdentifier, "fake") != nil {
- nowNode.fake = true
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed now-tag arguments.", nil)
- }
-
- return nowNode, nil
-}
-
-func init() {
- RegisterTag("now", tagNowParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_set.go b/vendor/github.com/flosch/pongo2/tags_set.go
deleted file mode 100644
index be121c1..0000000
--- a/vendor/github.com/flosch/pongo2/tags_set.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package pongo2
-
-type tagSetNode struct {
- name string
- expression IEvaluator
-}
-
-func (node *tagSetNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- // Evaluate expression
- value, err := node.expression.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- ctx.Private[node.name] = value
- return nil
-}
-
-func tagSetParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- node := &tagSetNode{}
-
- // Parse variable name
- typeToken := arguments.MatchType(TokenIdentifier)
- if typeToken == nil {
- return nil, arguments.Error("Expected an identifier.", nil)
- }
- node.name = typeToken.Val
-
- if arguments.Match(TokenSymbol, "=") == nil {
- return nil, arguments.Error("Expected '='.", nil)
- }
-
- // Variable expression
- keyExpression, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- node.expression = keyExpression
-
- // Remaining arguments
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed 'set'-tag arguments.", nil)
- }
-
- return node, nil
-}
-
-func init() {
- RegisterTag("set", tagSetParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_spaceless.go b/vendor/github.com/flosch/pongo2/tags_spaceless.go
deleted file mode 100644
index 4fa851b..0000000
--- a/vendor/github.com/flosch/pongo2/tags_spaceless.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package pongo2
-
-import (
- "bytes"
- "regexp"
-)
-
-type tagSpacelessNode struct {
- wrapper *NodeWrapper
-}
-
-var tagSpacelessRegexp = regexp.MustCompile(`(?U:(<.*>))([\t\n\v\f\r ]+)(?U:(<.*>))`)
-
-func (node *tagSpacelessNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- b := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB
-
- err := node.wrapper.Execute(ctx, b)
- if err != nil {
- return err
- }
-
- s := b.String()
- // Repeat this recursively
- changed := true
- for changed {
- s2 := tagSpacelessRegexp.ReplaceAllString(s, "$1$3")
- changed = s != s2
- s = s2
- }
-
- writer.WriteString(s)
-
- return nil
-}
-
-func tagSpacelessParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- spacelessNode := &tagSpacelessNode{}
-
- wrapper, _, err := doc.WrapUntilTag("endspaceless")
- if err != nil {
- return nil, err
- }
- spacelessNode.wrapper = wrapper
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed spaceless-tag arguments.", nil)
- }
-
- return spacelessNode, nil
-}
-
-func init() {
- RegisterTag("spaceless", tagSpacelessParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_ssi.go b/vendor/github.com/flosch/pongo2/tags_ssi.go
deleted file mode 100644
index c33858d..0000000
--- a/vendor/github.com/flosch/pongo2/tags_ssi.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package pongo2
-
-import (
- "io/ioutil"
-)
-
-type tagSSINode struct {
- filename string
- content string
- template *Template
-}
-
-func (node *tagSSINode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- if node.template != nil {
- // Execute the template within the current context
- includeCtx := make(Context)
- includeCtx.Update(ctx.Public)
- includeCtx.Update(ctx.Private)
-
- err := node.template.execute(includeCtx, writer)
- if err != nil {
- return err.(*Error)
- }
- } else {
- // Just print out the content
- writer.WriteString(node.content)
- }
- return nil
-}
-
-func tagSSIParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- SSINode := &tagSSINode{}
-
- if fileToken := arguments.MatchType(TokenString); fileToken != nil {
- SSINode.filename = fileToken.Val
-
- if arguments.Match(TokenIdentifier, "parsed") != nil {
- // parsed
- temporaryTpl, err := doc.template.set.FromFile(doc.template.set.resolveFilename(doc.template, fileToken.Val))
- if err != nil {
- return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, fileToken)
- }
- SSINode.template = temporaryTpl
- } else {
- // plaintext
- buf, err := ioutil.ReadFile(doc.template.set.resolveFilename(doc.template, fileToken.Val))
- if err != nil {
- return nil, (&Error{
- Sender: "tag:ssi",
- OrigError: err,
- }).updateFromTokenIfNeeded(doc.template, fileToken)
- }
- SSINode.content = string(buf)
- }
- } else {
- return nil, arguments.Error("First argument must be a string.", nil)
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed SSI-tag argument.", nil)
- }
-
- return SSINode, nil
-}
-
-func init() {
- RegisterTag("ssi", tagSSIParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_templatetag.go b/vendor/github.com/flosch/pongo2/tags_templatetag.go
deleted file mode 100644
index 164b4dc..0000000
--- a/vendor/github.com/flosch/pongo2/tags_templatetag.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package pongo2
-
-type tagTemplateTagNode struct {
- content string
-}
-
-var templateTagMapping = map[string]string{
- "openblock": "{%",
- "closeblock": "%}",
- "openvariable": "{{",
- "closevariable": "}}",
- "openbrace": "{",
- "closebrace": "}",
- "opencomment": "{#",
- "closecomment": "#}",
-}
-
-func (node *tagTemplateTagNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- writer.WriteString(node.content)
- return nil
-}
-
-func tagTemplateTagParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- ttNode := &tagTemplateTagNode{}
-
- if argToken := arguments.MatchType(TokenIdentifier); argToken != nil {
- output, found := templateTagMapping[argToken.Val]
- if !found {
- return nil, arguments.Error("Argument not found", argToken)
- }
- ttNode.content = output
- } else {
- return nil, arguments.Error("Identifier expected.", nil)
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed templatetag-tag argument.", nil)
- }
-
- return ttNode, nil
-}
-
-func init() {
- RegisterTag("templatetag", tagTemplateTagParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_widthratio.go b/vendor/github.com/flosch/pongo2/tags_widthratio.go
deleted file mode 100644
index 70c9c3e..0000000
--- a/vendor/github.com/flosch/pongo2/tags_widthratio.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "math"
-)
-
-type tagWidthratioNode struct {
- position *Token
- current, max IEvaluator
- width IEvaluator
- ctxName string
-}
-
-func (node *tagWidthratioNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- current, err := node.current.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- max, err := node.max.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- width, err := node.width.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- value := int(math.Ceil(current.Float()/max.Float()*width.Float() + 0.5))
-
- if node.ctxName == "" {
- writer.WriteString(fmt.Sprintf("%d", value))
- } else {
- ctx.Private[node.ctxName] = value
- }
-
- return nil
-}
-
-func tagWidthratioParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- widthratioNode := &tagWidthratioNode{
- position: start,
- }
-
- current, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- widthratioNode.current = current
-
- max, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- widthratioNode.max = max
-
- width, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- widthratioNode.width = width
-
- if arguments.MatchOne(TokenKeyword, "as") != nil {
- // Name follows
- nameToken := arguments.MatchType(TokenIdentifier)
- if nameToken == nil {
- return nil, arguments.Error("Expected name (identifier).", nil)
- }
- widthratioNode.ctxName = nameToken.Val
- }
-
- if arguments.Remaining() > 0 {
- return nil, arguments.Error("Malformed widthratio-tag arguments.", nil)
- }
-
- return widthratioNode, nil
-}
-
-func init() {
- RegisterTag("widthratio", tagWidthratioParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/tags_with.go b/vendor/github.com/flosch/pongo2/tags_with.go
deleted file mode 100644
index 32b3c1c..0000000
--- a/vendor/github.com/flosch/pongo2/tags_with.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pongo2
-
-type tagWithNode struct {
- withPairs map[string]IEvaluator
- wrapper *NodeWrapper
-}
-
-func (node *tagWithNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- //new context for block
- withctx := NewChildExecutionContext(ctx)
-
- // Put all custom with-pairs into the context
- for key, value := range node.withPairs {
- val, err := value.Evaluate(ctx)
- if err != nil {
- return err
- }
- withctx.Private[key] = val
- }
-
- return node.wrapper.Execute(withctx, writer)
-}
-
-func tagWithParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
- withNode := &tagWithNode{
- withPairs: make(map[string]IEvaluator),
- }
-
- if arguments.Count() == 0 {
- return nil, arguments.Error("Tag 'with' requires at least one argument.", nil)
- }
-
- wrapper, endargs, err := doc.WrapUntilTag("endwith")
- if err != nil {
- return nil, err
- }
- withNode.wrapper = wrapper
-
- if endargs.Count() > 0 {
- return nil, endargs.Error("Arguments not allowed here.", nil)
- }
-
- // Scan through all arguments to see which style the user uses (old or new style).
- // If we find any "as" keyword we will enforce old style; otherwise we will use new style.
- oldStyle := false // by default we're using the new_style
- for i := 0; i < arguments.Count(); i++ {
- if arguments.PeekN(i, TokenKeyword, "as") != nil {
- oldStyle = true
- break
- }
- }
-
- for arguments.Remaining() > 0 {
- if oldStyle {
- valueExpr, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- if arguments.Match(TokenKeyword, "as") == nil {
- return nil, arguments.Error("Expected 'as' keyword.", nil)
- }
- keyToken := arguments.MatchType(TokenIdentifier)
- if keyToken == nil {
- return nil, arguments.Error("Expected an identifier", nil)
- }
- withNode.withPairs[keyToken.Val] = valueExpr
- } else {
- keyToken := arguments.MatchType(TokenIdentifier)
- if keyToken == nil {
- return nil, arguments.Error("Expected an identifier", nil)
- }
- if arguments.Match(TokenSymbol, "=") == nil {
- return nil, arguments.Error("Expected '='.", nil)
- }
- valueExpr, err := arguments.ParseExpression()
- if err != nil {
- return nil, err
- }
- withNode.withPairs[keyToken.Val] = valueExpr
- }
- }
-
- return withNode, nil
-}
-
-func init() {
- RegisterTag("with", tagWithParser)
-}
diff --git a/vendor/github.com/flosch/pongo2/template.go b/vendor/github.com/flosch/pongo2/template.go
deleted file mode 100644
index 47666c9..0000000
--- a/vendor/github.com/flosch/pongo2/template.go
+++ /dev/null
@@ -1,276 +0,0 @@
-package pongo2
-
-import (
- "bytes"
- "fmt"
- "io"
- "strings"
-)
-
-type TemplateWriter interface {
- io.Writer
- WriteString(string) (int, error)
-}
-
-type templateWriter struct {
- w io.Writer
-}
-
-func (tw *templateWriter) WriteString(s string) (int, error) {
- return tw.w.Write([]byte(s))
-}
-
-func (tw *templateWriter) Write(b []byte) (int, error) {
- return tw.w.Write(b)
-}
-
-type Template struct {
- set *TemplateSet
-
- // Input
- isTplString bool
- name string
- tpl string
- size int
-
- // Calculation
- tokens []*Token
- parser *Parser
-
- // first come, first serve (it's important to not override existing entries in here)
- level int
- parent *Template
- child *Template
- blocks map[string]*NodeWrapper
- exportedMacros map[string]*tagMacroNode
-
- // Output
- root *nodeDocument
-
- // Options allow you to change the behavior of template-engine.
- // You can change the options before calling the Execute method.
- Options *Options
-}
-
-func newTemplateString(set *TemplateSet, tpl []byte) (*Template, error) {
- return newTemplate(set, "", true, tpl)
-}
-
-func newTemplate(set *TemplateSet, name string, isTplString bool, tpl []byte) (*Template, error) {
- strTpl := string(tpl)
-
- // Create the template
- t := &Template{
- set: set,
- isTplString: isTplString,
- name: name,
- tpl: strTpl,
- size: len(strTpl),
- blocks: make(map[string]*NodeWrapper),
- exportedMacros: make(map[string]*tagMacroNode),
- Options: newOptions(),
- }
- // Copy all settings from another Options.
- t.Options.Update(set.Options)
-
- // Tokenize it
- tokens, err := lex(name, strTpl)
- if err != nil {
- return nil, err
- }
- t.tokens = tokens
-
- // For debugging purposes, show all tokens:
- /*for i, t := range tokens {
- fmt.Printf("%3d. %s\n", i, t)
- }*/
-
- // Parse it
- err = t.parse()
- if err != nil {
- return nil, err
- }
-
- return t, nil
-}
-
-func (tpl *Template) newContextForExecution(context Context) (*Template, *ExecutionContext, error) {
- if tpl.Options.TrimBlocks || tpl.Options.LStripBlocks {
- // Issue #94 https://github.com/flosch/pongo2/issues/94
- // If an application configures pongo2 template to trim_blocks,
- // the first newline after a template tag is removed automatically (like in PHP).
- prev := &Token{
- Typ: TokenHTML,
- Val: "\n",
- }
-
- for _, t := range tpl.tokens {
- if tpl.Options.LStripBlocks {
- if prev.Typ == TokenHTML && t.Typ != TokenHTML && t.Val == "{%" {
- prev.Val = strings.TrimRight(prev.Val, "\t ")
- }
- }
-
- if tpl.Options.TrimBlocks {
- if prev.Typ != TokenHTML && t.Typ == TokenHTML && prev.Val == "%}" {
- if len(t.Val) > 0 && t.Val[0] == '\n' {
- t.Val = t.Val[1:len(t.Val)]
- }
- }
- }
-
- prev = t
- }
- }
-
- // Determine the parent to be executed (for template inheritance)
- parent := tpl
- for parent.parent != nil {
- parent = parent.parent
- }
-
- // Create context if none is given
- newContext := make(Context)
- newContext.Update(tpl.set.Globals)
-
- if context != nil {
- newContext.Update(context)
-
- if len(newContext) > 0 {
- // Check for context name syntax
- err := newContext.checkForValidIdentifiers()
- if err != nil {
- return parent, nil, err
- }
-
- // Check for clashes with macro names
- for k := range newContext {
- _, has := tpl.exportedMacros[k]
- if has {
- return parent, nil, &Error{
- Filename: tpl.name,
- Sender: "execution",
- OrigError: fmt.Errorf("context key name '%s' clashes with macro '%s'", k, k),
- }
- }
- }
- }
- }
-
- // Create operational context
- ctx := newExecutionContext(parent, newContext)
-
- return parent, ctx, nil
-}
-
-func (tpl *Template) execute(context Context, writer TemplateWriter) error {
- parent, ctx, err := tpl.newContextForExecution(context)
- if err != nil {
- return err
- }
-
- // Run the selected document
- if err := parent.root.Execute(ctx, writer); err != nil {
- return err
- }
-
- return nil
-}
-
-func (tpl *Template) newTemplateWriterAndExecute(context Context, writer io.Writer) error {
- return tpl.execute(context, &templateWriter{w: writer})
-}
-
-func (tpl *Template) newBufferAndExecute(context Context) (*bytes.Buffer, error) {
- // Create output buffer
- // We assume that the rendered template will be 30% larger
- buffer := bytes.NewBuffer(make([]byte, 0, int(float64(tpl.size)*1.3)))
- if err := tpl.execute(context, buffer); err != nil {
- return nil, err
- }
- return buffer, nil
-}
-
-// Executes the template with the given context and writes to writer (io.Writer)
-// on success. Context can be nil. Nothing is written on error; instead the error
-// is being returned.
-func (tpl *Template) ExecuteWriter(context Context, writer io.Writer) error {
- buf, err := tpl.newBufferAndExecute(context)
- if err != nil {
- return err
- }
- _, err = buf.WriteTo(writer)
- if err != nil {
- return err
- }
- return nil
-}
-
-// Same as ExecuteWriter. The only difference between both functions is that
-// this function might already have written parts of the generated template in the
-// case of an execution error because there's no intermediate buffer involved for
-// performance reasons. This is handy if you need high performance template
-// generation or if you want to manage your own pool of buffers.
-func (tpl *Template) ExecuteWriterUnbuffered(context Context, writer io.Writer) error {
- return tpl.newTemplateWriterAndExecute(context, writer)
-}
-
-// Executes the template and returns the rendered template as a []byte
-func (tpl *Template) ExecuteBytes(context Context) ([]byte, error) {
- // Execute template
- buffer, err := tpl.newBufferAndExecute(context)
- if err != nil {
- return nil, err
- }
- return buffer.Bytes(), nil
-}
-
-// Executes the template and returns the rendered template as a string
-func (tpl *Template) Execute(context Context) (string, error) {
- // Execute template
- buffer, err := tpl.newBufferAndExecute(context)
- if err != nil {
- return "", err
- }
-
- return buffer.String(), nil
-
-}
-
-func (tpl *Template) ExecuteBlocks(context Context, blocks []string) (map[string]string, error) {
- var parents []*Template
- result := make(map[string]string)
-
- parent := tpl
- for parent != nil {
- parents = append(parents, parent)
- parent = parent.parent
- }
-
- for _, t := range parents {
- buffer := bytes.NewBuffer(make([]byte, 0, int(float64(t.size)*1.3)))
- _, ctx, err := t.newContextForExecution(context)
- if err != nil {
- return nil, err
- }
- for _, blockName := range blocks {
- if _, ok := result[blockName]; ok {
- continue
- }
- if blockWrapper, ok := t.blocks[blockName]; ok {
- bErr := blockWrapper.Execute(ctx, buffer)
- if bErr != nil {
- return nil, bErr
- }
- result[blockName] = buffer.String()
- buffer.Reset()
- }
- }
- // We have found all blocks
- if len(blocks) == len(result) {
- break
- }
- }
-
- return result, nil
-}
diff --git a/vendor/github.com/flosch/pongo2/template_loader.go b/vendor/github.com/flosch/pongo2/template_loader.go
deleted file mode 100644
index abd2340..0000000
--- a/vendor/github.com/flosch/pongo2/template_loader.go
+++ /dev/null
@@ -1,156 +0,0 @@
-package pongo2
-
-import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
-)
-
-// LocalFilesystemLoader represents a local filesystem loader with basic
-// BaseDirectory capabilities. The access to the local filesystem is unrestricted.
-type LocalFilesystemLoader struct {
- baseDir string
-}
-
-// MustNewLocalFileSystemLoader creates a new LocalFilesystemLoader instance
-// and panics if there's any error during instantiation. The parameters
-// are the same like NewLocalFileSystemLoader.
-func MustNewLocalFileSystemLoader(baseDir string) *LocalFilesystemLoader {
- fs, err := NewLocalFileSystemLoader(baseDir)
- if err != nil {
- log.Panic(err)
- }
- return fs
-}
-
-// NewLocalFileSystemLoader creates a new LocalFilesystemLoader and allows
-// templatesto be loaded from disk (unrestricted). If any base directory
-// is given (or being set using SetBaseDir), this base directory is being used
-// for path calculation in template inclusions/imports. Otherwise the path
-// is calculated based relatively to the including template's path.
-func NewLocalFileSystemLoader(baseDir string) (*LocalFilesystemLoader, error) {
- fs := &LocalFilesystemLoader{}
- if baseDir != "" {
- if err := fs.SetBaseDir(baseDir); err != nil {
- return nil, err
- }
- }
- return fs, nil
-}
-
-// SetBaseDir sets the template's base directory. This directory will
-// be used for any relative path in filters, tags and From*-functions to determine
-// your template. See the comment for NewLocalFileSystemLoader as well.
-func (fs *LocalFilesystemLoader) SetBaseDir(path string) error {
- // Make the path absolute
- if !filepath.IsAbs(path) {
- abs, err := filepath.Abs(path)
- if err != nil {
- return err
- }
- path = abs
- }
-
- // Check for existence
- fi, err := os.Stat(path)
- if err != nil {
- return err
- }
- if !fi.IsDir() {
- return fmt.Errorf("The given path '%s' is not a directory.", path)
- }
-
- fs.baseDir = path
- return nil
-}
-
-// Get reads the path's content from your local filesystem.
-func (fs *LocalFilesystemLoader) Get(path string) (io.Reader, error) {
- buf, err := ioutil.ReadFile(path)
- if err != nil {
- return nil, err
- }
- return bytes.NewReader(buf), nil
-}
-
-// Abs resolves a filename relative to the base directory. Absolute paths are allowed.
-// When there's no base dir set, the absolute path to the filename
-// will be calculated based on either the provided base directory (which
-// might be a path of a template which includes another template) or
-// the current working directory.
-func (fs *LocalFilesystemLoader) Abs(base, name string) string {
- if filepath.IsAbs(name) {
- return name
- }
-
- // Our own base dir has always priority; if there's none
- // we use the path provided in base.
- var err error
- if fs.baseDir == "" {
- if base == "" {
- base, err = os.Getwd()
- if err != nil {
- panic(err)
- }
- return filepath.Join(base, name)
- }
-
- return filepath.Join(filepath.Dir(base), name)
- }
-
- return filepath.Join(fs.baseDir, name)
-}
-
-// SandboxedFilesystemLoader is still WIP.
-type SandboxedFilesystemLoader struct {
- *LocalFilesystemLoader
-}
-
-// NewSandboxedFilesystemLoader creates a new sandboxed local file system instance.
-func NewSandboxedFilesystemLoader(baseDir string) (*SandboxedFilesystemLoader, error) {
- fs, err := NewLocalFileSystemLoader(baseDir)
- if err != nil {
- return nil, err
- }
- return &SandboxedFilesystemLoader{
- LocalFilesystemLoader: fs,
- }, nil
-}
-
-// Move sandbox to a virtual fs
-
-/*
-if len(set.SandboxDirectories) > 0 {
- defer func() {
- // Remove any ".." or other crap
- resolvedPath = filepath.Clean(resolvedPath)
-
- // Make the path absolute
- absPath, err := filepath.Abs(resolvedPath)
- if err != nil {
- panic(err)
- }
- resolvedPath = absPath
-
- // Check against the sandbox directories (once one pattern matches, we're done and can allow it)
- for _, pattern := range set.SandboxDirectories {
- matched, err := filepath.Match(pattern, resolvedPath)
- if err != nil {
- panic("Wrong sandbox directory match pattern (see http://golang.org/pkg/path/filepath/#Match).")
- }
- if matched {
- // OK!
- return
- }
- }
-
- // No pattern matched, we have to log+deny the request
- set.logf("Access attempt outside of the sandbox directories (blocked): '%s'", resolvedPath)
- resolvedPath = ""
- }()
-}
-*/
diff --git a/vendor/github.com/flosch/pongo2/template_sets.go b/vendor/github.com/flosch/pongo2/template_sets.go
deleted file mode 100644
index 4b1e43d..0000000
--- a/vendor/github.com/flosch/pongo2/template_sets.go
+++ /dev/null
@@ -1,305 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "os"
- "sync"
-
- "errors"
-)
-
-// TemplateLoader allows to implement a virtual file system.
-type TemplateLoader interface {
- // Abs calculates the path to a given template. Whenever a path must be resolved
- // due to an import from another template, the base equals the parent template's path.
- Abs(base, name string) string
-
- // Get returns an io.Reader where the template's content can be read from.
- Get(path string) (io.Reader, error)
-}
-
-// TemplateSet allows you to create your own group of templates with their own
-// global context (which is shared among all members of the set) and their own
-// configuration.
-// It's useful for a separation of different kind of templates
-// (e. g. web templates vs. mail templates).
-type TemplateSet struct {
- name string
- loaders []TemplateLoader
-
- // Globals will be provided to all templates created within this template set
- Globals Context
-
- // If debug is true (default false), ExecutionContext.Logf() will work and output
- // to STDOUT. Furthermore, FromCache() won't cache the templates.
- // Make sure to synchronize the access to it in case you're changing this
- // variable during program execution (and template compilation/execution).
- Debug bool
-
- // Options allow you to change the behavior of template-engine.
- // You can change the options before calling the Execute method.
- Options *Options
-
- // Sandbox features
- // - Disallow access to specific tags and/or filters (using BanTag() and BanFilter())
- //
- // For efficiency reasons you can ban tags/filters only *before* you have
- // added your first template to the set (restrictions are statically checked).
- // After you added one, it's not possible anymore (for your personal security).
- firstTemplateCreated bool
- bannedTags map[string]bool
- bannedFilters map[string]bool
-
- // Template cache (for FromCache())
- templateCache map[string]*Template
- templateCacheMutex sync.Mutex
-}
-
-// NewSet can be used to create sets with different kind of templates
-// (e. g. web from mail templates), with different globals or
-// other configurations.
-func NewSet(name string, loaders ...TemplateLoader) *TemplateSet {
- if len(loaders) == 0 {
- panic(fmt.Errorf("at least one template loader must be specified"))
- }
-
- return &TemplateSet{
- name: name,
- loaders: loaders,
- Globals: make(Context),
- bannedTags: make(map[string]bool),
- bannedFilters: make(map[string]bool),
- templateCache: make(map[string]*Template),
- Options: newOptions(),
- }
-}
-
-func (set *TemplateSet) AddLoader(loaders ...TemplateLoader) {
- set.loaders = append(set.loaders, loaders...)
-}
-
-func (set *TemplateSet) resolveFilename(tpl *Template, path string) string {
- return set.resolveFilenameForLoader(set.loaders[0], tpl, path)
-}
-
-func (set *TemplateSet) resolveFilenameForLoader(loader TemplateLoader, tpl *Template, path string) string {
- name := ""
- if tpl != nil && tpl.isTplString {
- return path
- }
- if tpl != nil {
- name = tpl.name
- }
-
- return loader.Abs(name, path)
-}
-
-// BanTag bans a specific tag for this template set. See more in the documentation for TemplateSet.
-func (set *TemplateSet) BanTag(name string) error {
- _, has := tags[name]
- if !has {
- return fmt.Errorf("tag '%s' not found", name)
- }
- if set.firstTemplateCreated {
- return errors.New("you cannot ban any tags after you've added your first template to your template set")
- }
- _, has = set.bannedTags[name]
- if has {
- return fmt.Errorf("tag '%s' is already banned", name)
- }
- set.bannedTags[name] = true
-
- return nil
-}
-
-// BanFilter bans a specific filter for this template set. See more in the documentation for TemplateSet.
-func (set *TemplateSet) BanFilter(name string) error {
- _, has := filters[name]
- if !has {
- return fmt.Errorf("filter '%s' not found", name)
- }
- if set.firstTemplateCreated {
- return errors.New("you cannot ban any filters after you've added your first template to your template set")
- }
- _, has = set.bannedFilters[name]
- if has {
- return fmt.Errorf("filter '%s' is already banned", name)
- }
- set.bannedFilters[name] = true
-
- return nil
-}
-
-func (set *TemplateSet) resolveTemplate(tpl *Template, path string) (name string, loader TemplateLoader, fd io.Reader, err error) {
- // iterate over loaders until we appear to have a valid template
- for _, loader = range set.loaders {
- name = set.resolveFilenameForLoader(loader, tpl, path)
- fd, err = loader.Get(name)
- if err == nil {
- return
- }
- }
-
- return path, nil, nil, fmt.Errorf("unable to resolve template")
-}
-
-// CleanCache cleans the template cache. If filenames is not empty,
-// it will remove the template caches of those filenames.
-// Or it will empty the whole template cache. It is thread-safe.
-func (set *TemplateSet) CleanCache(filenames ...string) {
- set.templateCacheMutex.Lock()
- defer set.templateCacheMutex.Unlock()
-
- if len(filenames) == 0 {
- set.templateCache = make(map[string]*Template, len(set.templateCache))
- }
-
- for _, filename := range filenames {
- delete(set.templateCache, set.resolveFilename(nil, filename))
- }
-}
-
-// FromCache is a convenient method to cache templates. It is thread-safe
-// and will only compile the template associated with a filename once.
-// If TemplateSet.Debug is true (for example during development phase),
-// FromCache() will not cache the template and instead recompile it on any
-// call (to make changes to a template live instantaneously).
-func (set *TemplateSet) FromCache(filename string) (*Template, error) {
- if set.Debug {
- // Recompile on any request
- return set.FromFile(filename)
- }
- // Cache the template
- cleanedFilename := set.resolveFilename(nil, filename)
-
- set.templateCacheMutex.Lock()
- defer set.templateCacheMutex.Unlock()
-
- tpl, has := set.templateCache[cleanedFilename]
-
- // Cache miss
- if !has {
- tpl, err := set.FromFile(cleanedFilename)
- if err != nil {
- return nil, err
- }
- set.templateCache[cleanedFilename] = tpl
- return tpl, nil
- }
-
- // Cache hit
- return tpl, nil
-}
-
-// FromString loads a template from string and returns a Template instance.
-func (set *TemplateSet) FromString(tpl string) (*Template, error) {
- set.firstTemplateCreated = true
-
- return newTemplateString(set, []byte(tpl))
-}
-
-// FromBytes loads a template from bytes and returns a Template instance.
-func (set *TemplateSet) FromBytes(tpl []byte) (*Template, error) {
- set.firstTemplateCreated = true
-
- return newTemplateString(set, tpl)
-}
-
-// FromFile loads a template from a filename and returns a Template instance.
-func (set *TemplateSet) FromFile(filename string) (*Template, error) {
- set.firstTemplateCreated = true
-
- _, _, fd, err := set.resolveTemplate(nil, filename)
- if err != nil {
- return nil, &Error{
- Filename: filename,
- Sender: "fromfile",
- OrigError: err,
- }
- }
- buf, err := ioutil.ReadAll(fd)
- if err != nil {
- return nil, &Error{
- Filename: filename,
- Sender: "fromfile",
- OrigError: err,
- }
- }
-
- return newTemplate(set, filename, false, buf)
-}
-
-// RenderTemplateString is a shortcut and renders a template string directly.
-func (set *TemplateSet) RenderTemplateString(s string, ctx Context) (string, error) {
- set.firstTemplateCreated = true
-
- tpl := Must(set.FromString(s))
- result, err := tpl.Execute(ctx)
- if err != nil {
- return "", err
- }
- return result, nil
-}
-
-// RenderTemplateBytes is a shortcut and renders template bytes directly.
-func (set *TemplateSet) RenderTemplateBytes(b []byte, ctx Context) (string, error) {
- set.firstTemplateCreated = true
-
- tpl := Must(set.FromBytes(b))
- result, err := tpl.Execute(ctx)
- if err != nil {
- return "", err
- }
- return result, nil
-}
-
-// RenderTemplateFile is a shortcut and renders a template file directly.
-func (set *TemplateSet) RenderTemplateFile(fn string, ctx Context) (string, error) {
- set.firstTemplateCreated = true
-
- tpl := Must(set.FromFile(fn))
- result, err := tpl.Execute(ctx)
- if err != nil {
- return "", err
- }
- return result, nil
-}
-
-func (set *TemplateSet) logf(format string, args ...interface{}) {
- if set.Debug {
- logger.Printf(fmt.Sprintf("[template set: %s] %s", set.name, format), args...)
- }
-}
-
-// Logging function (internally used)
-func logf(format string, items ...interface{}) {
- if debug {
- logger.Printf(format, items...)
- }
-}
-
-var (
- debug bool // internal debugging
- logger = log.New(os.Stdout, "[pongo2] ", log.LstdFlags|log.Lshortfile)
-
- // DefaultLoader allows the default un-sandboxed access to the local file
- // system and is being used by the DefaultSet.
- DefaultLoader = MustNewLocalFileSystemLoader("")
-
- // DefaultSet is a set created for you for convinience reasons.
- DefaultSet = NewSet("default", DefaultLoader)
-
- // Methods on the default set
- FromString = DefaultSet.FromString
- FromBytes = DefaultSet.FromBytes
- FromFile = DefaultSet.FromFile
- FromCache = DefaultSet.FromCache
- RenderTemplateString = DefaultSet.RenderTemplateString
- RenderTemplateFile = DefaultSet.RenderTemplateFile
-
- // Globals for the default set
- Globals = DefaultSet.Globals
-)
diff --git a/vendor/github.com/flosch/pongo2/value.go b/vendor/github.com/flosch/pongo2/value.go
deleted file mode 100644
index 8b49adb..0000000
--- a/vendor/github.com/flosch/pongo2/value.go
+++ /dev/null
@@ -1,540 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "reflect"
- "sort"
- "strconv"
- "strings"
- "time"
-)
-
-type Value struct {
- val reflect.Value
- safe bool // used to indicate whether a Value needs explicit escaping in the template
-}
-
-// AsValue converts any given value to a pongo2.Value
-// Usually being used within own functions passed to a template
-// through a Context or within filter functions.
-//
-// Example:
-// AsValue("my string")
-func AsValue(i interface{}) *Value {
- return &Value{
- val: reflect.ValueOf(i),
- }
-}
-
-// AsSafeValue works like AsValue, but does not apply the 'escape' filter.
-func AsSafeValue(i interface{}) *Value {
- return &Value{
- val: reflect.ValueOf(i),
- safe: true,
- }
-}
-
-func (v *Value) getResolvedValue() reflect.Value {
- if v.val.IsValid() && v.val.Kind() == reflect.Ptr {
- return v.val.Elem()
- }
- return v.val
-}
-
-// IsString checks whether the underlying value is a string
-func (v *Value) IsString() bool {
- return v.getResolvedValue().Kind() == reflect.String
-}
-
-// IsBool checks whether the underlying value is a bool
-func (v *Value) IsBool() bool {
- return v.getResolvedValue().Kind() == reflect.Bool
-}
-
-// IsFloat checks whether the underlying value is a float
-func (v *Value) IsFloat() bool {
- return v.getResolvedValue().Kind() == reflect.Float32 ||
- v.getResolvedValue().Kind() == reflect.Float64
-}
-
-// IsInteger checks whether the underlying value is an integer
-func (v *Value) IsInteger() bool {
- return v.getResolvedValue().Kind() == reflect.Int ||
- v.getResolvedValue().Kind() == reflect.Int8 ||
- v.getResolvedValue().Kind() == reflect.Int16 ||
- v.getResolvedValue().Kind() == reflect.Int32 ||
- v.getResolvedValue().Kind() == reflect.Int64 ||
- v.getResolvedValue().Kind() == reflect.Uint ||
- v.getResolvedValue().Kind() == reflect.Uint8 ||
- v.getResolvedValue().Kind() == reflect.Uint16 ||
- v.getResolvedValue().Kind() == reflect.Uint32 ||
- v.getResolvedValue().Kind() == reflect.Uint64
-}
-
-// IsNumber checks whether the underlying value is either an integer
-// or a float.
-func (v *Value) IsNumber() bool {
- return v.IsInteger() || v.IsFloat()
-}
-
-// IsTime checks whether the underlying value is a time.Time.
-func (v *Value) IsTime() bool {
- _, ok := v.Interface().(time.Time)
- return ok
-}
-
-// IsNil checks whether the underlying value is NIL
-func (v *Value) IsNil() bool {
- //fmt.Printf("%+v\n", v.getResolvedValue().Type().String())
- return !v.getResolvedValue().IsValid()
-}
-
-// String returns a string for the underlying value. If this value is not
-// of type string, pongo2 tries to convert it. Currently the following
-// types for underlying values are supported:
-//
-// 1. string
-// 2. int/uint (any size)
-// 3. float (any precision)
-// 4. bool
-// 5. time.Time
-// 6. String() will be called on the underlying value if provided
-//
-// NIL values will lead to an empty string. Unsupported types are leading
-// to their respective type name.
-func (v *Value) String() string {
- if v.IsNil() {
- return ""
- }
-
- switch v.getResolvedValue().Kind() {
- case reflect.String:
- return v.getResolvedValue().String()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return strconv.FormatInt(v.getResolvedValue().Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return strconv.FormatUint(v.getResolvedValue().Uint(), 10)
- case reflect.Float32, reflect.Float64:
- return fmt.Sprintf("%f", v.getResolvedValue().Float())
- case reflect.Bool:
- if v.Bool() {
- return "True"
- }
- return "False"
- case reflect.Struct:
- if t, ok := v.Interface().(fmt.Stringer); ok {
- return t.String()
- }
- }
-
- logf("Value.String() not implemented for type: %s\n", v.getResolvedValue().Kind().String())
- return v.getResolvedValue().String()
-}
-
-// Integer returns the underlying value as an integer (converts the underlying
-// value, if necessary). If it's not possible to convert the underlying value,
-// it will return 0.
-func (v *Value) Integer() int {
- switch v.getResolvedValue().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return int(v.getResolvedValue().Int())
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return int(v.getResolvedValue().Uint())
- case reflect.Float32, reflect.Float64:
- return int(v.getResolvedValue().Float())
- case reflect.String:
- // Try to convert from string to int (base 10)
- f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
- if err != nil {
- return 0
- }
- return int(f)
- default:
- logf("Value.Integer() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return 0
- }
-}
-
-// Float returns the underlying value as a float (converts the underlying
-// value, if necessary). If it's not possible to convert the underlying value,
-// it will return 0.0.
-func (v *Value) Float() float64 {
- switch v.getResolvedValue().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return float64(v.getResolvedValue().Int())
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return float64(v.getResolvedValue().Uint())
- case reflect.Float32, reflect.Float64:
- return v.getResolvedValue().Float()
- case reflect.String:
- // Try to convert from string to float64 (base 10)
- f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
- if err != nil {
- return 0.0
- }
- return f
- default:
- logf("Value.Float() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return 0.0
- }
-}
-
-// Bool returns the underlying value as bool. If the value is not bool, false
-// will always be returned. If you're looking for true/false-evaluation of the
-// underlying value, have a look on the IsTrue()-function.
-func (v *Value) Bool() bool {
- switch v.getResolvedValue().Kind() {
- case reflect.Bool:
- return v.getResolvedValue().Bool()
- default:
- logf("Value.Bool() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return false
- }
-}
-
-// Time returns the underlying value as time.Time.
-// If the underlying value is not a time.Time, it returns the zero value of time.Time.
-func (v *Value) Time() time.Time {
- tm, ok := v.Interface().(time.Time)
- if ok {
- return tm
- }
- return time.Time{}
-}
-
-// IsTrue tries to evaluate the underlying value the Pythonic-way:
-//
-// Returns TRUE in one the following cases:
-//
-// * int != 0
-// * uint != 0
-// * float != 0.0
-// * len(array/chan/map/slice/string) > 0
-// * bool == true
-// * underlying value is a struct
-//
-// Otherwise returns always FALSE.
-func (v *Value) IsTrue() bool {
- switch v.getResolvedValue().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return v.getResolvedValue().Int() != 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return v.getResolvedValue().Uint() != 0
- case reflect.Float32, reflect.Float64:
- return v.getResolvedValue().Float() != 0
- case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
- return v.getResolvedValue().Len() > 0
- case reflect.Bool:
- return v.getResolvedValue().Bool()
- case reflect.Struct:
- return true // struct instance is always true
- default:
- logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return false
- }
-}
-
-// Negate tries to negate the underlying value. It's mainly used for
-// the NOT-operator and in conjunction with a call to
-// return_value.IsTrue() afterwards.
-//
-// Example:
-// AsValue(1).Negate().IsTrue() == false
-func (v *Value) Negate() *Value {
- switch v.getResolvedValue().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- if v.Integer() != 0 {
- return AsValue(0)
- }
- return AsValue(1)
- case reflect.Float32, reflect.Float64:
- if v.Float() != 0.0 {
- return AsValue(float64(0.0))
- }
- return AsValue(float64(1.1))
- case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
- return AsValue(v.getResolvedValue().Len() == 0)
- case reflect.Bool:
- return AsValue(!v.getResolvedValue().Bool())
- case reflect.Struct:
- return AsValue(false)
- default:
- logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return AsValue(true)
- }
-}
-
-// Len returns the length for an array, chan, map, slice or string.
-// Otherwise it will return 0.
-func (v *Value) Len() int {
- switch v.getResolvedValue().Kind() {
- case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
- return v.getResolvedValue().Len()
- case reflect.String:
- runes := []rune(v.getResolvedValue().String())
- return len(runes)
- default:
- logf("Value.Len() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return 0
- }
-}
-
-// Slice slices an array, slice or string. Otherwise it will
-// return an empty []int.
-func (v *Value) Slice(i, j int) *Value {
- switch v.getResolvedValue().Kind() {
- case reflect.Array, reflect.Slice:
- return AsValue(v.getResolvedValue().Slice(i, j).Interface())
- case reflect.String:
- runes := []rune(v.getResolvedValue().String())
- return AsValue(string(runes[i:j]))
- default:
- logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return AsValue([]int{})
- }
-}
-
-// Index gets the i-th item of an array, slice or string. Otherwise
-// it will return NIL.
-func (v *Value) Index(i int) *Value {
- switch v.getResolvedValue().Kind() {
- case reflect.Array, reflect.Slice:
- if i >= v.Len() {
- return AsValue(nil)
- }
- return AsValue(v.getResolvedValue().Index(i).Interface())
- case reflect.String:
- //return AsValue(v.getResolvedValue().Slice(i, i+1).Interface())
- s := v.getResolvedValue().String()
- runes := []rune(s)
- if i < len(runes) {
- return AsValue(string(runes[i]))
- }
- return AsValue("")
- default:
- logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return AsValue([]int{})
- }
-}
-
-// Contains checks whether the underlying value (which must be of type struct, map,
-// string, array or slice) contains of another Value (e. g. used to check
-// whether a struct contains of a specific field or a map contains a specific key).
-//
-// Example:
-// AsValue("Hello, World!").Contains(AsValue("World")) == true
-func (v *Value) Contains(other *Value) bool {
- switch v.getResolvedValue().Kind() {
- case reflect.Struct:
- fieldValue := v.getResolvedValue().FieldByName(other.String())
- return fieldValue.IsValid()
- case reflect.Map:
- var mapValue reflect.Value
- switch other.Interface().(type) {
- case int:
- mapValue = v.getResolvedValue().MapIndex(other.getResolvedValue())
- case string:
- mapValue = v.getResolvedValue().MapIndex(other.getResolvedValue())
- default:
- logf("Value.Contains() does not support lookup type '%s'\n", other.getResolvedValue().Kind().String())
- return false
- }
-
- return mapValue.IsValid()
- case reflect.String:
- return strings.Contains(v.getResolvedValue().String(), other.String())
-
- case reflect.Slice, reflect.Array:
- for i := 0; i < v.getResolvedValue().Len(); i++ {
- item := v.getResolvedValue().Index(i)
- if other.Interface() == item.Interface() {
- return true
- }
- }
- return false
-
- default:
- logf("Value.Contains() not available for type: %s\n", v.getResolvedValue().Kind().String())
- return false
- }
-}
-
-// CanSlice checks whether the underlying value is of type array, slice or string.
-// You normally would use CanSlice() before using the Slice() operation.
-func (v *Value) CanSlice() bool {
- switch v.getResolvedValue().Kind() {
- case reflect.Array, reflect.Slice, reflect.String:
- return true
- }
- return false
-}
-
-// Iterate iterates over a map, array, slice or a string. It calls the
-// function's first argument for every value with the following arguments:
-//
-// idx current 0-index
-// count total amount of items
-// key *Value for the key or item
-// value *Value (only for maps, the respective value for a specific key)
-//
-// If the underlying value has no items or is not one of the types above,
-// the empty function (function's second argument) will be called.
-func (v *Value) Iterate(fn func(idx, count int, key, value *Value) bool, empty func()) {
- v.IterateOrder(fn, empty, false, false)
-}
-
-// IterateOrder behaves like Value.Iterate, but can iterate through an array/slice/string in reverse. Does
-// not affect the iteration through a map because maps don't have any particular order.
-// However, you can force an order using the `sorted` keyword (and even use `reversed sorted`).
-func (v *Value) IterateOrder(fn func(idx, count int, key, value *Value) bool, empty func(), reverse bool, sorted bool) {
- switch v.getResolvedValue().Kind() {
- case reflect.Map:
- keys := sortedKeys(v.getResolvedValue().MapKeys())
- if sorted {
- if reverse {
- sort.Sort(sort.Reverse(keys))
- } else {
- sort.Sort(keys)
- }
- }
- keyLen := len(keys)
- for idx, key := range keys {
- value := v.getResolvedValue().MapIndex(key)
- if !fn(idx, keyLen, &Value{val: key}, &Value{val: value}) {
- return
- }
- }
- if keyLen == 0 {
- empty()
- }
- return // done
- case reflect.Array, reflect.Slice:
- var items valuesList
-
- itemCount := v.getResolvedValue().Len()
- for i := 0; i < itemCount; i++ {
- items = append(items, &Value{val: v.getResolvedValue().Index(i)})
- }
-
- if sorted {
- if reverse {
- sort.Sort(sort.Reverse(items))
- } else {
- sort.Sort(items)
- }
- } else {
- if reverse {
- for i := 0; i < itemCount/2; i++ {
- items[i], items[itemCount-1-i] = items[itemCount-1-i], items[i]
- }
- }
- }
-
- if len(items) > 0 {
- for idx, item := range items {
- if !fn(idx, itemCount, item, nil) {
- return
- }
- }
- } else {
- empty()
- }
- return // done
- case reflect.String:
- if sorted {
- // TODO(flosch): Handle sorted
- panic("TODO: handle sort for type string")
- }
-
- // TODO(flosch): Not utf8-compatible (utf8-decoding necessary)
- charCount := v.getResolvedValue().Len()
- if charCount > 0 {
- if reverse {
- for i := charCount - 1; i >= 0; i-- {
- if !fn(i, charCount, &Value{val: v.getResolvedValue().Slice(i, i+1)}, nil) {
- return
- }
- }
- } else {
- for i := 0; i < charCount; i++ {
- if !fn(i, charCount, &Value{val: v.getResolvedValue().Slice(i, i+1)}, nil) {
- return
- }
- }
- }
- } else {
- empty()
- }
- return // done
- default:
- logf("Value.Iterate() not available for type: %s\n", v.getResolvedValue().Kind().String())
- }
- empty()
-}
-
-// Interface gives you access to the underlying value.
-func (v *Value) Interface() interface{} {
- if v.val.IsValid() {
- return v.val.Interface()
- }
- return nil
-}
-
-// EqualValueTo checks whether two values are containing the same value or object.
-func (v *Value) EqualValueTo(other *Value) bool {
- // comparison of uint with int fails using .Interface()-comparison (see issue #64)
- if v.IsInteger() && other.IsInteger() {
- return v.Integer() == other.Integer()
- }
- if v.IsTime() && other.IsTime() {
- return v.Time().Equal(other.Time())
- }
- return v.Interface() == other.Interface()
-}
-
-type sortedKeys []reflect.Value
-
-func (sk sortedKeys) Len() int {
- return len(sk)
-}
-
-func (sk sortedKeys) Less(i, j int) bool {
- vi := &Value{val: sk[i]}
- vj := &Value{val: sk[j]}
- switch {
- case vi.IsInteger() && vj.IsInteger():
- return vi.Integer() < vj.Integer()
- case vi.IsFloat() && vj.IsFloat():
- return vi.Float() < vj.Float()
- default:
- return vi.String() < vj.String()
- }
-}
-
-func (sk sortedKeys) Swap(i, j int) {
- sk[i], sk[j] = sk[j], sk[i]
-}
-
-type valuesList []*Value
-
-func (vl valuesList) Len() int {
- return len(vl)
-}
-
-func (vl valuesList) Less(i, j int) bool {
- vi := vl[i]
- vj := vl[j]
- switch {
- case vi.IsInteger() && vj.IsInteger():
- return vi.Integer() < vj.Integer()
- case vi.IsFloat() && vj.IsFloat():
- return vi.Float() < vj.Float()
- default:
- return vi.String() < vj.String()
- }
-}
-
-func (vl valuesList) Swap(i, j int) {
- vl[i], vl[j] = vl[j], vl[i]
-}
diff --git a/vendor/github.com/flosch/pongo2/variable.go b/vendor/github.com/flosch/pongo2/variable.go
deleted file mode 100644
index 25e2af4..0000000
--- a/vendor/github.com/flosch/pongo2/variable.go
+++ /dev/null
@@ -1,693 +0,0 @@
-package pongo2
-
-import (
- "fmt"
- "reflect"
- "strconv"
- "strings"
-)
-
-const (
- varTypeInt = iota
- varTypeIdent
-)
-
-var (
- typeOfValuePtr = reflect.TypeOf(new(Value))
- typeOfExecCtxPtr = reflect.TypeOf(new(ExecutionContext))
-)
-
-type variablePart struct {
- typ int
- s string
- i int
-
- isFunctionCall bool
- callingArgs []functionCallArgument // needed for a function call, represents all argument nodes (INode supports nested function calls)
-}
-
-type functionCallArgument interface {
- Evaluate(*ExecutionContext) (*Value, *Error)
-}
-
-// TODO: Add location tokens
-type stringResolver struct {
- locationToken *Token
- val string
-}
-
-type intResolver struct {
- locationToken *Token
- val int
-}
-
-type floatResolver struct {
- locationToken *Token
- val float64
-}
-
-type boolResolver struct {
- locationToken *Token
- val bool
-}
-
-type variableResolver struct {
- locationToken *Token
-
- parts []*variablePart
-}
-
-type nodeFilteredVariable struct {
- locationToken *Token
-
- resolver IEvaluator
- filterChain []*filterCall
-}
-
-type nodeVariable struct {
- locationToken *Token
- expr IEvaluator
-}
-
-type executionCtxEval struct{}
-
-func (v *nodeFilteredVariable) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := v.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (vr *variableResolver) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := vr.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (s *stringResolver) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := s.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (i *intResolver) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := i.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (f *floatResolver) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := f.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (b *boolResolver) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := b.Evaluate(ctx)
- if err != nil {
- return err
- }
- writer.WriteString(value.String())
- return nil
-}
-
-func (v *nodeFilteredVariable) GetPositionToken() *Token {
- return v.locationToken
-}
-
-func (vr *variableResolver) GetPositionToken() *Token {
- return vr.locationToken
-}
-
-func (s *stringResolver) GetPositionToken() *Token {
- return s.locationToken
-}
-
-func (i *intResolver) GetPositionToken() *Token {
- return i.locationToken
-}
-
-func (f *floatResolver) GetPositionToken() *Token {
- return f.locationToken
-}
-
-func (b *boolResolver) GetPositionToken() *Token {
- return b.locationToken
-}
-
-func (s *stringResolver) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- return AsValue(s.val), nil
-}
-
-func (i *intResolver) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- return AsValue(i.val), nil
-}
-
-func (f *floatResolver) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- return AsValue(f.val), nil
-}
-
-func (b *boolResolver) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- return AsValue(b.val), nil
-}
-
-func (s *stringResolver) FilterApplied(name string) bool {
- return false
-}
-
-func (i *intResolver) FilterApplied(name string) bool {
- return false
-}
-
-func (f *floatResolver) FilterApplied(name string) bool {
- return false
-}
-
-func (b *boolResolver) FilterApplied(name string) bool {
- return false
-}
-
-func (nv *nodeVariable) FilterApplied(name string) bool {
- return nv.expr.FilterApplied(name)
-}
-
-func (nv *nodeVariable) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
- value, err := nv.expr.Evaluate(ctx)
- if err != nil {
- return err
- }
-
- if !nv.expr.FilterApplied("safe") && !value.safe && value.IsString() && ctx.Autoescape {
- // apply escape filter
- value, err = filters["escape"](value, nil)
- if err != nil {
- return err
- }
- }
-
- writer.WriteString(value.String())
- return nil
-}
-
-func (executionCtxEval) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- return AsValue(ctx), nil
-}
-
-func (vr *variableResolver) FilterApplied(name string) bool {
- return false
-}
-
-func (vr *variableResolver) String() string {
- parts := make([]string, 0, len(vr.parts))
- for _, p := range vr.parts {
- switch p.typ {
- case varTypeInt:
- parts = append(parts, strconv.Itoa(p.i))
- case varTypeIdent:
- parts = append(parts, p.s)
- default:
- panic("unimplemented")
- }
- }
- return strings.Join(parts, ".")
-}
-
-func (vr *variableResolver) resolve(ctx *ExecutionContext) (*Value, error) {
- var current reflect.Value
- var isSafe bool
-
- for idx, part := range vr.parts {
- if idx == 0 {
- // We're looking up the first part of the variable.
- // First we're having a look in our private
- // context (e. g. information provided by tags, like the forloop)
- val, inPrivate := ctx.Private[vr.parts[0].s]
- if !inPrivate {
- // Nothing found? Then have a final lookup in the public context
- val = ctx.Public[vr.parts[0].s]
- }
- current = reflect.ValueOf(val) // Get the initial value
- } else {
- // Next parts, resolve it from current
-
- // Before resolving the pointer, let's see if we have a method to call
- // Problem with resolving the pointer is we're changing the receiver
- isFunc := false
- if part.typ == varTypeIdent {
- funcValue := current.MethodByName(part.s)
- if funcValue.IsValid() {
- current = funcValue
- isFunc = true
- }
- }
-
- if !isFunc {
- // If current a pointer, resolve it
- if current.Kind() == reflect.Ptr {
- current = current.Elem()
- if !current.IsValid() {
- // Value is not valid (anymore)
- return AsValue(nil), nil
- }
- }
-
- // Look up which part must be called now
- switch part.typ {
- case varTypeInt:
- // Calling an index is only possible for:
- // * slices/arrays/strings
- switch current.Kind() {
- case reflect.String, reflect.Array, reflect.Slice:
- if part.i >= 0 && current.Len() > part.i {
- current = current.Index(part.i)
- } else {
- // In Django, exceeding the length of a list is just empty.
- return AsValue(nil), nil
- }
- default:
- return nil, fmt.Errorf("Can't access an index on type %s (variable %s)",
- current.Kind().String(), vr.String())
- }
- case varTypeIdent:
- // debugging:
- // fmt.Printf("now = %s (kind: %s)\n", part.s, current.Kind().String())
-
- // Calling a field or key
- switch current.Kind() {
- case reflect.Struct:
- current = current.FieldByName(part.s)
- case reflect.Map:
- current = current.MapIndex(reflect.ValueOf(part.s))
- default:
- return nil, fmt.Errorf("Can't access a field by name on type %s (variable %s)",
- current.Kind().String(), vr.String())
- }
- default:
- panic("unimplemented")
- }
- }
- }
-
- if !current.IsValid() {
- // Value is not valid (anymore)
- return AsValue(nil), nil
- }
-
- // If current is a reflect.ValueOf(pongo2.Value), then unpack it
- // Happens in function calls (as a return value) or by injecting
- // into the execution context (e.g. in a for-loop)
- if current.Type() == typeOfValuePtr {
- tmpValue := current.Interface().(*Value)
- current = tmpValue.val
- isSafe = tmpValue.safe
- }
-
- // Check whether this is an interface and resolve it where required
- if current.Kind() == reflect.Interface {
- current = reflect.ValueOf(current.Interface())
- }
-
- // Check if the part is a function call
- if part.isFunctionCall || current.Kind() == reflect.Func {
- // Check for callable
- if current.Kind() != reflect.Func {
- return nil, fmt.Errorf("'%s' is not a function (it is %s)", vr.String(), current.Kind().String())
- }
-
- // Check for correct function syntax and types
- // func(*Value, ...) *Value
- t := current.Type()
- currArgs := part.callingArgs
-
- // If an implicit ExecCtx is needed
- if t.NumIn() > 0 && t.In(0) == typeOfExecCtxPtr {
- currArgs = append([]functionCallArgument{executionCtxEval{}}, currArgs...)
- }
-
- // Input arguments
- if len(currArgs) != t.NumIn() && !(len(currArgs) >= t.NumIn()-1 && t.IsVariadic()) {
- return nil,
- fmt.Errorf("Function input argument count (%d) of '%s' must be equal to the calling argument count (%d).",
- t.NumIn(), vr.String(), len(currArgs))
- }
-
- // Output arguments
- if t.NumOut() != 1 && t.NumOut() != 2 {
- return nil, fmt.Errorf("'%s' must have exactly 1 or 2 output arguments, the second argument must be of type error", vr.String())
- }
-
- // Evaluate all parameters
- var parameters []reflect.Value
-
- numArgs := t.NumIn()
- isVariadic := t.IsVariadic()
- var fnArg reflect.Type
-
- for idx, arg := range currArgs {
- pv, err := arg.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
-
- if isVariadic {
- if idx >= t.NumIn()-1 {
- fnArg = t.In(numArgs - 1).Elem()
- } else {
- fnArg = t.In(idx)
- }
- } else {
- fnArg = t.In(idx)
- }
-
- if fnArg != typeOfValuePtr {
- // Function's argument is not a *pongo2.Value, then we have to check whether input argument is of the same type as the function's argument
- if !isVariadic {
- if fnArg != reflect.TypeOf(pv.Interface()) && fnArg.Kind() != reflect.Interface {
- return nil, fmt.Errorf("Function input argument %d of '%s' must be of type %s or *pongo2.Value (not %T).",
- idx, vr.String(), fnArg.String(), pv.Interface())
- }
- // Function's argument has another type, using the interface-value
- parameters = append(parameters, reflect.ValueOf(pv.Interface()))
- } else {
- if fnArg != reflect.TypeOf(pv.Interface()) && fnArg.Kind() != reflect.Interface {
- return nil, fmt.Errorf("Function variadic input argument of '%s' must be of type %s or *pongo2.Value (not %T).",
- vr.String(), fnArg.String(), pv.Interface())
- }
- // Function's argument has another type, using the interface-value
- parameters = append(parameters, reflect.ValueOf(pv.Interface()))
- }
- } else {
- // Function's argument is a *pongo2.Value
- parameters = append(parameters, reflect.ValueOf(pv))
- }
- }
-
- // Check if any of the values are invalid
- for _, p := range parameters {
- if p.Kind() == reflect.Invalid {
- return nil, fmt.Errorf("Calling a function using an invalid parameter")
- }
- }
-
- // Call it and get first return parameter back
- values := current.Call(parameters)
- rv := values[0]
- if t.NumOut() == 2 {
- e := values[1].Interface()
- if e != nil {
- err, ok := e.(error)
- if !ok {
- return nil, fmt.Errorf("The second return value is not an error")
- }
- if err != nil {
- return nil, err
- }
- }
- }
-
- if rv.Type() != typeOfValuePtr {
- current = reflect.ValueOf(rv.Interface())
- } else {
- // Return the function call value
- current = rv.Interface().(*Value).val
- isSafe = rv.Interface().(*Value).safe
- }
- }
-
- if !current.IsValid() {
- // Value is not valid (e. g. NIL value)
- return AsValue(nil), nil
- }
- }
-
- return &Value{val: current, safe: isSafe}, nil
-}
-
-func (vr *variableResolver) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- value, err := vr.resolve(ctx)
- if err != nil {
- return AsValue(nil), ctx.Error(err.Error(), vr.locationToken)
- }
- return value, nil
-}
-
-func (v *nodeFilteredVariable) FilterApplied(name string) bool {
- for _, filter := range v.filterChain {
- if filter.name == name {
- return true
- }
- }
- return false
-}
-
-func (v *nodeFilteredVariable) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
- value, err := v.resolver.Evaluate(ctx)
- if err != nil {
- return nil, err
- }
-
- for _, filter := range v.filterChain {
- value, err = filter.Execute(value, ctx)
- if err != nil {
- return nil, err
- }
- }
-
- return value, nil
-}
-
-// IDENT | IDENT.(IDENT|NUMBER)...
-func (p *Parser) parseVariableOrLiteral() (IEvaluator, *Error) {
- t := p.Current()
-
- if t == nil {
- return nil, p.Error("Unexpected EOF, expected a number, string, keyword or identifier.", p.lastToken)
- }
-
- // Is first part a number or a string, there's nothing to resolve (because there's only to return the value then)
- switch t.Typ {
- case TokenNumber:
- p.Consume()
-
- // One exception to the rule that we don't have float64 literals is at the beginning
- // of an expression (or a variable name). Since we know we started with an integer
- // which can't obviously be a variable name, we can check whether the first number
- // is followed by dot (and then a number again). If so we're converting it to a float64.
-
- if p.Match(TokenSymbol, ".") != nil {
- // float64
- t2 := p.MatchType(TokenNumber)
- if t2 == nil {
- return nil, p.Error("Expected a number after the '.'.", nil)
- }
- f, err := strconv.ParseFloat(fmt.Sprintf("%s.%s", t.Val, t2.Val), 64)
- if err != nil {
- return nil, p.Error(err.Error(), t)
- }
- fr := &floatResolver{
- locationToken: t,
- val: f,
- }
- return fr, nil
- }
- i, err := strconv.Atoi(t.Val)
- if err != nil {
- return nil, p.Error(err.Error(), t)
- }
- nr := &intResolver{
- locationToken: t,
- val: i,
- }
- return nr, nil
-
- case TokenString:
- p.Consume()
- sr := &stringResolver{
- locationToken: t,
- val: t.Val,
- }
- return sr, nil
- case TokenKeyword:
- p.Consume()
- switch t.Val {
- case "true":
- br := &boolResolver{
- locationToken: t,
- val: true,
- }
- return br, nil
- case "false":
- br := &boolResolver{
- locationToken: t,
- val: false,
- }
- return br, nil
- default:
- return nil, p.Error("This keyword is not allowed here.", nil)
- }
- }
-
- resolver := &variableResolver{
- locationToken: t,
- }
-
- // First part of a variable MUST be an identifier
- if t.Typ != TokenIdentifier {
- return nil, p.Error("Expected either a number, string, keyword or identifier.", t)
- }
-
- resolver.parts = append(resolver.parts, &variablePart{
- typ: varTypeIdent,
- s: t.Val,
- })
-
- p.Consume() // we consumed the first identifier of the variable name
-
-variableLoop:
- for p.Remaining() > 0 {
- t = p.Current()
-
- if p.Match(TokenSymbol, ".") != nil {
- // Next variable part (can be either NUMBER or IDENT)
- t2 := p.Current()
- if t2 != nil {
- switch t2.Typ {
- case TokenIdentifier:
- resolver.parts = append(resolver.parts, &variablePart{
- typ: varTypeIdent,
- s: t2.Val,
- })
- p.Consume() // consume: IDENT
- continue variableLoop
- case TokenNumber:
- i, err := strconv.Atoi(t2.Val)
- if err != nil {
- return nil, p.Error(err.Error(), t2)
- }
- resolver.parts = append(resolver.parts, &variablePart{
- typ: varTypeInt,
- i: i,
- })
- p.Consume() // consume: NUMBER
- continue variableLoop
- default:
- return nil, p.Error("This token is not allowed within a variable name.", t2)
- }
- } else {
- // EOF
- return nil, p.Error("Unexpected EOF, expected either IDENTIFIER or NUMBER after DOT.",
- p.lastToken)
- }
- } else if p.Match(TokenSymbol, "(") != nil {
- // Function call
- // FunctionName '(' Comma-separated list of expressions ')'
- part := resolver.parts[len(resolver.parts)-1]
- part.isFunctionCall = true
- argumentLoop:
- for {
- if p.Remaining() == 0 {
- return nil, p.Error("Unexpected EOF, expected function call argument list.", p.lastToken)
- }
-
- if p.Peek(TokenSymbol, ")") == nil {
- // No closing bracket, so we're parsing an expression
- exprArg, err := p.ParseExpression()
- if err != nil {
- return nil, err
- }
- part.callingArgs = append(part.callingArgs, exprArg)
-
- if p.Match(TokenSymbol, ")") != nil {
- // If there's a closing bracket after an expression, we will stop parsing the arguments
- break argumentLoop
- } else {
- // If there's NO closing bracket, there MUST be an comma
- if p.Match(TokenSymbol, ",") == nil {
- return nil, p.Error("Missing comma or closing bracket after argument.", nil)
- }
- }
- } else {
- // We got a closing bracket, so stop parsing arguments
- p.Consume()
- break argumentLoop
- }
-
- }
- // We're done parsing the function call, next variable part
- continue variableLoop
- }
-
- // No dot or function call? Then we're done with the variable parsing
- break
- }
-
- return resolver, nil
-}
-
-func (p *Parser) parseVariableOrLiteralWithFilter() (*nodeFilteredVariable, *Error) {
- v := &nodeFilteredVariable{
- locationToken: p.Current(),
- }
-
- // Parse the variable name
- resolver, err := p.parseVariableOrLiteral()
- if err != nil {
- return nil, err
- }
- v.resolver = resolver
-
- // Parse all the filters
-filterLoop:
- for p.Match(TokenSymbol, "|") != nil {
- // Parse one single filter
- filter, err := p.parseFilter()
- if err != nil {
- return nil, err
- }
-
- // Check sandbox filter restriction
- if _, isBanned := p.template.set.bannedFilters[filter.name]; isBanned {
- return nil, p.Error(fmt.Sprintf("Usage of filter '%s' is not allowed (sandbox restriction active).", filter.name), nil)
- }
-
- v.filterChain = append(v.filterChain, filter)
-
- continue filterLoop
- }
-
- return v, nil
-}
-
-func (p *Parser) parseVariableElement() (INode, *Error) {
- node := &nodeVariable{
- locationToken: p.Current(),
- }
-
- p.Consume() // consume '{{'
-
- expr, err := p.ParseExpression()
- if err != nil {
- return nil, err
- }
- node.expr = expr
-
- if p.Match(TokenSymbol, "}}") == nil {
- return nil, p.Error("'}}' expected", nil)
- }
-
- return node, nil
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index ba167f3..04e3482 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -56,11 +56,11 @@ github.com/extemporalgenome/slug
github.com/flosch/go-humanize
# github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3
## explicit
-github.com/flosch/pongo2
# github.com/flosch/pongo2-addons v0.0.0-20210526150811-f969446c5b72
## explicit
github.com/flosch/pongo2-addons
# github.com/flosch/pongo2/v4 v4.0.2
+## explicit
github.com/flosch/pongo2/v4
# github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1
github.com/gopherjs/gopherjs/js
@@ -125,6 +125,8 @@ golang.org/x/sys/unix
## explicit
golang.org/x/text/transform
golang.org/x/text/unicode/norm
+# gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
+## explicit
# gopkg.in/sourcemap.v1 v1.0.5
gopkg.in/sourcemap.v1
gopkg.in/sourcemap.v1/base64vlq