diff --git a/vendor/manifest b/vendor/manifest index 44085c2..064f43f 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -98,6 +98,12 @@ "revision": "5ec5e003b21ac1f06e175898413ada23a6797fc0", "branch": "master", "path": "/tiff" + }, + { + "importpath": "github.com/yosssi/ace", + "repository": "https://github.com/yosssi/ace", + "revision": "78e48a2f0ac5fb5a642585f96b03a5f47f7775f5", + "branch": "master" } ] } \ No newline at end of file diff --git a/vendor/src/github.com/yosssi/ace/LICENSE b/vendor/src/github.com/yosssi/ace/LICENSE new file mode 100644 index 0000000..73f313c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Keiji Yoshida + +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. \ No newline at end of file diff --git a/vendor/src/github.com/yosssi/ace/README.md b/vendor/src/github.com/yosssi/ace/README.md new file mode 100644 index 0000000..8f17d9b --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/README.md @@ -0,0 +1,109 @@ +# Ace - HTML template engine for Go + +[![wercker status](https://app.wercker.com/status/8d3c657bcae7f31d10c8f88bbfa966d8/m "wercker status")](https://app.wercker.com/project/bykey/8d3c657bcae7f31d10c8f88bbfa966d8) +[![GoDoc](http://godoc.org/github.com/yosssi/ace?status.svg)](http://godoc.org/github.com/yosssi/ace) + +## Overview + +Ace is an HTML template engine for Go. This is inspired by [Slim](http://slim-lang.com/) and [Jade](http://jade-lang.com/). This is a refinement of [Gold](http://gold.yoss.si/). + +## Example + +```ace += doctype html +html lang=en + head + title Hello Ace + = css + h1 { color: blue; } + body + h1 {{.Msg}} + #container.wrapper + p.. + Ace is an HTML template engine for Go. + This engine simplifies HTML coding in Go web application development. + = javascript + console.log('Welcome to Ace'); +``` + +becomes + +```html + + + + Hello Ace + + + +

Hello Ace

+
+

+ Ace is an HTML template engine for Go.
+ This engine simplifies HTML coding in Go web application development. +

+
+ + + +``` + +## Features + +### Making Use of the Go Standard Template Package + +**Ace fully utilizes the strength of the [html/template](http://golang.org/pkg/html/template/) package.** You can embed [actions](http://golang.org/pkg/text/template/#hdr-Actions) of the template package in Ace templates. Ace also uses [nested template definitions](http://golang.org/pkg/text/template/#hdr-Nested_template_definitions) of the template package and Ace templates can pass [pipelines](http://golang.org/pkg/text/template/#hdr-Pipelines) (parameters) to other templates which they include. + +### Simple Syntax + +Ace has a simple syntax and **this makes template files simple and light**. + +### Caching Function + +Ace has a caching function which caches the result data of the templates parsing process. **You can omit the templates parsing process and save template parsing time** by using this function. + +### Binary Template Load Function + +Ace has a binary template load function which loads Ace templates from binary data in memory instead of template files on disk. **You can compile your web application into one binary file** by using this function. [go-bindata](https://github.com/jteeuwen/go-bindata) is the best for generating binary data from template files. + +## Getting Started + +Please check the following documentation. + +* [Getting Started](documentation/getting-started.md) - shows the getting started guide. +* [Examples](examples) - shows the examples of the web applications which use the Ace template engine. + +## Documentation + +You can get the documentation about Ace via the following channels: + +* [Documentation](documentation) - includes the getting started guide and the syntax documentation. +* [GoDoc](https://godoc.org/github.com/yosssi/ace) - includes the API documentation. + +## Discussion & Contact + +You can discuss Ace and contact the Ace development team via the following channels: + +* [GitHub Issues](https://github.com/yosssi/ace/issues) +* [Gitter (Chat)](https://gitter.im/yosssi/ace) + +## Contributions + +**Any contributions are welcome.** Please feel free to [create an issue](https://github.com/yosssi/ace/issues/new) or [send a pull request](https://github.com/yosssi/ace/compare/). + +## Renderers for web frameworks + +* [Martini Acerender](https://github.com/yosssi/martini-acerender) - For [Martini](http://martini.codegangsta.io/) + +## Tools + +* [vim-ace](https://github.com/yosssi/vim-ace) - Vim syntax highlighting for Ace templates +* [ace-tmbundle](https://github.com/yosssi/ace-tmbundle) - TextMate/Sublime syntax highlighting for Ace templates + +## Projects using Ace + +[Here](documentation/projects-using-ace.md) is the list of the projects using Ace. Please feel free to add your awesome project to the list! diff --git a/vendor/src/github.com/yosssi/ace/ace.go b/vendor/src/github.com/yosssi/ace/ace.go new file mode 100644 index 0000000..879f9eb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/ace.go @@ -0,0 +1,70 @@ +package ace + +import ( + "html/template" + "sync" +) + +var cache = make(map[string]template.Template) +var cacheMutex = new(sync.RWMutex) + +// Load loads and returns an HTML template. Each Ace templates are parsed only once +// and cached if the "DynamicReload" option are not set. +func Load(basePath, innerPath string, opts *Options) (*template.Template, error) { + // Initialize the options. + opts = InitializeOptions(opts) + + name := basePath + colon + innerPath + + if !opts.DynamicReload { + if tpl, ok := getCache(name); ok { + return &tpl, nil + } + } + + // Read files. + src, err := readFiles(basePath, innerPath, opts) + if err != nil { + return nil, err + } + + // Parse the source. + rslt, err := ParseSource(src, opts) + if err != nil { + return nil, err + } + + // Compile the parsed result. + tpl, err := CompileResult(name, rslt, opts) + if err != nil { + return nil, err + } + + if !opts.DynamicReload { + setCache(name, *tpl) + } + + return tpl, nil +} + +// getCache returns the cached template. +func getCache(name string) (template.Template, bool) { + cacheMutex.RLock() + tpl, ok := cache[name] + cacheMutex.RUnlock() + return tpl, ok +} + +// setCache sets the template to the cache. +func setCache(name string, tpl template.Template) { + cacheMutex.Lock() + cache[name] = tpl + cacheMutex.Unlock() +} + +// FlushCache clears all cached templates. +func FlushCache() { + cacheMutex.Lock() + cache = make(map[string]template.Template) + cacheMutex.Unlock() +} diff --git a/vendor/src/github.com/yosssi/ace/action.go b/vendor/src/github.com/yosssi/ace/action.go new file mode 100644 index 0000000..525a535 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/action.go @@ -0,0 +1,38 @@ +package ace + +import ( + "bytes" + "io" + "strings" +) + +// action represents an action. +type action struct { + elementBase +} + +// WriteTo writes data to w. +func (e *action) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + // Write the action + bf.WriteString(strings.TrimSpace(e.ln.str)) + + // Write the children's HTML. + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err + +} + +// newAction creates and returns an action. +func newAction(ln *line, rslt *result, src *source, parent element, opts *Options) *action { + return &action{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + } +} diff --git a/vendor/src/github.com/yosssi/ace/cmd/ace/main.go b/vendor/src/github.com/yosssi/ace/cmd/ace/main.go new file mode 100644 index 0000000..d7fbf3e --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/cmd/ace/main.go @@ -0,0 +1,90 @@ +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/yosssi/ace" + "github.com/yosssi/gohtml" +) + +var ( + noFormat bool + lineNo bool +) + +func compileResultFromStdin() (string, error) { + b, err := ioutil.ReadAll(os.Stdin) + if err != nil { + return "", err + } + name, baseFile := "stdin", "stdin.ace" + base := ace.NewFile(baseFile, b) + inner := ace.NewFile("", []byte{}) + + src := ace.NewSource(base, inner, []*ace.File{}) + rslt, err := ace.ParseSource(src, nil) + if err != nil { + return "", err + } + + tpl, err := ace.CompileResult(name, rslt, nil) + if err != nil { + return "", err + } + return tpl.Lookup(name).Tree.Root.String(), nil +} + +func compileResultFromFile(baseFile, innerFile string) (string, error) { + base := baseFile[:len(baseFile)-len(filepath.Ext(baseFile))] + + var inner string + if len(innerFile) > 0 { + inner = innerFile[:len(innerFile)-len(filepath.Ext(innerFile))] + } + name := base + ":" + inner + + tpl, err := ace.Load(base, inner, nil) + if err != nil { + return "", err + } + return tpl.Lookup(name).Tree.Root.String(), nil +} + +func main() { + flag.BoolVar(&noFormat, "no-format", false, "output HTML without format") + flag.BoolVar(&lineNo, "lineno", false, "output formatted HTML with line numbers") + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage:\n %s [options] [base.ace] [inner.ace]\n\nOptions:\n", os.Args[0]) + flag.PrintDefaults() + } + flag.Parse() + + var ( + compiled string + err error + ) + baseFile := flag.Arg(0) + if len(baseFile) == 0 { + compiled, err = compileResultFromStdin() + } else { + compiled, err = compileResultFromFile(baseFile, flag.Arg(1)) + } + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if noFormat { + fmt.Println(compiled) + } else { + if lineNo { + fmt.Println(gohtml.FormatWithLineNo(compiled)) + } else { + fmt.Println(gohtml.Format(compiled)) + } + } +} diff --git a/vendor/src/github.com/yosssi/ace/comment.go b/vendor/src/github.com/yosssi/ace/comment.go new file mode 100644 index 0000000..fcf77da --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/comment.go @@ -0,0 +1,25 @@ +package ace + +import "io" + +// comment represents a comment. +type comment struct { + elementBase +} + +// Do nothing. +func (e *comment) WriteTo(w io.Writer) (int64, error) { + return 0, nil +} + +// ContainPlainText returns true. +func (e *comment) ContainPlainText() bool { + return true +} + +// newComment creates and returns a comment. +func newComment(ln *line, rslt *result, src *source, parent element, opts *Options) *comment { + return &comment{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + } +} diff --git a/vendor/src/github.com/yosssi/ace/compile.go b/vendor/src/github.com/yosssi/ace/compile.go new file mode 100644 index 0000000..d6cf788 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/compile.go @@ -0,0 +1,107 @@ +package ace + +import ( + "bytes" + "fmt" + "html/template" +) + +// Actions +const ( + actionDefine = `%sdefine "%s"%s` + actionEnd = "%send%s" + actionTemplate = `%stemplate "%s"%s` + actionTemplateWithPipeline = `%stemplate "%s" %s%s` +) + +// PreDefinedFuncs +const ( + preDefinedFuncNameHTML = "HTML" +) + +// CompileResult compiles the parsed result to the template.Template. +func CompileResult(name string, rslt *result, opts *Options) (*template.Template, error) { + // Initialize the options. + opts = InitializeOptions(opts) + + // Create a template. + t := template.New(name) + + return CompileResultWithTemplate(t, rslt, opts) +} + +// CompileResultWithTemplate compiles the parsed result and associates it with t. +func CompileResultWithTemplate(t *template.Template, rslt *result, opts *Options) (*template.Template, error) { + // Initialize the options. + opts = InitializeOptions(opts) + + var err error + + // Create a buffer. + baseBf := bytes.NewBuffer(nil) + innerBf := bytes.NewBuffer(nil) + includeBfs := make(map[string]*bytes.Buffer) + + // Write data to the buffer. + for _, e := range rslt.base { + if _, err := e.WriteTo(baseBf); err != nil { + return nil, err + } + } + + for _, e := range rslt.inner { + if _, err = e.WriteTo(innerBf); err != nil { + return nil, err + } + } + + for path, elements := range rslt.includes { + bf := bytes.NewBuffer(nil) + + // Write a define action. + bf.WriteString(fmt.Sprintf(actionDefine, opts.DelimLeft, path, opts.DelimRight)) + + for _, e := range elements { + if _, err = e.WriteTo(bf); err != nil { + return nil, err + } + } + + // Write an end action. + bf.WriteString(fmt.Sprintf(actionEnd, opts.DelimLeft, opts.DelimRight)) + + includeBfs[path] = bf + } + + // Set Delimiters. + t.Delims(opts.DelimLeft, opts.DelimRight) + + // Set FuncMaps. + t.Funcs(template.FuncMap{ + preDefinedFuncNameHTML: func(s string) template.HTML { + return template.HTML(s) + }, + }) + + t.Funcs(opts.FuncMap) + + // Parse a string to the template. + t, err = t.Parse(baseBf.String()) + if err != nil { + return nil, err + } + + t, err = t.Parse(innerBf.String()) + if err != nil { + return nil, err + } + + for _, bf := range includeBfs { + t, err = t.Parse(bf.String()) + if err != nil { + return nil, err + } + } + + return t, nil +} diff --git a/vendor/src/github.com/yosssi/ace/compile_test.go b/vendor/src/github.com/yosssi/ace/compile_test.go new file mode 100644 index 0000000..2fb03f5 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/compile_test.go @@ -0,0 +1,83 @@ +package ace + +import ( + "testing" +) + +func TestLineCompile(t *testing.T) { + for i, this := range []struct { + template string + expect string + }{ + { + template: `a href=./foo foo`, + expect: `foo`, + }, + { + template: `span.color-red red`, + expect: `red`, + }, + { + template: `span#ref1 text`, + expect: `text`, + }, + { + template: `span#ref1.color-red.text-big text`, + expect: `text`, + }, + { + template: `span.color-red#ref1.text-big text`, + expect: `text`, + }, + { + template: `#ref1 text`, + expect: `
text
`, + }, + { + template: `#ref1.color-red.text-big text`, + expect: `
text
`, + }, + { + template: `.color-red#ref1.text-big text`, + expect: `
text
`, + }, + { + template: "div class=\"dialog {{ if eq .Attr `important` }}color-red{{end}}\" text", + expect: "
text
", + }, + { + template: "div class=\"dialog {{ if eq .Attr `important` }}color-red text-big{{end}}\" text", + expect: "
text
", + }, + { + template: "div class=\"dialog {{ if eq .Attr \"important\" }}color-red{{end}}\" text", + expect: "
text
", + }, + { + template: "div class=\"dialog {{ if eq .Attr \"important\" }}color-red text-big{{end}}\" text", + expect: "
text
", + }, + } { + name, filepath := "dummy", "dummy.ace" + base := NewFile(filepath, []byte(this.template)) + inner := NewFile("", []byte{}) + + src := NewSource(base, inner, []*File{}) + rslt, err := ParseSource(src, nil) + if err != nil { + t.Errorf("[%d] failed: %s", i, err) + continue + } + + tpl, err := CompileResult(name, rslt, nil) + if err != nil { + t.Errorf("[%d] failed: %s", i, err) + continue + } + + compiled := tpl.Lookup(name).Tree.Root.String() + if compiled != this.expect { + t.Errorf("[%d] Compiler didn't return an expected value, got %v but expected %v", i, compiled, this.expect) + } + } +} diff --git a/vendor/src/github.com/yosssi/ace/doc.go b/vendor/src/github.com/yosssi/ace/doc.go new file mode 100644 index 0000000..f9a508d --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/doc.go @@ -0,0 +1,2 @@ +// Package ace provides an HTML template engine. +package ace diff --git a/vendor/src/github.com/yosssi/ace/documentation/README.md b/vendor/src/github.com/yosssi/ace/documentation/README.md new file mode 100644 index 0000000..7554b85 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/documentation/README.md @@ -0,0 +1,6 @@ +# Documentation + +* [Getting Started](getting-started.md) +* [Syntax](syntax.md) +* [Options](options.md) +* [Projects using Ace](projects-using-ace.md) diff --git a/vendor/src/github.com/yosssi/ace/documentation/getting-started.md b/vendor/src/github.com/yosssi/ace/documentation/getting-started.md new file mode 100644 index 0000000..7bf80f6 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/documentation/getting-started.md @@ -0,0 +1,104 @@ +# Getting Started + +This document explains a basic usage of Ace by showing a simple example. + +## 1. Create Ace templates + +Create the following Ace templates. + +base.ace + +```ace += doctype html +html lang=en + head + meta charset=utf-8 + title Ace example + = css + h1 { color: blue; } + body + h1 Base Template : {{.Msg}} + #container.wrapper + = yield main + = yield sub + = include inc .Msg + = javascript + alert('{{.Msg}}'); +``` + +inner.ace + +```ace += content main + h2 Inner Template - Main : {{.Msg}} + += content sub + h3 Inner Template - Sub : {{.Msg}} +``` + +inc.ace + +```ace +h4 Included Template : {{.}} +``` + +## 2. Create a web application + +Create the following web application. + +main.go + +```go +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("base", "inner", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, map[string]string{"Msg": "Hello Ace"}); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} +``` + +## 3. Check the result. + +Run the above web application and access [localhost:8080](http://localhost:8080). The following HTML will be rendered. + +```html + + + + + Ace example + + + +

Base Template : Hello Ace

+
+

Inner Template - Main : Hello Ace

+

Inner Template - Sub : Hello Ace

+

Included Template : Hello Ace

+
+ + + +``` diff --git a/vendor/src/github.com/yosssi/ace/documentation/options.md b/vendor/src/github.com/yosssi/ace/documentation/options.md new file mode 100644 index 0000000..15d70b5 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/documentation/options.md @@ -0,0 +1,36 @@ +# Options + +Here is a sample Go code which calls an Ace template engine. + +```go +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("base", "inner", nil) + if err != nil { + panic(err) + } + if err := tpl.Execute(w, map[string]string{"Msg": "Hello Ace"}); err != nil { + panic(err) + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} +``` + +You can pass parsing options to the Ace template engine via `ace.Load`'s third argument. + +```go +tpl, err := ace.Load("base", "inner", &ace.Options{DynamicReload: true}) +``` + +Please check [GoDoc](https://godoc.org/github.com/yosssi/ace#Options) for more detail about options. diff --git a/vendor/src/github.com/yosssi/ace/documentation/projects-using-ace.md b/vendor/src/github.com/yosssi/ace/documentation/projects-using-ace.md new file mode 100644 index 0000000..35d148b --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/documentation/projects-using-ace.md @@ -0,0 +1,6 @@ +# Projects using Ace + +* [Ace Proxy](https://github.com/yosssi/ace-proxy) - Proxy for the Ace template engine +* [ace.yoss.si](https://github.com/yosssi/ace.yoss.si) - Website of Ace +* [Martini Acerender](https://github.com/yosssi/martini-acerender) - Martini middleware/handler for parsing Ace templates and rendering HTML +* [Hugo](https://github.com/spf13/hugo) - Static Site Generator written in Go diff --git a/vendor/src/github.com/yosssi/ace/documentation/syntax.md b/vendor/src/github.com/yosssi/ace/documentation/syntax.md new file mode 100644 index 0000000..51124c4 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/documentation/syntax.md @@ -0,0 +1,330 @@ +# Syntax + +## Indent + +A unit of an indent must be 2 spaces. + +```ace +html + body + div + p +``` + +becomes + +```html + + +
+

+ + +``` + +## HTML Tags + +A head word of a line is interpreted as an HTML tag. The rest words of the same line are interpreted as attributes or a text. An attribute value which contains spaces must be surrounded by double quotes. An attribute without value (like "check" and "required") can be defined by specifying no value and ending with an equal (=). + +```ace +div id=container style="font-size: 12px; color: blue;" + p class=row This is interpreted as a text. + a href=https://github.com/ Go to GitHub + input type=checkbox checked= +``` + +becomes + +```html +
+

This is interpreted as a text.

+ Go to GitHub + +
+``` + +ID and classes can be defined with a head word of a line. + +```ace +p#foo.bar +#container +.wrapper +``` + +becomes + +```html +

+
+
+``` + +Block texts can be defined as a child element of an HTML tag by appending a dot (.) or double dot (..) to the head word of a line. BR tags are inserted to each line except for the last line by appending a double dot (..) to the head word of a line. + +```ace +script. + var msg = 'Hello Ace'; + alert(msg); +p.. + This is a block text. + BR tags are inserted + automatically. +``` + +becomes + +```html + +

+ This is a block text.
+ BR tags are inserted
+ automatically. +

+``` + +## Plain Texts + +A line which starts with a pipe (|) or double pipe (||) is interpreted as a block of plain texts. BR tags are inserted to each line except for the last line by having a line start with a double pipe (||). + +```ace +div + | This is a single line. +div + | + This is a + block line. +div + || + This is a + block line + with BR tags. +``` + +becomes + +```html +
+ This is a single line. +
+
+ This is a + block line. +
+
+ This is a
+ block line
+ with BR tags. +
+``` + +## Helper Methods + +A line which starts withs an equal (=) is interpreted as a helper method. + +```ace += helperMethodName +``` + +The following helper methods are available. + +### Conditional Comment Helper Method + +A conditional comment helper method generates a [conditional comment](http://en.wikipedia.org/wiki/Conditional_comment). + +```ace += conditionalComment commentType condition +``` + +The following comment types are acceptable: + +| Comment Type | Generated HTML | +| ------------ |----------------------------------------| +| hidden | | +| revealed | HTML | + +```ace += conditionalComment hidden IE 6 +

You are using Internet Explorer 6.

+= conditionalComment revealed !IE + +``` + +becomes + +```html + + + + +``` + +### Content Helper Method + +A content helper method defines a block content which is embedded in the base template. This helper method must be used only in the inner template. + +``` += content main + h2 Inner Template - Main : {{.Msg}} + += content sub + h3 Inner Template - Sub : {{.Msg}} +``` + +### CSS Helper Method + +A css helper method generates a style tag which has "text/css" type. + +```ace += css + body { + margin: 0; + } + h1 { + font-size: 200%; + color: blue; + } +``` + +becomes + +```html + +``` + +### Doctype Helper Method + +A doctype helper method generates a doctype tag. + +```ace += doctype doctypeName +``` + +The following doctype names are acceptable: + +| Doctype Name | Generated HTML | +| ------------ |--------------------------------------| +| html | | +| xml | | +| transitional | | +| strict | | +| frameset | | +| 1.1 | | +| basic | | +| mobile | | + +```ace += doctype html +``` + +becomes + +```html + +``` + +### Include Helper Method + +An include helper method includes another template. You can pass a pipeline (parameter) from the including template to the included template. + +```ace += include templatePathWithoutExtension pipeline +``` + +### Javascript Helper Method + +A javascript helper method generates a script tag which has "text/javascript" type. + +```ace += javascript + var msg = 'Hello Ace'; + alert(msg); +``` + +becomes + +```html + +``` + +### Yield Helper Method + +A yield helper method generates the HTML tags which are defined in the inner template. This helper method must be used only in the base template. + +``` += yield main + | This message is rendered if the "main" content is not defined in the inner template. + += yield sub + | This message is rendered if the "sub" content is not defined in the inner template. +``` + +## Comments + +A line which starts with a slash (/) or double slash (//) is interpreted as a comment. A line which starts with a slash (/) is not rendered. A line which starts with a double slash (//) is renderd as an HTML comment. + +```ace +/ This is a single line comment which is not rendered. +/ + This is a multiple lines comment + which is not rendered. +// This is a single line comment which is rendered as an HTML comment. +// + This is a multiple lines comment + which is rendered as an HTML comment. +``` + +becomes + +```html + + +``` + +## Actions + +[Actions](http://golang.org/pkg/text/template/#hdr-Actions) of the template package can be embedded in Ace templates. + +```ace +body + h1 Base Template : {{.Msg}} + {{if true}} + p Conditional block + {{end}} +``` + +The following functions are predefined. + +### HTML function + +HTML function returns a non-escaped stirng. + +```ace +{{"
"}} +{{HTML "
"}} +``` + +becomes + +```html +<br> +
+``` diff --git a/vendor/src/github.com/yosssi/ace/element.go b/vendor/src/github.com/yosssi/ace/element.go new file mode 100644 index 0000000..67bee22 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/element.go @@ -0,0 +1,72 @@ +package ace + +import ( + "fmt" + "io" +) + +// Helper method names +const ( + helperMethodNameConditionalComment = "conditionalComment" + helperMethodNameContent = "content" + helperMethodNameCSS = "css" + helperMethodNameDoctype = "doctype" + helperMethodNameYield = "yield" + helperMethodNameInclude = "include" + helperMethodNameJavascript = "javascript" +) + +// element is an interface for storing an element. +type element interface { + io.WriterTo + AppendChild(child element) + ContainPlainText() bool + Base() *elementBase + CanHaveChildren() bool + InsertBr() bool + SetLastChild(lastChild bool) +} + +// newElement creates and returns an element. +func newElement(ln *line, rslt *result, src *source, parent element, opts *Options) (element, error) { + var e element + var err error + + switch { + case parent != nil && parent.ContainPlainText(): + e = newPlainTextInner(ln, rslt, src, parent, parent.InsertBr(), opts) + case ln.isEmpty(): + e = newEmptyElement(ln, rslt, src, parent, opts) + case ln.isComment(): + e = newComment(ln, rslt, src, parent, opts) + case ln.isHTMLComment(): + e = newHTMLComment(ln, rslt, src, parent, opts) + case ln.isHelperMethod(): + switch { + case ln.isHelperMethodOf(helperMethodNameConditionalComment): + e, err = newHelperMethodConditionalComment(ln, rslt, src, parent, opts) + case ln.isHelperMethodOf(helperMethodNameContent): + e, err = newHelperMethodContent(ln, rslt, src, parent, opts) + case ln.isHelperMethodOf(helperMethodNameCSS): + e = newHelperMethodCSS(ln, rslt, src, parent, opts) + case ln.isHelperMethodOf(helperMethodNameDoctype): + e, err = newHelperMethodDoctype(ln, rslt, src, parent, opts) + case ln.isHelperMethodOf(helperMethodNameInclude): + e, err = newHelperMethodInclude(ln, rslt, src, parent, opts) + case ln.isHelperMethodOf(helperMethodNameJavascript): + e = newHelperMethodJavascript(ln, rslt, src, parent, opts) + case ln.isHelperMethodOf(helperMethodNameYield): + e, err = newHelperMethodYield(ln, rslt, src, parent, opts) + default: + err = fmt.Errorf("the helper method name is invalid [file: %s][line: %d]", ln.fileName(), ln.no) + } + case ln.isPlainText(): + e = newPlainText(ln, rslt, src, parent, opts) + case ln.isAction(): + e = newAction(ln, rslt, src, parent, opts) + default: + e, err = newHTMLTag(ln, rslt, src, parent, opts) + } + + return e, err +} diff --git a/vendor/src/github.com/yosssi/ace/element_base.go b/vendor/src/github.com/yosssi/ace/element_base.go new file mode 100644 index 0000000..d7a58cc --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/element_base.go @@ -0,0 +1,76 @@ +package ace + +import "bytes" + +// elementBase holds common fields for the elements. +type elementBase struct { + ln *line + rslt *result + src *source + parent element + children []element + opts *Options + lastChild bool +} + +// AppendChild appends the child element to the element. +func (e *elementBase) AppendChild(child element) { + e.children = append(e.children, child) +} + +// ContainPlainText returns false. +// This method should be overrided by a struct which contains +// the element base struct. +func (e *elementBase) ContainPlainText() bool { + return false +} + +// Base returns the element base. +func (e *elementBase) Base() *elementBase { + return e +} + +// CanHaveChildren returns true. +// This method should be overrided by a struct which contains +// the element base struct. +func (e *elementBase) CanHaveChildren() bool { + return true +} + +// InsertBr returns false. +// This method should be overrided by a struct which contains +// the element base struct. +func (e *elementBase) InsertBr() bool { + return false +} + +// SetLastChild set the value to the last child field. +func (e *elementBase) SetLastChild(lastChild bool) { + e.lastChild = lastChild +} + +// writeChildren writes the children's HTML. +func (e *elementBase) writeChildren(bf *bytes.Buffer) (int64, error) { + l := len(e.children) + for index, child := range e.children { + if index == l-1 { + child.SetLastChild(true) + } + + if i, err := child.WriteTo(bf); err != nil { + return int64(i), err + } + } + return 0, nil +} + +// newElementBase creates and returns an element base. +func newElementBase(ln *line, rslt *result, src *source, parent element, opts *Options) elementBase { + return elementBase{ + ln: ln, + rslt: rslt, + src: src, + parent: parent, + opts: opts, + } +} diff --git a/vendor/src/github.com/yosssi/ace/element_test.go b/vendor/src/github.com/yosssi/ace/element_test.go new file mode 100644 index 0000000..f52012f --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/element_test.go @@ -0,0 +1,7 @@ +package ace + +import "testing" + +func Test_newElement(t *testing.T) { + +} diff --git a/vendor/src/github.com/yosssi/ace/empty_element.go b/vendor/src/github.com/yosssi/ace/empty_element.go new file mode 100644 index 0000000..ea2abfd --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/empty_element.go @@ -0,0 +1,25 @@ +package ace + +import "io" + +// emptyElement represents an empty element. +type emptyElement struct { + elementBase +} + +// Do nothing. +func (e *emptyElement) WriteTo(w io.Writer) (int64, error) { + return 0, nil +} + +// CanHaveChildren returns false. +func (e *emptyElement) CanHaveChildren() bool { + return false +} + +// newEmpty creates and returns an empty element. +func newEmptyElement(ln *line, rslt *result, src *source, parent element, opts *Options) *emptyElement { + return &emptyElement{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + } +} diff --git a/vendor/src/github.com/yosssi/ace/examples/README.md b/vendor/src/github.com/yosssi/ace/examples/README.md new file mode 100644 index 0000000..87eb868 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/README.md @@ -0,0 +1,24 @@ +# Examples + +This documentation shows the examples of the web applications which use the Ace template engine. + +## Basic + +* [Single Template](single_template) +* [Base and Inner Template](base_inner_template) +* [HTML Tags](html_tags) +* [Plain Texts](plain_texts) +* [CSS and Javascript Helper Method](css_javascript_helper_method) +* [Comments](comments) +* [Include Helper Method](include_helper_method) +* [Actions](actions) + +## Advanced + +* [Dynamic Reload](dynamic_reload) +* [Load Templates from Binary Data](load_templates_from_binary_data) +* [Pass a Pipeline (Parameter) to the Included Template](pass_pipeline_to_included_template) +* [Set a Default Value to the Yield Helper Method](set_default_value_to_the_yield_helper_method) +* [Change the Action Delimiter](change_action_delimiter) +* [Set Custom Functions](set_custom_functions) +* [Cache Options](cache_options) diff --git a/vendor/src/github.com/yosssi/ace/examples/actions/README.md b/vendor/src/github.com/yosssi/ace/examples/actions/README.md new file mode 100644 index 0000000..9299e6a --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/actions/README.md @@ -0,0 +1,3 @@ +# Actions + +This example shows how to embed actions in Ace templates. diff --git a/vendor/src/github.com/yosssi/ace/examples/actions/example.ace b/vendor/src/github.com/yosssi/ace/examples/actions/example.ace new file mode 100644 index 0000000..3f10f29 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/actions/example.ace @@ -0,0 +1,15 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title {{.Title}} + body + h1 {{.Title}} + ul + {{range .Msgs}} + li {{.}} + {{end}} + div + {{"
Escaped String
"}} + div + {{HTML "
Non-Escaped String
"}} diff --git a/vendor/src/github.com/yosssi/ace/examples/actions/main.go b/vendor/src/github.com/yosssi/ace/examples/actions/main.go new file mode 100644 index 0000000..812998e --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/actions/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + data := map[string]interface{}{ + "Title": "Actions", + "Msgs": []string{ + "Message1", + "Message2", + "Message3", + }, + } + if err := tpl.Execute(w, data); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/base_inner_template/README.md b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/README.md new file mode 100644 index 0000000..9f7aba7 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/README.md @@ -0,0 +1,3 @@ +# Base and Inner Template + +This example shows how to use a base and inner Ace template file. diff --git a/vendor/src/github.com/yosssi/ace/examples/base_inner_template/base.ace b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/base.ace new file mode 100644 index 0000000..a381369 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/base.ace @@ -0,0 +1,9 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Base and Inner Template + body + h1 This is a base template + = yield main + = yield sub diff --git a/vendor/src/github.com/yosssi/ace/examples/base_inner_template/inner.ace b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/inner.ace new file mode 100644 index 0000000..5341fc9 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/inner.ace @@ -0,0 +1,5 @@ += content main + h2 This is a content named "main" of an inner template. + += content sub + h2 This is a content named "sub" of an inner template. diff --git a/vendor/src/github.com/yosssi/ace/examples/base_inner_template/main.go b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/main.go new file mode 100644 index 0000000..61c4cd0 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/base_inner_template/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("base", "inner", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/cache_options/README.md b/vendor/src/github.com/yosssi/ace/examples/cache_options/README.md new file mode 100644 index 0000000..adc1f2f --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/cache_options/README.md @@ -0,0 +1,3 @@ +# Cache Options + +This example shows how to cache the options for Ace template engine so that you don't have to specify them every time calling the Ace APIs. diff --git a/vendor/src/github.com/yosssi/ace/examples/cache_options/main.go b/vendor/src/github.com/yosssi/ace/examples/cache_options/main.go new file mode 100644 index 0000000..588a32c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/cache_options/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" + "github.com/yosssi/ace-proxy" +) + +var p = proxy.New(&ace.Options{BaseDir: "views", DynamicReload: true}) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := p.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/cache_options/views/example.ace b/vendor/src/github.com/yosssi/ace/examples/cache_options/views/example.ace new file mode 100644 index 0000000..ef3df41 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/cache_options/views/example.ace @@ -0,0 +1,7 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Cache Options + body + h1 Cache Options diff --git a/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/README.md b/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/README.md new file mode 100644 index 0000000..09e78c8 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/README.md @@ -0,0 +1,3 @@ +# Change the Action Delimiter + +This example shows how to change the action delimiter. diff --git a/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/example.ace b/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/example.ace new file mode 100644 index 0000000..fc94c06 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/example.ace @@ -0,0 +1,7 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Change the Action Delimiter + body + h1 <%.Msg%> diff --git a/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/main.go b/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/main.go new file mode 100644 index 0000000..54e3de5 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/change_action_delimiter/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", &ace.Options{ + DelimLeft: "<%", + DelimRight: "%>", + }) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + data := map[string]interface{}{ + "Msg": "Hello Ace", + } + if err := tpl.Execute(w, data); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/comments/README.md b/vendor/src/github.com/yosssi/ace/examples/comments/README.md new file mode 100644 index 0000000..595a8bd --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/comments/README.md @@ -0,0 +1,3 @@ +# Comments + +This example shows how to define comments. diff --git a/vendor/src/github.com/yosssi/ace/examples/comments/example.ace b/vendor/src/github.com/yosssi/ace/examples/comments/example.ace new file mode 100644 index 0000000..83e815d --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/comments/example.ace @@ -0,0 +1,18 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Comments + body + / This is a single line comment which is not rendered. + / + This is a multiple lines comment + which is not rendered. + // This is a single line comment which is rendered as an HTML comment. + // + This is a multiple lines comment + which is rendered as an HTML comment. + = conditionalComment hidden IE 6 +

You are using Internet Explorer 6.

+ = conditionalComment revealed !IE + diff --git a/vendor/src/github.com/yosssi/ace/examples/comments/main.go b/vendor/src/github.com/yosssi/ace/examples/comments/main.go new file mode 100644 index 0000000..594e7cb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/comments/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/README.md b/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/README.md new file mode 100644 index 0000000..d24717c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/README.md @@ -0,0 +1,3 @@ +# CSS and Javascript Helper Method + +This example shows how to use the css and javascript helper method. diff --git a/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/example.ace b/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/example.ace new file mode 100644 index 0000000..dfd2ef3 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/example.ace @@ -0,0 +1,18 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title CSS and Javascript Helper Method + = css + h1 { + color: blue; + } + h2 { + color: green; + } + body + h1 CSS and Javascript Helper Method + h2 This example shows how to use the css and javascript helper method. + = javascript + var msg = 'CSS and Javascript Helper Method'; + alert(msg); diff --git a/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/main.go b/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/main.go new file mode 100644 index 0000000..594e7cb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/css_javascript_helper_method/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/README.md b/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/README.md new file mode 100644 index 0000000..aa09c1d --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/README.md @@ -0,0 +1,3 @@ +# Dynamic Reload + +This example shows how to reload templates dynamically. Ace caches the parsed templates by default but you can have Ace reload templates dynamically by setting the "DynamicReload" option to the Ace template enginge. This option should be used in development. diff --git a/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/example.ace b/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/example.ace new file mode 100644 index 0000000..2f7ebdf --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/example.ace @@ -0,0 +1,7 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Dynamic Reload + body + h1 Dynamic Reload diff --git a/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/main.go b/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/main.go new file mode 100644 index 0000000..d034123 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/dynamic_reload/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", &ace.Options{DynamicReload: true}) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/html_tags/README.md b/vendor/src/github.com/yosssi/ace/examples/html_tags/README.md new file mode 100644 index 0000000..34b286d --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/html_tags/README.md @@ -0,0 +1,3 @@ +# HTML Tags + +This example shows how to generate various HTML tags. diff --git a/vendor/src/github.com/yosssi/ace/examples/html_tags/example.ace b/vendor/src/github.com/yosssi/ace/examples/html_tags/example.ace new file mode 100644 index 0000000..7e81055 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/html_tags/example.ace @@ -0,0 +1,21 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title HTML Tags + body + header + h1 HTML Tags + section#main-section.class1.class2 class=class3 + #container + .wrapper + div Single text line can follow the tag name. + p.. + This is a block text. + BR tags are inserted automatically. + a href=https://github.com Go to GitHub + input type=checkbox checked= + footer + script. + var msg = 'Hello Ace'; + alert(msg); diff --git a/vendor/src/github.com/yosssi/ace/examples/html_tags/main.go b/vendor/src/github.com/yosssi/ace/examples/html_tags/main.go new file mode 100644 index 0000000..594e7cb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/html_tags/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/include_helper_method/README.md b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/README.md new file mode 100644 index 0000000..4a71490 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/README.md @@ -0,0 +1,3 @@ +# Include Helper Method + +This example shows how to use an include helper method. diff --git a/vendor/src/github.com/yosssi/ace/examples/include_helper_method/example.ace b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/example.ace new file mode 100644 index 0000000..4670d39 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/example.ace @@ -0,0 +1,8 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Include Helper Method + body + h1 This is a base template + = include inc diff --git a/vendor/src/github.com/yosssi/ace/examples/include_helper_method/inc.ace b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/inc.ace new file mode 100644 index 0000000..7a5a4bc --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/inc.ace @@ -0,0 +1 @@ +h2 This is an included template. diff --git a/vendor/src/github.com/yosssi/ace/examples/include_helper_method/main.go b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/main.go new file mode 100644 index 0000000..594e7cb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/include_helper_method/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/README.md b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/README.md new file mode 100644 index 0000000..fb72a49 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/README.md @@ -0,0 +1,13 @@ +# Load Templates from Binary Data + +This example shows how to load templates from binary data instead of template files. + +You can run this example web application by executing the following command. + +```sh +$ go run main.go asset.go +``` + +`asset.go` is created by executing `make_asset.sh`. This shell script executes [go-bindata](https://github.com/jteeuwen/go-bindata) and generates binary data from the Ace template. + +**You can compile your web application into one binary file by using this function.** diff --git a/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/asset.go b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/asset.go new file mode 100644 index 0000000..638c7a2 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/asset.go @@ -0,0 +1,68 @@ +package main + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" +) + +func bindata_read(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + return buf.Bytes(), nil +} + +func views_example_ace() ([]byte, error) { + return bindata_read([]byte{ + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0x84, 0xcb, + 0xb1, 0x11, 0x83, 0x30, 0x14, 0x03, 0xd0, 0x9e, 0x29, 0xb4, 0x40, 0x8a, + 0x74, 0x69, 0xbc, 0x41, 0x96, 0x10, 0xfc, 0x4f, 0xcc, 0x9d, 0xed, 0xcf, + 0x19, 0xa5, 0xf0, 0xf6, 0x21, 0x2c, 0x40, 0x23, 0xdd, 0xe9, 0x9e, 0x12, + 0x2c, 0x16, 0x8d, 0xdd, 0x91, 0x55, 0xcb, 0xf4, 0x0f, 0x14, 0xb6, 0x4f, + 0xf2, 0x36, 0x01, 0xd9, 0x69, 0x67, 0x01, 0xd5, 0x45, 0x2c, 0x99, 0xfd, + 0x70, 0xa5, 0xaf, 0xd6, 0xc7, 0xeb, 0x9a, 0xb5, 0xa9, 0x38, 0xde, 0x41, + 0x83, 0xbc, 0xee, 0x85, 0xf2, 0x03, 0x6b, 0x8f, 0x8a, 0x79, 0x6b, 0xec, + 0x03, 0x46, 0xf1, 0x94, 0x73, 0xd8, 0xb8, 0x0e, 0xf9, 0x79, 0xab, 0x7f, + 0x01, 0x00, 0x00, 0xff, 0xff, 0x6b, 0xc6, 0x6a, 0x49, 0x92, 0x00, 0x00, + 0x00, + }, + "views/example.ace", + ) +} + + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + if f, ok := _bindata[name]; ok { + return f() + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string] func() ([]byte, error) { + "views/example.ace": views_example_ace, +} diff --git a/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/main.go b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/main.go new file mode 100644 index 0000000..ce32d81 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("views/example", "", &ace.Options{ + Asset: Asset, + }) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/make_asset.sh b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/make_asset.sh new file mode 100644 index 0000000..f2ffa2f --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/make_asset.sh @@ -0,0 +1,2 @@ +#!/bin/sh +go-bindata -o asset.go views diff --git a/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/views/example.ace b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/views/example.ace new file mode 100644 index 0000000..bfb6b14 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/load_templates_from_binary_data/views/example.ace @@ -0,0 +1,7 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Load templates from binary data + body + h1 Load templates from binary data diff --git a/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/README.md b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/README.md new file mode 100644 index 0000000..8037d5c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/README.md @@ -0,0 +1,3 @@ +# Pass a Pipeline (Parameter) to the Included Template + +This example shows how to pass a pipeline (parameter) to the included template. diff --git a/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/example.ace b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/example.ace new file mode 100644 index 0000000..3d3c7b5 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/example.ace @@ -0,0 +1,11 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Pass a Pipeline (Parameter) to the Included Template + body + h1 Pass a Pipeline (Parameter) to the Included Template + ul + {{range .Pets}} + = include pet . + {{end}} diff --git a/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/main.go b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/main.go new file mode 100644 index 0000000..fc01a8c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +// Pet represents a pet. +type Pet struct { + Species string + Name string + Age int +} + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + data := map[string]interface{}{ + "Pets": []Pet{ + Pet{Species: "Dog", Name: "Taro", Age: 5}, + Pet{Species: "Cat", Name: "Hanako", Age: 10}, + Pet{Species: "Rabbit", Name: "Jiro", Age: 1}, + }, + } + if err := tpl.Execute(w, data); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/pet.ace b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/pet.ace new file mode 100644 index 0000000..469dd9c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/pass_pipeline_to_included_template/pet.ace @@ -0,0 +1 @@ +li {{.Species}}, {{.Name}}, {{.Age}} diff --git a/vendor/src/github.com/yosssi/ace/examples/plain_texts/README.md b/vendor/src/github.com/yosssi/ace/examples/plain_texts/README.md new file mode 100644 index 0000000..b01a502 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/plain_texts/README.md @@ -0,0 +1,3 @@ +# Plain Texts + +This example shows how to generate plain texts. diff --git a/vendor/src/github.com/yosssi/ace/examples/plain_texts/example.ace b/vendor/src/github.com/yosssi/ace/examples/plain_texts/example.ace new file mode 100644 index 0000000..e660ef6 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/plain_texts/example.ace @@ -0,0 +1,17 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Plain Texts + body + div + | This is a single line. + div + | + This is a + block line. + div + || + This is a + block line + with BR tags. diff --git a/vendor/src/github.com/yosssi/ace/examples/plain_texts/main.go b/vendor/src/github.com/yosssi/ace/examples/plain_texts/main.go new file mode 100644 index 0000000..594e7cb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/plain_texts/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/README.md b/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/README.md new file mode 100644 index 0000000..df79161 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/README.md @@ -0,0 +1,3 @@ +# Set Custom Functions + +This example shows how to set custom functions. diff --git a/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/example.ace b/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/example.ace new file mode 100644 index 0000000..1d962c5 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/example.ace @@ -0,0 +1,7 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Set Custom Functions + body + h1 {{Greeting "Ace"}} diff --git a/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/main.go b/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/main.go new file mode 100644 index 0000000..f8b8ebd --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/set_custom_functions/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "html/template" + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + funcMap := template.FuncMap{ + "Greeting": func(s string) string { + return "Hello " + s + }, + } + tpl, err := ace.Load("example", "", &ace.Options{ + FuncMap: funcMap, + }) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/README.md b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/README.md new file mode 100644 index 0000000..37b807c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/README.md @@ -0,0 +1,3 @@ +# Set a Default Value to the Yield Helper Method + +This example shows how to set a default value to the yield helper method. diff --git a/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/base.ace b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/base.ace new file mode 100644 index 0000000..83513e2 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/base.ace @@ -0,0 +1,11 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Set a Default Value to the Yield Helper Method + body + h1 This is a base template + = yield main + | This message is rendered if the "main" content is not defined in the inner template. + = yield sub + | This message is rendered if the "sub" content is not defined in the inner template. diff --git a/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/inner.ace b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/inner.ace new file mode 100644 index 0000000..d75f033 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/inner.ace @@ -0,0 +1,2 @@ += content main + h2 This is a content named "main" of an inner template. diff --git a/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/main.go b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/main.go new file mode 100644 index 0000000..61c4cd0 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/set_default_value_to_the_yield_helper_method/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("base", "inner", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/examples/single_template/README.md b/vendor/src/github.com/yosssi/ace/examples/single_template/README.md new file mode 100644 index 0000000..1145984 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/single_template/README.md @@ -0,0 +1,3 @@ +# Single Template + +This example shows how to build a web application which uses a single Ace template file. diff --git a/vendor/src/github.com/yosssi/ace/examples/single_template/example.ace b/vendor/src/github.com/yosssi/ace/examples/single_template/example.ace new file mode 100644 index 0000000..64f68ed --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/single_template/example.ace @@ -0,0 +1,7 @@ += doctype html +html lang=en + head + meta charset=utf-8 + title Single Template + body + h1 Single Template diff --git a/vendor/src/github.com/yosssi/ace/examples/single_template/main.go b/vendor/src/github.com/yosssi/ace/examples/single_template/main.go new file mode 100644 index 0000000..594e7cb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/examples/single_template/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "net/http" + + "github.com/yosssi/ace" +) + +func handler(w http.ResponseWriter, r *http.Request) { + tpl, err := ace.Load("example", "", nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := tpl.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/vendor/src/github.com/yosssi/ace/file.go b/vendor/src/github.com/yosssi/ace/file.go new file mode 100644 index 0000000..998ffa1 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/file.go @@ -0,0 +1,15 @@ +package ace + +// File represents a file. +type File struct { + path string + data []byte +} + +// NewFile creates and returns a file. +func NewFile(path string, data []byte) *File { + return &File{ + path: path, + data: data, + } +} diff --git a/vendor/src/github.com/yosssi/ace/helper_method_conditional_comment.go b/vendor/src/github.com/yosssi/ace/helper_method_conditional_comment.go new file mode 100644 index 0000000..548b455 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/helper_method_conditional_comment.go @@ -0,0 +1,105 @@ +package ace + +import ( + "bytes" + "fmt" + "io" + "strings" +) + +// Comment types +const ( + commentTypeHidden = "hidden" + commentTypeRevealed = "revealed" +) + +// helperMethodConditionalComment represents a helper method +// conditional comment. +type helperMethodConditionalComment struct { + elementBase + commentType string + condition string +} + +// WriteTo writes data to w. +func (e *helperMethodConditionalComment) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + // Write an open tag. + bf.WriteString(e.opts.DelimLeft) + bf.WriteString(preDefinedFuncNameHTML) + bf.WriteString(space) + bf.WriteString(doubleQuote) + bf.WriteString(lt) + bf.WriteString(exclamation) + bf.WriteString(doubleQuote) + bf.WriteString(e.opts.DelimRight) + if e.commentType == commentTypeHidden { + bf.WriteString(hyphen) + bf.WriteString(hyphen) + } + bf.WriteString(bracketOpen) + bf.WriteString("if ") + bf.WriteString(e.condition) + bf.WriteString(bracketClose) + bf.WriteString(gt) + + bf.WriteString(lf) + + // Write the children's HTML. + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + + // Write a close tag. + bf.WriteString(e.opts.DelimLeft) + bf.WriteString(preDefinedFuncNameHTML) + bf.WriteString(space) + bf.WriteString(doubleQuote) + bf.WriteString(lt) + bf.WriteString(exclamation) + bf.WriteString(doubleQuote) + bf.WriteString(e.opts.DelimRight) + bf.WriteString(bracketOpen) + bf.WriteString("endif") + bf.WriteString(bracketClose) + if e.commentType == commentTypeHidden { + bf.WriteString(hyphen) + bf.WriteString(hyphen) + } + bf.WriteString(gt) + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// ContainPlainText returns true. +func (e *helperMethodConditionalComment) ContainPlainText() bool { + return true +} + +// newHelperMethodConditionalComment creates and returns an HTML comment. +func newHelperMethodConditionalComment(ln *line, rslt *result, src *source, parent element, opts *Options) (*helperMethodConditionalComment, error) { + switch len(ln.tokens) { + case 2: + return nil, fmt.Errorf("no comment type is specified [file: %s][line: %d]", ln.fileName(), ln.no) + case 3: + return nil, fmt.Errorf("no condition is specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + commentType := ln.tokens[2] + + if commentType != commentTypeHidden && commentType != commentTypeRevealed { + return nil, fmt.Errorf("the comment type is invalid [file: %s][line: %d]", ln.fileName(), ln.no) + } + + e := &helperMethodConditionalComment{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + commentType: commentType, + condition: strings.Join(ln.tokens[3:], space), + } + + return e, nil +} diff --git a/vendor/src/github.com/yosssi/ace/helper_method_content.go b/vendor/src/github.com/yosssi/ace/helper_method_content.go new file mode 100644 index 0000000..a020cf5 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/helper_method_content.go @@ -0,0 +1,53 @@ +package ace + +import ( + "bytes" + "fmt" + "io" +) + +// helperMethodContent represents a helper method content. +type helperMethodContent struct { + elementBase + name string +} + +// WriteTo writes data to w. +func (e *helperMethodContent) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + inner := e.src.inner + if inner == nil { + return 0, fmt.Errorf("inner is not specified [file: %s][line: %d]", e.ln.fileName(), e.ln.no) + } + + // Write a define action. + bf.WriteString(fmt.Sprintf(actionDefine, e.opts.DelimLeft, inner.path+doubleColon+e.name, e.opts.DelimRight)) + + // Write the children's HTML. + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + + // Write an end action. + bf.WriteString(fmt.Sprintf(actionEnd, e.opts.DelimLeft, e.opts.DelimRight)) + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// newHelperMethodContent creates and returns a helper method content. +func newHelperMethodContent(ln *line, rslt *result, src *source, parent element, opts *Options) (*helperMethodContent, error) { + if len(ln.tokens) < 3 || ln.tokens[2] == "" { + return nil, fmt.Errorf("no name is specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + e := &helperMethodContent{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + name: ln.tokens[2], + } + + return e, nil +} diff --git a/vendor/src/github.com/yosssi/ace/helper_method_css.go b/vendor/src/github.com/yosssi/ace/helper_method_css.go new file mode 100644 index 0000000..df800ae --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/helper_method_css.go @@ -0,0 +1,51 @@ +package ace + +import ( + "bytes" + "io" +) + +// helperMethodCSS represents a helper method css. +type helperMethodCSS struct { + elementBase +} + +// WriteTo writes data to w. +func (e *helperMethodCSS) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + // Write an open tag. + bf.WriteString(lt) + bf.WriteString(`style type="text/css"`) + bf.WriteString(gt) + + bf.WriteString(lf) + + // Write the children's HTML. + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + + // Write an open tag. + bf.WriteString(lt) + bf.WriteString(slash) + bf.WriteString("style") + bf.WriteString(gt) + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// ContainPlainText returns true. +func (e *helperMethodCSS) ContainPlainText() bool { + return true +} + +// helperMethodCSS creates and returns a helper method css. +func newHelperMethodCSS(ln *line, rslt *result, src *source, parent element, opts *Options) *helperMethodCSS { + return &helperMethodCSS{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + } +} diff --git a/vendor/src/github.com/yosssi/ace/helper_method_doctype.go b/vendor/src/github.com/yosssi/ace/helper_method_doctype.go new file mode 100644 index 0000000..bf1918d --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/helper_method_doctype.go @@ -0,0 +1,50 @@ +package ace + +import ( + "fmt" + "io" +) + +// Doctypes +var doctypes = map[string]string{ + "html": ``, + "xml": ``, + "transitional": ``, + "strict": ``, + "frameset": ``, + "1.1": ``, + "basic": ``, + "mobile": ``, +} + +// helperMethodDoctype represents a helper method doctype. +type helperMethodDoctype struct { + elementBase + doctype string +} + +// WriteTo writes data to w. +func (e *helperMethodDoctype) WriteTo(w io.Writer) (int64, error) { + i, err := w.Write([]byte(doctypes[e.doctype])) + return int64(i), err +} + +// newHelperMethodDoctype creates and returns a helper method doctype. +func newHelperMethodDoctype(ln *line, rslt *result, src *source, parent element, opts *Options) (*helperMethodDoctype, error) { + if len(ln.tokens) < 3 { + return nil, fmt.Errorf("doctype is not specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + doctype := ln.tokens[2] + + if _, ok := doctypes[doctype]; !ok { + return nil, fmt.Errorf("doctype is invalid [file: %s][line: %d][doctype: %s]", ln.fileName(), ln.no, doctype) + } + + e := &helperMethodDoctype{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + doctype: doctype, + } + + return e, nil +} diff --git a/vendor/src/github.com/yosssi/ace/helper_method_include.go b/vendor/src/github.com/yosssi/ace/helper_method_include.go new file mode 100644 index 0000000..bdcafd2 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/helper_method_include.go @@ -0,0 +1,50 @@ +package ace + +import ( + "fmt" + "io" + "strings" +) + +// helperMethodInclude represents a helper method include. +type helperMethodInclude struct { + elementBase + templateName string + pipeline string +} + +// WriteTo writes data to w. +func (e *helperMethodInclude) WriteTo(w io.Writer) (int64, error) { + var s string + + if e.pipeline == "" { + s = fmt.Sprintf(actionTemplate, e.opts.DelimLeft, e.templateName, e.opts.DelimRight) + } else { + s = fmt.Sprintf(actionTemplateWithPipeline, e.opts.DelimLeft, e.templateName, e.pipeline, e.opts.DelimRight) + } + + i, err := w.Write([]byte(s)) + + return int64(i), err +} + +// newHelperMethodInclude creates and returns a helper method include. +func newHelperMethodInclude(ln *line, rslt *result, src *source, parent element, opts *Options) (*helperMethodInclude, error) { + if len(ln.tokens) < 3 { + return nil, fmt.Errorf("no template name is specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + var pipeline string + + if len(ln.tokens) > 3 { + pipeline = strings.Join(ln.tokens[3:], space) + } + + e := &helperMethodInclude{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + templateName: ln.tokens[2], + pipeline: pipeline, + } + + return e, nil +} diff --git a/vendor/src/github.com/yosssi/ace/helper_method_javascript.go b/vendor/src/github.com/yosssi/ace/helper_method_javascript.go new file mode 100644 index 0000000..d7af21a --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/helper_method_javascript.go @@ -0,0 +1,51 @@ +package ace + +import ( + "bytes" + "io" +) + +// helperMethodJavascript represents a helper method javascript. +type helperMethodJavascript struct { + elementBase +} + +// WriteTo writes data to w. +func (e *helperMethodJavascript) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + // Write an open tag. + bf.WriteString(lt) + bf.WriteString(`script type="text/javascript"`) + bf.WriteString(gt) + + bf.WriteString(lf) + + // Write the children's HTML. + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + + // Write an open tag. + bf.WriteString(lt) + bf.WriteString(slash) + bf.WriteString("script") + bf.WriteString(gt) + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// ContainPlainText returns true. +func (e *helperMethodJavascript) ContainPlainText() bool { + return true +} + +// helperMethodJavascript creates and returns a helper method javascript. +func newHelperMethodJavascript(ln *line, rslt *result, src *source, parent element, opts *Options) *helperMethodJavascript { + return &helperMethodJavascript{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + } +} diff --git a/vendor/src/github.com/yosssi/ace/helper_method_yield.go b/vendor/src/github.com/yosssi/ace/helper_method_yield.go new file mode 100644 index 0000000..b34a010 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/helper_method_yield.go @@ -0,0 +1,60 @@ +package ace + +import ( + "bytes" + "fmt" + "io" +) + +// helperMethodYield represents a helper method yield. +type helperMethodYield struct { + elementBase + templateName string +} + +// WriteTo writes data to w. +func (e *helperMethodYield) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + inner := e.src.inner + if inner == nil { + return 0, fmt.Errorf("inner is not specified [file: %s][line: %d]", e.ln.fileName(), e.ln.no) + } + + var templateExists bool + + for _, innerE := range e.rslt.inner { + ln := innerE.Base().ln + if ln.isHelperMethodOf(helperMethodNameContent) && len(ln.tokens) > 2 && ln.tokens[2] == e.templateName { + templateExists = true + break + } + } + + if templateExists { + bf.WriteString(fmt.Sprintf(actionTemplateWithPipeline, e.opts.DelimLeft, inner.path+doubleColon+e.templateName, dot, e.opts.DelimRight)) + } else { + // Write the children's HTML. + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + } + + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// newHelperMethodYield creates and returns a helper method yield. +func newHelperMethodYield(ln *line, rslt *result, src *source, parent element, opts *Options) (*helperMethodYield, error) { + if len(ln.tokens) < 3 { + return nil, fmt.Errorf("no template name is specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + e := &helperMethodYield{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + templateName: ln.tokens[2], + } + + return e, nil +} diff --git a/vendor/src/github.com/yosssi/ace/html_comment.go b/vendor/src/github.com/yosssi/ace/html_comment.go new file mode 100644 index 0000000..9e863e6 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/html_comment.go @@ -0,0 +1,69 @@ +package ace + +import ( + "bytes" + "io" + "strings" +) + +// htmlComment represents an HTML comment. +type htmlComment struct { + elementBase +} + +// WriteTo writes data to w. +func (e *htmlComment) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + // Write an open tag. + bf.WriteString(e.opts.DelimLeft) + bf.WriteString(preDefinedFuncNameHTML) + bf.WriteString(space) + bf.WriteString(doubleQuote) + bf.WriteString(lt) + bf.WriteString(exclamation) + bf.WriteString(doubleQuote) + bf.WriteString(e.opts.DelimRight) + bf.WriteString(hyphen) + bf.WriteString(hyphen) + + // Write the HTML comment + if len(e.ln.tokens) > 1 { + bf.WriteString(space) + bf.WriteString(strings.Join(e.ln.tokens[1:], space)) + } + + // Write the children's HTML. + if len(e.children) > 0 { + bf.WriteString(lf) + + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + } else { + bf.WriteString(space) + + } + + // Write a close tag. + bf.WriteString(hyphen) + bf.WriteString(hyphen) + bf.WriteString(gt) + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// ContainPlainText returns true. +func (e *htmlComment) ContainPlainText() bool { + return true +} + +// newHTMLComment creates and returns an HTML comment. +func newHTMLComment(ln *line, rslt *result, src *source, parent element, opts *Options) *htmlComment { + return &htmlComment{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + } +} diff --git a/vendor/src/github.com/yosssi/ace/html_tag.go b/vendor/src/github.com/yosssi/ace/html_tag.go new file mode 100644 index 0000000..a971108 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/html_tag.go @@ -0,0 +1,305 @@ +package ace + +import ( + "bytes" + "fmt" + "io" + "strings" +) + +// Tag names +const ( + tagNameDiv = "div" +) + +// Attribute names +const ( + attributeNameID = "id" +) + +// htmlAttribute represents an HTML attribute. +type htmlAttribute struct { + key string + value string +} + +// htmlTag represents an HTML tag. +type htmlTag struct { + elementBase + tagName string + id string + classes []string + containPlainText bool + insertBr bool + attributes []htmlAttribute + textValue string +} + +// WriteTo writes data to w. +func (e *htmlTag) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + // Write an open tag. + bf.WriteString(lt) + bf.WriteString(e.tagName) + // Write an id. + if e.id != "" { + bf.WriteString(space) + bf.WriteString(attributeNameID) + bf.WriteString(equal) + bf.WriteString(doubleQuote) + bf.WriteString(e.id) + bf.WriteString(doubleQuote) + } + // Write classes. + if len(e.classes) > 0 { + bf.WriteString(space) + bf.WriteString(e.opts.AttributeNameClass) + bf.WriteString(equal) + bf.WriteString(doubleQuote) + for i, class := range e.classes { + if i > 0 { + bf.WriteString(space) + } + bf.WriteString(class) + } + bf.WriteString(doubleQuote) + } + // Write attributes. + if len(e.attributes) > 0 { + + for _, a := range e.attributes { + bf.WriteString(space) + bf.WriteString(a.key) + if a.value != "" { + bf.WriteString(equal) + bf.WriteString(doubleQuote) + bf.WriteString(a.value) + bf.WriteString(doubleQuote) + } + } + } + bf.WriteString(gt) + + // Write a text value + if e.textValue != "" { + bf.WriteString(e.textValue) + } + + if e.containPlainText { + bf.WriteString(lf) + } + + // Write children's HTML. + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + + // Write a close tag. + if !e.noCloseTag() { + bf.WriteString(lt) + bf.WriteString(slash) + bf.WriteString(e.tagName) + bf.WriteString(gt) + } + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// ContainPlainText returns the HTML tag's containPlainText field. +func (e *htmlTag) ContainPlainText() bool { + return e.containPlainText +} + +// InsertBr returns true if the br tag is inserted to the line. +func (e *htmlTag) InsertBr() bool { + return e.insertBr +} + +// setAttributes parses the tokens and set attributes to the element. +func (e *htmlTag) setAttributes() error { + parsedTokens := e.parseTokens() + + var i int + var token string + var setTextValue bool + + // Set attributes to the element. + for i, token = range parsedTokens { + kv := strings.Split(token, equal) + + if len(kv) < 2 { + setTextValue = true + break + } + + k := kv[0] + v := strings.Join(kv[1:], equal) + + // Remove the prefix and suffix of the double quotes. + if len(v) > 1 && strings.HasPrefix(v, doubleQuote) && strings.HasSuffix(v, doubleQuote) { + v = v[1 : len(v)-1] + } + + switch k { + case attributeNameID: + if e.id != "" { + return fmt.Errorf("multiple IDs are specified [file: %s][line: %d]", e.ln.fileName(), e.ln.no) + } + e.id = v + case e.opts.AttributeNameClass: + e.classes = append(e.classes, strings.Split(v, space)...) + default: + e.attributes = append(e.attributes, htmlAttribute{k, v}) + } + } + + // Set a text value to the element. + if setTextValue { + e.textValue = strings.Join(parsedTokens[i:], space) + } + + return nil +} + +// noCloseTag returns true is the HTML tag has no close tag. +func (e *htmlTag) noCloseTag() bool { + for _, name := range e.opts.NoCloseTagNames { + if e.tagName == name { + return true + } + } + + return false +} + +// newHTMLTag creates and returns an HTML tag. +func newHTMLTag(ln *line, rslt *result, src *source, parent element, opts *Options) (*htmlTag, error) { + if len(ln.tokens) < 1 { + return nil, fmt.Errorf("an HTML tag is not specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + s := ln.tokens[0] + + tagName := extractTagName(s) + + id, err := extractID(s, ln) + if err != nil { + return nil, err + } + + classes := extractClasses(s) + + e := &htmlTag{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + tagName: tagName, + id: id, + classes: classes, + containPlainText: strings.HasSuffix(s, dot), + insertBr: strings.HasSuffix(s, doubleDot), + attributes: make([]htmlAttribute, 0, 2), + } + + if err := e.setAttributes(); err != nil { + return nil, err + } + + return e, nil +} + +// extractTag extracts and returns a tag. +func extractTagName(s string) string { + tagName := strings.Split(strings.Split(s, sharp)[0], dot)[0] + + if tagName == "" { + tagName = tagNameDiv + } + + return tagName +} + +// extractID extracts and returns an ID. +func extractID(s string, ln *line) (string, error) { + tokens := strings.Split(s, sharp) + + l := len(tokens) + + if l < 2 { + return "", nil + } + + if l > 2 { + return "", fmt.Errorf("multiple IDs are specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + return strings.Split(tokens[1], dot)[0], nil +} + +// extractClasses extracts and returns classes. +func extractClasses(s string) []string { + var classes []string + + for i, token := range strings.Split(s, dot) { + if i == 0 { + continue + } + + class := strings.Split(token, sharp)[0] + + if class == "" { + continue + } + + classes = append(classes, class) + } + + return classes +} + +// parseTokens parses the tokens and return them +func (e *htmlTag) parseTokens() []string { + var inQuote bool + var inDelim bool + var tokens []string + var token string + + str := strings.Join(e.ln.tokens[1:], space) + for _, chr := range str { + switch c := string(chr); c { + case space: + if inQuote || inDelim { + token += c + } else { + tokens = append(tokens, token) + token = "" + } + case doubleQuote: + if !inDelim { + if inQuote { + inQuote = false + } else { + inQuote = true + } + } + token += c + default: + token += c + if inDelim { + if strings.HasSuffix(token, e.opts.DelimRight) { + inDelim = false + } + } else { + if strings.HasSuffix(token, e.opts.DelimLeft) { + inDelim = true + } + } + } + } + if len(token) > 0 { + tokens = append(tokens, token) + } + return tokens +} diff --git a/vendor/src/github.com/yosssi/ace/line.go b/vendor/src/github.com/yosssi/ace/line.go new file mode 100644 index 0000000..9032bdd --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/line.go @@ -0,0 +1,117 @@ +package ace + +import ( + "fmt" + "strings" +) + +const unicodeSpace = 32 + +const indentTop = 0 + +// line represents a line of codes. +type line struct { + no int + str string + indent int + tokens []string + opts *Options + file *File +} + +// isEmpty returns true if the line is empty. +func (l *line) isEmpty() bool { + return strings.TrimSpace(l.str) == "" +} + +// isTopIndent returns true if the line's indent is the top level. +func (l *line) isTopIndent() bool { + return l.indent == indentTop +} + +// isHelperMethod returns true if the line is a helper method. +func (l *line) isHelperMethod() bool { + return len(l.tokens) > 1 && l.tokens[0] == equal +} + +// isHelperMethodOf returns true if the line is a specified helper method. +func (l *line) isHelperMethodOf(name string) bool { + return l.isHelperMethod() && l.tokens[1] == name +} + +// isPlainText returns true if the line is a plain text. +func (l *line) isPlainText() bool { + return len(l.tokens) > 0 && (l.tokens[0] == pipe || l.tokens[0] == doublePipe) +} + +// isComment returns true if the line is a comment. +func (l *line) isComment() bool { + return len(l.tokens) > 0 && l.tokens[0] == slash +} + +// isHTMLComment returns true if the line is an HTML comment. +func (l *line) isHTMLComment() bool { + return len(l.tokens) > 0 && l.tokens[0] == slash+slash +} + +// isAction returns true if the line is an action. +func (l *line) isAction() bool { + str := strings.TrimSpace(l.str) + return strings.HasPrefix(str, l.opts.DelimLeft) && strings.HasSuffix(str, l.opts.DelimRight) +} + +// fileName returns the file name. +func (l *line) fileName() string { + return l.file.path + dot + l.opts.Extension +} + +// childOf returns true is the line is a child of the element. +func (l *line) childOf(parent element) (bool, error) { + var ok bool + var err error + + switch { + case l.isEmpty(): + ok = true + case parent.ContainPlainText(): + switch { + case parent.Base().ln.indent < l.indent: + ok = true + } + default: + switch { + case l.indent == parent.Base().ln.indent+1: + ok = true + case l.indent > parent.Base().ln.indent+1: + err = fmt.Errorf("the indent is invalid [file: %s][line: %d]", l.fileName(), l.no) + } + } + + return ok, err +} + +// newLine creates and returns a line. +func newLine(no int, str string, opts *Options, f *File) *line { + return &line{ + no: no, + str: str, + indent: indent(str), + tokens: strings.Split(strings.TrimLeft(str, space), space), + opts: opts, + file: f, + } +} + +// indent returns the line's indent. +func indent(str string) int { + var i int + + for _, b := range str { + if b != unicodeSpace { + break + } + i++ + } + + return i / 2 +} diff --git a/vendor/src/github.com/yosssi/ace/options.go b/vendor/src/github.com/yosssi/ace/options.go new file mode 100644 index 0000000..a2a7a2c --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/options.go @@ -0,0 +1,93 @@ +package ace + +import "html/template" + +// Defaults +const ( + defaultExtension = "ace" + defaultDelimLeft = "{{" + defaultDelimRight = "}}" + defaultAttributeNameClass = "class" +) + +// Default NoCloseTagNames +var defaultNoCloseTagNames = []string{ + "br", + "hr", + "img", + "input", + "link", + "meta", +} + +// Options represents options for the template engine. +type Options struct { + // Extension represents an extension of files. + Extension string + // DelimLeft represents a left delimiter for the html template. + DelimLeft string + // DelimRight represents a right delimiter for the html template. + DelimRight string + // AttributeNameClass is the attribute name for classes. + AttributeNameClass string + // NoCloseTagNames defines a set of tags which should not be closed. + NoCloseTagNames []string + // DynamicReload represents a flag which means whether Ace reloads + // templates dynamically. + // This option should only be true in development. + DynamicReload bool + // BaseDir represents a base directory of the Ace templates. + BaseDir string + // Asset loads and returns the asset for the given name. + // If this function is set, Ace load the template data from + // this function instead of the template files. + Asset func(name string) ([]byte, error) + // FuncMap represents a template.FuncMap which is set to + // the result template. + FuncMap template.FuncMap +} + +// InitializeOptions initializes the options. +func InitializeOptions(opts *Options) *Options { + if opts == nil { + opts = &Options{} + } + + if opts.Extension == "" { + opts.Extension = defaultExtension + } + + if opts.DelimLeft == "" { + opts.DelimLeft = defaultDelimLeft + } + + if opts.DelimRight == "" { + opts.DelimRight = defaultDelimRight + } + + if opts.AttributeNameClass == "" { + opts.AttributeNameClass = defaultAttributeNameClass + } + if opts.NoCloseTagNames == nil { + opts.NoCloseTagNames = make([]string, len(defaultNoCloseTagNames)) + copy(opts.NoCloseTagNames, defaultNoCloseTagNames) + } + + return opts +} + +// AddNoCloseTagName appends name to .NoCloseTagNames set. +func (opts *Options) AddNoCloseTagName(name string) { + opts.NoCloseTagNames = append(opts.NoCloseTagNames, name) +} + +// DeleteNoCloseTagName deletes name from .NoCloseTagNames set. +func (opts *Options) DeleteNoCloseTagName(name string) { + var newset []string + for _, n := range opts.NoCloseTagNames { + if n != name { + newset = append(newset, n) + } + } + opts.NoCloseTagNames = newset +} diff --git a/vendor/src/github.com/yosssi/ace/parse.go b/vendor/src/github.com/yosssi/ace/parse.go new file mode 100644 index 0000000..e8df8c2 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/parse.go @@ -0,0 +1,114 @@ +package ace + +import "strings" + +// ParseSource parses the source and returns the result. +func ParseSource(src *source, opts *Options) (*result, error) { + // Initialize the options. + opts = InitializeOptions(opts) + + rslt := newResult(nil, nil, nil) + + base, err := parseBytes(src.base.data, rslt, src, opts, src.base) + if err != nil { + return nil, err + } + + inner, err := parseBytes(src.inner.data, rslt, src, opts, src.inner) + if err != nil { + return nil, err + } + + includes := make(map[string][]element) + + for _, f := range src.includes { + includes[f.path], err = parseBytes(f.data, rslt, src, opts, f) + if err != nil { + return nil, err + } + } + + rslt.base = base + rslt.inner = inner + rslt.includes = includes + + return rslt, nil +} + +// parseBytes parses the byte data and returns the elements. +func parseBytes(data []byte, rslt *result, src *source, opts *Options, f *File) ([]element, error) { + var elements []element + + lines := strings.Split(formatLF(string(data)), lf) + + i := 0 + l := len(lines) + + // Ignore the last empty line. + if l > 0 && lines[l-1] == "" { + l-- + } + + for i < l { + // Fetch a line. + ln := newLine(i+1, lines[i], opts, f) + i++ + + // Ignore the empty line. + if ln.isEmpty() { + continue + } + + if ln.isTopIndent() { + e, err := newElement(ln, rslt, src, nil, opts) + if err != nil { + return nil, err + } + + // Append child elements to the element. + if err := appendChildren(e, rslt, lines, &i, l, src, opts, f); err != nil { + return nil, err + } + + elements = append(elements, e) + } + } + + return elements, nil +} + +// appendChildren parses the lines and appends the children to the element. +func appendChildren(parent element, rslt *result, lines []string, i *int, l int, src *source, opts *Options, f *File) error { + for *i < l { + // Fetch a line. + ln := newLine(*i+1, lines[*i], opts, f) + + // Check if the line is a child of the parent. + ok, err := ln.childOf(parent) + + if err != nil { + return err + } + + if !ok { + return nil + } + + child, err := newElement(ln, rslt, src, parent, opts) + if err != nil { + return err + } + + parent.AppendChild(child) + + *i++ + + if child.CanHaveChildren() { + if err := appendChildren(child, rslt, lines, i, l, src, opts, f); err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/src/github.com/yosssi/ace/plain_text.go b/vendor/src/github.com/yosssi/ace/plain_text.go new file mode 100644 index 0000000..7f6490a --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/plain_text.go @@ -0,0 +1,57 @@ +package ace + +import ( + "bytes" + "io" + "strings" +) + +// plainText represents a plain text. +type plainText struct { + elementBase + insertBr bool +} + +// WriteTo writes data to w. +func (e *plainText) WriteTo(w io.Writer) (int64, error) { + var bf bytes.Buffer + + // Write the plain text. + bf.WriteString(strings.Join(e.ln.tokens[1:], space)) + + if len(e.ln.tokens) > 1 && e.insertBr { + bf.WriteString(htmlBr) + } + + // Write the children's HTML. + if len(e.children) > 0 { + bf.WriteString(lf) + + if i, err := e.writeChildren(&bf); err != nil { + return i, err + } + } + + // Write the buffer. + i, err := w.Write(bf.Bytes()) + + return int64(i), err +} + +// ContainPlainText returns true. +func (e *plainText) ContainPlainText() bool { + return true +} + +// InsertBr returns true if the br tag is inserted to the line. +func (e *plainText) InsertBr() bool { + return e.insertBr +} + +// newPlainText creates and returns a plain text. +func newPlainText(ln *line, rslt *result, src *source, parent element, opts *Options) *plainText { + return &plainText{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + insertBr: ln.tokens[0] == doublePipe, + } +} diff --git a/vendor/src/github.com/yosssi/ace/plain_text_inner.go b/vendor/src/github.com/yosssi/ace/plain_text_inner.go new file mode 100644 index 0000000..3a70adb --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/plain_text_inner.go @@ -0,0 +1,44 @@ +package ace + +import "io" + +// HTML +const ( + htmlBr = "
" +) + +// plainTextInner represents a plain text inner. +type plainTextInner struct { + elementBase + insertBr bool +} + +// WriteTo writes data to w. +func (e *plainTextInner) WriteTo(w io.Writer) (int64, error) { + s := "" + + if (e.parent.Base().ln.indent+1)*2 <= len(e.ln.str) { + s = e.ln.str[(e.parent.Base().ln.indent+1)*2:] + } + + if e.insertBr && !e.lastChild { + s += htmlBr + } + + i, err := w.Write([]byte(s + lf)) + + return int64(i), err +} + +// CanHaveChildren returns false. +func (e *plainTextInner) CanHaveChildren() bool { + return false +} + +// newPlainTextInner creates and returns a plain text. +func newPlainTextInner(ln *line, rslt *result, src *source, parent element, insertBr bool, opts *Options) *plainTextInner { + return &plainTextInner{ + elementBase: newElementBase(ln, rslt, src, parent, opts), + insertBr: insertBr, + } +} diff --git a/vendor/src/github.com/yosssi/ace/read.go b/vendor/src/github.com/yosssi/ace/read.go new file mode 100644 index 0000000..61cb9f5 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/read.go @@ -0,0 +1,144 @@ +package ace + +import ( + "fmt" + "io/ioutil" + "path/filepath" + "strings" +) + +// Special characters +const ( + cr = "\r" + lf = "\n" + crlf = "\r\n" + + space = " " + equal = "=" + pipe = "|" + doublePipe = pipe + pipe + slash = "/" + sharp = "#" + dot = "." + doubleDot = dot + dot + colon = ":" + doubleColon = colon + colon + doubleQuote = `"` + lt = "<" + gt = ">" + exclamation = "!" + hyphen = "-" + bracketOpen = "[" + bracketClose = "]" +) + +// readFiles reads files and returns source for the parsing process. +func readFiles(basePath, innerPath string, opts *Options) (*source, error) { + // Read the base file. + base, err := readFile(basePath, opts) + if err != nil { + return nil, err + } + + // Read the inner file. + inner, err := readFile(innerPath, opts) + if err != nil { + return nil, err + } + + var includes []*File + + // Find include files from the base file. + if err := findIncludes(base.data, opts, &includes, base); err != nil { + return nil, err + } + + // Find include files from the inner file. + if err := findIncludes(inner.data, opts, &includes, inner); err != nil { + return nil, err + } + + return NewSource(base, inner, includes), nil +} + +// readFile reads a file and returns a file struct. +func readFile(path string, opts *Options) (*File, error) { + var data []byte + var err error + + if path != "" { + name := filepath.Join(opts.BaseDir, path+dot+opts.Extension) + + if opts.Asset != nil { + data, err = opts.Asset(name) + } else { + data, err = ioutil.ReadFile(name) + } + + if err != nil { + return nil, err + } + } + + return NewFile(path, data), nil +} + +// findIncludes finds and adds include files. +func findIncludes(data []byte, opts *Options, includes *[]*File, targetFile *File) error { + includePaths, err := findIncludePaths(data, opts, targetFile) + if err != nil { + return err + } + + for _, includePath := range includePaths { + if !hasFile(*includes, includePath) { + f, err := readFile(includePath, opts) + if err != nil { + return err + } + + *includes = append(*includes, f) + + if err := findIncludes(f.data, opts, includes, f); err != nil { + return err + } + } + } + + return nil +} + +// findIncludePaths finds and returns include paths. +func findIncludePaths(data []byte, opts *Options, f *File) ([]string, error) { + var includePaths []string + + for i, str := range strings.Split(formatLF(string(data)), lf) { + ln := newLine(i+1, str, opts, f) + + if ln.isHelperMethodOf(helperMethodNameInclude) { + if len(ln.tokens) < 3 { + return nil, fmt.Errorf("no template name is specified [file: %s][line: %d]", ln.fileName(), ln.no) + } + + includePaths = append(includePaths, ln.tokens[2]) + } + } + + return includePaths, nil +} + +// formatLF replaces the line feed codes with LF and returns the result. +func formatLF(s string) string { + return strings.Replace(strings.Replace(s, crlf, lf, -1), cr, lf, -1) +} + +// hasFile return if files has a file which has the path specified by the parameter. +func hasFile(files []*File, path string) bool { + for _, f := range files { + if f.path == path { + return true + } + } + + return false +} diff --git a/vendor/src/github.com/yosssi/ace/result.go b/vendor/src/github.com/yosssi/ace/result.go new file mode 100644 index 0000000..e43f455 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/result.go @@ -0,0 +1,17 @@ +package ace + +// result represents a result of the parsing process. +type result struct { + base []element + inner []element + includes map[string][]element +} + +// newResult creates and returns a result. +func newResult(base []element, inner []element, includes map[string][]element) *result { + return &result{ + base: base, + inner: inner, + includes: includes, + } +} diff --git a/vendor/src/github.com/yosssi/ace/source.go b/vendor/src/github.com/yosssi/ace/source.go new file mode 100644 index 0000000..471cfd2 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/source.go @@ -0,0 +1,17 @@ +package ace + +// source represents source for the parsing process. +type source struct { + base *File + inner *File + includes []*File +} + +// NewSource creates and returns source. +func NewSource(base, inner *File, includes []*File) *source { + return &source{ + base: base, + inner: inner, + includes: includes, + } +} diff --git a/vendor/src/github.com/yosssi/ace/wercker.yml b/vendor/src/github.com/yosssi/ace/wercker.yml new file mode 100644 index 0000000..be92c03 --- /dev/null +++ b/vendor/src/github.com/yosssi/ace/wercker.yml @@ -0,0 +1,35 @@ +box: yosssi/golang-latest@1.0.7 +# Build definition +build: + # The steps that will be executed on build + steps: + # Sets the go workspace and places you package + # at the right place in the workspace tree + - setup-go-workspace + + # Gets the dependencies + - script: + name: go get + code: | + cd $WERCKER_SOURCE_DIR + go version + go get -t ./... + + # Build the project + - script: + name: go build + code: | + go build ./... + + # Test the project + - script: + name: go test + code: | + go test -cover ./... + # Invoke goveralls + - script: + name: goveralls + code: | + go get github.com/mattn/goveralls + go test -v -covermode=count -coverprofile=coverage.out + goveralls -coverprofile=coverage.out -service=wercker.com -repotoken $COVERALLS_REPO_TOKEN