mirror of
https://github.com/Luzifer/promcertcheck.git
synced 2024-11-08 16:00:08 +00:00
Update vendored libs
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
dd7d942f30
commit
ce6a18fbf3
1137 changed files with 37335 additions and 167090 deletions
76
Gopkg.lock
generated
76
Gopkg.lock
generated
|
@ -11,43 +11,37 @@
|
|||
branch = "master"
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9"
|
||||
revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/flosch/pongo2"
|
||||
packages = ["."]
|
||||
revision = "1f4be1efe3b3529b7e58861f75d70120a9567dc4"
|
||||
revision = "5e81b817a0c48c1c57cdf1a9056cf76bdee02ca9"
|
||||
version = "v3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
revision = "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
|
||||
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/context"
|
||||
packages = ["."]
|
||||
revision = "1ea25387ff6f684839d82767c1733ff4d4d15d0a"
|
||||
version = "v1.1"
|
||||
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
revision = "24fca303ac6da784b9e8269f724ddeb0b2eea5e7"
|
||||
version = "v1.5.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/juju/errors"
|
||||
packages = ["."]
|
||||
revision = "c7d06af17c68cd34c835053720b21f6549d9b0ee"
|
||||
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
|
||||
version = "v1.6.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
revision = "3247c84500bff8d9fb6d579d800f20b3e091582c"
|
||||
version = "v1.0.0"
|
||||
revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
|
@ -59,65 +53,77 @@
|
|||
branch = "master"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
revision = "6f3806018612930941127f2a7c6c453ba2c527d2"
|
||||
revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = ["expfmt","internal/bitbucket.org/ww/goautoneg","model"]
|
||||
revision = "e3fb1a1acd7605367a2b378bc2e2f893c05174b7"
|
||||
packages = [
|
||||
"expfmt",
|
||||
"internal/bitbucket.org/ww/goautoneg",
|
||||
"model"
|
||||
]
|
||||
revision = "7600349dcfe1abd18d72d3a1770870d9800a7801"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [".","xfs"]
|
||||
revision = "a6e9df898b1336106c743392c48ee0b71f5c4efa"
|
||||
packages = [
|
||||
".",
|
||||
"internal/util",
|
||||
"nfs",
|
||||
"xfs"
|
||||
]
|
||||
revision = "94663424ae5ae9856b40a9f170762b4197024661"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/robfig/cron"
|
||||
packages = ["."]
|
||||
revision = "b024fc5ea0e34bc3f83d9941c8d60b0622bfaca4"
|
||||
version = "v1"
|
||||
revision = "b41be1df696709bb6395fe435af20370037c0b4c"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e"
|
||||
version = "v1.0.3"
|
||||
revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc"
|
||||
version = "v1.0.5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
|
||||
version = "v1.0.0"
|
||||
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
revision = "bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8"
|
||||
revision = "df8d4716b3472e4a531c33cedbe537dae921a1a9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix","windows"]
|
||||
revision = "8eb05f94d449fdf134ec24630ce69ada5b469c1c"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows"
|
||||
]
|
||||
revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/validator.v2"
|
||||
packages = ["."]
|
||||
revision = "460c83432a98c35224a6fe352acf8b23e067ad06"
|
||||
revision = "135c24b11c19e52befcae2ec3fca5d9b78c4e98e"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "f88f786b9ff5e99b5589aea171923fd8d9dcef123a4d6be68d7659b923e8dc1e"
|
||||
inputs-digest = "9e9921ed070369ec5c66299d9403b1d7dd184332dbf7f7e36c5d1ff493b88216"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
|
23
Gopkg.toml
23
Gopkg.toml
|
@ -1,7 +1,6 @@
|
|||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
|
@ -17,8 +16,13 @@
|
|||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
|
@ -27,17 +31,24 @@
|
|||
|
||||
[[constraint]]
|
||||
name = "github.com/flosch/pongo2"
|
||||
branch = "master"
|
||||
version = "3.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/mux"
|
||||
version = "1.6.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
version = "0.8.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/robfig/cron"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/sirupsen/logrus"
|
||||
version = "1.0.3"
|
||||
version = "1.0.5"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
|
70
vendor/github.com/Luzifer/rconfig/bool_test.go
generated
vendored
70
vendor/github.com/Luzifer/rconfig/bool_test.go
generated
vendored
|
@ -1,70 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing bool parsing", func() {
|
||||
type t struct {
|
||||
Test1 bool `default:"true"`
|
||||
Test2 bool `default:"false" flag:"test2"`
|
||||
Test3 bool `default:"true" flag:"test3,t"`
|
||||
Test4 bool `flag:"test4"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--test2",
|
||||
"-t",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.Test1).To(Equal(true))
|
||||
Expect(cfg.Test2).To(Equal(true))
|
||||
Expect(cfg.Test3).To(Equal(true))
|
||||
Expect(cfg.Test4).To(Equal(false))
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("Testing to set bool from ENV with default", func() {
|
||||
type t struct {
|
||||
Test1 bool `default:"true" env:"TEST1"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
os.Unsetenv("TEST1")
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.Test1).To(Equal(true))
|
||||
})
|
||||
})
|
41
vendor/github.com/Luzifer/rconfig/duration_test.go
generated
vendored
41
vendor/github.com/Luzifer/rconfig/duration_test.go
generated
vendored
|
@ -1,41 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Duration", func() {
|
||||
type t struct {
|
||||
Test time.Duration `flag:"duration"`
|
||||
TestS time.Duration `flag:"other-duration,o"`
|
||||
TestDef time.Duration `default:"30h"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--duration=23s", "-o", "45m",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.Test).To(Equal(23 * time.Second))
|
||||
Expect(cfg.TestS).To(Equal(45 * time.Minute))
|
||||
|
||||
Expect(cfg.TestDef).To(Equal(30 * time.Hour))
|
||||
})
|
||||
})
|
56
vendor/github.com/Luzifer/rconfig/errors_test.go
generated
vendored
56
vendor/github.com/Luzifer/rconfig/errors_test.go
generated
vendored
|
@ -1,56 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing errors", func() {
|
||||
|
||||
It("should not accept string as int", func() {
|
||||
Expect(parse(&struct {
|
||||
A int `default:"a"`
|
||||
}{}, []string{})).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should not accept string as float", func() {
|
||||
Expect(parse(&struct {
|
||||
A float32 `default:"a"`
|
||||
}{}, []string{})).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should not accept string as uint", func() {
|
||||
Expect(parse(&struct {
|
||||
A uint `default:"a"`
|
||||
}{}, []string{})).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should not accept string as uint in sub-struct", func() {
|
||||
Expect(parse(&struct {
|
||||
B struct {
|
||||
A uint `default:"a"`
|
||||
}
|
||||
}{}, []string{})).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should not accept string slice as int slice", func() {
|
||||
Expect(parse(&struct {
|
||||
A []int `default:"a,bn"`
|
||||
}{}, []string{})).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should not accept variables not being pointers", func() {
|
||||
cfg := struct {
|
||||
A string `default:"a"`
|
||||
}{}
|
||||
|
||||
Expect(parse(cfg, []string{})).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should not accept variables not being pointers to structs", func() {
|
||||
cfg := "test"
|
||||
|
||||
Expect(parse(cfg, []string{})).To(HaveOccurred())
|
||||
})
|
||||
|
||||
})
|
37
vendor/github.com/Luzifer/rconfig/example_test.go
generated
vendored
37
vendor/github.com/Luzifer/rconfig/example_test.go
generated
vendored
|
@ -1,37 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func ExampleParse() {
|
||||
// We're building an example configuration with a sub-struct to be filled
|
||||
// by the Parse command.
|
||||
config := struct {
|
||||
Username string `default:"unknown" flag:"user,u" description:"Your name"`
|
||||
Details struct {
|
||||
Age int `default:"25" flag:"age" description:"Your age"`
|
||||
}
|
||||
}{}
|
||||
|
||||
// To have more relieable results we're setting os.Args to a known value.
|
||||
// In real-life use cases you wouldn't do this but parse the original
|
||||
// commandline arguments.
|
||||
os.Args = []string{
|
||||
"example",
|
||||
"--user=Luzifer",
|
||||
}
|
||||
|
||||
Parse(&config)
|
||||
|
||||
fmt.Printf("Hello %s, happy birthday for your %dth birthday.",
|
||||
config.Username,
|
||||
config.Details.Age)
|
||||
|
||||
// You can also show an usage message for your user
|
||||
Usage()
|
||||
|
||||
// Output:
|
||||
// Hello Luzifer, happy birthday for your 25th birthday.
|
||||
}
|
44
vendor/github.com/Luzifer/rconfig/float_test.go
generated
vendored
44
vendor/github.com/Luzifer/rconfig/float_test.go
generated
vendored
|
@ -1,44 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing float parsing", func() {
|
||||
type t struct {
|
||||
Test32 float32 `flag:"float32"`
|
||||
Test32P float32 `flag:"float32p,3"`
|
||||
Test64 float64 `flag:"float64"`
|
||||
Test64P float64 `flag:"float64p,6"`
|
||||
TestDef float32 `default:"66.256"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--float32=5.5", "-3", "6.6",
|
||||
"--float64=7.7", "-6", "8.8",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.Test32).To(Equal(float32(5.5)))
|
||||
Expect(cfg.Test32P).To(Equal(float32(6.6)))
|
||||
Expect(cfg.Test64).To(Equal(float64(7.7)))
|
||||
Expect(cfg.Test64P).To(Equal(float64(8.8)))
|
||||
|
||||
Expect(cfg.TestDef).To(Equal(float32(66.256)))
|
||||
})
|
||||
})
|
128
vendor/github.com/Luzifer/rconfig/general_test.go
generated
vendored
128
vendor/github.com/Luzifer/rconfig/general_test.go
generated
vendored
|
@ -1,128 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing general parsing", func() {
|
||||
type t struct {
|
||||
Test string `default:"foo" env:"shell" flag:"shell" description:"Test"`
|
||||
Test2 string `default:"blub" env:"testvar" flag:"testvar,t" description:"Test"`
|
||||
DefaultFlag string `default:"goo"`
|
||||
SadFlag string
|
||||
}
|
||||
|
||||
type tValidated struct {
|
||||
Test string `flag:"test" default:"" validate:"nonzero"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
Context("with defined arguments", func() {
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--shell=test23",
|
||||
"-t", "bla",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have parsed the expected values", func() {
|
||||
Expect(cfg.Test).To(Equal("test23"))
|
||||
Expect(cfg.Test2).To(Equal("bla"))
|
||||
Expect(cfg.SadFlag).To(Equal(""))
|
||||
Expect(cfg.DefaultFlag).To(Equal("goo"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("with no arguments", func() {
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have used the default value", func() {
|
||||
Expect(cfg.Test).To(Equal("foo"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("with no arguments and set env", func() {
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{}
|
||||
os.Setenv("shell", "test546")
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
os.Unsetenv("shell")
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have used the value from env", func() {
|
||||
Expect(cfg.Test).To(Equal("test546"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("with additional arguments", func() {
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--shell=test23",
|
||||
"-t", "bla",
|
||||
"positional1", "positional2",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have parsed the expected values", func() {
|
||||
Expect(cfg.Test).To(Equal("test23"))
|
||||
Expect(cfg.Test2).To(Equal("bla"))
|
||||
Expect(cfg.SadFlag).To(Equal(""))
|
||||
Expect(cfg.DefaultFlag).To(Equal("goo"))
|
||||
})
|
||||
It("should have detected the positional arguments", func() {
|
||||
Expect(Args()).To(Equal([]string{"positional1", "positional2"}))
|
||||
})
|
||||
})
|
||||
|
||||
Context("making use of the validator package", func() {
|
||||
var cfgValidated tValidated
|
||||
|
||||
BeforeEach(func() {
|
||||
cfgValidated = tValidated{}
|
||||
args = []string{}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parseAndValidate(&cfgValidated, args)
|
||||
})
|
||||
|
||||
It("should have errored", func() { Expect(err).To(HaveOccurred()) })
|
||||
})
|
||||
|
||||
})
|
54
vendor/github.com/Luzifer/rconfig/int_test.go
generated
vendored
54
vendor/github.com/Luzifer/rconfig/int_test.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing int parsing", func() {
|
||||
type t struct {
|
||||
Test int `flag:"int"`
|
||||
TestP int `flag:"intp,i"`
|
||||
Test8 int8 `flag:"int8"`
|
||||
Test8P int8 `flag:"int8p,8"`
|
||||
Test32 int32 `flag:"int32"`
|
||||
Test32P int32 `flag:"int32p,3"`
|
||||
Test64 int64 `flag:"int64"`
|
||||
Test64P int64 `flag:"int64p,6"`
|
||||
TestDef int8 `default:"66"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--int=1", "-i", "2",
|
||||
"--int8=3", "-8", "4",
|
||||
"--int32=5", "-3", "6",
|
||||
"--int64=7", "-6", "8",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.Test).To(Equal(1))
|
||||
Expect(cfg.TestP).To(Equal(2))
|
||||
Expect(cfg.Test8).To(Equal(int8(3)))
|
||||
Expect(cfg.Test8P).To(Equal(int8(4)))
|
||||
Expect(cfg.Test32).To(Equal(int32(5)))
|
||||
Expect(cfg.Test32P).To(Equal(int32(6)))
|
||||
Expect(cfg.Test64).To(Equal(int64(7)))
|
||||
Expect(cfg.Test64P).To(Equal(int64(8)))
|
||||
|
||||
Expect(cfg.TestDef).To(Equal(int8(66)))
|
||||
})
|
||||
})
|
40
vendor/github.com/Luzifer/rconfig/os-args_test.go
generated
vendored
40
vendor/github.com/Luzifer/rconfig/os-args_test.go
generated
vendored
|
@ -1,40 +0,0 @@
|
|||
package rconfig_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/Luzifer/rconfig"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing os.Args", func() {
|
||||
type t struct {
|
||||
A string `default:"a" flag:"a"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
cfg t
|
||||
)
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = Parse(&cfg)
|
||||
})
|
||||
|
||||
Context("With only valid arguments", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
os.Args = []string{"--a=bar"}
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.A).To(Equal("bar"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
87
vendor/github.com/Luzifer/rconfig/precedence_test.go
generated
vendored
87
vendor/github.com/Luzifer/rconfig/precedence_test.go
generated
vendored
|
@ -1,87 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Precedence", func() {
|
||||
|
||||
type t struct {
|
||||
A int `default:"1" vardefault:"a" env:"a" flag:"avar,a" description:"a"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
cfg t
|
||||
args []string
|
||||
vardefaults map[string]string
|
||||
)
|
||||
|
||||
JustBeforeEach(func() {
|
||||
cfg = t{}
|
||||
SetVariableDefaults(vardefaults)
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
Context("Provided: Flag, Env, Default, VarDefault", func() {
|
||||
BeforeEach(func() {
|
||||
args = []string{"-a", "5"}
|
||||
os.Setenv("a", "8")
|
||||
vardefaults = map[string]string{
|
||||
"a": "3",
|
||||
}
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have used the flag value", func() {
|
||||
Expect(cfg.A).To(Equal(5))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Provided: Env, Default, VarDefault", func() {
|
||||
BeforeEach(func() {
|
||||
args = []string{}
|
||||
os.Setenv("a", "8")
|
||||
vardefaults = map[string]string{
|
||||
"a": "3",
|
||||
}
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have used the env value", func() {
|
||||
Expect(cfg.A).To(Equal(8))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Provided: Default, VarDefault", func() {
|
||||
BeforeEach(func() {
|
||||
args = []string{}
|
||||
os.Unsetenv("a")
|
||||
vardefaults = map[string]string{
|
||||
"a": "3",
|
||||
}
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have used the vardefault value", func() {
|
||||
Expect(cfg.A).To(Equal(3))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Provided: Default", func() {
|
||||
BeforeEach(func() {
|
||||
args = []string{}
|
||||
os.Unsetenv("a")
|
||||
vardefaults = map[string]string{}
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have used the default value", func() {
|
||||
Expect(cfg.A).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
13
vendor/github.com/Luzifer/rconfig/rconfig_suite_test.go
generated
vendored
13
vendor/github.com/Luzifer/rconfig/rconfig_suite_test.go
generated
vendored
|
@ -1,13 +0,0 @@
|
|||
package rconfig_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRconfig(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Rconfig Suite")
|
||||
}
|
51
vendor/github.com/Luzifer/rconfig/slice_test.go
generated
vendored
51
vendor/github.com/Luzifer/rconfig/slice_test.go
generated
vendored
|
@ -1,51 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing slices", func() {
|
||||
type t struct {
|
||||
Int []int `default:"1,2,3" flag:"int"`
|
||||
String []string `default:"a,b,c" flag:"string"`
|
||||
IntP []int `default:"1,2,3" flag:"intp,i"`
|
||||
StringP []string `default:"a,b,c" flag:"stringp,s"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--int=4,5", "-s", "hallo,welt",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values for int-slice", func() {
|
||||
Expect(len(cfg.Int)).To(Equal(2))
|
||||
Expect(cfg.Int).To(Equal([]int{4, 5}))
|
||||
Expect(cfg.Int).NotTo(Equal([]int{5, 4}))
|
||||
})
|
||||
It("should have the expected values for int-shorthand-slice", func() {
|
||||
Expect(len(cfg.IntP)).To(Equal(3))
|
||||
Expect(cfg.IntP).To(Equal([]int{1, 2, 3}))
|
||||
})
|
||||
It("should have the expected values for string-slice", func() {
|
||||
Expect(len(cfg.String)).To(Equal(3))
|
||||
Expect(cfg.String).To(Equal([]string{"a", "b", "c"}))
|
||||
})
|
||||
It("should have the expected values for string-shorthand-slice", func() {
|
||||
Expect(len(cfg.StringP)).To(Equal(2))
|
||||
Expect(cfg.StringP).To(Equal([]string{"hallo", "welt"}))
|
||||
})
|
||||
})
|
36
vendor/github.com/Luzifer/rconfig/sub-struct_test.go
generated
vendored
36
vendor/github.com/Luzifer/rconfig/sub-struct_test.go
generated
vendored
|
@ -1,36 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing sub-structs", func() {
|
||||
type t struct {
|
||||
Test string `default:"blubb"`
|
||||
Sub struct {
|
||||
Test string `default:"Hallo"`
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.Test).To(Equal("blubb"))
|
||||
Expect(cfg.Sub.Test).To(Equal("Hallo"))
|
||||
})
|
||||
})
|
59
vendor/github.com/Luzifer/rconfig/uint_test.go
generated
vendored
59
vendor/github.com/Luzifer/rconfig/uint_test.go
generated
vendored
|
@ -1,59 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing uint parsing", func() {
|
||||
type t struct {
|
||||
Test uint `flag:"int"`
|
||||
TestP uint `flag:"intp,i"`
|
||||
Test8 uint8 `flag:"int8"`
|
||||
Test8P uint8 `flag:"int8p,8"`
|
||||
Test16 uint16 `flag:"int16"`
|
||||
Test16P uint16 `flag:"int16p,1"`
|
||||
Test32 uint32 `flag:"int32"`
|
||||
Test32P uint32 `flag:"int32p,3"`
|
||||
Test64 uint64 `flag:"int64"`
|
||||
Test64P uint64 `flag:"int64p,6"`
|
||||
TestDef uint8 `default:"66"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
args []string
|
||||
cfg t
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
args = []string{
|
||||
"--int=1", "-i", "2",
|
||||
"--int8=3", "-8", "4",
|
||||
"--int32=5", "-3", "6",
|
||||
"--int64=7", "-6", "8",
|
||||
"--int16=9", "-1", "10",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.Test).To(Equal(uint(1)))
|
||||
Expect(cfg.TestP).To(Equal(uint(2)))
|
||||
Expect(cfg.Test8).To(Equal(uint8(3)))
|
||||
Expect(cfg.Test8P).To(Equal(uint8(4)))
|
||||
Expect(cfg.Test32).To(Equal(uint32(5)))
|
||||
Expect(cfg.Test32P).To(Equal(uint32(6)))
|
||||
Expect(cfg.Test64).To(Equal(uint64(7)))
|
||||
Expect(cfg.Test64P).To(Equal(uint64(8)))
|
||||
Expect(cfg.Test16).To(Equal(uint16(9)))
|
||||
Expect(cfg.Test16P).To(Equal(uint16(10)))
|
||||
|
||||
Expect(cfg.TestDef).To(Equal(uint8(66)))
|
||||
})
|
||||
})
|
122
vendor/github.com/Luzifer/rconfig/vardefault_test.go
generated
vendored
122
vendor/github.com/Luzifer/rconfig/vardefault_test.go
generated
vendored
|
@ -1,122 +0,0 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Testing variable defaults", func() {
|
||||
|
||||
type t struct {
|
||||
MySecretValue string `default:"secret" env:"foo" vardefault:"my_secret_value"`
|
||||
MyUsername string `default:"luzifer" vardefault:"username"`
|
||||
SomeVar string `flag:"var" description:"some variable"`
|
||||
IntVar int64 `vardefault:"int_var" default:"23"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
cfg t
|
||||
args = []string{}
|
||||
vardefaults = map[string]string{
|
||||
"my_secret_value": "veryverysecretkey",
|
||||
"unkownkey": "hi there",
|
||||
"int_var": "42",
|
||||
}
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
cfg = t{}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = parse(&cfg, args)
|
||||
})
|
||||
|
||||
Context("With manually provided variables", func() {
|
||||
BeforeEach(func() {
|
||||
SetVariableDefaults(vardefaults)
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.IntVar).To(Equal(int64(42)))
|
||||
Expect(cfg.MySecretValue).To(Equal("veryverysecretkey"))
|
||||
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||
Expect(cfg.SomeVar).To(Equal(""))
|
||||
})
|
||||
})
|
||||
|
||||
Context("With defaults from YAML data", func() {
|
||||
BeforeEach(func() {
|
||||
yamlData := []byte("---\nmy_secret_value: veryverysecretkey\nunknownkey: hi there\nint_var: 42\n")
|
||||
SetVariableDefaults(VarDefaultsFromYAML(yamlData))
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.IntVar).To(Equal(int64(42)))
|
||||
Expect(cfg.MySecretValue).To(Equal("veryverysecretkey"))
|
||||
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||
Expect(cfg.SomeVar).To(Equal(""))
|
||||
})
|
||||
})
|
||||
|
||||
Context("With defaults from YAML file", func() {
|
||||
var tmp *os.File
|
||||
|
||||
BeforeEach(func() {
|
||||
tmp, _ = ioutil.TempFile("", "")
|
||||
yamlData := "---\nmy_secret_value: veryverysecretkey\nunknownkey: hi there\nint_var: 42\n"
|
||||
tmp.WriteString(yamlData)
|
||||
SetVariableDefaults(VarDefaultsFromYAMLFile(tmp.Name()))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
tmp.Close()
|
||||
os.Remove(tmp.Name())
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.IntVar).To(Equal(int64(42)))
|
||||
Expect(cfg.MySecretValue).To(Equal("veryverysecretkey"))
|
||||
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||
Expect(cfg.SomeVar).To(Equal(""))
|
||||
})
|
||||
})
|
||||
|
||||
Context("With defaults from invalid YAML data", func() {
|
||||
BeforeEach(func() {
|
||||
yamlData := []byte("---\nmy_secret_value = veryverysecretkey\nunknownkey = hi there\nint_var = 42\n")
|
||||
SetVariableDefaults(VarDefaultsFromYAML(yamlData))
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.IntVar).To(Equal(int64(23)))
|
||||
Expect(cfg.MySecretValue).To(Equal("secret"))
|
||||
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||
Expect(cfg.SomeVar).To(Equal(""))
|
||||
})
|
||||
})
|
||||
|
||||
Context("With defaults from non existent YAML file", func() {
|
||||
BeforeEach(func() {
|
||||
file := "/tmp/this_file_should_not_exist_146e26723r"
|
||||
SetVariableDefaults(VarDefaultsFromYAMLFile(file))
|
||||
})
|
||||
|
||||
It("should not have errored", func() { Expect(err).NotTo(HaveOccurred()) })
|
||||
It("should have the expected values", func() {
|
||||
Expect(cfg.IntVar).To(Equal(int64(23)))
|
||||
Expect(cfg.MySecretValue).To(Equal("secret"))
|
||||
Expect(cfg.MyUsername).To(Equal("luzifer"))
|
||||
Expect(cfg.SomeVar).To(Equal(""))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
2
vendor/github.com/beorn7/perks/.gitignore
generated
vendored
2
vendor/github.com/beorn7/perks/.gitignore
generated
vendored
|
@ -1,2 +0,0 @@
|
|||
*.test
|
||||
*.prof
|
31
vendor/github.com/beorn7/perks/README.md
generated
vendored
31
vendor/github.com/beorn7/perks/README.md
generated
vendored
|
@ -1,31 +0,0 @@
|
|||
# Perks for Go (golang.org)
|
||||
|
||||
Perks contains the Go package quantile that computes approximate quantiles over
|
||||
an unbounded data stream within low memory and CPU bounds.
|
||||
|
||||
For more information and examples, see:
|
||||
http://godoc.org/github.com/bmizerany/perks
|
||||
|
||||
A very special thank you and shout out to Graham Cormode (Rutgers University),
|
||||
Flip Korn (AT&T Labs–Research), S. Muthukrishnan (Rutgers University), and
|
||||
Divesh Srivastava (AT&T Labs–Research) for their research and publication of
|
||||
[Effective Computation of Biased Quantiles over Data Streams](http://www.cs.rutgers.edu/~muthu/bquant.pdf)
|
||||
|
||||
Thank you, also:
|
||||
* Armon Dadgar (@armon)
|
||||
* Andrew Gerrand (@nf)
|
||||
* Brad Fitzpatrick (@bradfitz)
|
||||
* Keith Rarick (@kr)
|
||||
|
||||
FAQ:
|
||||
|
||||
Q: Why not move the quantile package into the project root?
|
||||
A: I want to add more packages to perks later.
|
||||
|
||||
Copyright (C) 2013 Blake Mizerany
|
||||
|
||||
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.
|
26
vendor/github.com/beorn7/perks/histogram/bench_test.go
generated
vendored
26
vendor/github.com/beorn7/perks/histogram/bench_test.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
package histogram
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkInsert10Bins(b *testing.B) {
|
||||
b.StopTimer()
|
||||
h := New(10)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
f := rand.ExpFloat64()
|
||||
h.Insert(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInsert100Bins(b *testing.B) {
|
||||
b.StopTimer()
|
||||
h := New(100)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
f := rand.ExpFloat64()
|
||||
h.Insert(f)
|
||||
}
|
||||
}
|
108
vendor/github.com/beorn7/perks/histogram/histogram.go
generated
vendored
108
vendor/github.com/beorn7/perks/histogram/histogram.go
generated
vendored
|
@ -1,108 +0,0 @@
|
|||
// Package histogram provides a Go implementation of BigML's histogram package
|
||||
// for Clojure/Java. It is currently experimental.
|
||||
package histogram
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"math"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Bin struct {
|
||||
Count int
|
||||
Sum float64
|
||||
}
|
||||
|
||||
func (b *Bin) Update(x *Bin) {
|
||||
b.Count += x.Count
|
||||
b.Sum += x.Sum
|
||||
}
|
||||
|
||||
func (b *Bin) Mean() float64 {
|
||||
return b.Sum / float64(b.Count)
|
||||
}
|
||||
|
||||
type Bins []*Bin
|
||||
|
||||
func (bs Bins) Len() int { return len(bs) }
|
||||
func (bs Bins) Less(i, j int) bool { return bs[i].Mean() < bs[j].Mean() }
|
||||
func (bs Bins) Swap(i, j int) { bs[i], bs[j] = bs[j], bs[i] }
|
||||
|
||||
func (bs *Bins) Push(x interface{}) {
|
||||
*bs = append(*bs, x.(*Bin))
|
||||
}
|
||||
|
||||
func (bs *Bins) Pop() interface{} {
|
||||
return bs.remove(len(*bs) - 1)
|
||||
}
|
||||
|
||||
func (bs *Bins) remove(n int) *Bin {
|
||||
if n < 0 || len(*bs) < n {
|
||||
return nil
|
||||
}
|
||||
x := (*bs)[n]
|
||||
*bs = append((*bs)[:n], (*bs)[n+1:]...)
|
||||
return x
|
||||
}
|
||||
|
||||
type Histogram struct {
|
||||
res *reservoir
|
||||
}
|
||||
|
||||
func New(maxBins int) *Histogram {
|
||||
return &Histogram{res: newReservoir(maxBins)}
|
||||
}
|
||||
|
||||
func (h *Histogram) Insert(f float64) {
|
||||
h.res.insert(&Bin{1, f})
|
||||
h.res.compress()
|
||||
}
|
||||
|
||||
func (h *Histogram) Bins() Bins {
|
||||
return h.res.bins
|
||||
}
|
||||
|
||||
type reservoir struct {
|
||||
n int
|
||||
maxBins int
|
||||
bins Bins
|
||||
}
|
||||
|
||||
func newReservoir(maxBins int) *reservoir {
|
||||
return &reservoir{maxBins: maxBins}
|
||||
}
|
||||
|
||||
func (r *reservoir) insert(bin *Bin) {
|
||||
r.n += bin.Count
|
||||
i := sort.Search(len(r.bins), func(i int) bool {
|
||||
return r.bins[i].Mean() >= bin.Mean()
|
||||
})
|
||||
if i < 0 || i == r.bins.Len() {
|
||||
// TODO(blake): Maybe use an .insert(i, bin) instead of
|
||||
// performing the extra work of a heap.Push.
|
||||
heap.Push(&r.bins, bin)
|
||||
return
|
||||
}
|
||||
r.bins[i].Update(bin)
|
||||
}
|
||||
|
||||
func (r *reservoir) compress() {
|
||||
for r.bins.Len() > r.maxBins {
|
||||
minGapIndex := -1
|
||||
minGap := math.MaxFloat64
|
||||
for i := 0; i < r.bins.Len()-1; i++ {
|
||||
gap := gapWeight(r.bins[i], r.bins[i+1])
|
||||
if minGap > gap {
|
||||
minGap = gap
|
||||
minGapIndex = i
|
||||
}
|
||||
}
|
||||
prev := r.bins[minGapIndex]
|
||||
next := r.bins.remove(minGapIndex + 1)
|
||||
prev.Update(next)
|
||||
}
|
||||
}
|
||||
|
||||
func gapWeight(prev, next *Bin) float64 {
|
||||
return next.Mean() - prev.Mean()
|
||||
}
|
38
vendor/github.com/beorn7/perks/histogram/histogram_test.go
generated
vendored
38
vendor/github.com/beorn7/perks/histogram/histogram_test.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
package histogram
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHistogram(t *testing.T) {
|
||||
const numPoints = 1e6
|
||||
const maxBins = 3
|
||||
|
||||
h := New(maxBins)
|
||||
for i := 0; i < numPoints; i++ {
|
||||
f := rand.ExpFloat64()
|
||||
h.Insert(f)
|
||||
}
|
||||
|
||||
bins := h.Bins()
|
||||
if g := len(bins); g > maxBins {
|
||||
t.Fatalf("got %d bins, wanted <= %d", g, maxBins)
|
||||
}
|
||||
|
||||
for _, b := range bins {
|
||||
t.Logf("%+v", b)
|
||||
}
|
||||
|
||||
if g := count(h.Bins()); g != numPoints {
|
||||
t.Fatalf("binned %d points, wanted %d", g, numPoints)
|
||||
}
|
||||
}
|
||||
|
||||
func count(bins Bins) int {
|
||||
binCounts := 0
|
||||
for _, b := range bins {
|
||||
binCounts += b.Count
|
||||
}
|
||||
return binCounts
|
||||
}
|
63
vendor/github.com/beorn7/perks/quantile/bench_test.go
generated
vendored
63
vendor/github.com/beorn7/perks/quantile/bench_test.go
generated
vendored
|
@ -1,63 +0,0 @@
|
|||
package quantile
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkInsertTargeted(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
s := NewTargeted(Targets)
|
||||
b.ResetTimer()
|
||||
for i := float64(0); i < float64(b.N); i++ {
|
||||
s.Insert(i)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInsertTargetedSmallEpsilon(b *testing.B) {
|
||||
s := NewTargeted(TargetsSmallEpsilon)
|
||||
b.ResetTimer()
|
||||
for i := float64(0); i < float64(b.N); i++ {
|
||||
s.Insert(i)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInsertBiased(b *testing.B) {
|
||||
s := NewLowBiased(0.01)
|
||||
b.ResetTimer()
|
||||
for i := float64(0); i < float64(b.N); i++ {
|
||||
s.Insert(i)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInsertBiasedSmallEpsilon(b *testing.B) {
|
||||
s := NewLowBiased(0.0001)
|
||||
b.ResetTimer()
|
||||
for i := float64(0); i < float64(b.N); i++ {
|
||||
s.Insert(i)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkQuery(b *testing.B) {
|
||||
s := NewTargeted(Targets)
|
||||
for i := float64(0); i < 1e6; i++ {
|
||||
s.Insert(i)
|
||||
}
|
||||
b.ResetTimer()
|
||||
n := float64(b.N)
|
||||
for i := float64(0); i < n; i++ {
|
||||
s.Query(i / n)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkQuerySmallEpsilon(b *testing.B) {
|
||||
s := NewTargeted(TargetsSmallEpsilon)
|
||||
for i := float64(0); i < 1e6; i++ {
|
||||
s.Insert(i)
|
||||
}
|
||||
b.ResetTimer()
|
||||
n := float64(b.N)
|
||||
for i := float64(0); i < n; i++ {
|
||||
s.Query(i / n)
|
||||
}
|
||||
}
|
121
vendor/github.com/beorn7/perks/quantile/example_test.go
generated
vendored
121
vendor/github.com/beorn7/perks/quantile/example_test.go
generated
vendored
|
@ -1,121 +0,0 @@
|
|||
// +build go1.1
|
||||
|
||||
package quantile_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/beorn7/perks/quantile"
|
||||
)
|
||||
|
||||
func Example_simple() {
|
||||
ch := make(chan float64)
|
||||
go sendFloats(ch)
|
||||
|
||||
// Compute the 50th, 90th, and 99th percentile.
|
||||
q := quantile.NewTargeted(map[float64]float64{
|
||||
0.50: 0.005,
|
||||
0.90: 0.001,
|
||||
0.99: 0.0001,
|
||||
})
|
||||
for v := range ch {
|
||||
q.Insert(v)
|
||||
}
|
||||
|
||||
fmt.Println("perc50:", q.Query(0.50))
|
||||
fmt.Println("perc90:", q.Query(0.90))
|
||||
fmt.Println("perc99:", q.Query(0.99))
|
||||
fmt.Println("count:", q.Count())
|
||||
// Output:
|
||||
// perc50: 5
|
||||
// perc90: 16
|
||||
// perc99: 223
|
||||
// count: 2388
|
||||
}
|
||||
|
||||
func Example_mergeMultipleStreams() {
|
||||
// Scenario:
|
||||
// We have multiple database shards. On each shard, there is a process
|
||||
// collecting query response times from the database logs and inserting
|
||||
// them into a Stream (created via NewTargeted(0.90)), much like the
|
||||
// Simple example. These processes expose a network interface for us to
|
||||
// ask them to serialize and send us the results of their
|
||||
// Stream.Samples so we may Merge and Query them.
|
||||
//
|
||||
// NOTES:
|
||||
// * These sample sets are small, allowing us to get them
|
||||
// across the network much faster than sending the entire list of data
|
||||
// points.
|
||||
//
|
||||
// * For this to work correctly, we must supply the same quantiles
|
||||
// a priori the process collecting the samples supplied to NewTargeted,
|
||||
// even if we do not plan to query them all here.
|
||||
ch := make(chan quantile.Samples)
|
||||
getDBQuerySamples(ch)
|
||||
q := quantile.NewTargeted(map[float64]float64{0.90: 0.001})
|
||||
for samples := range ch {
|
||||
q.Merge(samples)
|
||||
}
|
||||
fmt.Println("perc90:", q.Query(0.90))
|
||||
}
|
||||
|
||||
func Example_window() {
|
||||
// Scenario: We want the 90th, 95th, and 99th percentiles for each
|
||||
// minute.
|
||||
|
||||
ch := make(chan float64)
|
||||
go sendStreamValues(ch)
|
||||
|
||||
tick := time.NewTicker(1 * time.Minute)
|
||||
q := quantile.NewTargeted(map[float64]float64{
|
||||
0.90: 0.001,
|
||||
0.95: 0.0005,
|
||||
0.99: 0.0001,
|
||||
})
|
||||
for {
|
||||
select {
|
||||
case t := <-tick.C:
|
||||
flushToDB(t, q.Samples())
|
||||
q.Reset()
|
||||
case v := <-ch:
|
||||
q.Insert(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendStreamValues(ch chan float64) {
|
||||
// Use your imagination
|
||||
}
|
||||
|
||||
func flushToDB(t time.Time, samples quantile.Samples) {
|
||||
// Use your imagination
|
||||
}
|
||||
|
||||
// This is a stub for the above example. In reality this would hit the remote
|
||||
// servers via http or something like it.
|
||||
func getDBQuerySamples(ch chan quantile.Samples) {}
|
||||
|
||||
func sendFloats(ch chan<- float64) {
|
||||
f, err := os.Open("exampledata.txt")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
sc := bufio.NewScanner(f)
|
||||
for sc.Scan() {
|
||||
b := sc.Bytes()
|
||||
v, err := strconv.ParseFloat(string(b), 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ch <- v
|
||||
}
|
||||
if sc.Err() != nil {
|
||||
log.Fatal(sc.Err())
|
||||
}
|
||||
close(ch)
|
||||
}
|
34
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
34
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
|
@ -77,15 +77,20 @@ func NewHighBiased(epsilon float64) *Stream {
|
|||
// is guaranteed to be within (Quantile±Epsilon).
|
||||
//
|
||||
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
|
||||
func NewTargeted(targets map[float64]float64) *Stream {
|
||||
func NewTargeted(targetMap map[float64]float64) *Stream {
|
||||
// Convert map to slice to avoid slow iterations on a map.
|
||||
// ƒ is called on the hot path, so converting the map to a slice
|
||||
// beforehand results in significant CPU savings.
|
||||
targets := targetMapToSlice(targetMap)
|
||||
|
||||
ƒ := func(s *stream, r float64) float64 {
|
||||
var m = math.MaxFloat64
|
||||
var f float64
|
||||
for quantile, epsilon := range targets {
|
||||
if quantile*s.n <= r {
|
||||
f = (2 * epsilon * r) / quantile
|
||||
for _, t := range targets {
|
||||
if t.quantile*s.n <= r {
|
||||
f = (2 * t.epsilon * r) / t.quantile
|
||||
} else {
|
||||
f = (2 * epsilon * (s.n - r)) / (1 - quantile)
|
||||
f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile)
|
||||
}
|
||||
if f < m {
|
||||
m = f
|
||||
|
@ -96,6 +101,25 @@ func NewTargeted(targets map[float64]float64) *Stream {
|
|||
return newStream(ƒ)
|
||||
}
|
||||
|
||||
type target struct {
|
||||
quantile float64
|
||||
epsilon float64
|
||||
}
|
||||
|
||||
func targetMapToSlice(targetMap map[float64]float64) []target {
|
||||
targets := make([]target, 0, len(targetMap))
|
||||
|
||||
for quantile, epsilon := range targetMap {
|
||||
t := target{
|
||||
quantile: quantile,
|
||||
epsilon: epsilon,
|
||||
}
|
||||
targets = append(targets, t)
|
||||
}
|
||||
|
||||
return targets
|
||||
}
|
||||
|
||||
// Stream computes quantiles for a stream of float64s. It is not thread-safe by
|
||||
// design. Take care when using across multiple goroutines.
|
||||
type Stream struct {
|
||||
|
|
215
vendor/github.com/beorn7/perks/quantile/stream_test.go
generated
vendored
215
vendor/github.com/beorn7/perks/quantile/stream_test.go
generated
vendored
|
@ -1,215 +0,0 @@
|
|||
package quantile
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
Targets = map[float64]float64{
|
||||
0.01: 0.001,
|
||||
0.10: 0.01,
|
||||
0.50: 0.05,
|
||||
0.90: 0.01,
|
||||
0.99: 0.001,
|
||||
}
|
||||
TargetsSmallEpsilon = map[float64]float64{
|
||||
0.01: 0.0001,
|
||||
0.10: 0.001,
|
||||
0.50: 0.005,
|
||||
0.90: 0.001,
|
||||
0.99: 0.0001,
|
||||
}
|
||||
LowQuantiles = []float64{0.01, 0.1, 0.5}
|
||||
HighQuantiles = []float64{0.99, 0.9, 0.5}
|
||||
)
|
||||
|
||||
const RelativeEpsilon = 0.01
|
||||
|
||||
func verifyPercsWithAbsoluteEpsilon(t *testing.T, a []float64, s *Stream) {
|
||||
sort.Float64s(a)
|
||||
for quantile, epsilon := range Targets {
|
||||
n := float64(len(a))
|
||||
k := int(quantile * n)
|
||||
if k < 1 {
|
||||
k = 1
|
||||
}
|
||||
lower := int((quantile - epsilon) * n)
|
||||
if lower < 1 {
|
||||
lower = 1
|
||||
}
|
||||
upper := int(math.Ceil((quantile + epsilon) * n))
|
||||
if upper > len(a) {
|
||||
upper = len(a)
|
||||
}
|
||||
w, min, max := a[k-1], a[lower-1], a[upper-1]
|
||||
if g := s.Query(quantile); g < min || g > max {
|
||||
t.Errorf("q=%f: want %v [%f,%f], got %v", quantile, w, min, max, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func verifyLowPercsWithRelativeEpsilon(t *testing.T, a []float64, s *Stream) {
|
||||
sort.Float64s(a)
|
||||
for _, qu := range LowQuantiles {
|
||||
n := float64(len(a))
|
||||
k := int(qu * n)
|
||||
|
||||
lowerRank := int((1 - RelativeEpsilon) * qu * n)
|
||||
upperRank := int(math.Ceil((1 + RelativeEpsilon) * qu * n))
|
||||
w, min, max := a[k-1], a[lowerRank-1], a[upperRank-1]
|
||||
if g := s.Query(qu); g < min || g > max {
|
||||
t.Errorf("q=%f: want %v [%f,%f], got %v", qu, w, min, max, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func verifyHighPercsWithRelativeEpsilon(t *testing.T, a []float64, s *Stream) {
|
||||
sort.Float64s(a)
|
||||
for _, qu := range HighQuantiles {
|
||||
n := float64(len(a))
|
||||
k := int(qu * n)
|
||||
|
||||
lowerRank := int((1 - (1+RelativeEpsilon)*(1-qu)) * n)
|
||||
upperRank := int(math.Ceil((1 - (1-RelativeEpsilon)*(1-qu)) * n))
|
||||
w, min, max := a[k-1], a[lowerRank-1], a[upperRank-1]
|
||||
if g := s.Query(qu); g < min || g > max {
|
||||
t.Errorf("q=%f: want %v [%f,%f], got %v", qu, w, min, max, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func populateStream(s *Stream) []float64 {
|
||||
a := make([]float64, 0, 1e5+100)
|
||||
for i := 0; i < cap(a); i++ {
|
||||
v := rand.NormFloat64()
|
||||
// Add 5% asymmetric outliers.
|
||||
if i%20 == 0 {
|
||||
v = v*v + 1
|
||||
}
|
||||
s.Insert(v)
|
||||
a = append(a, v)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func TestTargetedQuery(t *testing.T) {
|
||||
rand.Seed(42)
|
||||
s := NewTargeted(Targets)
|
||||
a := populateStream(s)
|
||||
verifyPercsWithAbsoluteEpsilon(t, a, s)
|
||||
}
|
||||
|
||||
func TestTargetedQuerySmallSampleSize(t *testing.T) {
|
||||
rand.Seed(42)
|
||||
s := NewTargeted(TargetsSmallEpsilon)
|
||||
a := []float64{1, 2, 3, 4, 5}
|
||||
for _, v := range a {
|
||||
s.Insert(v)
|
||||
}
|
||||
verifyPercsWithAbsoluteEpsilon(t, a, s)
|
||||
// If not yet flushed, results should be precise:
|
||||
if !s.flushed() {
|
||||
for φ, want := range map[float64]float64{
|
||||
0.01: 1,
|
||||
0.10: 1,
|
||||
0.50: 3,
|
||||
0.90: 5,
|
||||
0.99: 5,
|
||||
} {
|
||||
if got := s.Query(φ); got != want {
|
||||
t.Errorf("want %f for φ=%f, got %f", want, φ, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLowBiasedQuery(t *testing.T) {
|
||||
rand.Seed(42)
|
||||
s := NewLowBiased(RelativeEpsilon)
|
||||
a := populateStream(s)
|
||||
verifyLowPercsWithRelativeEpsilon(t, a, s)
|
||||
}
|
||||
|
||||
func TestHighBiasedQuery(t *testing.T) {
|
||||
rand.Seed(42)
|
||||
s := NewHighBiased(RelativeEpsilon)
|
||||
a := populateStream(s)
|
||||
verifyHighPercsWithRelativeEpsilon(t, a, s)
|
||||
}
|
||||
|
||||
// BrokenTestTargetedMerge is broken, see Merge doc comment.
|
||||
func BrokenTestTargetedMerge(t *testing.T) {
|
||||
rand.Seed(42)
|
||||
s1 := NewTargeted(Targets)
|
||||
s2 := NewTargeted(Targets)
|
||||
a := populateStream(s1)
|
||||
a = append(a, populateStream(s2)...)
|
||||
s1.Merge(s2.Samples())
|
||||
verifyPercsWithAbsoluteEpsilon(t, a, s1)
|
||||
}
|
||||
|
||||
// BrokenTestLowBiasedMerge is broken, see Merge doc comment.
|
||||
func BrokenTestLowBiasedMerge(t *testing.T) {
|
||||
rand.Seed(42)
|
||||
s1 := NewLowBiased(RelativeEpsilon)
|
||||
s2 := NewLowBiased(RelativeEpsilon)
|
||||
a := populateStream(s1)
|
||||
a = append(a, populateStream(s2)...)
|
||||
s1.Merge(s2.Samples())
|
||||
verifyLowPercsWithRelativeEpsilon(t, a, s2)
|
||||
}
|
||||
|
||||
// BrokenTestHighBiasedMerge is broken, see Merge doc comment.
|
||||
func BrokenTestHighBiasedMerge(t *testing.T) {
|
||||
rand.Seed(42)
|
||||
s1 := NewHighBiased(RelativeEpsilon)
|
||||
s2 := NewHighBiased(RelativeEpsilon)
|
||||
a := populateStream(s1)
|
||||
a = append(a, populateStream(s2)...)
|
||||
s1.Merge(s2.Samples())
|
||||
verifyHighPercsWithRelativeEpsilon(t, a, s2)
|
||||
}
|
||||
|
||||
func TestUncompressed(t *testing.T) {
|
||||
q := NewTargeted(Targets)
|
||||
for i := 100; i > 0; i-- {
|
||||
q.Insert(float64(i))
|
||||
}
|
||||
if g := q.Count(); g != 100 {
|
||||
t.Errorf("want count 100, got %d", g)
|
||||
}
|
||||
// Before compression, Query should have 100% accuracy.
|
||||
for quantile := range Targets {
|
||||
w := quantile * 100
|
||||
if g := q.Query(quantile); g != w {
|
||||
t.Errorf("want %f, got %f", w, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUncompressedSamples(t *testing.T) {
|
||||
q := NewTargeted(map[float64]float64{0.99: 0.001})
|
||||
for i := 1; i <= 100; i++ {
|
||||
q.Insert(float64(i))
|
||||
}
|
||||
if g := q.Samples().Len(); g != 100 {
|
||||
t.Errorf("want count 100, got %d", g)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUncompressedOne(t *testing.T) {
|
||||
q := NewTargeted(map[float64]float64{0.99: 0.01})
|
||||
q.Insert(3.14)
|
||||
if g := q.Query(0.90); g != 3.14 {
|
||||
t.Error("want PI, got", g)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaults(t *testing.T) {
|
||||
if g := NewTargeted(map[float64]float64{0.99: 0.001}).Query(0.99); g != 0 {
|
||||
t.Errorf("want 0, got %f", g)
|
||||
}
|
||||
}
|
90
vendor/github.com/beorn7/perks/topk/topk.go
generated
vendored
90
vendor/github.com/beorn7/perks/topk/topk.go
generated
vendored
|
@ -1,90 +0,0 @@
|
|||
package topk
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// http://www.cs.ucsb.edu/research/tech_reports/reports/2005-23.pdf
|
||||
|
||||
type Element struct {
|
||||
Value string
|
||||
Count int
|
||||
}
|
||||
|
||||
type Samples []*Element
|
||||
|
||||
func (sm Samples) Len() int {
|
||||
return len(sm)
|
||||
}
|
||||
|
||||
func (sm Samples) Less(i, j int) bool {
|
||||
return sm[i].Count < sm[j].Count
|
||||
}
|
||||
|
||||
func (sm Samples) Swap(i, j int) {
|
||||
sm[i], sm[j] = sm[j], sm[i]
|
||||
}
|
||||
|
||||
type Stream struct {
|
||||
k int
|
||||
mon map[string]*Element
|
||||
|
||||
// the minimum Element
|
||||
min *Element
|
||||
}
|
||||
|
||||
func New(k int) *Stream {
|
||||
s := new(Stream)
|
||||
s.k = k
|
||||
s.mon = make(map[string]*Element)
|
||||
s.min = &Element{}
|
||||
|
||||
// Track k+1 so that less frequenet items contended for that spot,
|
||||
// resulting in k being more accurate.
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Stream) Insert(x string) {
|
||||
s.insert(&Element{x, 1})
|
||||
}
|
||||
|
||||
func (s *Stream) Merge(sm Samples) {
|
||||
for _, e := range sm {
|
||||
s.insert(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Stream) insert(in *Element) {
|
||||
e := s.mon[in.Value]
|
||||
if e != nil {
|
||||
e.Count++
|
||||
} else {
|
||||
if len(s.mon) < s.k+1 {
|
||||
e = &Element{in.Value, in.Count}
|
||||
s.mon[in.Value] = e
|
||||
} else {
|
||||
e = s.min
|
||||
delete(s.mon, e.Value)
|
||||
e.Value = in.Value
|
||||
e.Count += in.Count
|
||||
s.min = e
|
||||
}
|
||||
}
|
||||
if e.Count < s.min.Count {
|
||||
s.min = e
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Stream) Query() Samples {
|
||||
var sm Samples
|
||||
for _, e := range s.mon {
|
||||
sm = append(sm, e)
|
||||
}
|
||||
sort.Sort(sort.Reverse(sm))
|
||||
|
||||
if len(sm) < s.k {
|
||||
return sm
|
||||
}
|
||||
|
||||
return sm[:s.k]
|
||||
}
|
57
vendor/github.com/beorn7/perks/topk/topk_test.go
generated
vendored
57
vendor/github.com/beorn7/perks/topk/topk_test.go
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
package topk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTopK(t *testing.T) {
|
||||
stream := New(10)
|
||||
ss := []*Stream{New(10), New(10), New(10)}
|
||||
m := make(map[string]int)
|
||||
for _, s := range ss {
|
||||
for i := 0; i < 1e6; i++ {
|
||||
v := fmt.Sprintf("%x", int8(rand.ExpFloat64()))
|
||||
s.Insert(v)
|
||||
m[v]++
|
||||
}
|
||||
stream.Merge(s.Query())
|
||||
}
|
||||
|
||||
var sm Samples
|
||||
for x, s := range m {
|
||||
sm = append(sm, &Element{x, s})
|
||||
}
|
||||
sort.Sort(sort.Reverse(sm))
|
||||
|
||||
g := stream.Query()
|
||||
if len(g) != 10 {
|
||||
t.Fatalf("got %d, want 10", len(g))
|
||||
}
|
||||
for i, e := range g {
|
||||
if sm[i].Value != e.Value {
|
||||
t.Errorf("at %d: want %q, got %q", i, sm[i].Value, e.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuery(t *testing.T) {
|
||||
queryTests := []struct {
|
||||
value string
|
||||
expected int
|
||||
}{
|
||||
{"a", 1},
|
||||
{"b", 2},
|
||||
{"c", 2},
|
||||
}
|
||||
|
||||
stream := New(2)
|
||||
for _, tt := range queryTests {
|
||||
stream.Insert(tt.value)
|
||||
if n := len(stream.Query()); n != tt.expected {
|
||||
t.Errorf("want %d, got %d", tt.expected, n)
|
||||
}
|
||||
}
|
||||
}
|
1
vendor/github.com/flosch/pongo2/.gitignore
generated
vendored
1
vendor/github.com/flosch/pongo2/.gitignore
generated
vendored
|
@ -7,7 +7,6 @@
|
|||
_obj
|
||||
_test
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
|
|
5
vendor/github.com/flosch/pongo2/.travis.yml
generated
vendored
5
vendor/github.com/flosch/pongo2/.travis.yml
generated
vendored
|
@ -1,13 +1,12 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
- 1.3
|
||||
- tip
|
||||
install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get code.google.com/p/go.tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get gopkg.in/check.v1
|
||||
- go get github.com/juju/errors
|
||||
script:
|
||||
- go test -v -covermode=count -coverprofile=coverage.out -bench . -cpu 1,4
|
||||
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN || true'
|
||||
|
|
19
vendor/github.com/flosch/pongo2/README.md
generated
vendored
19
vendor/github.com/flosch/pongo2/README.md
generated
vendored
|
@ -1,9 +1,8 @@
|
|||
# [pongo](https://en.wikipedia.org/wiki/Pongo_%28genus%29)2
|
||||
|
||||
[![Join the chat at https://gitter.im/flosch/pongo2](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/flosch/pongo2)
|
||||
[![GoDoc](https://godoc.org/github.com/flosch/pongo2?status.svg)](https://godoc.org/github.com/flosch/pongo2)
|
||||
[![GoDoc](https://godoc.org/github.com/flosch/pongo2?status.png)](https://godoc.org/github.com/flosch/pongo2)
|
||||
[![Build Status](https://travis-ci.org/flosch/pongo2.svg?branch=master)](https://travis-ci.org/flosch/pongo2)
|
||||
[![Coverage Status](https://coveralls.io/repos/flosch/pongo2/badge.svg?branch=master)](https://coveralls.io/r/flosch/pongo2?branch=master)
|
||||
[![Coverage Status](https://coveralls.io/repos/flosch/pongo2/badge.png?branch=master)](https://coveralls.io/r/flosch/pongo2?branch=master)
|
||||
[![gratipay](http://img.shields.io/badge/gratipay-support%20pongo-brightgreen.svg)](https://gratipay.com/flosch/)
|
||||
[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3654947)](https://www.bountysource.com/trackers/3654947-pongo2?utm_source=3654947&utm_medium=shield&utm_campaign=TRACKER_BADGE)
|
||||
|
||||
|
@ -96,7 +95,6 @@ Please also have a look on the [caveats](https://github.com/flosch/pongo2#caveat
|
|||
|
||||
If you're using the `master`-branch of pongo2, you might be interested in this section. Since pongo2 is still in development (even though there is a first stable release!), there could be (backwards-incompatible) API changes over time. To keep track of these and therefore make it painless for you to adapt your codebase, I'll list them here.
|
||||
|
||||
* Function signature for tag execution changed: not taking a `bytes.Buffer` anymore; instead `Execute()`-functions are now taking a `TemplateWriter` interface.
|
||||
* Function signature for tag and filter parsing/execution changed (`error` return type changed to `*Error`).
|
||||
* `INodeEvaluator` has been removed and got replaced by `IEvaluator`. You can change your existing tags/filters by simply replacing the interface.
|
||||
* Two new helper functions: [`RenderTemplateFile()`](https://godoc.org/github.com/flosch/pongo2#RenderTemplateFile) and [`RenderTemplateString()`](https://godoc.org/github.com/flosch/pongo2#RenderTemplateString).
|
||||
|
@ -106,7 +104,7 @@ If you're using the `master`-branch of pongo2, you might be interested in this s
|
|||
## How you can help
|
||||
|
||||
* Write [filters](https://github.com/flosch/pongo2/blob/master/filters_builtin.go#L3) / [tags](https://github.com/flosch/pongo2/blob/master/tags.go#L4) (see [tutorial](https://www.florian-schlachter.de/post/pongo2/)) by forking pongo2 and sending pull requests
|
||||
* Write/improve code tests (use the following command to see what tests are missing: `go test -v -cover -covermode=count -coverprofile=cover.out && go tool cover -html=cover.out` or have a look on [gocover.io/github.com/flosch/pongo2](http://gocover.io/github.com/flosch/pongo2))
|
||||
* Write/improve code tests (use the following command to see what tests are missing: `go test -v -cover -covermode=count -coverprofile=cover.out && go tool cover -html=cover.out`)
|
||||
* Write/improve template tests (see the `template_tests/` directory)
|
||||
* Write middleware, libraries and websites using pongo2. :-)
|
||||
|
||||
|
@ -117,8 +115,7 @@ For a documentation on how the templating language works you can [head over to t
|
|||
You can access pongo2's API documentation on [godoc](https://godoc.org/github.com/flosch/pongo2).
|
||||
|
||||
## Blog post series
|
||||
|
||||
* [pongo2 v3 released](https://www.florian-schlachter.de/post/pongo2-v3/)
|
||||
|
||||
* [pongo2 v2 released](https://www.florian-schlachter.de/post/pongo2-v2/)
|
||||
* [pongo2 1.0 released](https://www.florian-schlachter.de/post/pongo2-10/) [August 8th 2014]
|
||||
* [pongo2 playground](https://www.florian-schlachter.de/post/pongo2-playground/) [August 1st 2014]
|
||||
|
@ -157,12 +154,8 @@ You can access pongo2's API documentation on [godoc](https://godoc.org/github.co
|
|||
* [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://github.com/robvdl/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
|
||||
|
||||
* [pongo2-trans](https://github.com/fromYukki/pongo2trans) - `trans`-tag implementation for internationalization
|
||||
|
||||
Please add your project to this list and send me a pull request when you've developed something nice for pongo2.
|
||||
|
||||
# API-usage examples
|
||||
|
|
30
vendor/github.com/flosch/pongo2/context.go
generated
vendored
30
vendor/github.com/flosch/pongo2/context.go
generated
vendored
|
@ -1,14 +1,13 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
var reIdentifiers = regexp.MustCompile("^[a-zA-Z0-9_]+$")
|
||||
|
||||
// A Context type provides constants, variables, instances or functions to a template.
|
||||
// Use this Context type to provide constants, variables, instances or functions to your template.
|
||||
//
|
||||
// pongo2 automatically provides meta-information or functions through the "pongo2"-key.
|
||||
// Currently, context["pongo2"] contains the following keys:
|
||||
|
@ -25,15 +24,14 @@ func (c Context) checkForValidIdentifiers() *Error {
|
|||
for k, v := range c {
|
||||
if !reIdentifiers.MatchString(k) {
|
||||
return &Error{
|
||||
Sender: "checkForValidIdentifiers",
|
||||
OrigError: errors.Errorf("context-key '%s' (value: '%+v') is not a valid identifier", k, v),
|
||||
Sender: "checkForValidIdentifiers",
|
||||
ErrorMsg: fmt.Sprintf("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
|
||||
|
@ -41,8 +39,6 @@ func (c Context) Update(other Context) Context {
|
|||
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
|
||||
|
@ -101,10 +97,6 @@ func NewChildExecutionContext(parent *ExecutionContext) *ExecutionContext {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -115,13 +107,13 @@ func (ctx *ExecutionContext) OrigError(err error, token *Token) *Error {
|
|||
col = token.Col
|
||||
}
|
||||
return &Error{
|
||||
Template: ctx.template,
|
||||
Filename: filename,
|
||||
Line: line,
|
||||
Column: col,
|
||||
Token: token,
|
||||
Sender: "execution",
|
||||
OrigError: err,
|
||||
Template: ctx.template,
|
||||
Filename: filename,
|
||||
Line: line,
|
||||
Column: col,
|
||||
Token: token,
|
||||
Sender: "execution",
|
||||
ErrorMsg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
vendor/github.com/flosch/pongo2/docs/examples.md
generated
vendored
1
vendor/github.com/flosch/pongo2/docs/examples.md
generated
vendored
|
@ -1 +0,0 @@
|
|||
(Stub, TBA)
|
68
vendor/github.com/flosch/pongo2/docs/filters.md
generated
vendored
68
vendor/github.com/flosch/pongo2/docs/filters.md
generated
vendored
|
@ -1,68 +0,0 @@
|
|||
TODO:
|
||||
|
||||
* What are filters?
|
||||
* List+explain all existing filters (pongo2 + pongo2-addons)
|
||||
|
||||
Implemented filters so far which needs documentation:
|
||||
|
||||
* escape
|
||||
* safe
|
||||
* escapejs
|
||||
* add
|
||||
* addslashes
|
||||
* capfirst
|
||||
* center
|
||||
* cut
|
||||
* date
|
||||
* default
|
||||
* default_if_none
|
||||
* divisibleby
|
||||
* first
|
||||
* floatformat
|
||||
* get_digit
|
||||
* iriencode
|
||||
* join
|
||||
* last
|
||||
* length
|
||||
* length_is
|
||||
* linebreaks
|
||||
* linebreaksbr
|
||||
* linenumbers
|
||||
* ljust
|
||||
* lower
|
||||
* make_list
|
||||
* phone2numeric
|
||||
* pluralize
|
||||
* random
|
||||
* removetags
|
||||
* rjust
|
||||
* slice
|
||||
* stringformat
|
||||
* striptags
|
||||
* time
|
||||
* title
|
||||
* truncatechars
|
||||
* truncatechars_html
|
||||
* truncatewords
|
||||
* truncatewords_html
|
||||
* upper
|
||||
* urlencode
|
||||
* urlize
|
||||
* urlizetrunc
|
||||
* wordcount
|
||||
* wordwrap
|
||||
* yesno
|
||||
|
||||
* filesizeformat*
|
||||
* slugify*
|
||||
* truncatesentences*
|
||||
* truncatesentences_html*
|
||||
* markdown*
|
||||
* intcomma*
|
||||
* ordinal*
|
||||
* naturalday*
|
||||
* timesince*
|
||||
* timeuntil*
|
||||
* naturaltime*
|
||||
|
||||
Filters marked with * are available through [pongo2-addons](https://github.com/flosch/pongo2-addons).
|
1
vendor/github.com/flosch/pongo2/docs/index.md
generated
vendored
1
vendor/github.com/flosch/pongo2/docs/index.md
generated
vendored
|
@ -1 +0,0 @@
|
|||
(Stub, TBA)
|
1
vendor/github.com/flosch/pongo2/docs/macros.md
generated
vendored
1
vendor/github.com/flosch/pongo2/docs/macros.md
generated
vendored
|
@ -1 +0,0 @@
|
|||
(Stub, TBA)
|
31
vendor/github.com/flosch/pongo2/docs/tags.md
generated
vendored
31
vendor/github.com/flosch/pongo2/docs/tags.md
generated
vendored
|
@ -1,31 +0,0 @@
|
|||
TODO:
|
||||
|
||||
* What are tags?
|
||||
* List+explain all existing tags (pongo2 + pongo2-addons)
|
||||
|
||||
Implemented tags so far which needs documentation:
|
||||
|
||||
* autoescape
|
||||
* block
|
||||
* comment
|
||||
* cycle
|
||||
* extends
|
||||
* filter
|
||||
* firstof
|
||||
* for
|
||||
* if
|
||||
* ifchanged
|
||||
* ifequal
|
||||
* ifnotequal
|
||||
* import
|
||||
* include
|
||||
* lorem
|
||||
* macro
|
||||
* now
|
||||
* set
|
||||
* spaceless
|
||||
* ssi
|
||||
* templatetag
|
||||
* verbatim
|
||||
* widthratio
|
||||
* with
|
1
vendor/github.com/flosch/pongo2/docs/template_sets.md
generated
vendored
1
vendor/github.com/flosch/pongo2/docs/template_sets.md
generated
vendored
|
@ -1 +0,0 @@
|
|||
(Stub, TBA)
|
0
vendor/github.com/flosch/pongo2/docs/write_filters.md
generated
vendored
0
vendor/github.com/flosch/pongo2/docs/write_filters.md
generated
vendored
0
vendor/github.com/flosch/pongo2/docs/write_tags.md
generated
vendored
0
vendor/github.com/flosch/pongo2/docs/write_tags.md
generated
vendored
37
vendor/github.com/flosch/pongo2/error.go
generated
vendored
37
vendor/github.com/flosch/pongo2/error.go
generated
vendored
|
@ -6,20 +6,20 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
// The Error type is being used to address an error during lexing, parsing or
|
||||
// This 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
|
||||
Template *Template
|
||||
Filename string
|
||||
Line int
|
||||
Column int
|
||||
Token *Token
|
||||
Sender string
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
func (e *Error) updateFromTokenIfNeeded(template *Template, t *Token) *Error {
|
||||
|
@ -54,14 +54,14 @@ func (e *Error) Error() string {
|
|||
}
|
||||
}
|
||||
s += "] "
|
||||
s += e.OrigError.Error()
|
||||
s += e.ErrorMsg
|
||||
return s
|
||||
}
|
||||
|
||||
// RawLine returns the affected line from the original template, if available.
|
||||
func (e *Error) RawLine() (line string, available bool, outErr error) {
|
||||
// Returns the affected line from the original template, if available.
|
||||
func (e *Error) RawLine() (line string, available bool) {
|
||||
if e.Line <= 0 || e.Filename == "<string>" {
|
||||
return "", false, nil
|
||||
return "", false
|
||||
}
|
||||
|
||||
filename := e.Filename
|
||||
|
@ -70,22 +70,17 @@ func (e *Error) RawLine() (line string, available bool, outErr error) {
|
|||
}
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
panic(err)
|
||||
}
|
||||
defer func() {
|
||||
err := file.Close()
|
||||
if err != nil && outErr == nil {
|
||||
outErr = err
|
||||
}
|
||||
}()
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
l := 0
|
||||
for scanner.Scan() {
|
||||
l++
|
||||
if l == e.Line {
|
||||
return scanner.Text(), true, nil
|
||||
return scanner.Text(), true
|
||||
}
|
||||
}
|
||||
return "", false, nil
|
||||
return "", false
|
||||
}
|
||||
|
|
54
vendor/github.com/flosch/pongo2/filters.go
generated
vendored
54
vendor/github.com/flosch/pongo2/filters.go
generated
vendored
|
@ -2,11 +2,8 @@ package pongo2
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
// FilterFunction is the type filter functions must fulfil
|
||||
type FilterFunction func(in *Value, param *Value) (out *Value, err *Error)
|
||||
|
||||
var filters map[string]FilterFunction
|
||||
|
@ -15,38 +12,32 @@ 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
|
||||
// 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 errors.Errorf("filter with name '%s' is already registered", name)
|
||||
func RegisterFilter(name string, fn FilterFunction) {
|
||||
_, existing := filters[name]
|
||||
if existing {
|
||||
panic(fmt.Sprintf("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
|
||||
// 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 errors.Errorf("filter with name '%s' does not exist (therefore cannot be overridden)", name)
|
||||
func ReplaceFilter(name string, fn FilterFunction) {
|
||||
_, existing := filters[name]
|
||||
if !existing {
|
||||
panic(fmt.Sprintf("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.
|
||||
// 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 {
|
||||
|
@ -55,14 +46,13 @@ func MustApplyFilter(name string, value *Value, param *Value) *Value {
|
|||
return val
|
||||
}
|
||||
|
||||
// ApplyFilter applies a filter to a given value using the given parameters.
|
||||
// Returns a *pongo2.Value or an error.
|
||||
// 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: errors.Errorf("Filter with name '%s' not found.", name),
|
||||
Sender: "applyfilter",
|
||||
ErrorMsg: fmt.Sprintf("Filter with name '%s' not found.", name),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,31 +86,31 @@ func (fc *filterCall) Execute(v *Value, ctx *ExecutionContext) (*Value, *Error)
|
|||
param = AsValue(nil)
|
||||
}
|
||||
|
||||
filteredValue, err := fc.filterFunc(v, param)
|
||||
filtered_value, err := fc.filterFunc(v, param)
|
||||
if err != nil {
|
||||
return nil, err.updateFromTokenIfNeeded(ctx.template, fc.token)
|
||||
}
|
||||
return filteredValue, nil
|
||||
return filtered_value, nil
|
||||
}
|
||||
|
||||
// Filter = IDENT | IDENT ":" FilterArg | IDENT "|" Filter
|
||||
func (p *Parser) parseFilter() (*filterCall, *Error) {
|
||||
identToken := p.MatchType(TokenIdentifier)
|
||||
ident_token := p.MatchType(TokenIdentifier)
|
||||
|
||||
// Check filter ident
|
||||
if identToken == nil {
|
||||
if ident_token == nil {
|
||||
return nil, p.Error("Filter name must be an identifier.", nil)
|
||||
}
|
||||
|
||||
filter := &filterCall{
|
||||
token: identToken,
|
||||
name: identToken.Val,
|
||||
token: ident_token,
|
||||
name: ident_token.Val,
|
||||
}
|
||||
|
||||
// Get the appropriate filter function and bind it
|
||||
filterFn, exists := filters[identToken.Val]
|
||||
filterFn, exists := filters[ident_token.Val]
|
||||
if !exists {
|
||||
return nil, p.Error(fmt.Sprintf("Filter '%s' does not exist.", identToken.Val), identToken)
|
||||
return nil, p.Error(fmt.Sprintf("Filter '%s' does not exist.", ident_token.Val), ident_token)
|
||||
}
|
||||
|
||||
filter.filterFunc = filterFn
|
||||
|
|
178
vendor/github.com/flosch/pongo2/filters_builtin.go
generated
vendored
178
vendor/github.com/flosch/pongo2/filters_builtin.go
generated
vendored
|
@ -35,8 +35,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -75,15 +73,14 @@ func init() {
|
|||
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("truncatechars_html", filterTruncatecharsHtml)
|
||||
RegisterFilter("truncatewords", filterTruncatewords)
|
||||
RegisterFilter("truncatewords_html", filterTruncatewordsHTML)
|
||||
RegisterFilter("truncatewords_html", filterTruncatewordsHtml)
|
||||
RegisterFilter("upper", filterUpper)
|
||||
RegisterFilter("urlencode", filterUrlencode)
|
||||
RegisterFilter("urlize", filterUrlize)
|
||||
|
@ -108,9 +105,9 @@ func filterTruncatecharsHelper(s string, newLen int) string {
|
|||
return string(runes)
|
||||
}
|
||||
|
||||
func filterTruncateHTMLHelper(value string, newOutput *bytes.Buffer, cond func() bool, fn func(c rune, s int, idx int) int, finalize func()) {
|
||||
func filterTruncateHtmlHelper(value string, new_output *bytes.Buffer, cond func() bool, fn func(c rune, s int, idx int) int, finalize func()) {
|
||||
vLen := len(value)
|
||||
var tagStack []string
|
||||
tag_stack := make([]string, 0)
|
||||
idx := 0
|
||||
|
||||
for idx < vLen && !cond() {
|
||||
|
@ -121,17 +118,17 @@ func filterTruncateHTMLHelper(value string, newOutput *bytes.Buffer, cond func()
|
|||
}
|
||||
|
||||
if c == '<' {
|
||||
newOutput.WriteRune(c)
|
||||
new_output.WriteRune(c)
|
||||
idx += s // consume "<"
|
||||
|
||||
if idx+1 < vLen {
|
||||
if value[idx] == '/' {
|
||||
// Close tag
|
||||
|
||||
newOutput.WriteString("/")
|
||||
new_output.WriteString("/")
|
||||
|
||||
tag := ""
|
||||
idx++ // consume "/"
|
||||
idx += 1 // consume "/"
|
||||
|
||||
for idx < vLen {
|
||||
c2, size2 := utf8.DecodeRuneInString(value[idx:])
|
||||
|
@ -149,21 +146,21 @@ func filterTruncateHTMLHelper(value string, newOutput *bytes.Buffer, cond func()
|
|||
idx += size2
|
||||
}
|
||||
|
||||
if len(tagStack) > 0 {
|
||||
if len(tag_stack) > 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 {
|
||||
for i := len(tag_stack) - 1; i >= 0; i-- {
|
||||
if tag_stack[i] == tag {
|
||||
// Found the tag
|
||||
tagStack[i] = tagStack[len(tagStack)-1]
|
||||
tagStack = tagStack[:len(tagStack)-1]
|
||||
tag_stack[i] = tag_stack[len(tag_stack)-1]
|
||||
tag_stack = tag_stack[:len(tag_stack)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newOutput.WriteString(tag)
|
||||
newOutput.WriteString(">")
|
||||
new_output.WriteString(tag)
|
||||
new_output.WriteString(">")
|
||||
} else {
|
||||
// Open tag
|
||||
|
||||
|
@ -177,7 +174,7 @@ func filterTruncateHTMLHelper(value string, newOutput *bytes.Buffer, cond func()
|
|||
continue
|
||||
}
|
||||
|
||||
newOutput.WriteRune(c2)
|
||||
new_output.WriteRune(c2)
|
||||
|
||||
// End of tag found
|
||||
if c2 == '>' {
|
||||
|
@ -197,7 +194,7 @@ func filterTruncateHTMLHelper(value string, newOutput *bytes.Buffer, cond func()
|
|||
}
|
||||
|
||||
// Add tag to stack
|
||||
tagStack = append(tagStack, tag)
|
||||
tag_stack = append(tag_stack, tag)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -207,10 +204,10 @@ func filterTruncateHTMLHelper(value string, newOutput *bytes.Buffer, cond func()
|
|||
|
||||
finalize()
|
||||
|
||||
for i := len(tagStack) - 1; i >= 0; i-- {
|
||||
tag := tagStack[i]
|
||||
for i := len(tag_stack) - 1; i >= 0; i-- {
|
||||
tag := tag_stack[i]
|
||||
// Close everything from the regular tag stack
|
||||
newOutput.WriteString(fmt.Sprintf("</%s>", tag))
|
||||
new_output.WriteString(fmt.Sprintf("</%s>", tag))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,28 +217,28 @@ func filterTruncatechars(in *Value, param *Value) (*Value, *Error) {
|
|||
return AsValue(filterTruncatecharsHelper(s, newLen)), nil
|
||||
}
|
||||
|
||||
func filterTruncatecharsHTML(in *Value, param *Value) (*Value, *Error) {
|
||||
func filterTruncatecharsHtml(in *Value, param *Value) (*Value, *Error) {
|
||||
value := in.String()
|
||||
newLen := max(param.Integer()-3, 0)
|
||||
|
||||
newOutput := bytes.NewBuffer(nil)
|
||||
new_output := bytes.NewBuffer(nil)
|
||||
|
||||
textcounter := 0
|
||||
|
||||
filterTruncateHTMLHelper(value, newOutput, func() bool {
|
||||
filterTruncateHtmlHelper(value, new_output, func() bool {
|
||||
return textcounter >= newLen
|
||||
}, func(c rune, s int, idx int) int {
|
||||
textcounter++
|
||||
newOutput.WriteRune(c)
|
||||
new_output.WriteRune(c)
|
||||
|
||||
return idx + s
|
||||
}, func() {
|
||||
if textcounter >= newLen && textcounter < len(value) {
|
||||
newOutput.WriteString("...")
|
||||
new_output.WriteString("...")
|
||||
}
|
||||
})
|
||||
|
||||
return AsSafeValue(newOutput.String()), nil
|
||||
return AsSafeValue(new_output.String()), nil
|
||||
}
|
||||
|
||||
func filterTruncatewords(in *Value, param *Value) (*Value, *Error) {
|
||||
|
@ -263,19 +260,19 @@ func filterTruncatewords(in *Value, param *Value) (*Value, *Error) {
|
|||
return AsValue(strings.Join(out, " ")), nil
|
||||
}
|
||||
|
||||
func filterTruncatewordsHTML(in *Value, param *Value) (*Value, *Error) {
|
||||
func filterTruncatewordsHtml(in *Value, param *Value) (*Value, *Error) {
|
||||
value := in.String()
|
||||
newLen := max(param.Integer(), 0)
|
||||
|
||||
newOutput := bytes.NewBuffer(nil)
|
||||
new_output := bytes.NewBuffer(nil)
|
||||
|
||||
wordcounter := 0
|
||||
|
||||
filterTruncateHTMLHelper(value, newOutput, func() bool {
|
||||
filterTruncateHtmlHelper(value, new_output, func() bool {
|
||||
return wordcounter >= newLen
|
||||
}, func(_ rune, _ int, idx int) int {
|
||||
// Get next word
|
||||
wordFound := false
|
||||
word_found := false
|
||||
|
||||
for idx < len(value) {
|
||||
c2, size2 := utf8.DecodeRuneInString(value[idx:])
|
||||
|
@ -289,29 +286,29 @@ func filterTruncatewordsHTML(in *Value, param *Value) (*Value, *Error) {
|
|||
return idx
|
||||
}
|
||||
|
||||
newOutput.WriteRune(c2)
|
||||
new_output.WriteRune(c2)
|
||||
idx += size2
|
||||
|
||||
if c2 == ' ' || c2 == '.' || c2 == ',' || c2 == ';' {
|
||||
// Word ends here, stop capturing it now
|
||||
break
|
||||
} else {
|
||||
wordFound = true
|
||||
word_found = true
|
||||
}
|
||||
}
|
||||
|
||||
if wordFound {
|
||||
if word_found {
|
||||
wordcounter++
|
||||
}
|
||||
|
||||
return idx
|
||||
}, func() {
|
||||
if wordcounter >= newLen {
|
||||
newOutput.WriteString("...")
|
||||
new_output.WriteString("...")
|
||||
}
|
||||
})
|
||||
|
||||
return AsSafeValue(newOutput.String()), nil
|
||||
return AsSafeValue(new_output.String()), nil
|
||||
}
|
||||
|
||||
func filterEscape(in *Value, param *Value) (*Value, *Error) {
|
||||
|
@ -380,11 +377,12 @@ 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
|
||||
} else {
|
||||
return AsValue(in.Integer() + param.Integer()), 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
|
||||
// Value's String() convertion and just add them both together
|
||||
return AsValue(in.String() + param.String()), nil
|
||||
}
|
||||
|
||||
|
@ -552,11 +550,11 @@ func filterCenter(in *Value, param *Value) (*Value, *Error) {
|
|||
}
|
||||
|
||||
func filterDate(in *Value, param *Value) (*Value, *Error) {
|
||||
t, isTime := in.Interface().(time.Time)
|
||||
if !isTime {
|
||||
t, is_time := in.Interface().(time.Time)
|
||||
if !is_time {
|
||||
return nil, &Error{
|
||||
Sender: "filter:date",
|
||||
OrigError: errors.New("filter input argument must be of type 'time.Time'"),
|
||||
Sender: "filter:date",
|
||||
ErrorMsg: "Filter input argument must be of type 'time.Time'.",
|
||||
}
|
||||
}
|
||||
return AsValue(t.Format(param.String())), nil
|
||||
|
@ -614,12 +612,6 @@ func filterLinebreaks(in *Value, param *Value) (*Value, *Error) {
|
|||
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", "<br />", -1)), nil
|
||||
}
|
||||
|
@ -649,8 +641,7 @@ func filterUrlencode(in *Value, param *Value) (*Value, *Error) {
|
|||
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
|
||||
func filterUrlizeHelper(input string, autoescape bool, trunc int) string {
|
||||
sout := filterUrlizeURLRegexp.ReplaceAllStringFunc(input, func(raw_url string) string {
|
||||
var prefix string
|
||||
var suffix string
|
||||
|
@ -665,8 +656,7 @@ func filterUrlizeHelper(input string, autoescape bool, trunc int) (string, error
|
|||
|
||||
t, err := ApplyFilter("iriencode", AsValue(raw_url), nil)
|
||||
if err != nil {
|
||||
soutErr = err
|
||||
return ""
|
||||
panic(err)
|
||||
}
|
||||
url := t.String()
|
||||
|
||||
|
@ -683,19 +673,16 @@ func filterUrlizeHelper(input string, autoescape bool, trunc int) (string, error
|
|||
if autoescape {
|
||||
t, err := ApplyFilter("escape", AsValue(title), nil)
|
||||
if err != nil {
|
||||
soutErr = err
|
||||
return ""
|
||||
panic(err)
|
||||
}
|
||||
title = t.String()
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`%s<a href="%s" rel="nofollow">%s</a>%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 {
|
||||
|
@ -705,7 +692,7 @@ func filterUrlizeHelper(input string, autoescape bool, trunc int) (string, error
|
|||
return fmt.Sprintf(`<a href="mailto:%s">%s</a>`, mail, title)
|
||||
})
|
||||
|
||||
return sout, nil
|
||||
return sout
|
||||
}
|
||||
|
||||
func filterUrlize(in *Value, param *Value) (*Value, *Error) {
|
||||
|
@ -714,36 +701,24 @@ func filterUrlize(in *Value, param *Value) (*Value, *Error) {
|
|||
autoescape = param.Bool()
|
||||
}
|
||||
|
||||
s, err := filterUrlizeHelper(in.String(), autoescape, -1)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
|
||||
return AsValue(s), nil
|
||||
return AsValue(filterUrlizeHelper(in.String(), autoescape, -1)), 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
|
||||
return AsValue(filterUrlizeHelper(in.String(), true, param.Integer())), nil
|
||||
}
|
||||
|
||||
func filterStringformat(in *Value, param *Value) (*Value, *Error) {
|
||||
return AsValue(fmt.Sprintf(param.String(), in.Interface())), nil
|
||||
}
|
||||
|
||||
var reStriptags = regexp.MustCompile("<[^>]*?>")
|
||||
var re_striptags = regexp.MustCompile("<[^>]*?>")
|
||||
|
||||
func filterStriptags(in *Value, param *Value) (*Value, *Error) {
|
||||
s := in.String()
|
||||
|
||||
// Strip all tags
|
||||
s = reStriptags.ReplaceAllString(s, "")
|
||||
s = re_striptags.ReplaceAllString(s, "")
|
||||
|
||||
return AsValue(strings.TrimSpace(s)), nil
|
||||
}
|
||||
|
@ -771,8 +746,8 @@ func filterPluralize(in *Value, param *Value) (*Value, *Error) {
|
|||
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'"),
|
||||
Sender: "filter:pluralize",
|
||||
ErrorMsg: "You cannot pass more than 2 arguments to filter 'pluralize'.",
|
||||
}
|
||||
}
|
||||
if len(endings) == 1 {
|
||||
|
@ -795,10 +770,11 @@ func filterPluralize(in *Value, param *Value) (*Value, *Error) {
|
|||
}
|
||||
|
||||
return AsValue(""), nil
|
||||
}
|
||||
return nil, &Error{
|
||||
Sender: "filter:pluralize",
|
||||
OrigError: errors.New("filter 'pluralize' does only work on numbers"),
|
||||
} else {
|
||||
return nil, &Error{
|
||||
Sender: "filter:pluralize",
|
||||
ErrorMsg: "Filter 'pluralize' does only work on numbers.",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -831,8 +807,8 @@ 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]"),
|
||||
Sender: "filter:slice",
|
||||
ErrorMsg: "Slice string must have the format 'from:to' [from/to can be omitted, but the ':' is required]",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,16 +844,16 @@ func filterWordcount(in *Value, param *Value) (*Value, *Error) {
|
|||
|
||||
func filterWordwrap(in *Value, param *Value) (*Value, *Error) {
|
||||
words := strings.Fields(in.String())
|
||||
wordsLen := len(words)
|
||||
wrapAt := param.Integer()
|
||||
if wrapAt <= 0 {
|
||||
words_len := len(words)
|
||||
wrap_at := param.Integer()
|
||||
if wrap_at <= 0 {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
linecount := wordsLen/wrapAt + wordsLen%wrapAt
|
||||
linecount := words_len/wrap_at + words_len%wrap_at
|
||||
lines := make([]string, 0, linecount)
|
||||
for i := 0; i < linecount; i++ {
|
||||
lines = append(lines, strings.Join(words[wrapAt*i:min(wrapAt*(i+1), wordsLen)], " "))
|
||||
lines = append(lines, strings.Join(words[wrap_at*i:min(wrap_at*(i+1), words_len)], " "))
|
||||
}
|
||||
return AsValue(strings.Join(lines, "\n")), nil
|
||||
}
|
||||
|
@ -888,27 +864,27 @@ func filterYesno(in *Value, param *Value) (*Value, *Error) {
|
|||
1: "no",
|
||||
2: "maybe",
|
||||
}
|
||||
paramString := param.String()
|
||||
customChoices := strings.Split(paramString, ",")
|
||||
if len(paramString) > 0 {
|
||||
if len(customChoices) > 3 {
|
||||
param_string := param.String()
|
||||
custom_choices := strings.Split(param_string, ",")
|
||||
if len(param_string) > 0 {
|
||||
if len(custom_choices) > 3 {
|
||||
return nil, &Error{
|
||||
Sender: "filter:yesno",
|
||||
OrigError: errors.Errorf("You cannot pass more than 3 options to the 'yesno'-filter (got: '%s').", paramString),
|
||||
Sender: "filter:yesno",
|
||||
ErrorMsg: fmt.Sprintf("You cannot pass more than 3 options to the 'yesno'-filter (got: '%s').", param_string),
|
||||
}
|
||||
}
|
||||
if len(customChoices) < 2 {
|
||||
if len(custom_choices) < 2 {
|
||||
return nil, &Error{
|
||||
Sender: "filter:yesno",
|
||||
OrigError: errors.Errorf("You must pass either no or at least 2 arguments to the 'yesno'-filter (got: '%s').", paramString),
|
||||
Sender: "filter:yesno",
|
||||
ErrorMsg: fmt.Sprintf("You must pass either no or at least 2 arguments to the 'yesno'-filter (got: '%s').", param_string),
|
||||
}
|
||||
}
|
||||
|
||||
// Map to the options now
|
||||
choices[0] = customChoices[0]
|
||||
choices[1] = customChoices[1]
|
||||
if len(customChoices) == 3 {
|
||||
choices[2] = customChoices[2]
|
||||
choices[0] = custom_choices[0]
|
||||
choices[1] = custom_choices[1]
|
||||
if len(custom_choices) == 3 {
|
||||
choices[2] = custom_choices[2]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
44
vendor/github.com/flosch/pongo2/lexer.go
generated
vendored
44
vendor/github.com/flosch/pongo2/lexer.go
generated
vendored
|
@ -4,8 +4,6 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -65,8 +63,8 @@ type lexer struct {
|
|||
line int
|
||||
col int
|
||||
|
||||
inVerbatim bool
|
||||
verbatimName string
|
||||
in_verbatim bool
|
||||
verbatim_name string
|
||||
}
|
||||
|
||||
func (t *Token) String() string {
|
||||
|
@ -113,11 +111,11 @@ func lex(name string, input string) ([]*Token, *Error) {
|
|||
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),
|
||||
Filename: name,
|
||||
Line: errtoken.Line,
|
||||
Column: errtoken.Col,
|
||||
Sender: "lexer",
|
||||
ErrorMsg: errtoken.Val,
|
||||
}
|
||||
}
|
||||
return l.tokens, nil
|
||||
|
@ -218,8 +216,8 @@ 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 l.in_verbatim {
|
||||
name := l.verbatim_name
|
||||
if name != "" {
|
||||
name += " "
|
||||
}
|
||||
|
@ -231,20 +229,20 @@ func (l *lexer) run() {
|
|||
l.pos += w
|
||||
l.col += w
|
||||
l.ignore()
|
||||
l.inVerbatim = false
|
||||
l.in_verbatim = false
|
||||
}
|
||||
} else if strings.HasPrefix(l.input[l.pos:], "{% verbatim %}") { // tag
|
||||
if l.pos > l.start {
|
||||
l.emit(TokenHTML)
|
||||
}
|
||||
l.inVerbatim = true
|
||||
l.in_verbatim = true
|
||||
w := len("{% verbatim %}")
|
||||
l.pos += w
|
||||
l.col += w
|
||||
l.ignore()
|
||||
}
|
||||
|
||||
if !l.inVerbatim {
|
||||
if !l.in_verbatim {
|
||||
// Ignore single-line comments {# ... #}
|
||||
if strings.HasPrefix(l.input[l.pos:], "{#") {
|
||||
if l.pos > l.start {
|
||||
|
@ -305,7 +303,7 @@ func (l *lexer) run() {
|
|||
l.emit(TokenHTML)
|
||||
}
|
||||
|
||||
if l.inVerbatim {
|
||||
if l.in_verbatim {
|
||||
l.errorf("verbatim-tag not closed, got EOF.")
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +328,7 @@ outer_loop:
|
|||
return l.stateIdentifier
|
||||
case l.accept(tokenDigits):
|
||||
return l.stateNumber
|
||||
case l.accept(`"'`):
|
||||
case l.accept(`"`):
|
||||
return l.stateString
|
||||
}
|
||||
|
||||
|
@ -350,6 +348,10 @@ outer_loop:
|
|||
}
|
||||
}
|
||||
|
||||
if l.pos < len(l.input) {
|
||||
return l.errorf("Unknown character: %q (%d)", l.peek(), l.peek())
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -372,11 +374,6 @@ func (l *lexer) stateIdentifier() lexerStateFn {
|
|||
|
||||
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
|
||||
|
@ -396,10 +393,9 @@ func (l *lexer) stateNumber() lexerStateFn {
|
|||
}
|
||||
|
||||
func (l *lexer) stateString() lexerStateFn {
|
||||
quotationMark := l.value()
|
||||
l.ignore()
|
||||
l.startcol-- // we're starting the position at the first "
|
||||
for !l.accept(quotationMark) {
|
||||
l.startcol -= 1 // we're starting the position at the first "
|
||||
for !l.accept(`"`) {
|
||||
switch l.next() {
|
||||
case '\\':
|
||||
// escape sequence
|
||||
|
|
8
vendor/github.com/flosch/pongo2/nodes.go
generated
vendored
8
vendor/github.com/flosch/pongo2/nodes.go
generated
vendored
|
@ -1,13 +1,17 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// The root document
|
||||
type nodeDocument struct {
|
||||
Nodes []INode
|
||||
}
|
||||
|
||||
func (doc *nodeDocument) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (doc *nodeDocument) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
for _, n := range doc.Nodes {
|
||||
err := n.Execute(ctx, writer)
|
||||
err := n.Execute(ctx, buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
8
vendor/github.com/flosch/pongo2/nodes_html.go
generated
vendored
8
vendor/github.com/flosch/pongo2/nodes_html.go
generated
vendored
|
@ -1,10 +1,14 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type nodeHTML struct {
|
||||
token *Token
|
||||
}
|
||||
|
||||
func (n *nodeHTML) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
writer.WriteString(n.token.Val)
|
||||
func (n *nodeHTML) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
buffer.WriteString(n.token.Val)
|
||||
return nil
|
||||
}
|
||||
|
|
8
vendor/github.com/flosch/pongo2/nodes_wrapper.go
generated
vendored
8
vendor/github.com/flosch/pongo2/nodes_wrapper.go
generated
vendored
|
@ -1,13 +1,17 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type NodeWrapper struct {
|
||||
Endtag string
|
||||
nodes []INode
|
||||
}
|
||||
|
||||
func (wrapper *NodeWrapper) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (wrapper *NodeWrapper) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
for _, n := range wrapper.nodes {
|
||||
err := n.Execute(ctx, writer)
|
||||
err := n.Execute(ctx, buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
98
vendor/github.com/flosch/pongo2/parser.go
generated
vendored
98
vendor/github.com/flosch/pongo2/parser.go
generated
vendored
|
@ -1,14 +1,13 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
type INode interface {
|
||||
Execute(*ExecutionContext, TemplateWriter) *Error
|
||||
Execute(*ExecutionContext, *bytes.Buffer) *Error
|
||||
}
|
||||
|
||||
type IEvaluator interface {
|
||||
|
@ -28,10 +27,10 @@ type IEvaluator interface {
|
|||
//
|
||||
// (See Token's documentation for more about tokens)
|
||||
type Parser struct {
|
||||
name string
|
||||
idx int
|
||||
tokens []*Token
|
||||
lastToken *Token
|
||||
name string
|
||||
idx int
|
||||
tokens []*Token
|
||||
last_token *Token
|
||||
|
||||
// if the parser parses a template document, here will be
|
||||
// a reference to it (needed to access the template through Tags)
|
||||
|
@ -48,7 +47,7 @@ func newParser(name string, tokens []*Token, template *Template) *Parser {
|
|||
template: template,
|
||||
}
|
||||
if len(tokens) > 0 {
|
||||
p.lastToken = tokens[len(tokens)-1]
|
||||
p.last_token = tokens[len(tokens)-1]
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
@ -176,7 +175,7 @@ func (p *Parser) GetR(shift int) *Token {
|
|||
return p.Get(i)
|
||||
}
|
||||
|
||||
// Error produces a nice error message and returns an error-object.
|
||||
// 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.
|
||||
|
@ -197,13 +196,13 @@ func (p *Parser) Error(msg string, token *Token) *Error {
|
|||
col = token.Col
|
||||
}
|
||||
return &Error{
|
||||
Template: p.template,
|
||||
Filename: p.name,
|
||||
Sender: "parser",
|
||||
Line: line,
|
||||
Column: col,
|
||||
Token: token,
|
||||
OrigError: errors.New(msg),
|
||||
Template: p.template,
|
||||
Filename: p.name,
|
||||
Sender: "parser",
|
||||
Line: line,
|
||||
Column: col,
|
||||
Token: token,
|
||||
ErrorMsg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,19 +212,19 @@ func (p *Parser) Error(msg string, token *Token) *Error {
|
|||
func (p *Parser) WrapUntilTag(names ...string) (*NodeWrapper, *Parser, *Error) {
|
||||
wrapper := &NodeWrapper{}
|
||||
|
||||
var tagArgs []*Token
|
||||
tagArgs := make([]*Token, 0)
|
||||
|
||||
for p.Remaining() > 0 {
|
||||
// New tag, check whether we have to stop wrapping here
|
||||
if p.Peek(TokenSymbol, "{%") != nil {
|
||||
tagIdent := p.PeekTypeN(1, TokenIdentifier)
|
||||
tag_ident := p.PeekTypeN(1, TokenIdentifier)
|
||||
|
||||
if tagIdent != nil {
|
||||
if tag_ident != nil {
|
||||
// We've found a (!) end-tag
|
||||
|
||||
found := false
|
||||
for _, n := range names {
|
||||
if tagIdent.Val == n {
|
||||
if tag_ident.Val == n {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
@ -239,15 +238,16 @@ func (p *Parser) WrapUntilTag(names ...string) (*NodeWrapper, *Parser, *Error) {
|
|||
for {
|
||||
if p.Match(TokenSymbol, "%}") != nil {
|
||||
// Okay, end the wrapping here
|
||||
wrapper.Endtag = tagIdent.Val
|
||||
wrapper.Endtag = tag_ident.Val
|
||||
return wrapper, newParser(p.template.name, tagArgs, p.template), nil
|
||||
} else {
|
||||
t := p.Current()
|
||||
p.Consume()
|
||||
if t == nil {
|
||||
return nil, nil, p.Error("Unexpected EOF.", p.last_token)
|
||||
}
|
||||
tagArgs = append(tagArgs, t)
|
||||
}
|
||||
t := p.Current()
|
||||
p.Consume()
|
||||
if t == nil {
|
||||
return nil, nil, p.Error("Unexpected EOF.", p.lastToken)
|
||||
}
|
||||
tagArgs = append(tagArgs, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -263,47 +263,5 @@ func (p *Parser) WrapUntilTag(names ...string) (*NodeWrapper, *Parser, *Error) {
|
|||
}
|
||||
|
||||
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)
|
||||
p.last_token)
|
||||
}
|
||||
|
|
156
vendor/github.com/flosch/pongo2/parser_expression.go
generated
vendored
156
vendor/github.com/flosch/pongo2/parser_expression.go
generated
vendored
|
@ -1,37 +1,38 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type Expression struct {
|
||||
// TODO: Add location token?
|
||||
expr1 IEvaluator
|
||||
expr2 IEvaluator
|
||||
opToken *Token
|
||||
expr1 IEvaluator
|
||||
expr2 IEvaluator
|
||||
op_token *Token
|
||||
}
|
||||
|
||||
type relationalExpression struct {
|
||||
// TODO: Add location token?
|
||||
expr1 IEvaluator
|
||||
expr2 IEvaluator
|
||||
opToken *Token
|
||||
expr1 IEvaluator
|
||||
expr2 IEvaluator
|
||||
op_token *Token
|
||||
}
|
||||
|
||||
type simpleExpression struct {
|
||||
negate bool
|
||||
negativeSign bool
|
||||
term1 IEvaluator
|
||||
term2 IEvaluator
|
||||
opToken *Token
|
||||
negate bool
|
||||
negative_sign bool
|
||||
term1 IEvaluator
|
||||
term2 IEvaluator
|
||||
op_token *Token
|
||||
}
|
||||
|
||||
type term struct {
|
||||
// TODO: Add location token?
|
||||
factor1 IEvaluator
|
||||
factor2 IEvaluator
|
||||
opToken *Token
|
||||
factor1 IEvaluator
|
||||
factor2 IEvaluator
|
||||
op_token *Token
|
||||
}
|
||||
|
||||
type power struct {
|
||||
|
@ -55,14 +56,14 @@ func (expr *simpleExpression) FilterApplied(name string) bool {
|
|||
(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 (t *term) FilterApplied(name string) bool {
|
||||
return t.factor1.FilterApplied(name) && (t.factor2 == nil ||
|
||||
(t.factor2 != nil && t.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 (p *power) FilterApplied(name string) bool {
|
||||
return p.power1.FilterApplied(name) && (p.power2 == nil ||
|
||||
(p.power2 != nil && p.power2.FilterApplied(name)))
|
||||
}
|
||||
|
||||
func (expr *Expression) GetPositionToken() *Token {
|
||||
|
@ -85,48 +86,48 @@ func (expr *power) GetPositionToken() *Token {
|
|||
return expr.power1.GetPositionToken()
|
||||
}
|
||||
|
||||
func (expr *Expression) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (expr *Expression) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
value, err := expr.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer.WriteString(value.String())
|
||||
buffer.WriteString(value.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (expr *relationalExpression) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (expr *relationalExpression) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
value, err := expr.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer.WriteString(value.String())
|
||||
buffer.WriteString(value.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (expr *simpleExpression) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (expr *simpleExpression) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
value, err := expr.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer.WriteString(value.String())
|
||||
buffer.WriteString(value.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (expr *term) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (expr *term) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
value, err := expr.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer.WriteString(value.String())
|
||||
buffer.WriteString(value.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (expr *power) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (expr *power) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
value, err := expr.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer.WriteString(value.String())
|
||||
buffer.WriteString(value.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -140,13 +141,13 @@ func (expr *Expression) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch expr.opToken.Val {
|
||||
switch expr.op_token.Val {
|
||||
case "and", "&&":
|
||||
return AsValue(v1.IsTrue() && v2.IsTrue()), nil
|
||||
case "or", "||":
|
||||
return AsValue(v1.IsTrue() || v2.IsTrue()), nil
|
||||
default:
|
||||
return nil, ctx.Error(fmt.Sprintf("unimplemented: %s", expr.opToken.Val), expr.opToken)
|
||||
panic(fmt.Sprintf("unimplemented: %s", expr.op_token.Val))
|
||||
}
|
||||
} else {
|
||||
return v1, nil
|
||||
|
@ -163,35 +164,39 @@ func (expr *relationalExpression) Evaluate(ctx *ExecutionContext) (*Value, *Erro
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch expr.opToken.Val {
|
||||
switch expr.op_token.Val {
|
||||
case "<=":
|
||||
if v1.IsFloat() || v2.IsFloat() {
|
||||
return AsValue(v1.Float() <= v2.Float()), nil
|
||||
} else {
|
||||
return AsValue(v1.Integer() <= v2.Integer()), nil
|
||||
}
|
||||
return AsValue(v1.Integer() <= v2.Integer()), nil
|
||||
case ">=":
|
||||
if v1.IsFloat() || v2.IsFloat() {
|
||||
return AsValue(v1.Float() >= v2.Float()), nil
|
||||
} else {
|
||||
return AsValue(v1.Integer() >= v2.Integer()), 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
|
||||
} else {
|
||||
return AsValue(v1.Integer() > v2.Integer()), nil
|
||||
}
|
||||
return AsValue(v1.Integer() > v2.Integer()), nil
|
||||
case "<":
|
||||
if v1.IsFloat() || v2.IsFloat() {
|
||||
return AsValue(v1.Float() < v2.Float()), nil
|
||||
} else {
|
||||
return AsValue(v1.Integer() < v2.Integer()), 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)
|
||||
panic(fmt.Sprintf("unimplemented: %s", expr.op_token.Val))
|
||||
}
|
||||
} else {
|
||||
return v1, nil
|
||||
|
@ -209,7 +214,7 @@ func (expr *simpleExpression) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
|||
result = result.Negate()
|
||||
}
|
||||
|
||||
if expr.negativeSign {
|
||||
if expr.negative_sign {
|
||||
if result.IsNumber() {
|
||||
switch {
|
||||
case result.IsFloat():
|
||||
|
@ -217,7 +222,7 @@ func (expr *simpleExpression) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
|||
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)
|
||||
panic("not possible")
|
||||
}
|
||||
} else {
|
||||
return nil, ctx.Error("Negative sign on a non-number expression", expr.GetPositionToken())
|
||||
|
@ -229,40 +234,42 @@ func (expr *simpleExpression) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch expr.opToken.Val {
|
||||
switch expr.op_token.Val {
|
||||
case "+":
|
||||
if result.IsFloat() || t2.IsFloat() {
|
||||
// Result will be a float
|
||||
return AsValue(result.Float() + t2.Float()), nil
|
||||
} else {
|
||||
// Result will be an integer
|
||||
return AsValue(result.Integer() + t2.Integer()), 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
|
||||
} else {
|
||||
// Result will be an integer
|
||||
return AsValue(result.Integer() - t2.Integer()), nil
|
||||
}
|
||||
// Result will be an integer
|
||||
return AsValue(result.Integer() - t2.Integer()), nil
|
||||
default:
|
||||
return nil, ctx.Error("Unimplemented", expr.GetPositionToken())
|
||||
panic("unimplemented")
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (expr *term) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
||||
f1, err := expr.factor1.Evaluate(ctx)
|
||||
func (t *term) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
||||
f1, err := t.factor1.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if expr.factor2 != nil {
|
||||
f2, err := expr.factor2.Evaluate(ctx)
|
||||
if t.factor2 != nil {
|
||||
f2, err := t.factor2.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch expr.opToken.Val {
|
||||
switch t.op_token.Val {
|
||||
case "*":
|
||||
if f1.IsFloat() || f2.IsFloat() {
|
||||
// Result will be float
|
||||
|
@ -281,26 +288,27 @@ func (expr *term) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
|||
// Result will be int
|
||||
return AsValue(f1.Integer() % f2.Integer()), nil
|
||||
default:
|
||||
return nil, ctx.Error("unimplemented", expr.opToken)
|
||||
panic("unimplemented")
|
||||
}
|
||||
} else {
|
||||
return f1, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (expr *power) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
||||
p1, err := expr.power1.Evaluate(ctx)
|
||||
func (pw *power) Evaluate(ctx *ExecutionContext) (*Value, *Error) {
|
||||
p1, err := pw.power1.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if expr.power2 != nil {
|
||||
p2, err := expr.power2.Evaluate(ctx)
|
||||
if pw.power2 != nil {
|
||||
p2, err := pw.power2.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return AsValue(math.Pow(p1.Float(), p2.Float())), nil
|
||||
} else {
|
||||
return p1, nil
|
||||
}
|
||||
return p1, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseFactor() (IEvaluator, *Error) {
|
||||
|
@ -344,19 +352,19 @@ func (p *Parser) parsePower() (IEvaluator, *Error) {
|
|||
}
|
||||
|
||||
func (p *Parser) parseTerm() (IEvaluator, *Error) {
|
||||
returnTerm := new(term)
|
||||
return_term := new(term)
|
||||
|
||||
factor1, err := p.parsePower()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
returnTerm.factor1 = factor1
|
||||
return_term.factor1 = factor1
|
||||
|
||||
for p.PeekOne(TokenSymbol, "*", "/", "%") != nil {
|
||||
if returnTerm.opToken != nil {
|
||||
if return_term.op_token != nil {
|
||||
// Create new sub-term
|
||||
returnTerm = &term{
|
||||
factor1: returnTerm,
|
||||
return_term = &term{
|
||||
factor1: return_term,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,16 +376,16 @@ func (p *Parser) parseTerm() (IEvaluator, *Error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
returnTerm.opToken = op
|
||||
returnTerm.factor2 = factor2
|
||||
return_term.op_token = op
|
||||
return_term.factor2 = factor2
|
||||
}
|
||||
|
||||
if returnTerm.opToken == nil {
|
||||
if return_term.op_token == nil {
|
||||
// Shortcut for faster evaluation
|
||||
return returnTerm.factor1, nil
|
||||
return return_term.factor1, nil
|
||||
}
|
||||
|
||||
return returnTerm, nil
|
||||
return return_term, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseSimpleExpression() (IEvaluator, *Error) {
|
||||
|
@ -385,7 +393,7 @@ func (p *Parser) parseSimpleExpression() (IEvaluator, *Error) {
|
|||
|
||||
if sign := p.MatchOne(TokenSymbol, "+", "-"); sign != nil {
|
||||
if sign.Val == "-" {
|
||||
expr.negativeSign = true
|
||||
expr.negative_sign = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,7 +408,7 @@ func (p *Parser) parseSimpleExpression() (IEvaluator, *Error) {
|
|||
expr.term1 = term1
|
||||
|
||||
for p.PeekOne(TokenSymbol, "+", "-") != nil {
|
||||
if expr.opToken != nil {
|
||||
if expr.op_token != nil {
|
||||
// New sub expr
|
||||
expr = &simpleExpression{
|
||||
term1: expr,
|
||||
|
@ -416,10 +424,10 @@ func (p *Parser) parseSimpleExpression() (IEvaluator, *Error) {
|
|||
}
|
||||
|
||||
expr.term2 = term2
|
||||
expr.opToken = op
|
||||
expr.op_token = op
|
||||
}
|
||||
|
||||
if expr.negate == false && expr.negativeSign == false && expr.term2 == nil {
|
||||
if expr.negate == false && expr.negative_sign == false && expr.term2 == nil {
|
||||
// Shortcut for faster evaluation
|
||||
return expr.term1, nil
|
||||
}
|
||||
|
@ -442,14 +450,14 @@ func (p *Parser) parseRelationalExpression() (IEvaluator, *Error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
expr.opToken = t
|
||||
expr.op_token = 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.op_token = t
|
||||
expr.expr2 = expr2
|
||||
}
|
||||
|
||||
|
@ -479,7 +487,7 @@ func (p *Parser) ParseExpression() (IEvaluator, *Error) {
|
|||
return nil, err
|
||||
}
|
||||
exp.expr2 = expr2
|
||||
exp.opToken = op
|
||||
exp.op_token = op
|
||||
}
|
||||
|
||||
if exp.expr2 == nil {
|
||||
|
|
6
vendor/github.com/flosch/pongo2/pongo2.go
generated
vendored
6
vendor/github.com/flosch/pongo2/pongo2.go
generated
vendored
|
@ -1,10 +1,10 @@
|
|||
package pongo2
|
||||
|
||||
// Version string
|
||||
const Version = "dev"
|
||||
const Version = "v3"
|
||||
|
||||
// Must panics, if a Template couldn't successfully parsed. This is how you
|
||||
// would use it:
|
||||
// Helper function which 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 {
|
||||
|
|
29
vendor/github.com/flosch/pongo2/pongo2_issues_test.go
generated
vendored
29
vendor/github.com/flosch/pongo2/pongo2_issues_test.go
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
package pongo2_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/flosch/pongo2"
|
||||
)
|
||||
|
||||
func TestIssue151(t *testing.T) {
|
||||
tpl, err := pongo2.FromString("{{ mydict.51232_3 }}{{ 12345_123}}{{ 995189baz }}")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
str, err := tpl.Execute(pongo2.Context{
|
||||
"mydict": map[string]string{
|
||||
"51232_3": "foo",
|
||||
},
|
||||
"12345_123": "bar",
|
||||
"995189baz": "baz",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if str != "foobarbaz" {
|
||||
t.Fatalf("Expected output 'foobarbaz', but got '%s'.", str)
|
||||
}
|
||||
}
|
534
vendor/github.com/flosch/pongo2/pongo2_template_test.go
generated
vendored
534
vendor/github.com/flosch/pongo2/pongo2_template_test.go
generated
vendored
|
@ -1,534 +0,0 @@
|
|||
package pongo2_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/flosch/pongo2"
|
||||
)
|
||||
|
||||
var adminList = []string{"user2"}
|
||||
|
||||
var time1 = time.Date(2014, 06, 10, 15, 30, 15, 0, time.UTC)
|
||||
var time2 = time.Date(2011, 03, 21, 8, 37, 56, 12, time.UTC)
|
||||
|
||||
type post struct {
|
||||
Text string
|
||||
Created time.Time
|
||||
}
|
||||
|
||||
type user struct {
|
||||
Name string
|
||||
Validated bool
|
||||
}
|
||||
|
||||
type comment struct {
|
||||
Author *user
|
||||
Date time.Time
|
||||
Text string
|
||||
}
|
||||
|
||||
func isAdmin(u *user) bool {
|
||||
for _, a := range adminList {
|
||||
if a == u.Name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *user) Is_admin() *pongo2.Value {
|
||||
return pongo2.AsValue(isAdmin(u))
|
||||
}
|
||||
|
||||
func (u *user) Is_admin2() bool {
|
||||
return isAdmin(u)
|
||||
}
|
||||
|
||||
func (p *post) String() string {
|
||||
return ":-)"
|
||||
}
|
||||
|
||||
/*
|
||||
* Start setup sandbox
|
||||
*/
|
||||
|
||||
type tagSandboxDemoTag struct {
|
||||
}
|
||||
|
||||
func (node *tagSandboxDemoTag) Execute(ctx *pongo2.ExecutionContext, writer pongo2.TemplateWriter) *pongo2.Error {
|
||||
writer.WriteString("hello")
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagSandboxDemoTagParser(doc *pongo2.Parser, start *pongo2.Token, arguments *pongo2.Parser) (pongo2.INodeTag, *pongo2.Error) {
|
||||
return &tagSandboxDemoTag{}, nil
|
||||
}
|
||||
|
||||
func BannedFilterFn(in *pongo2.Value, params *pongo2.Value) (*pongo2.Value, *pongo2.Error) {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
pongo2.DefaultSet.Debug = true
|
||||
|
||||
pongo2.RegisterFilter("banned_filter", BannedFilterFn)
|
||||
pongo2.RegisterFilter("unbanned_filter", BannedFilterFn)
|
||||
pongo2.RegisterTag("banned_tag", tagSandboxDemoTagParser)
|
||||
pongo2.RegisterTag("unbanned_tag", tagSandboxDemoTagParser)
|
||||
|
||||
pongo2.DefaultSet.BanFilter("banned_filter")
|
||||
pongo2.DefaultSet.BanTag("banned_tag")
|
||||
|
||||
f, err := ioutil.TempFile("/tmp/", "pongo2_")
|
||||
if err != nil {
|
||||
panic("cannot write to /tmp/")
|
||||
}
|
||||
f.Write([]byte("Hello from pongo2"))
|
||||
pongo2.DefaultSet.Globals["temp_file"] = f.Name()
|
||||
}
|
||||
|
||||
/*
|
||||
* End setup sandbox
|
||||
*/
|
||||
|
||||
var tplContext = pongo2.Context{
|
||||
"number": 11,
|
||||
"simple": map[string]interface{}{
|
||||
"number": 42,
|
||||
"name": "john doe",
|
||||
"included_file": "INCLUDES.helper",
|
||||
"included_file_not_exists": "INCLUDES.helper.not_exists",
|
||||
"nil": nil,
|
||||
"uint": uint(8),
|
||||
"float": float64(3.1415),
|
||||
"str": "string",
|
||||
"chinese_hello_world": "你好世界",
|
||||
"bool_true": true,
|
||||
"bool_false": false,
|
||||
"newline_text": `this is a text
|
||||
with a new line in it`,
|
||||
"long_text": `This is a simple text.
|
||||
|
||||
This too, as a paragraph.
|
||||
Right?
|
||||
|
||||
Yep!`,
|
||||
"escape_js_test": `escape sequences \r\n\'\" special chars "?!=$<>`,
|
||||
"one_item_list": []int{99},
|
||||
"multiple_item_list": []int{1, 1, 2, 3, 5, 8, 13, 21, 34, 55},
|
||||
"unsorted_int_list": []int{192, 581, 22, 1, 249, 9999, 1828591, 8271},
|
||||
"fixed_item_list": [...]int{1, 2, 3, 4},
|
||||
"misc_list": []interface{}{"Hello", 99, 3.14, "good"},
|
||||
"escape_text": "This is \\a Test. \"Yep\". 'Yep'.",
|
||||
"xss": "<script>alert(\"uh oh\");</script>",
|
||||
"intmap": map[int]string{
|
||||
1: "one",
|
||||
5: "five",
|
||||
2: "two",
|
||||
},
|
||||
"strmap": map[string]string{
|
||||
"abc": "def",
|
||||
"bcd": "efg",
|
||||
"zab": "cde",
|
||||
"gh": "kqm",
|
||||
"ukq": "qqa",
|
||||
"aab": "aba",
|
||||
},
|
||||
"func_add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"func_add_iface": func(a, b interface{}) interface{} {
|
||||
return a.(int) + b.(int)
|
||||
},
|
||||
"func_variadic": func(msg string, args ...interface{}) string {
|
||||
return fmt.Sprintf(msg, args...)
|
||||
},
|
||||
"func_variadic_sum_int": func(args ...int) int {
|
||||
// Create a sum
|
||||
s := 0
|
||||
for _, i := range args {
|
||||
s += i
|
||||
}
|
||||
return s
|
||||
},
|
||||
"func_variadic_sum_int2": func(args ...*pongo2.Value) *pongo2.Value {
|
||||
// Create a sum
|
||||
s := 0
|
||||
for _, i := range args {
|
||||
s += i.Integer()
|
||||
}
|
||||
return pongo2.AsValue(s)
|
||||
},
|
||||
},
|
||||
"complex": map[string]interface{}{
|
||||
"is_admin": isAdmin,
|
||||
"post": post{
|
||||
Text: "<h2>Hello!</h2><p>Welcome to my new blog page. I'm using pongo2 which supports {{ variables }} and {% tags %}.</p>",
|
||||
Created: time2,
|
||||
},
|
||||
"comments": []*comment{
|
||||
&comment{
|
||||
Author: &user{
|
||||
Name: "user1",
|
||||
Validated: true,
|
||||
},
|
||||
Date: time1,
|
||||
Text: "\"pongo2 is nice!\"",
|
||||
},
|
||||
&comment{
|
||||
Author: &user{
|
||||
Name: "user2",
|
||||
Validated: true,
|
||||
},
|
||||
Date: time2,
|
||||
Text: "comment2 with <script>unsafe</script> tags in it",
|
||||
},
|
||||
&comment{
|
||||
Author: &user{
|
||||
Name: "user3",
|
||||
Validated: false,
|
||||
},
|
||||
Date: time1,
|
||||
Text: "<b>hello!</b> there",
|
||||
},
|
||||
},
|
||||
"comments2": []*comment{
|
||||
&comment{
|
||||
Author: &user{
|
||||
Name: "user1",
|
||||
Validated: true,
|
||||
},
|
||||
Date: time2,
|
||||
Text: "\"pongo2 is nice!\"",
|
||||
},
|
||||
&comment{
|
||||
Author: &user{
|
||||
Name: "user1",
|
||||
Validated: true,
|
||||
},
|
||||
Date: time1,
|
||||
Text: "comment2 with <script>unsafe</script> tags in it",
|
||||
},
|
||||
&comment{
|
||||
Author: &user{
|
||||
Name: "user3",
|
||||
Validated: false,
|
||||
},
|
||||
Date: time1,
|
||||
Text: "<b>hello!</b> there",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestTemplates(t *testing.T) {
|
||||
// Add a global to the default set
|
||||
pongo2.Globals["this_is_a_global_variable"] = "this is a global text"
|
||||
|
||||
matches, err := filepath.Glob("./template_tests/*.tpl")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for idx, match := range matches {
|
||||
t.Logf("[Template %3d] Testing '%s'", idx+1, match)
|
||||
tpl, err := pongo2.FromFile(match)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on FromFile('%s'): %s", match, err.Error())
|
||||
}
|
||||
testFilename := fmt.Sprintf("%s.out", match)
|
||||
testOut, rerr := ioutil.ReadFile(testFilename)
|
||||
if rerr != nil {
|
||||
t.Fatalf("Error on ReadFile('%s'): %s", testFilename, rerr.Error())
|
||||
}
|
||||
tplOut, err := tpl.ExecuteBytes(tplContext)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on Execute('%s'): %s", match, err.Error())
|
||||
}
|
||||
if bytes.Compare(testOut, tplOut) != 0 {
|
||||
t.Logf("Template (rendered) '%s': '%s'", match, tplOut)
|
||||
errFilename := filepath.Base(fmt.Sprintf("%s.error", match))
|
||||
err := ioutil.WriteFile(errFilename, []byte(tplOut), 0600)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
t.Logf("get a complete diff with command: 'diff -ya %s %s'", testFilename, errFilename)
|
||||
t.Errorf("Failed: test_out != tpl_out for %s", match)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecutionErrors(t *testing.T) {
|
||||
//debug = true
|
||||
|
||||
matches, err := filepath.Glob("./template_tests/*-execution.err")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for idx, match := range matches {
|
||||
t.Logf("[Errors %3d] Testing '%s'", idx+1, match)
|
||||
|
||||
testData, err := ioutil.ReadFile(match)
|
||||
tests := strings.Split(string(testData), "\n")
|
||||
|
||||
checkFilename := fmt.Sprintf("%s.out", match)
|
||||
checkData, err := ioutil.ReadFile(checkFilename)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on ReadFile('%s'): %s", checkFilename, err.Error())
|
||||
}
|
||||
checks := strings.Split(string(checkData), "\n")
|
||||
|
||||
if len(checks) != len(tests) {
|
||||
t.Fatal("Template lines != Checks lines")
|
||||
}
|
||||
|
||||
for idx, test := range tests {
|
||||
if strings.TrimSpace(test) == "" {
|
||||
continue
|
||||
}
|
||||
if strings.TrimSpace(checks[idx]) == "" {
|
||||
t.Fatalf("[%s Line %d] Check is empty (must contain an regular expression).",
|
||||
match, idx+1)
|
||||
}
|
||||
|
||||
tpl, err := pongo2.FromString(test)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on FromString('%s'): %s", test, err.Error())
|
||||
}
|
||||
|
||||
tpl, err = pongo2.FromBytes([]byte(test))
|
||||
if err != nil {
|
||||
t.Fatalf("Error on FromBytes('%s'): %s", test, err.Error())
|
||||
}
|
||||
|
||||
_, err = tpl.ExecuteBytes(tplContext)
|
||||
if err == nil {
|
||||
t.Fatalf("[%s Line %d] Expected error for (got none): %s",
|
||||
match, idx+1, tests[idx])
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(fmt.Sprintf("^%s$", checks[idx]))
|
||||
if !re.MatchString(err.Error()) {
|
||||
t.Fatalf("[%s Line %d] Error for '%s' (err = '%s') does not match the (regexp-)check: %s",
|
||||
match, idx+1, test, err.Error(), checks[idx])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompilationErrors(t *testing.T) {
|
||||
//debug = true
|
||||
|
||||
matches, err := filepath.Glob("./template_tests/*-compilation.err")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for idx, match := range matches {
|
||||
t.Logf("[Errors %3d] Testing '%s'", idx+1, match)
|
||||
|
||||
testData, err := ioutil.ReadFile(match)
|
||||
tests := strings.Split(string(testData), "\n")
|
||||
|
||||
checkFilename := fmt.Sprintf("%s.out", match)
|
||||
checkData, err := ioutil.ReadFile(checkFilename)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on ReadFile('%s'): %s", checkFilename, err.Error())
|
||||
}
|
||||
checks := strings.Split(string(checkData), "\n")
|
||||
|
||||
if len(checks) != len(tests) {
|
||||
t.Fatal("Template lines != Checks lines")
|
||||
}
|
||||
|
||||
for idx, test := range tests {
|
||||
if strings.TrimSpace(test) == "" {
|
||||
continue
|
||||
}
|
||||
if strings.TrimSpace(checks[idx]) == "" {
|
||||
t.Fatalf("[%s Line %d] Check is empty (must contain an regular expression).",
|
||||
match, idx+1)
|
||||
}
|
||||
|
||||
_, err = pongo2.FromString(test)
|
||||
if err == nil {
|
||||
t.Fatalf("[%s | Line %d] Expected error for (got none): %s", match, idx+1, tests[idx])
|
||||
}
|
||||
re := regexp.MustCompile(fmt.Sprintf("^%s$", checks[idx]))
|
||||
if !re.MatchString(err.Error()) {
|
||||
t.Fatalf("[%s | Line %d] Error for '%s' (err = '%s') does not match the (regexp-)check: %s",
|
||||
match, idx+1, test, err.Error(), checks[idx])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseDirectory(t *testing.T) {
|
||||
mustStr := "Hello from template_tests/base_dir_test/"
|
||||
|
||||
fs := pongo2.MustNewLocalFileSystemLoader("")
|
||||
s := pongo2.NewSet("test set with base directory", fs)
|
||||
s.Globals["base_directory"] = "template_tests/base_dir_test/"
|
||||
if err := fs.SetBaseDir(s.Globals["base_directory"].(string)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
matches, err := filepath.Glob("./template_tests/base_dir_test/subdir/*")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, match := range matches {
|
||||
match = strings.Replace(match, "template_tests/base_dir_test/", "", -1)
|
||||
|
||||
tpl, err := s.FromFile(match)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
out, err := tpl.Execute(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if out != mustStr {
|
||||
t.Errorf("%s: out ('%s') != mustStr ('%s')", match, out, mustStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCache(b *testing.B) {
|
||||
cacheSet := pongo2.NewSet("cache set", pongo2.MustNewLocalFileSystemLoader(""))
|
||||
for i := 0; i < b.N; i++ {
|
||||
tpl, err := cacheSet.FromCache("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
err = tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCacheDebugOn(b *testing.B) {
|
||||
cacheDebugSet := pongo2.NewSet("cache set", pongo2.MustNewLocalFileSystemLoader(""))
|
||||
cacheDebugSet.Debug = true
|
||||
for i := 0; i < b.N; i++ {
|
||||
tpl, err := cacheDebugSet.FromFile("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
err = tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkExecuteComplexWithSandboxActive(b *testing.B) {
|
||||
tpl, err := pongo2.FromFile("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
err = tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCompileAndExecuteComplexWithSandboxActive(b *testing.B) {
|
||||
buf, err := ioutil.ReadFile("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
preloadedTpl := string(buf)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
tpl, err := pongo2.FromString(preloadedTpl)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
err = tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParallelExecuteComplexWithSandboxActive(b *testing.B) {
|
||||
tpl, err := pongo2.FromFile("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
err := tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkExecuteComplexWithoutSandbox(b *testing.B) {
|
||||
s := pongo2.NewSet("set without sandbox", pongo2.MustNewLocalFileSystemLoader(""))
|
||||
tpl, err := s.FromFile("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
err = tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCompileAndExecuteComplexWithoutSandbox(b *testing.B) {
|
||||
buf, err := ioutil.ReadFile("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
preloadedTpl := string(buf)
|
||||
|
||||
s := pongo2.NewSet("set without sandbox", pongo2.MustNewLocalFileSystemLoader(""))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
tpl, err := s.FromString(preloadedTpl)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
err = tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParallelExecuteComplexWithoutSandbox(b *testing.B) {
|
||||
s := pongo2.NewSet("set without sandbox", pongo2.MustNewLocalFileSystemLoader(""))
|
||||
tpl, err := s.FromFile("template_tests/complex.tpl")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
err := tpl.ExecuteWriterUnbuffered(tplContext, ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
103
vendor/github.com/flosch/pongo2/pongo2_test.go
generated
vendored
103
vendor/github.com/flosch/pongo2/pongo2_test.go
generated
vendored
|
@ -1,103 +0,0 @@
|
|||
package pongo2_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/flosch/pongo2"
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
// Hook up gocheck into the "go test" runner.
|
||||
func Test(t *testing.T) { TestingT(t) }
|
||||
|
||||
type TestSuite struct {
|
||||
tpl *pongo2.Template
|
||||
}
|
||||
|
||||
var (
|
||||
_ = Suite(&TestSuite{})
|
||||
testSuite2 = pongo2.NewSet("test suite 2", pongo2.MustNewLocalFileSystemLoader(""))
|
||||
)
|
||||
|
||||
func parseTemplate(s string, c pongo2.Context) string {
|
||||
t, err := testSuite2.FromString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
out, err := t.Execute(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func parseTemplateFn(s string, c pongo2.Context) func() {
|
||||
return func() {
|
||||
parseTemplate(s, c)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestMisc(c *C) {
|
||||
// Must
|
||||
// TODO: Add better error message (see issue #18)
|
||||
c.Check(
|
||||
func() { pongo2.Must(testSuite2.FromFile("template_tests/inheritance/base2.tpl")) },
|
||||
PanicMatches,
|
||||
`\[Error \(where: fromfile\) in .*template_tests/inheritance/doesnotexist.tpl | Line 1 Col 12 near 'doesnotexist.tpl'\] open .*template_tests/inheritance/doesnotexist.tpl: no such file or directory`,
|
||||
)
|
||||
|
||||
// Context
|
||||
c.Check(parseTemplateFn("", pongo2.Context{"'illegal": nil}), PanicMatches, ".*not a valid identifier.*")
|
||||
|
||||
// Registers
|
||||
c.Check(pongo2.RegisterFilter("escape", nil).Error(), Matches, ".*is already registered")
|
||||
c.Check(pongo2.RegisterTag("for", nil).Error(), Matches, ".*is already registered")
|
||||
|
||||
// ApplyFilter
|
||||
v, err := pongo2.ApplyFilter("title", pongo2.AsValue("this is a title"), nil)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Check(v.String(), Equals, "This Is A Title")
|
||||
c.Check(func() {
|
||||
_, err := pongo2.ApplyFilter("doesnotexist", nil, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}, PanicMatches, `\[Error \(where: applyfilter\)\] Filter with name 'doesnotexist' not found.`)
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestImplicitExecCtx(c *C) {
|
||||
tpl, err := pongo2.FromString("{{ ImplicitExec }}")
|
||||
if err != nil {
|
||||
c.Fatalf("Error in FromString: %v", err)
|
||||
}
|
||||
|
||||
val := "a stringy thing"
|
||||
|
||||
res, err := tpl.Execute(pongo2.Context{
|
||||
"Value": val,
|
||||
"ImplicitExec": func(ctx *pongo2.ExecutionContext) string {
|
||||
return ctx.Public["Value"].(string)
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
c.Fatalf("Error executing template: %v", err)
|
||||
}
|
||||
|
||||
c.Check(res, Equals, val)
|
||||
|
||||
// The implicit ctx should not be persisted from call-to-call
|
||||
res, err = tpl.Execute(pongo2.Context{
|
||||
"ImplicitExec": func() string {
|
||||
return val
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
c.Fatalf("Error executing template: %v", err)
|
||||
}
|
||||
|
||||
c.Check(res, Equals, val)
|
||||
}
|
41
vendor/github.com/flosch/pongo2/tags.go
generated
vendored
41
vendor/github.com/flosch/pongo2/tags.go
generated
vendored
|
@ -21,8 +21,6 @@ package pongo2
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
type INodeTag interface {
|
||||
|
@ -55,81 +53,80 @@ func init() {
|
|||
tags = make(map[string]*tag)
|
||||
}
|
||||
|
||||
// Registers a new tag. You usually want to call this
|
||||
// Registers a new tag. If there's already a tag with the same
|
||||
// name, RegisterTag will panic. 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 {
|
||||
func RegisterTag(name string, parserFn TagParser) {
|
||||
_, existing := tags[name]
|
||||
if existing {
|
||||
return errors.Errorf("tag with name '%s' is already registered", name)
|
||||
panic(fmt.Sprintf("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 {
|
||||
func ReplaceTag(name string, parserFn TagParser) {
|
||||
_, existing := tags[name]
|
||||
if !existing {
|
||||
return errors.Errorf("tag with name '%s' does not exist (therefore cannot be overridden)", name)
|
||||
panic(fmt.Sprintf("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)
|
||||
token_name := p.MatchType(TokenIdentifier)
|
||||
|
||||
// Check for identifier
|
||||
if tokenName == nil {
|
||||
if token_name == nil {
|
||||
return nil, p.Error("Tag name must be an identifier.", nil)
|
||||
}
|
||||
|
||||
// Check for the existing tag
|
||||
tag, exists := tags[tokenName.Val]
|
||||
tag, exists := tags[token_name.Val]
|
||||
if !exists {
|
||||
// Does not exists
|
||||
return nil, p.Error(fmt.Sprintf("Tag '%s' not found (or beginning tag not provided)", tokenName.Val), tokenName)
|
||||
return nil, p.Error(fmt.Sprintf("Tag '%s' not found (or beginning tag not provided)", token_name.Val), token_name)
|
||||
}
|
||||
|
||||
// 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)
|
||||
if _, is_banned := p.template.set.bannedTags[token_name.Val]; is_banned {
|
||||
return nil, p.Error(fmt.Sprintf("Usage of tag '%s' is not allowed (sandbox restriction active).", token_name.Val), token_name)
|
||||
}
|
||||
|
||||
var argsToken []*Token
|
||||
args_token := make([]*Token, 0)
|
||||
for p.Peek(TokenSymbol, "%}") == nil && p.Remaining() > 0 {
|
||||
// Add token to args
|
||||
argsToken = append(argsToken, p.Current())
|
||||
args_token = append(args_token, p.Current())
|
||||
p.Consume() // next token
|
||||
}
|
||||
|
||||
// EOF?
|
||||
if p.Remaining() == 0 {
|
||||
return nil, p.Error("Unexpectedly reached EOF, no tag end found.", p.lastToken)
|
||||
return nil, p.Error("Unexpectedly reached EOF, no tag end found.", p.last_token)
|
||||
}
|
||||
|
||||
p.Match(TokenSymbol, "%}")
|
||||
|
||||
argParser := newParser(p.name, argsToken, p.template)
|
||||
if len(argsToken) == 0 {
|
||||
arg_parser := newParser(p.name, args_token, p.template)
|
||||
if len(args_token) == 0 {
|
||||
// This is done to have nice EOF error messages
|
||||
argParser.lastToken = tokenName
|
||||
arg_parser.last_token = token_name
|
||||
}
|
||||
|
||||
p.template.level++
|
||||
defer func() { p.template.level-- }()
|
||||
return tag.parser(p, tokenName, argParser)
|
||||
return tag.parser(p, token_name, arg_parser)
|
||||
}
|
||||
|
|
26
vendor/github.com/flosch/pongo2/tags_autoescape.go
generated
vendored
26
vendor/github.com/flosch/pongo2/tags_autoescape.go
generated
vendored
|
@ -1,15 +1,19 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagAutoescapeNode struct {
|
||||
wrapper *NodeWrapper
|
||||
autoescape bool
|
||||
}
|
||||
|
||||
func (node *tagAutoescapeNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagAutoescapeNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
old := ctx.Autoescape
|
||||
ctx.Autoescape = node.autoescape
|
||||
|
||||
err := node.wrapper.Execute(ctx, writer)
|
||||
err := node.wrapper.Execute(ctx, buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -20,22 +24,22 @@ func (node *tagAutoescapeNode) Execute(ctx *ExecutionContext, writer TemplateWri
|
|||
}
|
||||
|
||||
func tagAutoescapeParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
autoescapeNode := &tagAutoescapeNode{}
|
||||
autoescape_node := &tagAutoescapeNode{}
|
||||
|
||||
wrapper, _, err := doc.WrapUntilTag("endautoescape")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
autoescapeNode.wrapper = wrapper
|
||||
autoescape_node.wrapper = wrapper
|
||||
|
||||
modeToken := arguments.MatchType(TokenIdentifier)
|
||||
if modeToken == nil {
|
||||
mode_token := arguments.MatchType(TokenIdentifier)
|
||||
if mode_token == 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
|
||||
if mode_token.Val == "on" {
|
||||
autoescape_node.autoescape = true
|
||||
} else if mode_token.Val == "off" {
|
||||
autoescape_node.autoescape = false
|
||||
} else {
|
||||
return nil, arguments.Error("Only 'on' or 'off' is valid as an autoescape-mode.", nil)
|
||||
}
|
||||
|
@ -44,7 +48,7 @@ func tagAutoescapeParser(doc *Parser, start *Token, arguments *Parser) (INodeTag
|
|||
return nil, arguments.Error("Malformed autoescape-tag arguments.", nil)
|
||||
}
|
||||
|
||||
return autoescapeNode, nil
|
||||
return autoescape_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
93
vendor/github.com/flosch/pongo2/tags_block.go
generated
vendored
93
vendor/github.com/flosch/pongo2/tags_block.go
generated
vendored
|
@ -9,82 +9,47 @@ type tagBlockNode struct {
|
|||
name string
|
||||
}
|
||||
|
||||
func (node *tagBlockNode) getBlockWrappers(tpl *Template) []*NodeWrapper {
|
||||
nodeWrappers := make([]*NodeWrapper, 0)
|
||||
func (node *tagBlockNode) getBlockWrapperByName(tpl *Template) *NodeWrapper {
|
||||
var t *NodeWrapper
|
||||
|
||||
for tpl != nil {
|
||||
t = tpl.blocks[node.name]
|
||||
if t != nil {
|
||||
nodeWrappers = append(nodeWrappers, t)
|
||||
}
|
||||
tpl = tpl.child
|
||||
if tpl.child != nil {
|
||||
// First ask the child for the block
|
||||
t = node.getBlockWrapperByName(tpl.child)
|
||||
}
|
||||
|
||||
return nodeWrappers
|
||||
if t == nil {
|
||||
// Child has no block, lets look up here at parent
|
||||
t = tpl.blocks[node.name]
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (node *tagBlockNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagBlockNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *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)
|
||||
block_wrapper := node.getBlockWrapperByName(tpl)
|
||||
if block_wrapper == nil {
|
||||
// fmt.Printf("could not find: %s\n", node.name)
|
||||
return ctx.Error("internal error: block_wrapper == nil in tagBlockNode.Execute()", nil)
|
||||
}
|
||||
|
||||
blockWrapper := blockWrappers[lenBlockWrappers-1]
|
||||
ctx.Private["block"] = tagBlockInformation{
|
||||
ctx: ctx,
|
||||
wrappers: blockWrappers[0 : lenBlockWrappers-1],
|
||||
}
|
||||
err := blockWrapper.Execute(ctx, writer)
|
||||
err := block_wrapper.Execute(ctx, buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: Add support for {{ block.super }}
|
||||
|
||||
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 {
|
||||
name_token := arguments.MatchType(TokenIdentifier)
|
||||
if name_token == nil {
|
||||
return nil, arguments.Error("First argument for tag 'block' must be an identifier.", nil)
|
||||
}
|
||||
|
||||
|
@ -97,15 +62,15 @@ func tagBlockParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Er
|
|||
return nil, err
|
||||
}
|
||||
if endtagargs.Remaining() > 0 {
|
||||
endtagnameToken := endtagargs.MatchType(TokenIdentifier)
|
||||
if endtagnameToken != nil {
|
||||
if endtagnameToken.Val != nameToken.Val {
|
||||
endtagname_token := endtagargs.MatchType(TokenIdentifier)
|
||||
if endtagname_token != nil {
|
||||
if endtagname_token.Val != name_token.Val {
|
||||
return nil, endtagargs.Error(fmt.Sprintf("Name for 'endblock' must equal to 'block'-tag's name ('%s' != '%s').",
|
||||
nameToken.Val, endtagnameToken.Val), nil)
|
||||
name_token.Val, endtagname_token.Val), nil)
|
||||
}
|
||||
}
|
||||
|
||||
if endtagnameToken == nil || endtagargs.Remaining() > 0 {
|
||||
if endtagname_token == nil || endtagargs.Remaining() > 0 {
|
||||
return nil, endtagargs.Error("Either no or only one argument (identifier) allowed for 'endblock'.", nil)
|
||||
}
|
||||
}
|
||||
|
@ -114,14 +79,14 @@ func tagBlockParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Er
|
|||
if tpl == nil {
|
||||
panic("internal error: tpl == nil")
|
||||
}
|
||||
_, hasBlock := tpl.blocks[nameToken.Val]
|
||||
if !hasBlock {
|
||||
tpl.blocks[nameToken.Val] = wrapper
|
||||
_, has_block := tpl.blocks[name_token.Val]
|
||||
if !has_block {
|
||||
tpl.blocks[name_token.Val] = wrapper
|
||||
} else {
|
||||
return nil, arguments.Error(fmt.Sprintf("Block named '%s' already defined", nameToken.Val), nil)
|
||||
return nil, arguments.Error(fmt.Sprintf("Block named '%s' already defined", name_token.Val), nil)
|
||||
}
|
||||
|
||||
return &tagBlockNode{name: nameToken.Val}, nil
|
||||
return &tagBlockNode{name: name_token.Val}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
12
vendor/github.com/flosch/pongo2/tags_comment.go
generated
vendored
12
vendor/github.com/flosch/pongo2/tags_comment.go
generated
vendored
|
@ -1,16 +1,20 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagCommentNode struct{}
|
||||
|
||||
func (node *tagCommentNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagCommentNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagCommentParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
commentNode := &tagCommentNode{}
|
||||
comment_node := &tagCommentNode{}
|
||||
|
||||
// TODO: Process the endtag's arguments (see django 'comment'-tag documentation)
|
||||
err := doc.SkipUntilTag("endcomment")
|
||||
_, _, err := doc.WrapUntilTag("endcomment")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -19,7 +23,7 @@ func tagCommentParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
return nil, arguments.Error("Tag 'comment' does not take any argument.", nil)
|
||||
}
|
||||
|
||||
return commentNode, nil
|
||||
return comment_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
34
vendor/github.com/flosch/pongo2/tags_cycle.go
generated
vendored
34
vendor/github.com/flosch/pongo2/tags_cycle.go
generated
vendored
|
@ -1,5 +1,9 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagCycleValue struct {
|
||||
node *tagCycleNode
|
||||
value *Value
|
||||
|
@ -9,7 +13,7 @@ type tagCycleNode struct {
|
|||
position *Token
|
||||
args []IEvaluator
|
||||
idx int
|
||||
asName string
|
||||
as_name string
|
||||
silent bool
|
||||
}
|
||||
|
||||
|
@ -17,7 +21,7 @@ func (cv *tagCycleValue) String() string {
|
|||
return cv.value.String()
|
||||
}
|
||||
|
||||
func (node *tagCycleNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagCycleNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
item := node.args[node.idx%len(node.args)]
|
||||
node.idx++
|
||||
|
||||
|
@ -42,30 +46,30 @@ func (node *tagCycleNode) Execute(ctx *ExecutionContext, writer TemplateWriter)
|
|||
t.value = val
|
||||
|
||||
if !t.node.silent {
|
||||
writer.WriteString(val.String())
|
||||
buffer.WriteString(val.String())
|
||||
}
|
||||
} else {
|
||||
// Regular call
|
||||
|
||||
cycleValue := &tagCycleValue{
|
||||
cycle_value := &tagCycleValue{
|
||||
node: node,
|
||||
value: val,
|
||||
}
|
||||
|
||||
if node.asName != "" {
|
||||
ctx.Private[node.asName] = cycleValue
|
||||
if node.as_name != "" {
|
||||
ctx.Private[node.as_name] = cycle_value
|
||||
}
|
||||
if !node.silent {
|
||||
writer.WriteString(val.String())
|
||||
buffer.WriteString(val.String())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HINT: We're not supporting the old comma-separated list of expressions argument-style
|
||||
// HINT: We're not supporting the old comma-seperated list of expresions argument-style
|
||||
func tagCycleParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
cycleNode := &tagCycleNode{
|
||||
cycle_node := &tagCycleNode{
|
||||
position: start,
|
||||
}
|
||||
|
||||
|
@ -74,19 +78,19 @@ func tagCycleParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Er
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cycleNode.args = append(cycleNode.args, node)
|
||||
cycle_node.args = append(cycle_node.args, node)
|
||||
|
||||
if arguments.MatchOne(TokenKeyword, "as") != nil {
|
||||
// as
|
||||
|
||||
nameToken := arguments.MatchType(TokenIdentifier)
|
||||
if nameToken == nil {
|
||||
name_token := arguments.MatchType(TokenIdentifier)
|
||||
if name_token == nil {
|
||||
return nil, arguments.Error("Name (identifier) expected after 'as'.", nil)
|
||||
}
|
||||
cycleNode.asName = nameToken.Val
|
||||
cycle_node.as_name = name_token.Val
|
||||
|
||||
if arguments.MatchOne(TokenIdentifier, "silent") != nil {
|
||||
cycleNode.silent = true
|
||||
cycle_node.silent = true
|
||||
}
|
||||
|
||||
// Now we're finished
|
||||
|
@ -98,7 +102,7 @@ func tagCycleParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Er
|
|||
return nil, arguments.Error("Malformed cycle-tag.", nil)
|
||||
}
|
||||
|
||||
return cycleNode, nil
|
||||
return cycle_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
22
vendor/github.com/flosch/pongo2/tags_extends.go
generated
vendored
22
vendor/github.com/flosch/pongo2/tags_extends.go
generated
vendored
|
@ -1,15 +1,19 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagExtendsNode struct {
|
||||
filename string
|
||||
}
|
||||
|
||||
func (node *tagExtendsNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagExtendsNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagExtendsParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
extendsNode := &tagExtendsNode{}
|
||||
extends_node := &tagExtendsNode{}
|
||||
|
||||
if doc.template.level > 1 {
|
||||
return nil, arguments.Error("The 'extends' tag can only defined on root level.", start)
|
||||
|
@ -20,22 +24,22 @@ func tagExtendsParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
return nil, arguments.Error("This template has already one parent.", start)
|
||||
}
|
||||
|
||||
if filenameToken := arguments.MatchType(TokenString); filenameToken != nil {
|
||||
if filename_token := arguments.MatchType(TokenString); filename_token != nil {
|
||||
// prepared, static template
|
||||
|
||||
// Get parent's filename
|
||||
parentFilename := doc.template.set.resolveFilename(doc.template, filenameToken.Val)
|
||||
parent_filename := doc.template.set.resolveFilename(doc.template, filename_token.Val)
|
||||
|
||||
// Parse the parent
|
||||
parentTemplate, err := doc.template.set.FromFile(parentFilename)
|
||||
parent_template, err := doc.template.set.FromFile(parent_filename)
|
||||
if err != nil {
|
||||
return nil, err.(*Error)
|
||||
}
|
||||
|
||||
// Keep track of things
|
||||
parentTemplate.child = doc.template
|
||||
doc.template.parent = parentTemplate
|
||||
extendsNode.filename = parentFilename
|
||||
parent_template.child = doc.template
|
||||
doc.template.parent = parent_template
|
||||
extends_node.filename = parent_filename
|
||||
} else {
|
||||
return nil, arguments.Error("Tag 'extends' requires a template filename as string.", nil)
|
||||
}
|
||||
|
@ -44,7 +48,7 @@ func tagExtendsParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
return nil, arguments.Error("Tag 'extends' does only take 1 argument.", nil)
|
||||
}
|
||||
|
||||
return extendsNode, nil
|
||||
return extends_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
28
vendor/github.com/flosch/pongo2/tags_filter.go
generated
vendored
28
vendor/github.com/flosch/pongo2/tags_filter.go
generated
vendored
|
@ -5,8 +5,8 @@ import (
|
|||
)
|
||||
|
||||
type nodeFilterCall struct {
|
||||
name string
|
||||
paramExpr IEvaluator
|
||||
name string
|
||||
param_expr IEvaluator
|
||||
}
|
||||
|
||||
type tagFilterNode struct {
|
||||
|
@ -15,7 +15,7 @@ type tagFilterNode struct {
|
|||
filterChain []*nodeFilterCall
|
||||
}
|
||||
|
||||
func (node *tagFilterNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagFilterNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
temp := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB size
|
||||
|
||||
err := node.bodyWrapper.Execute(ctx, temp)
|
||||
|
@ -27,8 +27,8 @@ func (node *tagFilterNode) Execute(ctx *ExecutionContext, writer TemplateWriter)
|
|||
|
||||
for _, call := range node.filterChain {
|
||||
var param *Value
|
||||
if call.paramExpr != nil {
|
||||
param, err = call.paramExpr.Evaluate(ctx)
|
||||
if call.param_expr != nil {
|
||||
param, err = call.param_expr.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ func (node *tagFilterNode) Execute(ctx *ExecutionContext, writer TemplateWriter)
|
|||
}
|
||||
}
|
||||
|
||||
writer.WriteString(value.String())
|
||||
buffer.WriteString(value.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagFilterParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
filterNode := &tagFilterNode{
|
||||
filter_node := &tagFilterNode{
|
||||
position: start,
|
||||
}
|
||||
|
||||
|
@ -55,16 +55,16 @@ func tagFilterParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *E
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filterNode.bodyWrapper = wrapper
|
||||
filter_node.bodyWrapper = wrapper
|
||||
|
||||
for arguments.Remaining() > 0 {
|
||||
filterCall := &nodeFilterCall{}
|
||||
|
||||
nameToken := arguments.MatchType(TokenIdentifier)
|
||||
if nameToken == nil {
|
||||
name_token := arguments.MatchType(TokenIdentifier)
|
||||
if name_token == nil {
|
||||
return nil, arguments.Error("Expected a filter name (identifier).", nil)
|
||||
}
|
||||
filterCall.name = nameToken.Val
|
||||
filterCall.name = name_token.Val
|
||||
|
||||
if arguments.MatchOne(TokenSymbol, ":") != nil {
|
||||
// Filter parameter
|
||||
|
@ -73,10 +73,10 @@ func tagFilterParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *E
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filterCall.paramExpr = expr
|
||||
filterCall.param_expr = expr
|
||||
}
|
||||
|
||||
filterNode.filterChain = append(filterNode.filterChain, filterCall)
|
||||
filter_node.filterChain = append(filter_node.filterChain, filterCall)
|
||||
|
||||
if arguments.MatchOne(TokenSymbol, "|") == nil {
|
||||
break
|
||||
|
@ -87,7 +87,7 @@ func tagFilterParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *E
|
|||
return nil, arguments.Error("Malformed filter-tag arguments.", nil)
|
||||
}
|
||||
|
||||
return filterNode, nil
|
||||
return filter_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
14
vendor/github.com/flosch/pongo2/tags_firstof.go
generated
vendored
14
vendor/github.com/flosch/pongo2/tags_firstof.go
generated
vendored
|
@ -1,11 +1,15 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagFirstofNode struct {
|
||||
position *Token
|
||||
args []IEvaluator
|
||||
}
|
||||
|
||||
func (node *tagFirstofNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagFirstofNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
for _, arg := range node.args {
|
||||
val, err := arg.Evaluate(ctx)
|
||||
if err != nil {
|
||||
|
@ -20,7 +24,7 @@ func (node *tagFirstofNode) Execute(ctx *ExecutionContext, writer TemplateWriter
|
|||
}
|
||||
}
|
||||
|
||||
writer.WriteString(val.String())
|
||||
buffer.WriteString(val.String())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +33,7 @@ func (node *tagFirstofNode) Execute(ctx *ExecutionContext, writer TemplateWriter
|
|||
}
|
||||
|
||||
func tagFirstofParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
firstofNode := &tagFirstofNode{
|
||||
firstof_node := &tagFirstofNode{
|
||||
position: start,
|
||||
}
|
||||
|
||||
|
@ -38,10 +42,10 @@ func tagFirstofParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
firstofNode.args = append(firstofNode.args, node)
|
||||
firstof_node.args = append(firstof_node.args, node)
|
||||
}
|
||||
|
||||
return firstofNode, nil
|
||||
return firstof_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
59
vendor/github.com/flosch/pongo2/tags_for.go
generated
vendored
59
vendor/github.com/flosch/pongo2/tags_for.go
generated
vendored
|
@ -1,11 +1,14 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagForNode struct {
|
||||
key string
|
||||
value string // only for maps: for key, value in map
|
||||
objectEvaluator IEvaluator
|
||||
reversed bool
|
||||
sorted bool
|
||||
key string
|
||||
value string // only for maps: for key, value in map
|
||||
object_evaluator IEvaluator
|
||||
reversed bool
|
||||
|
||||
bodyWrapper *NodeWrapper
|
||||
emptyWrapper *NodeWrapper
|
||||
|
@ -21,7 +24,7 @@ type tagForLoopInformation struct {
|
|||
Parentloop *tagForLoopInformation
|
||||
}
|
||||
|
||||
func (node *tagForNode) Execute(ctx *ExecutionContext, writer TemplateWriter) (forError *Error) {
|
||||
func (node *tagForNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) (forError *Error) {
|
||||
// Backup forloop (as parentloop in public context), key-name and value-name
|
||||
forCtx := NewChildExecutionContext(ctx)
|
||||
parentloop := forCtx.Private["forloop"]
|
||||
|
@ -39,7 +42,7 @@ func (node *tagForNode) Execute(ctx *ExecutionContext, writer TemplateWriter) (f
|
|||
// Register loopInfo in public context
|
||||
forCtx.Private["forloop"] = loopInfo
|
||||
|
||||
obj, err := node.objectEvaluator.Evaluate(forCtx)
|
||||
obj, err := node.object_evaluator.Evaluate(forCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -64,7 +67,7 @@ func (node *tagForNode) Execute(ctx *ExecutionContext, writer TemplateWriter) (f
|
|||
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)
|
||||
err := node.bodyWrapper.Execute(forCtx, buffer)
|
||||
if err != nil {
|
||||
forError = err
|
||||
return false
|
||||
|
@ -73,30 +76,30 @@ func (node *tagForNode) Execute(ctx *ExecutionContext, writer TemplateWriter) (f
|
|||
}, func() {
|
||||
// Nothing to iterate over (maybe wrong type or no items)
|
||||
if node.emptyWrapper != nil {
|
||||
err := node.emptyWrapper.Execute(forCtx, writer)
|
||||
err := node.emptyWrapper.Execute(forCtx, buffer)
|
||||
if err != nil {
|
||||
forError = err
|
||||
}
|
||||
}
|
||||
}, node.reversed, node.sorted)
|
||||
}, node.reversed)
|
||||
|
||||
return forError
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagForParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
forNode := &tagForNode{}
|
||||
for_node := &tagForNode{}
|
||||
|
||||
// Arguments parsing
|
||||
var valueToken *Token
|
||||
keyToken := arguments.MatchType(TokenIdentifier)
|
||||
if keyToken == nil {
|
||||
var value_token *Token
|
||||
key_token := arguments.MatchType(TokenIdentifier)
|
||||
if key_token == 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 {
|
||||
value_token = arguments.MatchType(TokenIdentifier)
|
||||
if value_token == nil {
|
||||
return nil, arguments.Error("Value name must be an identifier.", nil)
|
||||
}
|
||||
}
|
||||
|
@ -105,22 +108,18 @@ func tagForParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Erro
|
|||
return nil, arguments.Error("Expected keyword 'in'.", nil)
|
||||
}
|
||||
|
||||
objectEvaluator, err := arguments.ParseExpression()
|
||||
object_evaluator, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
forNode.objectEvaluator = objectEvaluator
|
||||
forNode.key = keyToken.Val
|
||||
if valueToken != nil {
|
||||
forNode.value = valueToken.Val
|
||||
for_node.object_evaluator = object_evaluator
|
||||
for_node.key = key_token.Val
|
||||
if value_token != nil {
|
||||
for_node.value = value_token.Val
|
||||
}
|
||||
|
||||
if arguments.MatchOne(TokenIdentifier, "reversed") != nil {
|
||||
forNode.reversed = true
|
||||
}
|
||||
|
||||
if arguments.MatchOne(TokenIdentifier, "sorted") != nil {
|
||||
forNode.sorted = true
|
||||
for_node.reversed = true
|
||||
}
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
|
@ -132,7 +131,7 @@ func tagForParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Erro
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
forNode.bodyWrapper = wrapper
|
||||
for_node.bodyWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
|
@ -144,14 +143,14 @@ func tagForParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Erro
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
forNode.emptyWrapper = wrapper
|
||||
for_node.emptyWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return forNode, nil
|
||||
return for_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
39
vendor/github.com/flosch/pongo2/tags_if.go
generated
vendored
39
vendor/github.com/flosch/pongo2/tags_if.go
generated
vendored
|
@ -1,11 +1,15 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagIfNode struct {
|
||||
conditions []IEvaluator
|
||||
wrappers []*NodeWrapper
|
||||
}
|
||||
|
||||
func (node *tagIfNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagIfNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
for i, condition := range node.conditions {
|
||||
result, err := condition.Evaluate(ctx)
|
||||
if err != nil {
|
||||
|
@ -13,25 +17,26 @@ func (node *tagIfNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Er
|
|||
}
|
||||
|
||||
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 node.wrappers[i].Execute(ctx, buffer)
|
||||
} else {
|
||||
// Last condition?
|
||||
if len(node.conditions) == i+1 && len(node.wrappers) > i+1 {
|
||||
return node.wrappers[i+1].Execute(ctx, buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagIfParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
ifNode := &tagIfNode{}
|
||||
if_node := &tagIfNode{}
|
||||
|
||||
// Parse first and main IF condition
|
||||
condition, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifNode.conditions = append(ifNode.conditions, condition)
|
||||
if_node.conditions = append(if_node.conditions, condition)
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
return nil, arguments.Error("If-condition is malformed.", nil)
|
||||
|
@ -39,27 +44,27 @@ func tagIfParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error
|
|||
|
||||
// Check the rest
|
||||
for {
|
||||
wrapper, tagArgs, err := doc.WrapUntilTag("elif", "else", "endif")
|
||||
wrapper, tag_args, err := doc.WrapUntilTag("elif", "else", "endif")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifNode.wrappers = append(ifNode.wrappers, wrapper)
|
||||
if_node.wrappers = append(if_node.wrappers, wrapper)
|
||||
|
||||
if wrapper.Endtag == "elif" {
|
||||
// elif can take a condition
|
||||
condition, err = tagArgs.ParseExpression()
|
||||
condition, err := tag_args.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifNode.conditions = append(ifNode.conditions, condition)
|
||||
if_node.conditions = append(if_node.conditions, condition)
|
||||
|
||||
if tagArgs.Remaining() > 0 {
|
||||
return nil, tagArgs.Error("Elif-condition is malformed.", nil)
|
||||
if tag_args.Remaining() > 0 {
|
||||
return nil, tag_args.Error("Elif-condition is malformed.", nil)
|
||||
}
|
||||
} else {
|
||||
if tagArgs.Count() > 0 {
|
||||
if tag_args.Count() > 0 {
|
||||
// else/endif can't take any conditions
|
||||
return nil, tagArgs.Error("Arguments not allowed here.", nil)
|
||||
return nil, tag_args.Error("Arguments not allowed here.", nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +73,7 @@ func tagIfParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error
|
|||
}
|
||||
}
|
||||
|
||||
return ifNode, nil
|
||||
return if_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
51
vendor/github.com/flosch/pongo2/tags_ifchanged.go
generated
vendored
51
vendor/github.com/flosch/pongo2/tags_ifchanged.go
generated
vendored
|
@ -5,15 +5,16 @@ import (
|
|||
)
|
||||
|
||||
type tagIfchangedNode struct {
|
||||
watchedExpr []IEvaluator
|
||||
lastValues []*Value
|
||||
lastContent []byte
|
||||
thenWrapper *NodeWrapper
|
||||
elseWrapper *NodeWrapper
|
||||
watched_expr []IEvaluator
|
||||
last_values []*Value
|
||||
last_content []byte
|
||||
thenWrapper *NodeWrapper
|
||||
elseWrapper *NodeWrapper
|
||||
}
|
||||
|
||||
func (node *tagIfchangedNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
if len(node.watchedExpr) == 0 {
|
||||
func (node *tagIfchangedNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
|
||||
if len(node.watched_expr) == 0 {
|
||||
// Check against own rendered body
|
||||
|
||||
buf := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB
|
||||
|
@ -22,43 +23,43 @@ func (node *tagIfchangedNode) Execute(ctx *ExecutionContext, writer TemplateWrit
|
|||
return err
|
||||
}
|
||||
|
||||
bufBytes := buf.Bytes()
|
||||
if !bytes.Equal(node.lastContent, bufBytes) {
|
||||
buf_bytes := buf.Bytes()
|
||||
if !bytes.Equal(node.last_content, buf_bytes) {
|
||||
// Rendered content changed, output it
|
||||
writer.Write(bufBytes)
|
||||
node.lastContent = bufBytes
|
||||
buffer.Write(buf_bytes)
|
||||
node.last_content = buf_bytes
|
||||
}
|
||||
} else {
|
||||
nowValues := make([]*Value, 0, len(node.watchedExpr))
|
||||
for _, expr := range node.watchedExpr {
|
||||
now_values := make([]*Value, 0, len(node.watched_expr))
|
||||
for _, expr := range node.watched_expr {
|
||||
val, err := expr.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nowValues = append(nowValues, val)
|
||||
now_values = append(now_values, val)
|
||||
}
|
||||
|
||||
// Compare old to new values now
|
||||
changed := len(node.lastValues) == 0
|
||||
changed := len(node.last_values) == 0
|
||||
|
||||
for idx, oldVal := range node.lastValues {
|
||||
if !oldVal.EqualValueTo(nowValues[idx]) {
|
||||
for idx, old_val := range node.last_values {
|
||||
if !old_val.EqualValueTo(now_values[idx]) {
|
||||
changed = true
|
||||
break // we can stop here because ONE value changed
|
||||
}
|
||||
}
|
||||
|
||||
node.lastValues = nowValues
|
||||
node.last_values = now_values
|
||||
|
||||
if changed {
|
||||
// Render thenWrapper
|
||||
err := node.thenWrapper.Execute(ctx, writer)
|
||||
err := node.thenWrapper.Execute(ctx, buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Render elseWrapper
|
||||
err := node.elseWrapper.Execute(ctx, writer)
|
||||
err := node.elseWrapper.Execute(ctx, buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -69,7 +70,7 @@ func (node *tagIfchangedNode) Execute(ctx *ExecutionContext, writer TemplateWrit
|
|||
}
|
||||
|
||||
func tagIfchangedParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
ifchangedNode := &tagIfchangedNode{}
|
||||
ifchanged_node := &tagIfchangedNode{}
|
||||
|
||||
for arguments.Remaining() > 0 {
|
||||
// Parse condition
|
||||
|
@ -77,7 +78,7 @@ func tagIfchangedParser(doc *Parser, start *Token, arguments *Parser) (INodeTag,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifchangedNode.watchedExpr = append(ifchangedNode.watchedExpr, expr)
|
||||
ifchanged_node.watched_expr = append(ifchanged_node.watched_expr, expr)
|
||||
}
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
|
@ -89,7 +90,7 @@ func tagIfchangedParser(doc *Parser, start *Token, arguments *Parser) (INodeTag,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifchangedNode.thenWrapper = wrapper
|
||||
ifchanged_node.thenWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
|
@ -101,14 +102,14 @@ func tagIfchangedParser(doc *Parser, start *Token, arguments *Parser) (INodeTag,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifchangedNode.elseWrapper = wrapper
|
||||
ifchanged_node.elseWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return ifchangedNode, nil
|
||||
return ifchanged_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
27
vendor/github.com/flosch/pongo2/tags_ifequal.go
generated
vendored
27
vendor/github.com/flosch/pongo2/tags_ifequal.go
generated
vendored
|
@ -1,12 +1,16 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagIfEqualNode struct {
|
||||
var1, var2 IEvaluator
|
||||
thenWrapper *NodeWrapper
|
||||
elseWrapper *NodeWrapper
|
||||
}
|
||||
|
||||
func (node *tagIfEqualNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagIfEqualNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
r1, err := node.var1.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -19,16 +23,17 @@ func (node *tagIfEqualNode) Execute(ctx *ExecutionContext, writer TemplateWriter
|
|||
result := r1.EqualValueTo(r2)
|
||||
|
||||
if result {
|
||||
return node.thenWrapper.Execute(ctx, writer)
|
||||
}
|
||||
if node.elseWrapper != nil {
|
||||
return node.elseWrapper.Execute(ctx, writer)
|
||||
return node.thenWrapper.Execute(ctx, buffer)
|
||||
} else {
|
||||
if node.elseWrapper != nil {
|
||||
return node.elseWrapper.Execute(ctx, buffer)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagIfEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
ifequalNode := &tagIfEqualNode{}
|
||||
ifequal_node := &tagIfEqualNode{}
|
||||
|
||||
// Parse two expressions
|
||||
var1, err := arguments.ParseExpression()
|
||||
|
@ -39,8 +44,8 @@ func tagIfEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifequalNode.var1 = var1
|
||||
ifequalNode.var2 = var2
|
||||
ifequal_node.var1 = var1
|
||||
ifequal_node.var2 = var2
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
return nil, arguments.Error("ifequal only takes 2 arguments.", nil)
|
||||
|
@ -51,7 +56,7 @@ func tagIfEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifequalNode.thenWrapper = wrapper
|
||||
ifequal_node.thenWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
|
@ -63,14 +68,14 @@ func tagIfEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifequalNode.elseWrapper = wrapper
|
||||
ifequal_node.elseWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return ifequalNode, nil
|
||||
return ifequal_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
31
vendor/github.com/flosch/pongo2/tags_ifnotequal.go
generated
vendored
31
vendor/github.com/flosch/pongo2/tags_ifnotequal.go
generated
vendored
|
@ -1,12 +1,16 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagIfNotEqualNode struct {
|
||||
var1, var2 IEvaluator
|
||||
thenWrapper *NodeWrapper
|
||||
elseWrapper *NodeWrapper
|
||||
}
|
||||
|
||||
func (node *tagIfNotEqualNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagIfNotEqualNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
r1, err := node.var1.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -19,16 +23,17 @@ func (node *tagIfNotEqualNode) Execute(ctx *ExecutionContext, writer TemplateWri
|
|||
result := !r1.EqualValueTo(r2)
|
||||
|
||||
if result {
|
||||
return node.thenWrapper.Execute(ctx, writer)
|
||||
}
|
||||
if node.elseWrapper != nil {
|
||||
return node.elseWrapper.Execute(ctx, writer)
|
||||
return node.thenWrapper.Execute(ctx, buffer)
|
||||
} else {
|
||||
if node.elseWrapper != nil {
|
||||
return node.elseWrapper.Execute(ctx, buffer)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagIfNotEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
ifnotequalNode := &tagIfNotEqualNode{}
|
||||
ifnotequal_node := &tagIfNotEqualNode{}
|
||||
|
||||
// Parse two expressions
|
||||
var1, err := arguments.ParseExpression()
|
||||
|
@ -39,19 +44,19 @@ func tagIfNotEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifnotequalNode.var1 = var1
|
||||
ifnotequalNode.var2 = var2
|
||||
ifnotequal_node.var1 = var1
|
||||
ifnotequal_node.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")
|
||||
wrapper, endargs, err := doc.WrapUntilTag("else", "endifequal")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifnotequalNode.thenWrapper = wrapper
|
||||
ifnotequal_node.thenWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
|
@ -59,18 +64,18 @@ func tagIfNotEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag
|
|||
|
||||
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")
|
||||
wrapper, endargs, err = doc.WrapUntilTag("endifequal")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifnotequalNode.elseWrapper = wrapper
|
||||
ifnotequal_node.elseWrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return ifnotequalNode, nil
|
||||
return ifnotequal_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
36
vendor/github.com/flosch/pongo2/tags_import.go
generated
vendored
36
vendor/github.com/flosch/pongo2/tags_import.go
generated
vendored
|
@ -1,16 +1,18 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type tagImportNode struct {
|
||||
position *Token
|
||||
filename string
|
||||
template *Template
|
||||
macros map[string]*tagMacroNode // alias/name -> macro instance
|
||||
}
|
||||
|
||||
func (node *tagImportNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagImportNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
for name, macro := range node.macros {
|
||||
func(name string, macro *tagMacroNode) {
|
||||
ctx.Private[name] = func(args ...*Value) *Value {
|
||||
|
@ -22,50 +24,50 @@ func (node *tagImportNode) Execute(ctx *ExecutionContext, writer TemplateWriter)
|
|||
}
|
||||
|
||||
func tagImportParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
importNode := &tagImportNode{
|
||||
import_node := &tagImportNode{
|
||||
position: start,
|
||||
macros: make(map[string]*tagMacroNode),
|
||||
}
|
||||
|
||||
filenameToken := arguments.MatchType(TokenString)
|
||||
if filenameToken == nil {
|
||||
filename_token := arguments.MatchType(TokenString)
|
||||
if filename_token == nil {
|
||||
return nil, arguments.Error("Import-tag needs a filename as string.", nil)
|
||||
}
|
||||
|
||||
importNode.filename = doc.template.set.resolveFilename(doc.template, filenameToken.Val)
|
||||
import_node.filename = doc.template.set.resolveFilename(doc.template, filename_token.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)
|
||||
tpl, err := doc.template.set.FromFile(import_node.filename)
|
||||
if err != nil {
|
||||
return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, start)
|
||||
}
|
||||
|
||||
for arguments.Remaining() > 0 {
|
||||
macroNameToken := arguments.MatchType(TokenIdentifier)
|
||||
if macroNameToken == nil {
|
||||
macro_name_token := arguments.MatchType(TokenIdentifier)
|
||||
if macro_name_token == nil {
|
||||
return nil, arguments.Error("Expected macro name (identifier).", nil)
|
||||
}
|
||||
|
||||
asName := macroNameToken.Val
|
||||
as_name := macro_name_token.Val
|
||||
if arguments.Match(TokenKeyword, "as") != nil {
|
||||
aliasToken := arguments.MatchType(TokenIdentifier)
|
||||
if aliasToken == nil {
|
||||
alias_token := arguments.MatchType(TokenIdentifier)
|
||||
if alias_token == nil {
|
||||
return nil, arguments.Error("Expected macro alias name (identifier).", nil)
|
||||
}
|
||||
asName = aliasToken.Val
|
||||
as_name = alias_token.Val
|
||||
}
|
||||
|
||||
macroInstance, has := tpl.exportedMacros[macroNameToken.Val]
|
||||
macro_instance, has := tpl.exported_macros[macro_name_token.Val]
|
||||
if !has {
|
||||
return nil, arguments.Error(fmt.Sprintf("Macro '%s' not found (or not exported) in '%s'.", macroNameToken.Val,
|
||||
importNode.filename), macroNameToken)
|
||||
return nil, arguments.Error(fmt.Sprintf("Macro '%s' not found (or not exported) in '%s'.", macro_name_token.Val,
|
||||
import_node.filename), macro_name_token)
|
||||
}
|
||||
|
||||
importNode.macros[asName] = macroInstance
|
||||
import_node.macros[as_name] = macro_instance
|
||||
|
||||
if arguments.Remaining() == 0 {
|
||||
break
|
||||
|
@ -76,7 +78,7 @@ func tagImportParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *E
|
|||
}
|
||||
}
|
||||
|
||||
return importNode, nil
|
||||
return import_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
106
vendor/github.com/flosch/pongo2/tags_include.go
generated
vendored
106
vendor/github.com/flosch/pongo2/tags_include.go
generated
vendored
|
@ -1,38 +1,41 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagIncludeNode struct {
|
||||
tpl *Template
|
||||
filenameEvaluator IEvaluator
|
||||
lazy bool
|
||||
only bool
|
||||
filename string
|
||||
withPairs map[string]IEvaluator
|
||||
ifExists bool
|
||||
tpl *Template
|
||||
filename_evaluator IEvaluator
|
||||
lazy bool
|
||||
only bool
|
||||
filename string
|
||||
with_pairs map[string]IEvaluator
|
||||
}
|
||||
|
||||
func (node *tagIncludeNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagIncludeNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
// Building the context for the template
|
||||
includeCtx := make(Context)
|
||||
include_ctx := make(Context)
|
||||
|
||||
// Fill the context with all data from the parent
|
||||
if !node.only {
|
||||
includeCtx.Update(ctx.Public)
|
||||
includeCtx.Update(ctx.Private)
|
||||
include_ctx.Update(ctx.Public)
|
||||
include_ctx.Update(ctx.Private)
|
||||
}
|
||||
|
||||
// Put all custom with-pairs into the context
|
||||
for key, value := range node.withPairs {
|
||||
for key, value := range node.with_pairs {
|
||||
val, err := value.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
includeCtx[key] = val
|
||||
include_ctx[key] = val
|
||||
}
|
||||
|
||||
// Execute the template
|
||||
if node.lazy {
|
||||
// Evaluate the filename
|
||||
filename, err := node.filenameEvaluator.Evaluate(ctx)
|
||||
filename, err := node.filename_evaluator.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -42,93 +45,76 @@ func (node *tagIncludeNode) Execute(ctx *ExecutionContext, writer TemplateWriter
|
|||
}
|
||||
|
||||
// Get include-filename
|
||||
includedFilename := ctx.template.set.resolveFilename(ctx.template, filename.String())
|
||||
included_filename := ctx.template.set.resolveFilename(ctx.template, filename.String())
|
||||
|
||||
includedTpl, err2 := ctx.template.set.FromFile(includedFilename)
|
||||
included_tpl, err2 := ctx.template.set.FromFile(included_filename)
|
||||
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)
|
||||
err2 = included_tpl.ExecuteWriter(include_ctx, buffer)
|
||||
if err2 != nil {
|
||||
return err2.(*Error)
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
// Template is already parsed with static filename
|
||||
err := node.tpl.ExecuteWriter(include_ctx, buffer)
|
||||
if err != nil {
|
||||
return err.(*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),
|
||||
include_node := &tagIncludeNode{
|
||||
with_pairs: make(map[string]IEvaluator),
|
||||
}
|
||||
|
||||
if filenameToken := arguments.MatchType(TokenString); filenameToken != nil {
|
||||
if filename_token := arguments.MatchType(TokenString); filename_token != 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)
|
||||
included_filename := doc.template.set.resolveFilename(doc.template, filename_token.Val)
|
||||
|
||||
// Parse the parent
|
||||
includeNode.filename = includedFilename
|
||||
includedTpl, err := doc.template.set.FromFile(includedFilename)
|
||||
include_node.filename = included_filename
|
||||
included_tpl, err := doc.template.set.FromFile(included_filename)
|
||||
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)
|
||||
return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, filename_token)
|
||||
}
|
||||
includeNode.tpl = includedTpl
|
||||
include_node.tpl = included_tpl
|
||||
} else {
|
||||
// No String, then the user wants to use lazy-evaluation (slower, but possible)
|
||||
filenameEvaluator, err := arguments.ParseExpression()
|
||||
filename_evaluator, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err.updateFromTokenIfNeeded(doc.template, filenameToken)
|
||||
return nil, err.updateFromTokenIfNeeded(doc.template, filename_token)
|
||||
}
|
||||
includeNode.filenameEvaluator = filenameEvaluator
|
||||
includeNode.lazy = true
|
||||
includeNode.ifExists = arguments.Match(TokenIdentifier, "if_exists") != nil // "if_exists" flag
|
||||
include_node.filename_evaluator = filename_evaluator
|
||||
include_node.lazy = true
|
||||
}
|
||||
|
||||
// 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 {
|
||||
key_token := arguments.MatchType(TokenIdentifier)
|
||||
if key_token == nil {
|
||||
return nil, arguments.Error("Expected an identifier", nil)
|
||||
}
|
||||
if arguments.Match(TokenSymbol, "=") == nil {
|
||||
return nil, arguments.Error("Expected '='.", nil)
|
||||
}
|
||||
valueExpr, err := arguments.ParseExpression()
|
||||
value_expr, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err.updateFromTokenIfNeeded(doc.template, keyToken)
|
||||
return nil, err.updateFromTokenIfNeeded(doc.template, key_token)
|
||||
}
|
||||
|
||||
includeNode.withPairs[keyToken.Val] = valueExpr
|
||||
include_node.with_pairs[key_token.Val] = value_expr
|
||||
|
||||
// Only?
|
||||
if arguments.Match(TokenIdentifier, "only") != nil {
|
||||
includeNode.only = true
|
||||
include_node.only = true
|
||||
break // stop parsing arguments because it's the last option
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +124,7 @@ func tagIncludeParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *
|
|||
return nil, arguments.Error("Malformed 'include'-tag arguments.", nil)
|
||||
}
|
||||
|
||||
return includeNode, nil
|
||||
return include_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
55
vendor/github.com/flosch/pongo2/tags_lorem.go
generated
vendored
55
vendor/github.com/flosch/pongo2/tags_lorem.go
generated
vendored
|
@ -1,11 +1,10 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -20,102 +19,102 @@ type tagLoremNode struct {
|
|||
random bool // does not use the default paragraph "Lorem ipsum dolor sit amet, ..."
|
||||
}
|
||||
|
||||
func (node *tagLoremNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagLoremNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
switch node.method {
|
||||
case "b":
|
||||
if node.random {
|
||||
for i := 0; i < node.count; i++ {
|
||||
if i > 0 {
|
||||
writer.WriteString("\n")
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
par := tagLoremParagraphs[rand.Intn(len(tagLoremParagraphs))]
|
||||
writer.WriteString(par)
|
||||
buffer.WriteString(par)
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < node.count; i++ {
|
||||
if i > 0 {
|
||||
writer.WriteString("\n")
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
par := tagLoremParagraphs[i%len(tagLoremParagraphs)]
|
||||
writer.WriteString(par)
|
||||
buffer.WriteString(par)
|
||||
}
|
||||
}
|
||||
case "w":
|
||||
if node.random {
|
||||
for i := 0; i < node.count; i++ {
|
||||
if i > 0 {
|
||||
writer.WriteString(" ")
|
||||
buffer.WriteString(" ")
|
||||
}
|
||||
word := tagLoremWords[rand.Intn(len(tagLoremWords))]
|
||||
writer.WriteString(word)
|
||||
buffer.WriteString(word)
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < node.count; i++ {
|
||||
if i > 0 {
|
||||
writer.WriteString(" ")
|
||||
buffer.WriteString(" ")
|
||||
}
|
||||
word := tagLoremWords[i%len(tagLoremWords)]
|
||||
writer.WriteString(word)
|
||||
buffer.WriteString(word)
|
||||
}
|
||||
}
|
||||
case "p":
|
||||
if node.random {
|
||||
for i := 0; i < node.count; i++ {
|
||||
if i > 0 {
|
||||
writer.WriteString("\n")
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
writer.WriteString("<p>")
|
||||
buffer.WriteString("<p>")
|
||||
par := tagLoremParagraphs[rand.Intn(len(tagLoremParagraphs))]
|
||||
writer.WriteString(par)
|
||||
writer.WriteString("</p>")
|
||||
buffer.WriteString(par)
|
||||
buffer.WriteString("</p>")
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < node.count; i++ {
|
||||
if i > 0 {
|
||||
writer.WriteString("\n")
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
writer.WriteString("<p>")
|
||||
buffer.WriteString("<p>")
|
||||
par := tagLoremParagraphs[i%len(tagLoremParagraphs)]
|
||||
writer.WriteString(par)
|
||||
writer.WriteString("</p>")
|
||||
buffer.WriteString(par)
|
||||
buffer.WriteString("</p>")
|
||||
|
||||
}
|
||||
}
|
||||
default:
|
||||
return ctx.OrigError(errors.Errorf("unsupported method: %s", node.method), nil)
|
||||
panic("unsupported method")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagLoremParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
loremNode := &tagLoremNode{
|
||||
lorem_node := &tagLoremNode{
|
||||
position: start,
|
||||
count: 1,
|
||||
method: "b",
|
||||
}
|
||||
|
||||
if countToken := arguments.MatchType(TokenNumber); countToken != nil {
|
||||
loremNode.count = AsValue(countToken.Val).Integer()
|
||||
if count_token := arguments.MatchType(TokenNumber); count_token != nil {
|
||||
lorem_node.count = AsValue(count_token.Val).Integer()
|
||||
}
|
||||
|
||||
if methodToken := arguments.MatchType(TokenIdentifier); methodToken != nil {
|
||||
if methodToken.Val != "w" && methodToken.Val != "p" && methodToken.Val != "b" {
|
||||
if method_token := arguments.MatchType(TokenIdentifier); method_token != nil {
|
||||
if method_token.Val != "w" && method_token.Val != "p" && method_token.Val != "b" {
|
||||
return nil, arguments.Error("lorem-method must be either 'w', 'p' or 'b'.", nil)
|
||||
}
|
||||
|
||||
loremNode.method = methodToken.Val
|
||||
lorem_node.method = method_token.Val
|
||||
}
|
||||
|
||||
if arguments.MatchOne(TokenIdentifier, "random") != nil {
|
||||
loremNode.random = true
|
||||
lorem_node.random = true
|
||||
}
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
return nil, arguments.Error("Malformed lorem-tag arguments.", nil)
|
||||
}
|
||||
|
||||
return loremNode, nil
|
||||
return lorem_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
64
vendor/github.com/flosch/pongo2/tags_macro.go
generated
vendored
64
vendor/github.com/flosch/pongo2/tags_macro.go
generated
vendored
|
@ -6,16 +6,16 @@ import (
|
|||
)
|
||||
|
||||
type tagMacroNode struct {
|
||||
position *Token
|
||||
name string
|
||||
argsOrder []string
|
||||
args map[string]IEvaluator
|
||||
exported bool
|
||||
position *Token
|
||||
name string
|
||||
args_order []string
|
||||
args map[string]IEvaluator
|
||||
exported bool
|
||||
|
||||
wrapper *NodeWrapper
|
||||
}
|
||||
|
||||
func (node *tagMacroNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagMacroNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
ctx.Private[node.name] = func(args ...*Value) *Value {
|
||||
return node.call(ctx, args...)
|
||||
}
|
||||
|
@ -24,28 +24,28 @@ func (node *tagMacroNode) Execute(ctx *ExecutionContext, writer TemplateWriter)
|
|||
}
|
||||
|
||||
func (node *tagMacroNode) call(ctx *ExecutionContext, args ...*Value) *Value {
|
||||
argsCtx := make(Context)
|
||||
args_ctx := make(Context)
|
||||
|
||||
for k, v := range node.args {
|
||||
if v == nil {
|
||||
// User did not provided a default value
|
||||
argsCtx[k] = nil
|
||||
args_ctx[k] = nil
|
||||
} else {
|
||||
// Evaluate the default value
|
||||
valueExpr, err := v.Evaluate(ctx)
|
||||
value_expr, err := v.Evaluate(ctx)
|
||||
if err != nil {
|
||||
ctx.Logf(err.Error())
|
||||
return AsSafeValue(err.Error())
|
||||
}
|
||||
|
||||
argsCtx[k] = valueExpr
|
||||
args_ctx[k] = value_expr
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) > len(node.argsOrder) {
|
||||
if len(args) > len(node.args_order) {
|
||||
// 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)
|
||||
node.name, len(args), len(node.args_order)), 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())
|
||||
|
@ -55,10 +55,10 @@ func (node *tagMacroNode) call(ctx *ExecutionContext, args ...*Value) *Value {
|
|||
macroCtx := NewChildExecutionContext(ctx)
|
||||
|
||||
// Register all arguments in the private context
|
||||
macroCtx.Private.Update(argsCtx)
|
||||
macroCtx.Private.Update(args_ctx)
|
||||
|
||||
for idx, argValue := range args {
|
||||
macroCtx.Private[node.argsOrder[idx]] = argValue.Interface()
|
||||
for idx, arg_value := range args {
|
||||
macroCtx.Private[node.args_order[idx]] = arg_value.Interface()
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
|
@ -71,38 +71,38 @@ func (node *tagMacroNode) call(ctx *ExecutionContext, args ...*Value) *Value {
|
|||
}
|
||||
|
||||
func tagMacroParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
macroNode := &tagMacroNode{
|
||||
macro_node := &tagMacroNode{
|
||||
position: start,
|
||||
args: make(map[string]IEvaluator),
|
||||
}
|
||||
|
||||
nameToken := arguments.MatchType(TokenIdentifier)
|
||||
if nameToken == nil {
|
||||
name_token := arguments.MatchType(TokenIdentifier)
|
||||
if name_token == nil {
|
||||
return nil, arguments.Error("Macro-tag needs at least an identifier as name.", nil)
|
||||
}
|
||||
macroNode.name = nameToken.Val
|
||||
macro_node.name = name_token.Val
|
||||
|
||||
if arguments.MatchOne(TokenSymbol, "(") == nil {
|
||||
return nil, arguments.Error("Expected '('.", nil)
|
||||
}
|
||||
|
||||
for arguments.Match(TokenSymbol, ")") == nil {
|
||||
argNameToken := arguments.MatchType(TokenIdentifier)
|
||||
if argNameToken == nil {
|
||||
arg_name_token := arguments.MatchType(TokenIdentifier)
|
||||
if arg_name_token == nil {
|
||||
return nil, arguments.Error("Expected argument name as identifier.", nil)
|
||||
}
|
||||
macroNode.argsOrder = append(macroNode.argsOrder, argNameToken.Val)
|
||||
macro_node.args_order = append(macro_node.args_order, arg_name_token.Val)
|
||||
|
||||
if arguments.Match(TokenSymbol, "=") != nil {
|
||||
// Default expression follows
|
||||
argDefaultExpr, err := arguments.ParseExpression()
|
||||
arg_default_expr, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
macroNode.args[argNameToken.Val] = argDefaultExpr
|
||||
macro_node.args[arg_name_token.Val] = arg_default_expr
|
||||
} else {
|
||||
// No default expression
|
||||
macroNode.args[argNameToken.Val] = nil
|
||||
macro_node.args[arg_name_token.Val] = nil
|
||||
}
|
||||
|
||||
if arguments.Match(TokenSymbol, ")") != nil {
|
||||
|
@ -114,7 +114,7 @@ func tagMacroParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Er
|
|||
}
|
||||
|
||||
if arguments.Match(TokenKeyword, "export") != nil {
|
||||
macroNode.exported = true
|
||||
macro_node.exported = true
|
||||
}
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
|
@ -126,22 +126,22 @@ func tagMacroParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Er
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
macroNode.wrapper = wrapper
|
||||
macro_node.wrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
}
|
||||
|
||||
if macroNode.exported {
|
||||
if macro_node.exported {
|
||||
// Now register the macro if it wants to be exported
|
||||
_, has := doc.template.exportedMacros[macroNode.name]
|
||||
_, has := doc.template.exported_macros[macro_node.name]
|
||||
if has {
|
||||
return nil, doc.Error(fmt.Sprintf("another macro with name '%s' already exported", macroNode.name), start)
|
||||
return nil, doc.Error(fmt.Sprintf("Another macro with name '%s' already exported.", macro_node.name), start)
|
||||
}
|
||||
doc.template.exportedMacros[macroNode.name] = macroNode
|
||||
doc.template.exported_macros[macro_node.name] = macro_node
|
||||
}
|
||||
|
||||
return macroNode, nil
|
||||
return macro_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
17
vendor/github.com/flosch/pongo2/tags_now.go
generated
vendored
17
vendor/github.com/flosch/pongo2/tags_now.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -10,7 +11,7 @@ type tagNowNode struct {
|
|||
fake bool
|
||||
}
|
||||
|
||||
func (node *tagNowNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagNowNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
var t time.Time
|
||||
if node.fake {
|
||||
t = time.Date(2014, time.February, 05, 18, 31, 45, 00, time.UTC)
|
||||
|
@ -18,31 +19,31 @@ func (node *tagNowNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *E
|
|||
t = time.Now()
|
||||
}
|
||||
|
||||
writer.WriteString(t.Format(node.format))
|
||||
buffer.WriteString(t.Format(node.format))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagNowParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
nowNode := &tagNowNode{
|
||||
now_node := &tagNowNode{
|
||||
position: start,
|
||||
}
|
||||
|
||||
formatToken := arguments.MatchType(TokenString)
|
||||
if formatToken == nil {
|
||||
format_token := arguments.MatchType(TokenString)
|
||||
if format_token == nil {
|
||||
return nil, arguments.Error("Expected a format string.", nil)
|
||||
}
|
||||
nowNode.format = formatToken.Val
|
||||
now_node.format = format_token.Val
|
||||
|
||||
if arguments.MatchOne(TokenIdentifier, "fake") != nil {
|
||||
nowNode.fake = true
|
||||
now_node.fake = true
|
||||
}
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
return nil, arguments.Error("Malformed now-tag arguments.", nil)
|
||||
}
|
||||
|
||||
return nowNode, nil
|
||||
return now_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
4
vendor/github.com/flosch/pongo2/tags_set.go
generated
vendored
4
vendor/github.com/flosch/pongo2/tags_set.go
generated
vendored
|
@ -1,11 +1,13 @@
|
|||
package pongo2
|
||||
|
||||
import "bytes"
|
||||
|
||||
type tagSetNode struct {
|
||||
name string
|
||||
expression IEvaluator
|
||||
}
|
||||
|
||||
func (node *tagSetNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagSetNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
// Evaluate expression
|
||||
value, err := node.expression.Evaluate(ctx)
|
||||
if err != nil {
|
||||
|
|
10
vendor/github.com/flosch/pongo2/tags_spaceless.go
generated
vendored
10
vendor/github.com/flosch/pongo2/tags_spaceless.go
generated
vendored
|
@ -11,7 +11,7 @@ type tagSpacelessNode struct {
|
|||
|
||||
var tagSpacelessRegexp = regexp.MustCompile(`(?U:(<.*>))([\t\n\v\f\r ]+)(?U:(<.*>))`)
|
||||
|
||||
func (node *tagSpacelessNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagSpacelessNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
b := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB
|
||||
|
||||
err := node.wrapper.Execute(ctx, b)
|
||||
|
@ -28,25 +28,25 @@ func (node *tagSpacelessNode) Execute(ctx *ExecutionContext, writer TemplateWrit
|
|||
s = s2
|
||||
}
|
||||
|
||||
writer.WriteString(s)
|
||||
buffer.WriteString(s)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagSpacelessParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
spacelessNode := &tagSpacelessNode{}
|
||||
spaceless_node := &tagSpacelessNode{}
|
||||
|
||||
wrapper, _, err := doc.WrapUntilTag("endspaceless")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
spacelessNode.wrapper = wrapper
|
||||
spaceless_node.wrapper = wrapper
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
return nil, arguments.Error("Malformed spaceless-tag arguments.", nil)
|
||||
}
|
||||
|
||||
return spacelessNode, nil
|
||||
return spaceless_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
31
vendor/github.com/flosch/pongo2/tags_ssi.go
generated
vendored
31
vendor/github.com/flosch/pongo2/tags_ssi.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
|
@ -10,47 +11,47 @@ type tagSSINode struct {
|
|||
template *Template
|
||||
}
|
||||
|
||||
func (node *tagSSINode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagSSINode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *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)
|
||||
err := node.template.ExecuteWriter(includeCtx, buffer)
|
||||
if err != nil {
|
||||
return err.(*Error)
|
||||
}
|
||||
} else {
|
||||
// Just print out the content
|
||||
writer.WriteString(node.content)
|
||||
buffer.WriteString(node.content)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagSSIParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
SSINode := &tagSSINode{}
|
||||
ssi_node := &tagSSINode{}
|
||||
|
||||
if fileToken := arguments.MatchType(TokenString); fileToken != nil {
|
||||
SSINode.filename = fileToken.Val
|
||||
if file_token := arguments.MatchType(TokenString); file_token != nil {
|
||||
ssi_node.filename = file_token.Val
|
||||
|
||||
if arguments.Match(TokenIdentifier, "parsed") != nil {
|
||||
// parsed
|
||||
temporaryTpl, err := doc.template.set.FromFile(doc.template.set.resolveFilename(doc.template, fileToken.Val))
|
||||
temporary_tpl, err := doc.template.set.FromFile(doc.template.set.resolveFilename(doc.template, file_token.Val))
|
||||
if err != nil {
|
||||
return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, fileToken)
|
||||
return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, file_token)
|
||||
}
|
||||
SSINode.template = temporaryTpl
|
||||
ssi_node.template = temporary_tpl
|
||||
} else {
|
||||
// plaintext
|
||||
buf, err := ioutil.ReadFile(doc.template.set.resolveFilename(doc.template, fileToken.Val))
|
||||
buf, err := ioutil.ReadFile(doc.template.set.resolveFilename(doc.template, file_token.Val))
|
||||
if err != nil {
|
||||
return nil, (&Error{
|
||||
Sender: "tag:ssi",
|
||||
OrigError: err,
|
||||
}).updateFromTokenIfNeeded(doc.template, fileToken)
|
||||
Sender: "tag:ssi",
|
||||
ErrorMsg: err.Error(),
|
||||
}).updateFromTokenIfNeeded(doc.template, file_token)
|
||||
}
|
||||
SSINode.content = string(buf)
|
||||
ssi_node.content = string(buf)
|
||||
}
|
||||
} else {
|
||||
return nil, arguments.Error("First argument must be a string.", nil)
|
||||
|
@ -60,7 +61,7 @@ func tagSSIParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Erro
|
|||
return nil, arguments.Error("Malformed SSI-tag argument.", nil)
|
||||
}
|
||||
|
||||
return SSINode, nil
|
||||
return ssi_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
20
vendor/github.com/flosch/pongo2/tags_templatetag.go
generated
vendored
20
vendor/github.com/flosch/pongo2/tags_templatetag.go
generated
vendored
|
@ -1,5 +1,9 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagTemplateTagNode struct {
|
||||
content string
|
||||
}
|
||||
|
@ -15,20 +19,20 @@ var templateTagMapping = map[string]string{
|
|||
"closecomment": "#}",
|
||||
}
|
||||
|
||||
func (node *tagTemplateTagNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
writer.WriteString(node.content)
|
||||
func (node *tagTemplateTagNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
buffer.WriteString(node.content)
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagTemplateTagParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
ttNode := &tagTemplateTagNode{}
|
||||
tt_node := &tagTemplateTagNode{}
|
||||
|
||||
if argToken := arguments.MatchType(TokenIdentifier); argToken != nil {
|
||||
output, found := templateTagMapping[argToken.Val]
|
||||
if arg_token := arguments.MatchType(TokenIdentifier); arg_token != nil {
|
||||
output, found := templateTagMapping[arg_token.Val]
|
||||
if !found {
|
||||
return nil, arguments.Error("Argument not found", argToken)
|
||||
return nil, arguments.Error("Argument not found", arg_token)
|
||||
}
|
||||
ttNode.content = output
|
||||
tt_node.content = output
|
||||
} else {
|
||||
return nil, arguments.Error("Identifier expected.", nil)
|
||||
}
|
||||
|
@ -37,7 +41,7 @@ func tagTemplateTagParser(doc *Parser, start *Token, arguments *Parser) (INodeTa
|
|||
return nil, arguments.Error("Malformed templatetag-tag argument.", nil)
|
||||
}
|
||||
|
||||
return ttNode, nil
|
||||
return tt_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
27
vendor/github.com/flosch/pongo2/tags_widthratio.go
generated
vendored
27
vendor/github.com/flosch/pongo2/tags_widthratio.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
@ -9,10 +10,10 @@ type tagWidthratioNode struct {
|
|||
position *Token
|
||||
current, max IEvaluator
|
||||
width IEvaluator
|
||||
ctxName string
|
||||
ctx_name string
|
||||
}
|
||||
|
||||
func (node *tagWidthratioNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagWidthratioNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
current, err := node.current.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -30,17 +31,17 @@ func (node *tagWidthratioNode) Execute(ctx *ExecutionContext, writer TemplateWri
|
|||
|
||||
value := int(math.Ceil(current.Float()/max.Float()*width.Float() + 0.5))
|
||||
|
||||
if node.ctxName == "" {
|
||||
writer.WriteString(fmt.Sprintf("%d", value))
|
||||
if node.ctx_name == "" {
|
||||
buffer.WriteString(fmt.Sprintf("%d", value))
|
||||
} else {
|
||||
ctx.Private[node.ctxName] = value
|
||||
ctx.Private[node.ctx_name] = value
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagWidthratioParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
widthratioNode := &tagWidthratioNode{
|
||||
widthratio_node := &tagWidthratioNode{
|
||||
position: start,
|
||||
}
|
||||
|
||||
|
@ -48,34 +49,34 @@ func tagWidthratioParser(doc *Parser, start *Token, arguments *Parser) (INodeTag
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
widthratioNode.current = current
|
||||
widthratio_node.current = current
|
||||
|
||||
max, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
widthratioNode.max = max
|
||||
widthratio_node.max = max
|
||||
|
||||
width, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
widthratioNode.width = width
|
||||
widthratio_node.width = width
|
||||
|
||||
if arguments.MatchOne(TokenKeyword, "as") != nil {
|
||||
// Name follows
|
||||
nameToken := arguments.MatchType(TokenIdentifier)
|
||||
if nameToken == nil {
|
||||
name_token := arguments.MatchType(TokenIdentifier)
|
||||
if name_token == nil {
|
||||
return nil, arguments.Error("Expected name (identifier).", nil)
|
||||
}
|
||||
widthratioNode.ctxName = nameToken.Val
|
||||
widthratio_node.ctx_name = name_token.Val
|
||||
}
|
||||
|
||||
if arguments.Remaining() > 0 {
|
||||
return nil, arguments.Error("Malformed widthratio-tag arguments.", nil)
|
||||
}
|
||||
|
||||
return widthratioNode, nil
|
||||
return widthratio_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
44
vendor/github.com/flosch/pongo2/tags_with.go
generated
vendored
44
vendor/github.com/flosch/pongo2/tags_with.go
generated
vendored
|
@ -1,16 +1,20 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type tagWithNode struct {
|
||||
withPairs map[string]IEvaluator
|
||||
wrapper *NodeWrapper
|
||||
with_pairs map[string]IEvaluator
|
||||
wrapper *NodeWrapper
|
||||
}
|
||||
|
||||
func (node *tagWithNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error {
|
||||
func (node *tagWithNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
|
||||
//new context for block
|
||||
withctx := NewChildExecutionContext(ctx)
|
||||
|
||||
// Put all custom with-pairs into the context
|
||||
for key, value := range node.withPairs {
|
||||
for key, value := range node.with_pairs {
|
||||
val, err := value.Evaluate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -18,12 +22,12 @@ func (node *tagWithNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *
|
|||
withctx.Private[key] = val
|
||||
}
|
||||
|
||||
return node.wrapper.Execute(withctx, writer)
|
||||
return node.wrapper.Execute(withctx, buffer)
|
||||
}
|
||||
|
||||
func tagWithParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
|
||||
withNode := &tagWithNode{
|
||||
withPairs: make(map[string]IEvaluator),
|
||||
with_node := &tagWithNode{
|
||||
with_pairs: make(map[string]IEvaluator),
|
||||
}
|
||||
|
||||
if arguments.Count() == 0 {
|
||||
|
@ -34,7 +38,7 @@ func tagWithParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Err
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
withNode.wrapper = wrapper
|
||||
with_node.wrapper = wrapper
|
||||
|
||||
if endargs.Count() > 0 {
|
||||
return nil, endargs.Error("Arguments not allowed here.", nil)
|
||||
|
@ -42,45 +46,45 @@ func tagWithParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Err
|
|||
|
||||
// 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
|
||||
old_style := 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
|
||||
old_style = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for arguments.Remaining() > 0 {
|
||||
if oldStyle {
|
||||
valueExpr, err := arguments.ParseExpression()
|
||||
if old_style {
|
||||
value_expr, 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 {
|
||||
key_token := arguments.MatchType(TokenIdentifier)
|
||||
if key_token == nil {
|
||||
return nil, arguments.Error("Expected an identifier", nil)
|
||||
}
|
||||
withNode.withPairs[keyToken.Val] = valueExpr
|
||||
with_node.with_pairs[key_token.Val] = value_expr
|
||||
} else {
|
||||
keyToken := arguments.MatchType(TokenIdentifier)
|
||||
if keyToken == nil {
|
||||
key_token := arguments.MatchType(TokenIdentifier)
|
||||
if key_token == nil {
|
||||
return nil, arguments.Error("Expected an identifier", nil)
|
||||
}
|
||||
if arguments.Match(TokenSymbol, "=") == nil {
|
||||
return nil, arguments.Error("Expected '='.", nil)
|
||||
}
|
||||
valueExpr, err := arguments.ParseExpression()
|
||||
value_expr, err := arguments.ParseExpression()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
withNode.withPairs[keyToken.Val] = valueExpr
|
||||
with_node.with_pairs[key_token.Val] = value_expr
|
||||
}
|
||||
}
|
||||
|
||||
return withNode, nil
|
||||
return with_node, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
128
vendor/github.com/flosch/pongo2/template.go
generated
vendored
128
vendor/github.com/flosch/pongo2/template.go
generated
vendored
|
@ -2,72 +2,52 @@ package pongo2
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
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
|
||||
is_tpl_string 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
|
||||
level int
|
||||
parent *Template
|
||||
child *Template
|
||||
blocks map[string]*NodeWrapper
|
||||
exported_macros map[string]*tagMacroNode
|
||||
|
||||
// Output
|
||||
root *nodeDocument
|
||||
}
|
||||
|
||||
func newTemplateString(set *TemplateSet, tpl []byte) (*Template, error) {
|
||||
func newTemplateString(set *TemplateSet, tpl string) (*Template, error) {
|
||||
return newTemplate(set, "<string>", true, tpl)
|
||||
}
|
||||
|
||||
func newTemplate(set *TemplateSet, name string, isTplString bool, tpl []byte) (*Template, error) {
|
||||
strTpl := string(tpl)
|
||||
|
||||
func newTemplate(set *TemplateSet, name string, is_tpl_string bool, tpl string) (*Template, error) {
|
||||
// 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),
|
||||
set: set,
|
||||
is_tpl_string: is_tpl_string,
|
||||
name: name,
|
||||
tpl: tpl,
|
||||
size: len(tpl),
|
||||
blocks: make(map[string]*NodeWrapper),
|
||||
exported_macros: make(map[string]*tagMacroNode),
|
||||
}
|
||||
|
||||
// Tokenize it
|
||||
tokens, err := lex(name, strTpl)
|
||||
tokens, err := lex(name, tpl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -87,7 +67,11 @@ func newTemplate(set *TemplateSet, name string, isTplString bool, tpl []byte) (*
|
|||
return t, nil
|
||||
}
|
||||
|
||||
func (tpl *Template) execute(context Context, writer TemplateWriter) error {
|
||||
func (tpl *Template) execute(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)))
|
||||
|
||||
// Determine the parent to be executed (for template inheritance)
|
||||
parent := tpl
|
||||
for parent.parent != nil {
|
||||
|
@ -105,17 +89,17 @@ func (tpl *Template) execute(context Context, writer TemplateWriter) error {
|
|||
// Check for context name syntax
|
||||
err := newContext.checkForValidIdentifiers()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check for clashes with macro names
|
||||
for k := range newContext {
|
||||
_, has := tpl.exportedMacros[k]
|
||||
for k, _ := range newContext {
|
||||
_, has := tpl.exported_macros[k]
|
||||
if has {
|
||||
return &Error{
|
||||
Filename: tpl.name,
|
||||
Sender: "execution",
|
||||
OrigError: errors.Errorf("context key name '%s' clashes with macro '%s'", k, k),
|
||||
return nil, &Error{
|
||||
Filename: tpl.name,
|
||||
Sender: "execution",
|
||||
ErrorMsg: fmt.Sprintf("Context key name '%s' clashes with macro '%s'.", k, k),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,22 +110,8 @@ func (tpl *Template) execute(context Context, writer TemplateWriter) error {
|
|||
ctx := newExecutionContext(parent, newContext)
|
||||
|
||||
// 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 {
|
||||
err := parent.root.Execute(ctx, buffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buffer, nil
|
||||
|
@ -151,30 +121,30 @@ func (tpl *Template) newBufferAndExecute(context Context) (*bytes.Buffer, error)
|
|||
// 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)
|
||||
buffer, err := tpl.execute(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = buf.WriteTo(writer)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
l := buffer.Len()
|
||||
n, werr := buffer.WriteTo(writer)
|
||||
if int(n) != l {
|
||||
panic(fmt.Sprintf("error on writing template: n(%d) != buffer.Len(%d)", n, l))
|
||||
}
|
||||
if werr != nil {
|
||||
return &Error{
|
||||
Filename: tpl.name,
|
||||
Sender: "execution",
|
||||
ErrorMsg: werr.Error(),
|
||||
}
|
||||
}
|
||||
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)
|
||||
buffer, err := tpl.execute(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -184,7 +154,7 @@ func (tpl *Template) ExecuteBytes(context Context) ([]byte, error) {
|
|||
// 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)
|
||||
buffer, err := tpl.execute(context)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
157
vendor/github.com/flosch/pongo2/template_loader.go
generated
vendored
157
vendor/github.com/flosch/pongo2/template_loader.go
generated
vendored
|
@ -1,157 +0,0 @@
|
|||
package pongo2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
// 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 errors.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 = ""
|
||||
}()
|
||||
}
|
||||
*/
|
276
vendor/github.com/flosch/pongo2/template_sets.go
generated
vendored
276
vendor/github.com/flosch/pongo2/template_sets.go
generated
vendored
|
@ -2,49 +2,48 @@ package pongo2
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/juju/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).
|
||||
// A template set allows you to create your own group of templates with their own global context (which is shared
|
||||
// among all members of the set), their own configuration (like a specific base directory) and their own sandbox.
|
||||
// It's useful for a separation of different kind of templates (e. g. web templates vs. mail templates).
|
||||
type TemplateSet struct {
|
||||
name string
|
||||
loader TemplateLoader
|
||||
name string
|
||||
|
||||
// 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
|
||||
// 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
|
||||
|
||||
// Base directory: If you set the base directory (string is non-empty), all filename lookups in tags/filters are
|
||||
// relative to this directory. If it's empty, all lookups are relative to the current filename which is importing.
|
||||
baseDirectory string
|
||||
|
||||
// Sandbox features
|
||||
// - Limit access to directories (using SandboxDirectories)
|
||||
// - 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).
|
||||
// You can limit file accesses (for all tags/filters which are using pongo2's file resolver technique)
|
||||
// to these sandbox directories. All default pongo2 filters/tags are respecting these restrictions.
|
||||
// For example, if you only have your base directory in the list, a {% ssi "/etc/passwd" %} will not work.
|
||||
// No items in SandboxDirectories means no restrictions at all.
|
||||
//
|
||||
// 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).
|
||||
//
|
||||
// SandboxDirectories can be changed at runtime. Please synchronize the access to it if you need to change it
|
||||
// after you've added your first template to the set. You *must* use this match pattern for your directories:
|
||||
// http://golang.org/pkg/path/filepath/#Match
|
||||
SandboxDirectories []string
|
||||
firstTemplateCreated bool
|
||||
bannedTags map[string]bool
|
||||
bannedFilters map[string]bool
|
||||
|
@ -54,13 +53,11 @@ type TemplateSet struct {
|
|||
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, loader TemplateLoader) *TemplateSet {
|
||||
// Create your own template sets to separate different kind of templates (e. g. web from mail templates) with
|
||||
// different globals or other configurations (like base directories).
|
||||
func NewSet(name string) *TemplateSet {
|
||||
return &TemplateSet{
|
||||
name: name,
|
||||
loader: loader,
|
||||
Globals: make(Context),
|
||||
bannedTags: make(map[string]bool),
|
||||
bannedFilters: make(map[string]bool),
|
||||
|
@ -68,157 +65,151 @@ func NewSet(name string, loader TemplateLoader) *TemplateSet {
|
|||
}
|
||||
}
|
||||
|
||||
func (set *TemplateSet) resolveFilename(tpl *Template, path string) string {
|
||||
name := ""
|
||||
if tpl != nil && tpl.isTplString {
|
||||
return path
|
||||
// Use this function to set your template set's base directory. This directory will be used for any relative
|
||||
// path in filters, tags and From*-functions to determine your template.
|
||||
func (set *TemplateSet) SetBaseDirectory(name string) error {
|
||||
// Make the path absolute
|
||||
if !filepath.IsAbs(name) {
|
||||
abs, err := filepath.Abs(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name = abs
|
||||
}
|
||||
if tpl != nil {
|
||||
name = tpl.name
|
||||
|
||||
// Check for existence
|
||||
fi, err := os.Stat(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return set.loader.Abs(name, path)
|
||||
if !fi.IsDir() {
|
||||
return fmt.Errorf("The given path '%s' is not a directory.")
|
||||
}
|
||||
|
||||
set.baseDirectory = name
|
||||
return nil
|
||||
}
|
||||
|
||||
// BanTag bans a specific tag for this template set. See more in the documentation for TemplateSet.
|
||||
func (set *TemplateSet) BanTag(name string) error {
|
||||
func (set *TemplateSet) BaseDirectory() string {
|
||||
return set.baseDirectory
|
||||
}
|
||||
|
||||
// Ban a specific tag for this template set. See more in the documentation for TemplateSet.
|
||||
func (set *TemplateSet) BanTag(name string) {
|
||||
_, has := tags[name]
|
||||
if !has {
|
||||
return errors.Errorf("tag '%s' not found", name)
|
||||
panic(fmt.Sprintf("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")
|
||||
panic("You cannot ban any tags after you've added your first template to your template set.")
|
||||
}
|
||||
_, has = set.bannedTags[name]
|
||||
if has {
|
||||
return errors.Errorf("tag '%s' is already banned", name)
|
||||
panic(fmt.Sprintf("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 {
|
||||
// Ban a specific filter for this template set. See more in the documentation for TemplateSet.
|
||||
func (set *TemplateSet) BanFilter(name string) {
|
||||
_, has := filters[name]
|
||||
if !has {
|
||||
return errors.Errorf("filter '%s' not found", name)
|
||||
panic(fmt.Sprintf("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")
|
||||
panic("You cannot ban any filters after you've added your first template to your template set.")
|
||||
}
|
||||
_, has = set.bannedFilters[name]
|
||||
if has {
|
||||
return errors.Errorf("filter '%s' is already banned", name)
|
||||
panic(fmt.Sprintf("Filter '%s' is already banned.", name))
|
||||
}
|
||||
set.bannedFilters[name] = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromCache is a convenient method to cache templates. It is thread-safe
|
||||
// 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).
|
||||
// Like FromFile(), FromCache() takes a relative path to a set base directory.
|
||||
// Sandbox restrictions apply (if given).
|
||||
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)
|
||||
} else {
|
||||
// Cache the template
|
||||
cleaned_filename := set.resolveFilename(nil, filename)
|
||||
|
||||
set.templateCacheMutex.Lock()
|
||||
defer set.templateCacheMutex.Unlock()
|
||||
set.templateCacheMutex.Lock()
|
||||
defer set.templateCacheMutex.Unlock()
|
||||
|
||||
tpl, has := set.templateCache[cleanedFilename]
|
||||
tpl, has := set.templateCache[cleaned_filename]
|
||||
|
||||
// Cache miss
|
||||
if !has {
|
||||
tpl, err := set.FromFile(cleanedFilename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// Cache miss
|
||||
if !has {
|
||||
tpl, err := set.FromFile(cleaned_filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
set.templateCache[cleaned_filename] = tpl
|
||||
return tpl, nil
|
||||
}
|
||||
set.templateCache[cleanedFilename] = tpl
|
||||
|
||||
// Cache hit
|
||||
return tpl, nil
|
||||
}
|
||||
|
||||
// Cache hit
|
||||
return tpl, nil
|
||||
}
|
||||
|
||||
// FromString loads a template from string and returns a Template instance.
|
||||
// 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.
|
||||
// Loads a template from a filename and returns a Template instance.
|
||||
// If a base directory is set, the filename must be either relative to it
|
||||
// or be an absolute path. Sandbox restrictions (SandboxDirectories) apply
|
||||
// if given.
|
||||
func (set *TemplateSet) FromFile(filename string) (*Template, error) {
|
||||
set.firstTemplateCreated = true
|
||||
|
||||
fd, err := set.loader.Get(set.resolveFilename(nil, filename))
|
||||
buf, err := ioutil.ReadFile(set.resolveFilename(nil, filename))
|
||||
if err != nil {
|
||||
return nil, &Error{
|
||||
Filename: filename,
|
||||
Sender: "fromfile",
|
||||
OrigError: err,
|
||||
Filename: filename,
|
||||
Sender: "fromfile",
|
||||
ErrorMsg: err.Error(),
|
||||
}
|
||||
}
|
||||
buf, err := ioutil.ReadAll(fd)
|
||||
if err != nil {
|
||||
return nil, &Error{
|
||||
Filename: filename,
|
||||
Sender: "fromfile",
|
||||
OrigError: err,
|
||||
}
|
||||
}
|
||||
|
||||
return newTemplate(set, filename, false, buf)
|
||||
return newTemplate(set, filename, false, string(buf))
|
||||
}
|
||||
|
||||
// RenderTemplateString is a shortcut and renders a template string directly.
|
||||
func (set *TemplateSet) RenderTemplateString(s string, ctx Context) (string, error) {
|
||||
// Shortcut; renders a template string directly. Panics when providing a
|
||||
// malformed template or an error occurs during execution.
|
||||
func (set *TemplateSet) RenderTemplateString(s string, ctx Context) string {
|
||||
set.firstTemplateCreated = true
|
||||
|
||||
tpl := Must(set.FromString(s))
|
||||
result, err := tpl.Execute(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
panic(err)
|
||||
}
|
||||
return result, nil
|
||||
return result
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Shortcut; renders a template file directly. Panics when providing a
|
||||
// malformed template or an error occurs during execution.
|
||||
func (set *TemplateSet) RenderTemplateFile(fn string, ctx Context) string {
|
||||
set.firstTemplateCreated = true
|
||||
|
||||
tpl := Must(set.FromFile(fn))
|
||||
result, err := tpl.Execute(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
panic(err)
|
||||
}
|
||||
return result, nil
|
||||
return result
|
||||
}
|
||||
|
||||
func (set *TemplateSet) logf(format string, args ...interface{}) {
|
||||
|
@ -227,6 +218,58 @@ func (set *TemplateSet) logf(format string, args ...interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
// Resolves a filename relative to the base directory. Absolute paths are allowed.
|
||||
// If sandbox restrictions are given (SandboxDirectories), they will be respected and checked.
|
||||
// On sandbox restriction violation, resolveFilename() panics.
|
||||
func (set *TemplateSet) resolveFilename(tpl *Template, filename string) (resolved_path string) {
|
||||
if len(set.SandboxDirectories) > 0 {
|
||||
defer func() {
|
||||
// Remove any ".." or other crap
|
||||
resolved_path = filepath.Clean(resolved_path)
|
||||
|
||||
// Make the path absolute
|
||||
abs_path, err := filepath.Abs(resolved_path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resolved_path = abs_path
|
||||
|
||||
// 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, resolved_path)
|
||||
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'", resolved_path)
|
||||
resolved_path = ""
|
||||
}()
|
||||
}
|
||||
|
||||
if filepath.IsAbs(filename) {
|
||||
return filename
|
||||
}
|
||||
|
||||
if set.baseDirectory == "" {
|
||||
if tpl != nil {
|
||||
if tpl.is_tpl_string {
|
||||
return filename
|
||||
}
|
||||
base := filepath.Dir(tpl.name)
|
||||
return filepath.Join(base, filename)
|
||||
}
|
||||
return filename
|
||||
} else {
|
||||
return filepath.Join(set.baseDirectory, filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Logging function (internally used)
|
||||
func logf(format string, items ...interface{}) {
|
||||
if debug {
|
||||
|
@ -236,18 +279,13 @@ func logf(format string, items ...interface{}) {
|
|||
|
||||
var (
|
||||
debug bool // internal debugging
|
||||
logger = log.New(os.Stdout, "[pongo2] ", log.LstdFlags|log.Lshortfile)
|
||||
logger = log.New(os.Stdout, "[pongo2] ", log.LstdFlags)
|
||||
|
||||
// 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)
|
||||
// Creating a default set
|
||||
DefaultSet = NewSet("default")
|
||||
|
||||
// Methods on the default set
|
||||
FromString = DefaultSet.FromString
|
||||
FromBytes = DefaultSet.FromBytes
|
||||
FromFile = DefaultSet.FromFile
|
||||
FromCache = DefaultSet.FromCache
|
||||
RenderTemplateString = DefaultSet.RenderTemplateString
|
||||
|
|
10
vendor/github.com/flosch/pongo2/template_tests/autoescape.tpl
generated
vendored
10
vendor/github.com/flosch/pongo2/template_tests/autoescape.tpl
generated
vendored
|
@ -1,10 +0,0 @@
|
|||
{{ "<script>alert('xss');</script>" }}
|
||||
{% autoescape off %}
|
||||
{{ "<script>alert('xss');</script>" }}
|
||||
{% endautoescape %}
|
||||
{% autoescape on %}
|
||||
{{ "<script>alert('xss');</script>" }}
|
||||
{% endautoescape %}
|
||||
{% autoescape off %}
|
||||
{{ "<script>alert('xss');</script>"|escape }}
|
||||
{% endautoescape %}
|
9
vendor/github.com/flosch/pongo2/template_tests/autoescape.tpl.out
generated
vendored
9
vendor/github.com/flosch/pongo2/template_tests/autoescape.tpl.out
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
<script>alert('xss');</script>
|
||||
|
||||
<script>alert('xss');</script>
|
||||
|
||||
|
||||
<script>alert('xss');</script>
|
||||
|
||||
|
||||
<script>alert('xss');</script>
|
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/base.html
generated
vendored
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/base.html
generated
vendored
|
@ -1 +0,0 @@
|
|||
Hello from {{ base_directory }}
|
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/subdir/include.html
generated
vendored
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/subdir/include.html
generated
vendored
|
@ -1 +0,0 @@
|
|||
{% include "base.html" %}
|
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/subdir/index.html
generated
vendored
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/subdir/index.html
generated
vendored
|
@ -1 +0,0 @@
|
|||
{% extends "base.html" %}
|
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/subdir/ssi.html
generated
vendored
1
vendor/github.com/flosch/pongo2/template_tests/base_dir_test/subdir/ssi.html
generated
vendored
|
@ -1 +0,0 @@
|
|||
{% ssi "base.html" parsed %}
|
50
vendor/github.com/flosch/pongo2/template_tests/comment.tpl
generated
vendored
50
vendor/github.com/flosch/pongo2/template_tests/comment.tpl
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
empty single line comment
|
||||
{# #}
|
||||
|
||||
filled single line comment
|
||||
{# testing single line comment #}
|
||||
|
||||
filled single line comment with valid tags
|
||||
{# testing single line comment {% if thing %}{% endif %} #}
|
||||
|
||||
filled single line comment with invalid tags
|
||||
{# testing single line comment {% if thing %} #}
|
||||
|
||||
filled single line comment with invalid syntax
|
||||
{# testing single line comment {% if thing('') %}wow{% endif %} #}
|
||||
|
||||
empty block comment
|
||||
{% comment %}{% endcomment %}
|
||||
|
||||
filled text single line block comment
|
||||
{% comment %}filled block comment {% endcomment %}
|
||||
|
||||
empty multi line block comment
|
||||
{% comment %}
|
||||
|
||||
|
||||
{% endcomment %}
|
||||
|
||||
block comment with other tags inside of it
|
||||
{% comment %}
|
||||
{{ thing_goes_here }}
|
||||
{% if stuff %}do stuff{% endif %}
|
||||
{% endcomment %}
|
||||
|
||||
block comment with invalid tags inside of it
|
||||
{% comment %}
|
||||
{% if thing %}
|
||||
{% endcomment %}
|
||||
|
||||
block comment with invalid syntax inside of it
|
||||
{% comment %}
|
||||
{% thing('') %}
|
||||
{% endcomment %}
|
||||
|
||||
Regular tags between comments to verify it doesn't break in the lexer
|
||||
{% if hello %}
|
||||
{% endif %}
|
||||
after if
|
||||
{% comment %}All done{% endcomment %}
|
||||
|
||||
end of file
|
39
vendor/github.com/flosch/pongo2/template_tests/comment.tpl.out
generated
vendored
39
vendor/github.com/flosch/pongo2/template_tests/comment.tpl.out
generated
vendored
|
@ -1,39 +0,0 @@
|
|||
empty single line comment
|
||||
|
||||
|
||||
filled single line comment
|
||||
|
||||
|
||||
filled single line comment with valid tags
|
||||
|
||||
|
||||
filled single line comment with invalid tags
|
||||
|
||||
|
||||
filled single line comment with invalid syntax
|
||||
|
||||
|
||||
empty block comment
|
||||
|
||||
|
||||
filled text single line block comment
|
||||
|
||||
|
||||
empty multi line block comment
|
||||
|
||||
|
||||
block comment with other tags inside of it
|
||||
|
||||
|
||||
block comment with invalid tags inside of it
|
||||
|
||||
|
||||
block comment with invalid syntax inside of it
|
||||
|
||||
|
||||
Regular tags between comments to verify it doesn't break in the lexer
|
||||
|
||||
after if
|
||||
|
||||
|
||||
end of file
|
32
vendor/github.com/flosch/pongo2/template_tests/complex.tpl
generated
vendored
32
vendor/github.com/flosch/pongo2/template_tests/complex.tpl
generated
vendored
|
@ -1,32 +0,0 @@
|
|||
{# A more complex template using pongo2 (fully django-compatible template) #}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>My blog page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Blogpost</h1>
|
||||
<div id="content">
|
||||
{{ complex.post.Text|safe }}
|
||||
</div>
|
||||
|
||||
<h1>Comments</h1>
|
||||
|
||||
{% for comment in complex.comments %}
|
||||
<h2>{{ forloop.Counter }}. Comment ({{ forloop.Revcounter}} comment{{ forloop.Revcounter|pluralize:"s" }} left)</h2>
|
||||
<p>From: {{ comment.Author.Name }} ({{ comment.Author.Validated|yesno:"validated,not validated,unknown validation status" }})</p>
|
||||
|
||||
{% if complex.is_admin(comment.Author) %}
|
||||
<p>This user is an admin (verify: {{ comment.Author.Is_admin }})!</p>
|
||||
{% else %}
|
||||
<p>This user is not admin!</p>
|
||||
{% endif %}
|
||||
|
||||
<p>Written {{ comment.Date }}</p>
|
||||
<p>{{ comment.Text|striptags }}</p>
|
||||
{% endfor %}
|
||||
</body>
|
||||
|
||||
</html>
|
50
vendor/github.com/flosch/pongo2/template_tests/complex.tpl.out
generated
vendored
50
vendor/github.com/flosch/pongo2/template_tests/complex.tpl.out
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>My blog page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Blogpost</h1>
|
||||
<div id="content">
|
||||
<h2>Hello!</h2><p>Welcome to my new blog page. I'm using pongo2 which supports {{ variables }} and {% tags %}.</p>
|
||||
</div>
|
||||
|
||||
<h1>Comments</h1>
|
||||
|
||||
|
||||
<h2>1. Comment (3 comments left)</h2>
|
||||
<p>From: user1 (validated)</p>
|
||||
|
||||
|
||||
<p>This user is not admin!</p>
|
||||
|
||||
|
||||
<p>Written 2014-06-10 15:30:15 +0000 UTC</p>
|
||||
<p>"pongo2 is nice!"</p>
|
||||
|
||||
<h2>2. Comment (2 comments left)</h2>
|
||||
<p>From: user2 (validated)</p>
|
||||
|
||||
|
||||
<p>This user is an admin (verify: True)!</p>
|
||||
|
||||
|
||||
<p>Written 2011-03-21 08:37:56.000000012 +0000 UTC</p>
|
||||
<p>comment2 with unsafe tags in it</p>
|
||||
|
||||
<h2>3. Comment (1 comment left)</h2>
|
||||
<p>From: user3 (not validated)</p>
|
||||
|
||||
|
||||
<p>This user is not admin!</p>
|
||||
|
||||
|
||||
<p>Written 2014-06-10 15:30:15 +0000 UTC</p>
|
||||
<p>hello! there</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
22
vendor/github.com/flosch/pongo2/template_tests/cycle.tpl
generated
vendored
22
vendor/github.com/flosch/pongo2/template_tests/cycle.tpl
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
{% for item in simple.multiple_item_list %}
|
||||
'{% cycle "item1" simple.name simple.number %}'
|
||||
{% endfor %}
|
||||
{% for item in simple.multiple_item_list %}
|
||||
'{% cycle "item1" simple.name simple.number as cycleitem %}'
|
||||
May I present the cycle item again: '{{ cycleitem }}'
|
||||
{% endfor %}
|
||||
{% for item in simple.multiple_item_list %}
|
||||
'{% cycle "item1" simple.name simple.number as cycleitem silent %}'
|
||||
May I present the cycle item: '{{ cycleitem }}'
|
||||
{% endfor %}
|
||||
{% for item in simple.multiple_item_list %}
|
||||
'{% cycle "item1" simple.name simple.number as cycleitem silent %}'
|
||||
May I present the cycle item: '{{ cycleitem }}'
|
||||
{% include "inheritance/cycle_include.tpl" %}
|
||||
{% endfor %}
|
||||
'{% cycle "item1" simple.name simple.number as cycleitem %}'
|
||||
'{% cycle cycleitem %}'
|
||||
'{% cycle "item1" simple.name simple.number as cycleitem silent %}'
|
||||
'{{ cycleitem }}'
|
||||
'{% cycle cycleitem %}'
|
||||
'{{ cycleitem }}'
|
130
vendor/github.com/flosch/pongo2/template_tests/cycle.tpl.out
generated
vendored
130
vendor/github.com/flosch/pongo2/template_tests/cycle.tpl.out
generated
vendored
|
@ -1,130 +0,0 @@
|
|||
|
||||
'item1'
|
||||
|
||||
'john doe'
|
||||
|
||||
'42'
|
||||
|
||||
'item1'
|
||||
|
||||
'john doe'
|
||||
|
||||
'42'
|
||||
|
||||
'item1'
|
||||
|
||||
'john doe'
|
||||
|
||||
'42'
|
||||
|
||||
'item1'
|
||||
|
||||
|
||||
'item1'
|
||||
May I present the cycle item again: 'item1'
|
||||
|
||||
'john doe'
|
||||
May I present the cycle item again: 'john doe'
|
||||
|
||||
'42'
|
||||
May I present the cycle item again: '42'
|
||||
|
||||
'item1'
|
||||
May I present the cycle item again: 'item1'
|
||||
|
||||
'john doe'
|
||||
May I present the cycle item again: 'john doe'
|
||||
|
||||
'42'
|
||||
May I present the cycle item again: '42'
|
||||
|
||||
'item1'
|
||||
May I present the cycle item again: 'item1'
|
||||
|
||||
'john doe'
|
||||
May I present the cycle item again: 'john doe'
|
||||
|
||||
'42'
|
||||
May I present the cycle item again: '42'
|
||||
|
||||
'item1'
|
||||
May I present the cycle item again: 'item1'
|
||||
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
|
||||
''
|
||||
May I present the cycle item: 'john doe'
|
||||
|
||||
''
|
||||
May I present the cycle item: '42'
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
|
||||
''
|
||||
May I present the cycle item: 'john doe'
|
||||
|
||||
''
|
||||
May I present the cycle item: '42'
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
|
||||
''
|
||||
May I present the cycle item: 'john doe'
|
||||
|
||||
''
|
||||
May I present the cycle item: '42'
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
Included 'item1'.
|
||||
|
||||
''
|
||||
May I present the cycle item: 'john doe'
|
||||
Included 'john doe'.
|
||||
|
||||
''
|
||||
May I present the cycle item: '42'
|
||||
Included '42'.
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
Included 'item1'.
|
||||
|
||||
''
|
||||
May I present the cycle item: 'john doe'
|
||||
Included 'john doe'.
|
||||
|
||||
''
|
||||
May I present the cycle item: '42'
|
||||
Included '42'.
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
Included 'item1'.
|
||||
|
||||
''
|
||||
May I present the cycle item: 'john doe'
|
||||
Included 'john doe'.
|
||||
|
||||
''
|
||||
May I present the cycle item: '42'
|
||||
Included '42'.
|
||||
|
||||
''
|
||||
May I present the cycle item: 'item1'
|
||||
Included 'item1'.
|
||||
|
||||
'item1'
|
||||
'john doe'
|
||||
''
|
||||
'item1'
|
||||
''
|
||||
'john doe'
|
0
vendor/github.com/flosch/pongo2/template_tests/empty.tpl
generated
vendored
0
vendor/github.com/flosch/pongo2/template_tests/empty.tpl
generated
vendored
0
vendor/github.com/flosch/pongo2/template_tests/empty.tpl.out
generated
vendored
0
vendor/github.com/flosch/pongo2/template_tests/empty.tpl.out
generated
vendored
69
vendor/github.com/flosch/pongo2/template_tests/expressions.tpl
generated
vendored
69
vendor/github.com/flosch/pongo2/template_tests/expressions.tpl
generated
vendored
|
@ -1,69 +0,0 @@
|
|||
integers and complex expressions
|
||||
{{ 10-100 }}
|
||||
{{ -(10-100) }}
|
||||
{{ -(-(10-100)) }}
|
||||
{{ -1 * (-(-(10-100))) }}
|
||||
{{ -1 * (-(-(10-100)) ^ 2) ^ 3 + 3 * (5 - 17) + 1 + 2 }}
|
||||
|
||||
floats
|
||||
{{ 5.5 }}
|
||||
{{ 5.172841 }}
|
||||
{{ 5.5 - 1.5 == 4 }}
|
||||
{{ 5.5 - 1.5 == 4.0 }}
|
||||
|
||||
mul/div
|
||||
{{ 2 * 5 }}
|
||||
{{ 2 * 5.0 }}
|
||||
{{ 2 * 0 }}
|
||||
{{ 2.5 * 5.3 }}
|
||||
{{ 1/2 }}
|
||||
{{ 1/2.0 }}
|
||||
{{ 1/0.000001 }}
|
||||
|
||||
logic expressions
|
||||
{{ !true }}
|
||||
{{ !(true || false) }}
|
||||
{{ true || false }}
|
||||
{{ true or false }}
|
||||
{{ false or false }}
|
||||
{{ false || false }}
|
||||
{{ true && (true && (true && (true && (1 == 1 || false)))) }}
|
||||
|
||||
float comparison
|
||||
{{ 5.5 <= 5.5 }}
|
||||
{{ 5.5 < 5.5 }}
|
||||
{{ 5.5 > 5.5 }}
|
||||
{{ 5.5 >= 5.5 }}
|
||||
|
||||
remainders
|
||||
{{ (simple.number+7)%7 }}
|
||||
{{ (simple.number+7)%7 == 0 }}
|
||||
{{ (simple.number+7)%6 }}
|
||||
|
||||
in/not in
|
||||
{{ 5 in simple.intmap }}
|
||||
{{ 2 in simple.intmap }}
|
||||
{{ 7 in simple.intmap }}
|
||||
{{ !(5 in simple.intmap) }}
|
||||
{{ not(7 in simple.intmap) }}
|
||||
{{ 1 in simple.multiple_item_list }}
|
||||
{{ 4 in simple.multiple_item_list }}
|
||||
{{ !(4 in simple.multiple_item_list) }}
|
||||
{{ "Hello" in simple.misc_list }}
|
||||
{{ "Hello2" in simple.misc_list }}
|
||||
{{ 99 in simple.misc_list }}
|
||||
{{ False in simple.misc_list }}
|
||||
|
||||
issue #48 (associativity for infix operators)
|
||||
{{ 34/3*3 }}
|
||||
{{ 10 + 24 / 6 / 2 }}
|
||||
{{ 6 - 4 - 2 }}
|
||||
|
||||
issue #64 (uint comparison with int const)
|
||||
{{ simple.uint }}
|
||||
{{ simple.uint == 8 }}
|
||||
{{ simple.uint == 9 }}
|
||||
{{ simple.uint >= 8 }}
|
||||
{{ simple.uint <= 8 }}
|
||||
{{ simple.uint < 8 }}
|
||||
{{ simple.uint > 8 }}
|
69
vendor/github.com/flosch/pongo2/template_tests/expressions.tpl.out
generated
vendored
69
vendor/github.com/flosch/pongo2/template_tests/expressions.tpl.out
generated
vendored
|
@ -1,69 +0,0 @@
|
|||
integers and complex expressions
|
||||
-90
|
||||
90
|
||||
-90
|
||||
90
|
||||
531440999967.000000
|
||||
|
||||
floats
|
||||
5.500000
|
||||
5.172841
|
||||
False
|
||||
True
|
||||
|
||||
mul/div
|
||||
10
|
||||
10.000000
|
||||
0
|
||||
13.250000
|
||||
0
|
||||
0.500000
|
||||
1000000.000000
|
||||
|
||||
logic expressions
|
||||
False
|
||||
False
|
||||
True
|
||||
True
|
||||
False
|
||||
False
|
||||
True
|
||||
|
||||
float comparison
|
||||
True
|
||||
False
|
||||
False
|
||||
True
|
||||
|
||||
remainders
|
||||
0
|
||||
True
|
||||
1
|
||||
|
||||
in/not in
|
||||
True
|
||||
True
|
||||
False
|
||||
False
|
||||
True
|
||||
True
|
||||
False
|
||||
True
|
||||
True
|
||||
False
|
||||
True
|
||||
False
|
||||
|
||||
issue #48 (associativity for infix operators)
|
||||
33
|
||||
12
|
||||
0
|
||||
|
||||
issue #64 (uint comparison with int const)
|
||||
8
|
||||
True
|
||||
False
|
||||
True
|
||||
True
|
||||
False
|
||||
False
|
3
vendor/github.com/flosch/pongo2/template_tests/extends.tpl
generated
vendored
3
vendor/github.com/flosch/pongo2/template_tests/extends.tpl
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
{% extends "inheritance/base.tpl" %}
|
||||
|
||||
{% block content %}Extends' content{% endblock %}
|
1
vendor/github.com/flosch/pongo2/template_tests/extends.tpl.out
generated
vendored
1
vendor/github.com/flosch/pongo2/template_tests/extends.tpl.out
generated
vendored
|
@ -1 +0,0 @@
|
|||
Start#This is base's bodyExtends' content#End
|
3
vendor/github.com/flosch/pongo2/template_tests/extends_super.tpl
generated
vendored
3
vendor/github.com/flosch/pongo2/template_tests/extends_super.tpl
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
{% extends "inheritance/base.tpl" %}
|
||||
|
||||
{% block content %}{{ block.Super }}extends-level-1{% endblock %}
|
1
vendor/github.com/flosch/pongo2/template_tests/extends_super.tpl.out
generated
vendored
1
vendor/github.com/flosch/pongo2/template_tests/extends_super.tpl.out
generated
vendored
|
@ -1 +0,0 @@
|
|||
Start#This is base's bodyDefault contentextends-level-1#End
|
3
vendor/github.com/flosch/pongo2/template_tests/extends_super2.tpl
generated
vendored
3
vendor/github.com/flosch/pongo2/template_tests/extends_super2.tpl
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
{% extends "extends_super.tpl" %}
|
||||
|
||||
{% block content %}{{ block.Super }}extends-level-2{% endblock %}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue