ref: 6dd2e9a49acde23dcf5e9701915f7e8ed692ce5a
parent: ff9f6e1b2a000a24e677b9a3fa8dfbdef11c404c
author: Tibor Vass <[email protected]>
date: Wed Jan 29 09:50:31 EST 2014
gofmt all go code
--- a/commands/server.go
+++ b/commands/server.go
@@ -52,11 +52,11 @@
BaseUrl = "http://" + BaseUrl
}
- if serverAppend {
- Config.BaseUrl = strings.TrimSuffix(BaseUrl, "/") + ":" + strconv.Itoa(serverPort)
- } else {
- Config.BaseUrl = strings.TrimSuffix(BaseUrl, "/")
- }
+ if serverAppend {
+ Config.BaseUrl = strings.TrimSuffix(BaseUrl, "/") + ":" + strconv.Itoa(serverPort)
+ } else {
+ Config.BaseUrl = strings.TrimSuffix(BaseUrl, "/")
+ }
build(serverWatch)
--- a/helpers/pygments.go
+++ b/helpers/pygments.go
@@ -14,32 +14,32 @@
package helpers
import (
- "bytes"
- "log"
- "os/exec"
- "strings"
+ "bytes"
+ "log"
+ "os/exec"
+ "strings"
)
func Highlight(code string, lexer string) string {
- var pygmentsBin = "pygmentize"
+ var pygmentsBin = "pygmentize"
- if _, err := exec.LookPath(pygmentsBin); err != nil {
- log.Print("Highlighting requries Pygments to be installed and in the path")
- return code
- }
+ if _, err := exec.LookPath(pygmentsBin); err != nil {
+ log.Print("Highlighting requries Pygments to be installed and in the path")
+ return code
+ }
- var out bytes.Buffer
- var stderr bytes.Buffer
+ var out bytes.Buffer
+ var stderr bytes.Buffer
- cmd := exec.Command(pygmentsBin, "-l"+lexer, "-fhtml", "-O style=monokai,noclasses=true,encoding=utf-8")
- cmd.Stdin = strings.NewReader(code)
- cmd.Stdout = &out
- cmd.Stderr = &stderr
+ cmd := exec.Command(pygmentsBin, "-l"+lexer, "-fhtml", "-O style=monokai,noclasses=true,encoding=utf-8")
+ cmd.Stdin = strings.NewReader(code)
+ cmd.Stdout = &out
+ cmd.Stderr = &stderr
- if err := cmd.Run(); err != nil {
- log.Print(stderr.String())
- return code
- }
+ if err := cmd.Run(); err != nil {
+ log.Print(stderr.String())
+ return code
+ }
- return out.String()
+ return out.String()
}
--- a/hugolib/config.go
+++ b/hugolib/config.go
@@ -36,7 +36,7 @@
Params map[string]interface{}
Permalinks PermalinkOverrides
BuildDrafts, UglyUrls, Verbose bool
- CanonifyUrls bool
+ CanonifyUrls bool
}
var c Config
--- a/hugolib/indexing_test.go
+++ b/hugolib/indexing_test.go
@@ -1,18 +1,18 @@
package hugolib
import (
- "strings"
- "testing"
+ "strings"
+ "testing"
)
func TestSitePossibleIndexes(t *testing.T) {
- site := new(Site)
- page, _ := ReadFrom(strings.NewReader(PAGE_YAML_WITH_INDEXES_A), "path/to/page")
- site.Pages = append(site.Pages, page)
- indexes := site.possibleIndexes()
- if !compareStringSlice(indexes, []string{"tags", "categories"}) {
- if !compareStringSlice(indexes, []string{"categories", "tags"}) {
- t.Fatalf("possible indexes do not match [tags categories]. Got: %s", indexes)
- }
- }
+ site := new(Site)
+ page, _ := ReadFrom(strings.NewReader(PAGE_YAML_WITH_INDEXES_A), "path/to/page")
+ site.Pages = append(site.Pages, page)
+ indexes := site.possibleIndexes()
+ if !compareStringSlice(indexes, []string{"tags", "categories"}) {
+ if !compareStringSlice(indexes, []string{"categories", "tags"}) {
+ t.Fatalf("possible indexes do not match [tags categories]. Got: %s", indexes)
+ }
+ }
}
--- a/hugolib/node.go
+++ b/hugolib/node.go
@@ -14,29 +14,29 @@
package hugolib
import (
- "html/template"
- "time"
+ "html/template"
+ "time"
)
type Node struct {
- RSSLink template.HTML
- Site SiteInfo
- // layout string
- Data map[string]interface{}
- Title string
- Description string
- Keywords []string
- Date time.Time
- UrlPath
+ RSSLink template.HTML
+ Site SiteInfo
+ // layout string
+ Data map[string]interface{}
+ Title string
+ Description string
+ Keywords []string
+ Date time.Time
+ UrlPath
}
func (n Node) RSSlink() template.HTML {
- return n.RSSLink
+ return n.RSSLink
}
type UrlPath struct {
- Url string
- Permalink template.HTML
- Slug string
- Section string
+ Url string
+ Permalink template.HTML
+ Slug string
+ Section string
}
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -14,458 +14,458 @@
package hugolib
import (
- "bytes"
- "errors"
- "fmt"
- "github.com/BurntSushi/toml"
- "github.com/spf13/hugo/helpers"
- "github.com/spf13/hugo/parser"
- "github.com/spf13/hugo/template/bundle"
- "github.com/theplant/blackfriday"
- "html/template"
- "io"
- "launchpad.net/goyaml"
- json "launchpad.net/rjson"
- "net/url"
- "path"
- "strings"
- "time"
+ "bytes"
+ "errors"
+ "fmt"
+ "github.com/BurntSushi/toml"
+ "github.com/spf13/hugo/helpers"
+ "github.com/spf13/hugo/parser"
+ "github.com/spf13/hugo/template/bundle"
+ "github.com/theplant/blackfriday"
+ "html/template"
+ "io"
+ "launchpad.net/goyaml"
+ json "launchpad.net/rjson"
+ "net/url"
+ "path"
+ "strings"
+ "time"
)
type Page struct {
- Status string
- Images []string
- rawContent []byte
- Content template.HTML
- Summary template.HTML
- TableOfContents template.HTML
- Truncated bool
- plain string // TODO should be []byte
- Params map[string]interface{}
- contentType string
- Draft bool
- Aliases []string
- Tmpl bundle.Template
- Markup string
- renderable bool
- layout string
- linkTitle string
- PageMeta
- File
- Position
- Node
+ Status string
+ Images []string
+ rawContent []byte
+ Content template.HTML
+ Summary template.HTML
+ TableOfContents template.HTML
+ Truncated bool
+ plain string // TODO should be []byte
+ Params map[string]interface{}
+ contentType string
+ Draft bool
+ Aliases []string
+ Tmpl bundle.Template
+ Markup string
+ renderable bool
+ layout string
+ linkTitle string
+ PageMeta
+ File
+ Position
+ Node
}
type File struct {
- FileName, Extension, Dir string
+ FileName, Extension, Dir string
}
type PageMeta struct {
- WordCount int
- FuzzyWordCount int
- ReadingTime int
- Weight int
+ WordCount int
+ FuzzyWordCount int
+ ReadingTime int
+ Weight int
}
type Position struct {
- Prev *Page
- Next *Page
+ Prev *Page
+ Next *Page
}
type Pages []*Page
func (p *Page) Plain() string {
- if len(p.plain) == 0 {
- p.plain = StripHTML(StripShortcodes(string(p.renderBytes(p.rawContent))))
- }
- return p.plain
+ if len(p.plain) == 0 {
+ p.plain = StripHTML(StripShortcodes(string(p.renderBytes(p.rawContent))))
+ }
+ return p.plain
}
func (p *Page) setSummary() {
- if bytes.Contains(p.rawContent, summaryDivider) {
- // If user defines split:
- // Split then render
- p.Truncated = true // by definition
- header := bytes.Split(p.rawContent, summaryDivider)[0]
- p.Summary = bytesToHTML(p.renderBytes(header))
- } else {
- // If hugo defines split:
- // render, strip html, then split
- plain := strings.TrimSpace(p.Plain())
- p.Summary = bytesToHTML([]byte(TruncateWordsToWholeSentence(plain, summaryLength)))
- p.Truncated = len(p.Summary) != len(plain)
- }
+ if bytes.Contains(p.rawContent, summaryDivider) {
+ // If user defines split:
+ // Split then render
+ p.Truncated = true // by definition
+ header := bytes.Split(p.rawContent, summaryDivider)[0]
+ p.Summary = bytesToHTML(p.renderBytes(header))
+ } else {
+ // If hugo defines split:
+ // render, strip html, then split
+ plain := strings.TrimSpace(p.Plain())
+ p.Summary = bytesToHTML([]byte(TruncateWordsToWholeSentence(plain, summaryLength)))
+ p.Truncated = len(p.Summary) != len(plain)
+ }
}
func stripEmptyNav(in []byte) []byte {
- return bytes.Replace(in, []byte("<nav>\n</nav>\n\n"), []byte(``), -1)
+ return bytes.Replace(in, []byte("<nav>\n</nav>\n\n"), []byte(``), -1)
}
func bytesToHTML(b []byte) template.HTML {
- return template.HTML(string(b))
+ return template.HTML(string(b))
}
func (p *Page) renderBytes(content []byte) []byte {
- return renderBytes(content, p.guessMarkupType())
+ return renderBytes(content, p.guessMarkupType())
}
func (p *Page) renderContent(content []byte) []byte {
- return renderBytesWithTOC(content, p.guessMarkupType())
+ return renderBytesWithTOC(content, p.guessMarkupType())
}
func renderBytesWithTOC(content []byte, pagefmt string) []byte {
- switch pagefmt {
- default:
- return markdownRenderWithTOC(content)
- case "markdown":
- return markdownRenderWithTOC(content)
- case "rst":
- return []byte(getRstContent(content))
- }
+ switch pagefmt {
+ default:
+ return markdownRenderWithTOC(content)
+ case "markdown":
+ return markdownRenderWithTOC(content)
+ case "rst":
+ return []byte(getRstContent(content))
+ }
}
func renderBytes(content []byte, pagefmt string) []byte {
- switch pagefmt {
- default:
- return markdownRender(content)
- case "markdown":
- return markdownRender(content)
- case "rst":
- return []byte(getRstContent(content))
- }
+ switch pagefmt {
+ default:
+ return markdownRender(content)
+ case "markdown":
+ return markdownRender(content)
+ case "rst":
+ return []byte(getRstContent(content))
+ }
}
// TODO abstract further to support loading from more
// than just files on disk. Should load reader (file, []byte)
func newPage(filename string) *Page {
- page := Page{contentType: "",
- File: File{FileName: filename, Extension: "html"},
- Node: Node{Keywords: make([]string, 10, 30)},
- Params: make(map[string]interface{})}
- page.Date, _ = time.Parse("20060102", "20080101")
- page.guessSection()
- return &page
+ page := Page{contentType: "",
+ File: File{FileName: filename, Extension: "html"},
+ Node: Node{Keywords: make([]string, 10, 30)},
+ Params: make(map[string]interface{})}
+ page.Date, _ = time.Parse("20060102", "20080101")
+ page.guessSection()
+ return &page
}
func StripHTML(s string) string {
- output := ""
+ output := ""
- // Shortcut strings with no tags in them
- if !strings.ContainsAny(s, "<>") {
- output = s
- } else {
- s = strings.Replace(s, "\n", " ", -1)
- s = strings.Replace(s, "</p>", " \n", -1)
- s = strings.Replace(s, "<br>", " \n", -1)
- s = strings.Replace(s, "</br>", " \n", -1)
+ // Shortcut strings with no tags in them
+ if !strings.ContainsAny(s, "<>") {
+ output = s
+ } else {
+ s = strings.Replace(s, "\n", " ", -1)
+ s = strings.Replace(s, "</p>", " \n", -1)
+ s = strings.Replace(s, "<br>", " \n", -1)
+ s = strings.Replace(s, "</br>", " \n", -1)
- // Walk through the string removing all tags
- b := new(bytes.Buffer)
- inTag := false
- for _, r := range s {
- switch r {
- case '<':
- inTag = true
- case '>':
- inTag = false
- default:
- if !inTag {
- b.WriteRune(r)
- }
- }
- }
- output = b.String()
- }
- return output
-}
+ // Walk through the string removing all tags
+ b := new(bytes.Buffer)
+ inTag := false
+ for _, r := range s {
+ switch r {
+ case '<':
+ inTag = true
+ case '>':
+ inTag = false
+ default:
+ if !inTag {
+ b.WriteRune(r)
+ }
+ }
+ }
+ output = b.String()
+ }
+ return output
+}
func (p *Page) IsRenderable() bool {
- return p.renderable
+ return p.renderable
}
func (p *Page) guessSection() {
- if p.Section == "" {
- x := strings.Split(p.FileName, "/")
- x = x[:len(x)-1]
- if len(x) == 0 {
- return
- }
- if x[0] == "content" {
- x = x[1:]
- }
- p.Section = path.Join(x...)
- }
+ if p.Section == "" {
+ x := strings.Split(p.FileName, "/")
+ x = x[:len(x)-1]
+ if len(x) == 0 {
+ return
+ }
+ if x[0] == "content" {
+ x = x[1:]
+ }
+ p.Section = path.Join(x...)
+ }
}
func (page *Page) Type() string {
- if page.contentType != "" {
- return page.contentType
- }
- page.guessSection()
- if x := page.Section; x != "" {
- return x
- }
+ if page.contentType != "" {
+ return page.contentType
+ }
+ page.guessSection()
+ if x := page.Section; x != "" {
+ return x
+ }
- return "page"
+ return "page"
}
func (page *Page) Layout(l ...string) []string {
- if page.layout != "" {
- return layouts(page.Type(), page.layout)
- }
+ if page.layout != "" {
+ return layouts(page.Type(), page.layout)
+ }
- layout := ""
- if len(l) == 0 {
- layout = "single"
- } else {
- layout = l[0]
- }
+ layout := ""
+ if len(l) == 0 {
+ layout = "single"
+ } else {
+ layout = l[0]
+ }
- return layouts(page.Type(), layout)
+ return layouts(page.Type(), layout)
}
func layouts(types string, layout string) (layouts []string) {
- t := strings.Split(types, "/")
- for i := range t {
- search := t[:len(t)-i]
- layouts = append(layouts, fmt.Sprintf("%s/%s.html", strings.ToLower(path.Join(search...)), layout))
- }
- layouts = append(layouts, fmt.Sprintf("%s.html", layout))
- return
+ t := strings.Split(types, "/")
+ for i := range t {
+ search := t[:len(t)-i]
+ layouts = append(layouts, fmt.Sprintf("%s/%s.html", strings.ToLower(path.Join(search...)), layout))
+ }
+ layouts = append(layouts, fmt.Sprintf("%s.html", layout))
+ return
}
func ReadFrom(buf io.Reader, name string) (page *Page, err error) {
- if len(name) == 0 {
- return nil, errors.New("Zero length page name")
- }
+ if len(name) == 0 {
+ return nil, errors.New("Zero length page name")
+ }
- // Create new page
- p := newPage(name)
+ // Create new page
+ p := newPage(name)
- // Parse for metadata & body
- if err = p.parse(buf); err != nil {
- return
- }
+ // Parse for metadata & body
+ if err = p.parse(buf); err != nil {
+ return
+ }
- //analyze for raw stats
- p.analyzePage()
+ //analyze for raw stats
+ p.analyzePage()
- return p, nil
+ return p, nil
}
func (p *Page) analyzePage() {
- p.WordCount = TotalWords(p.Plain())
- p.FuzzyWordCount = int((p.WordCount+100)/100) * 100
- p.ReadingTime = int((p.WordCount + 212) / 213)
+ p.WordCount = TotalWords(p.Plain())
+ p.FuzzyWordCount = int((p.WordCount+100)/100) * 100
+ p.ReadingTime = int((p.WordCount + 212) / 213)
}
func (p *Page) permalink() (*url.URL, error) {
- baseUrl := string(p.Site.BaseUrl)
- dir := strings.TrimSpace(p.Dir)
- pSlug := strings.TrimSpace(p.Slug)
- pUrl := strings.TrimSpace(p.Url)
- var permalink string
- var err error
+ baseUrl := string(p.Site.BaseUrl)
+ dir := strings.TrimSpace(p.Dir)
+ pSlug := strings.TrimSpace(p.Slug)
+ pUrl := strings.TrimSpace(p.Url)
+ var permalink string
+ var err error
- if override, ok := p.Site.Permalinks[p.Section]; ok {
- permalink, err = override.Expand(p)
- if err != nil {
- return nil, err
- }
- //fmt.Printf("have an override for %q in section %s → %s\n", p.Title, p.Section, permalink)
- } else {
+ if override, ok := p.Site.Permalinks[p.Section]; ok {
+ permalink, err = override.Expand(p)
+ if err != nil {
+ return nil, err
+ }
+ //fmt.Printf("have an override for %q in section %s → %s\n", p.Title, p.Section, permalink)
+ } else {
- if len(pSlug) > 0 {
- if p.Site.Config != nil && p.Site.Config.UglyUrls {
- permalink = path.Join(dir, p.Slug, p.Extension)
- } else {
- permalink = path.Join(dir, p.Slug) + "/"
- }
- } else if len(pUrl) > 2 {
- permalink = pUrl
- } else {
- _, t := path.Split(p.FileName)
- if p.Site.Config != nil && p.Site.Config.UglyUrls {
- x := replaceExtension(strings.TrimSpace(t), p.Extension)
- permalink = path.Join(dir, x)
- } else {
- file, _ := fileExt(strings.TrimSpace(t))
- permalink = path.Join(dir, file)
- }
- }
+ if len(pSlug) > 0 {
+ if p.Site.Config != nil && p.Site.Config.UglyUrls {
+ permalink = path.Join(dir, p.Slug, p.Extension)
+ } else {
+ permalink = path.Join(dir, p.Slug) + "/"
+ }
+ } else if len(pUrl) > 2 {
+ permalink = pUrl
+ } else {
+ _, t := path.Split(p.FileName)
+ if p.Site.Config != nil && p.Site.Config.UglyUrls {
+ x := replaceExtension(strings.TrimSpace(t), p.Extension)
+ permalink = path.Join(dir, x)
+ } else {
+ file, _ := fileExt(strings.TrimSpace(t))
+ permalink = path.Join(dir, file)
+ }
+ }
- }
+ }
- base, err := url.Parse(baseUrl)
- if err != nil {
- return nil, err
- }
+ base, err := url.Parse(baseUrl)
+ if err != nil {
+ return nil, err
+ }
- path, err := url.Parse(permalink)
- if err != nil {
- return nil, err
- }
+ path, err := url.Parse(permalink)
+ if err != nil {
+ return nil, err
+ }
- return MakePermalink(base, path), nil
+ return MakePermalink(base, path), nil
}
func (p *Page) LinkTitle() string {
- if len(p.linkTitle) > 0 {
- return p.linkTitle
- } else {
- return p.Title
- }
+ if len(p.linkTitle) > 0 {
+ return p.linkTitle
+ } else {
+ return p.Title
+ }
}
func (p *Page) Permalink() (string, error) {
- link, err := p.permalink()
- if err != nil {
- return "", err
- }
- return link.String(), nil
+ link, err := p.permalink()
+ if err != nil {
+ return "", err
+ }
+ return link.String(), nil
}
func (p *Page) RelPermalink() (string, error) {
- link, err := p.permalink()
- if err != nil {
- return "", err
- }
+ link, err := p.permalink()
+ if err != nil {
+ return "", err
+ }
- link.Scheme = ""
- link.Host = ""
- link.User = nil
- link.Opaque = ""
- return link.String(), nil
+ link.Scheme = ""
+ link.Host = ""
+ link.User = nil
+ link.Opaque = ""
+ return link.String(), nil
}
func (page *Page) handleTomlMetaData(datum []byte) (interface{}, error) {
- m := map[string]interface{}{}
- datum = removeTomlIdentifier(datum)
- if _, err := toml.Decode(string(datum), &m); err != nil {
- return m, fmt.Errorf("Invalid TOML in %s \nError parsing page meta data: %s", page.FileName, err)
- }
- return m, nil
+ m := map[string]interface{}{}
+ datum = removeTomlIdentifier(datum)
+ if _, err := toml.Decode(string(datum), &m); err != nil {
+ return m, fmt.Errorf("Invalid TOML in %s \nError parsing page meta data: %s", page.FileName, err)
+ }
+ return m, nil
}
func removeTomlIdentifier(datum []byte) []byte {
- return bytes.Replace(datum, []byte("+++"), []byte(""), -1)
+ return bytes.Replace(datum, []byte("+++"), []byte(""), -1)
}
func (page *Page) handleYamlMetaData(datum []byte) (interface{}, error) {
- m := map[string]interface{}{}
- if err := goyaml.Unmarshal(datum, &m); err != nil {
- return m, fmt.Errorf("Invalid YAML in %s \nError parsing page meta data: %s", page.FileName, err)
- }
- return m, nil
+ m := map[string]interface{}{}
+ if err := goyaml.Unmarshal(datum, &m); err != nil {
+ return m, fmt.Errorf("Invalid YAML in %s \nError parsing page meta data: %s", page.FileName, err)
+ }
+ return m, nil
}
func (page *Page) handleJsonMetaData(datum []byte) (interface{}, error) {
- var f interface{}
- if err := json.Unmarshal(datum, &f); err != nil {
- return f, fmt.Errorf("Invalid JSON in %v \nError parsing page meta data: %s", page.FileName, err)
- }
- return f, nil
+ var f interface{}
+ if err := json.Unmarshal(datum, &f); err != nil {
+ return f, fmt.Errorf("Invalid JSON in %v \nError parsing page meta data: %s", page.FileName, err)
+ }
+ return f, nil
}
func (page *Page) update(f interface{}) error {
- m := f.(map[string]interface{})
+ m := f.(map[string]interface{})
- for k, v := range m {
- loki := strings.ToLower(k)
- switch loki {
- case "title":
- page.Title = interfaceToString(v)
- case "linktitle":
- page.linkTitle = interfaceToString(v)
- case "description":
- page.Description = interfaceToString(v)
- case "slug":
- page.Slug = helpers.Urlize(interfaceToString(v))
- case "url":
- if url := interfaceToString(v); strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
- return fmt.Errorf("Only relative urls are supported, %v provided", url)
- }
- page.Url = helpers.Urlize(interfaceToString(v))
- case "type":
- page.contentType = interfaceToString(v)
- case "keywords":
- page.Keywords = interfaceArrayToStringArray(v)
- case "date", "pubdate":
- page.Date = interfaceToTime(v)
- case "draft":
- page.Draft = interfaceToBool(v)
- case "layout":
- page.layout = interfaceToString(v)
- case "markup":
- page.Markup = interfaceToString(v)
- case "weight":
- page.Weight = interfaceToInt(v)
- case "aliases":
- page.Aliases = interfaceArrayToStringArray(v)
- for _, alias := range page.Aliases {
- if strings.HasPrefix(alias, "http://") || strings.HasPrefix(alias, "https://") {
- return fmt.Errorf("Only relative aliases are supported, %v provided", alias)
- }
- }
- case "status":
- page.Status = interfaceToString(v)
- default:
- // If not one of the explicit values, store in Params
- switch vv := v.(type) {
- case bool:
- page.Params[loki] = vv
- case string:
- page.Params[loki] = vv
- case int64, int32, int16, int8, int:
- page.Params[loki] = vv
- case float64, float32:
- page.Params[loki] = vv
- case time.Time:
- page.Params[loki] = vv
- default: // handle array of strings as well
- switch vvv := vv.(type) {
- case []interface{}:
- var a = make([]string, len(vvv))
- for i, u := range vvv {
- a[i] = interfaceToString(u)
- }
- page.Params[loki] = a
- }
- }
- }
- }
- return nil
+ for k, v := range m {
+ loki := strings.ToLower(k)
+ switch loki {
+ case "title":
+ page.Title = interfaceToString(v)
+ case "linktitle":
+ page.linkTitle = interfaceToString(v)
+ case "description":
+ page.Description = interfaceToString(v)
+ case "slug":
+ page.Slug = helpers.Urlize(interfaceToString(v))
+ case "url":
+ if url := interfaceToString(v); strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
+ return fmt.Errorf("Only relative urls are supported, %v provided", url)
+ }
+ page.Url = helpers.Urlize(interfaceToString(v))
+ case "type":
+ page.contentType = interfaceToString(v)
+ case "keywords":
+ page.Keywords = interfaceArrayToStringArray(v)
+ case "date", "pubdate":
+ page.Date = interfaceToTime(v)
+ case "draft":
+ page.Draft = interfaceToBool(v)
+ case "layout":
+ page.layout = interfaceToString(v)
+ case "markup":
+ page.Markup = interfaceToString(v)
+ case "weight":
+ page.Weight = interfaceToInt(v)
+ case "aliases":
+ page.Aliases = interfaceArrayToStringArray(v)
+ for _, alias := range page.Aliases {
+ if strings.HasPrefix(alias, "http://") || strings.HasPrefix(alias, "https://") {
+ return fmt.Errorf("Only relative aliases are supported, %v provided", alias)
+ }
+ }
+ case "status":
+ page.Status = interfaceToString(v)
+ default:
+ // If not one of the explicit values, store in Params
+ switch vv := v.(type) {
+ case bool:
+ page.Params[loki] = vv
+ case string:
+ page.Params[loki] = vv
+ case int64, int32, int16, int8, int:
+ page.Params[loki] = vv
+ case float64, float32:
+ page.Params[loki] = vv
+ case time.Time:
+ page.Params[loki] = vv
+ default: // handle array of strings as well
+ switch vvv := vv.(type) {
+ case []interface{}:
+ var a = make([]string, len(vvv))
+ for i, u := range vvv {
+ a[i] = interfaceToString(u)
+ }
+ page.Params[loki] = a
+ }
+ }
+ }
+ }
+ return nil
}
func (page *Page) GetParam(key string) interface{} {
- v := page.Params[strings.ToLower(key)]
+ v := page.Params[strings.ToLower(key)]
- if v == nil {
- return nil
- }
+ if v == nil {
+ return nil
+ }
- switch v.(type) {
- case bool:
- return interfaceToBool(v)
- case string:
- return interfaceToString(v)
- case int64, int32, int16, int8, int:
- return interfaceToInt(v)
- case float64, float32:
- return interfaceToFloat64(v)
- case time.Time:
- return interfaceToTime(v)
- case []string:
- return v
- }
- return nil
+ switch v.(type) {
+ case bool:
+ return interfaceToBool(v)
+ case string:
+ return interfaceToString(v)
+ case int64, int32, int16, int8, int:
+ return interfaceToInt(v)
+ case float64, float32:
+ return interfaceToFloat64(v)
+ case time.Time:
+ return interfaceToTime(v)
+ case []string:
+ return v
+ }
+ return nil
}
type frontmatterType struct {
- markstart, markend []byte
- parse func([]byte) (interface{}, error)
- includeMark bool
+ markstart, markend []byte
+ parse func([]byte) (interface{}, error)
+ includeMark bool
}
const YAML_DELIM = "---"
@@ -472,209 +472,209 @@
const TOML_DELIM = "+++"
func (page *Page) detectFrontMatter(mark rune) (f *frontmatterType) {
- switch mark {
- case '-':
- return &frontmatterType{[]byte(YAML_DELIM), []byte(YAML_DELIM), page.handleYamlMetaData, false}
- case '+':
- return &frontmatterType{[]byte(TOML_DELIM), []byte(TOML_DELIM), page.handleTomlMetaData, false}
- case '{':
- return &frontmatterType{[]byte{'{'}, []byte{'}'}, page.handleJsonMetaData, true}
- default:
- return nil
- }
+ switch mark {
+ case '-':
+ return &frontmatterType{[]byte(YAML_DELIM), []byte(YAML_DELIM), page.handleYamlMetaData, false}
+ case '+':
+ return &frontmatterType{[]byte(TOML_DELIM), []byte(TOML_DELIM), page.handleTomlMetaData, false}
+ case '{':
+ return &frontmatterType{[]byte{'{'}, []byte{'}'}, page.handleJsonMetaData, true}
+ default:
+ return nil
+ }
}
func (p *Page) Render(layout ...string) template.HTML {
- curLayout := ""
+ curLayout := ""
- if len(layout) > 0 {
- curLayout = layout[0]
- }
+ if len(layout) > 0 {
+ curLayout = layout[0]
+ }
- return bytesToHTML(p.ExecuteTemplate(curLayout).Bytes())
+ return bytesToHTML(p.ExecuteTemplate(curLayout).Bytes())
}
func (p *Page) ExecuteTemplate(layout string) *bytes.Buffer {
- l := p.Layout(layout)
- buffer := new(bytes.Buffer)
- for _, layout := range l {
- if p.Tmpl.Lookup(layout) != nil {
- p.Tmpl.ExecuteTemplate(buffer, layout, p)
- break
- }
- }
- return buffer
+ l := p.Layout(layout)
+ buffer := new(bytes.Buffer)
+ for _, layout := range l {
+ if p.Tmpl.Lookup(layout) != nil {
+ p.Tmpl.ExecuteTemplate(buffer, layout, p)
+ break
+ }
+ }
+ return buffer
}
func (page *Page) guessMarkupType() string {
- // First try the explicitly set markup from the frontmatter
- if page.Markup != "" {
- format := guessType(page.Markup)
- if format != "unknown" {
- return format
- }
- }
+ // First try the explicitly set markup from the frontmatter
+ if page.Markup != "" {
+ format := guessType(page.Markup)
+ if format != "unknown" {
+ return format
+ }
+ }
- // Then try to guess from the extension
- ext := strings.ToLower(path.Ext(page.FileName))
- if strings.HasPrefix(ext, ".") {
- return guessType(ext[1:])
- }
+ // Then try to guess from the extension
+ ext := strings.ToLower(path.Ext(page.FileName))
+ if strings.HasPrefix(ext, ".") {
+ return guessType(ext[1:])
+ }
- return "unknown"
+ return "unknown"
}
func guessType(in string) string {
- switch strings.ToLower(in) {
- case "md", "markdown", "mdown":
- return "markdown"
- case "rst":
- return "rst"
- case "html", "htm":
- return "html"
- }
- return "unknown"
+ switch strings.ToLower(in) {
+ case "md", "markdown", "mdown":
+ return "markdown"
+ case "rst":
+ return "rst"
+ case "html", "htm":
+ return "html"
+ }
+ return "unknown"
}
func (page *Page) parse(reader io.Reader) error {
- p, err := parser.ReadFrom(reader)
- if err != nil {
- return err
- }
+ p, err := parser.ReadFrom(reader)
+ if err != nil {
+ return err
+ }
- page.renderable = p.IsRenderable()
+ page.renderable = p.IsRenderable()
- front := p.FrontMatter()
+ front := p.FrontMatter()
- if len(front) != 0 {
- fm := page.detectFrontMatter(rune(front[0]))
- meta, err := fm.parse(front)
- if err != nil {
- return err
- }
+ if len(front) != 0 {
+ fm := page.detectFrontMatter(rune(front[0]))
+ meta, err := fm.parse(front)
+ if err != nil {
+ return err
+ }
- if err = page.update(meta); err != nil {
- return err
- }
+ if err = page.update(meta); err != nil {
+ return err
+ }
- }
- page.rawContent = p.Content()
- page.setSummary()
+ }
+ page.rawContent = p.Content()
+ page.setSummary()
- return nil
+ return nil
}
func (p *Page) ProcessShortcodes(t bundle.Template) {
- p.rawContent = []byte(ShortcodesHandle(string(p.rawContent), p, t))
- p.Summary = template.HTML(ShortcodesHandle(string(p.Summary), p, t))
+ p.rawContent = []byte(ShortcodesHandle(string(p.rawContent), p, t))
+ p.Summary = template.HTML(ShortcodesHandle(string(p.Summary), p, t))
}
func (page *Page) Convert() error {
- markupType := page.guessMarkupType()
- switch markupType {
- case "markdown", "rst":
- tmpContent, tmpTableOfContents := extractTOC(page.renderContent(RemoveSummaryDivider(page.rawContent)))
- page.Content = bytesToHTML(tmpContent)
- page.TableOfContents = bytesToHTML(tmpTableOfContents)
- case "html":
- page.Content = bytesToHTML(page.rawContent)
- default:
- return errors.New("Error converting unsupported file type " + markupType)
- }
- return nil
+ markupType := page.guessMarkupType()
+ switch markupType {
+ case "markdown", "rst":
+ tmpContent, tmpTableOfContents := extractTOC(page.renderContent(RemoveSummaryDivider(page.rawContent)))
+ page.Content = bytesToHTML(tmpContent)
+ page.TableOfContents = bytesToHTML(tmpTableOfContents)
+ case "html":
+ page.Content = bytesToHTML(page.rawContent)
+ default:
+ return errors.New("Error converting unsupported file type " + markupType)
+ }
+ return nil
}
func markdownRender(content []byte) []byte {
- htmlFlags := 0
- htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
- htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
- renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
+ htmlFlags := 0
+ htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
+ htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
+ renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
- return blackfriday.Markdown(content, renderer, 0)
+ return blackfriday.Markdown(content, renderer, 0)
}
func markdownRenderWithTOC(content []byte) []byte {
- htmlFlags := 0
- htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
- htmlFlags |= blackfriday.HTML_TOC
- htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
- renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
+ htmlFlags := 0
+ htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
+ htmlFlags |= blackfriday.HTML_TOC
+ htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
+ renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
- return blackfriday.Markdown(content, renderer, 0)
+ return blackfriday.Markdown(content, renderer, 0)
}
func extractTOC(content []byte) (newcontent []byte, toc []byte) {
- origContent := make([]byte, len(content))
- copy(origContent, content)
- first := []byte(`<nav>
+ origContent := make([]byte, len(content))
+ copy(origContent, content)
+ first := []byte(`<nav>
<ul>`)
- last := []byte(`</ul>
+ last := []byte(`</ul>
</nav>`)
- replacement := []byte(`<nav id="TableOfContents">
+ replacement := []byte(`<nav id="TableOfContents">
<ul>`)
- startOfTOC := bytes.Index(content, first)
+ startOfTOC := bytes.Index(content, first)
- peekEnd := len(content)
- if peekEnd > 70+startOfTOC {
- peekEnd = 70 + startOfTOC
- }
+ peekEnd := len(content)
+ if peekEnd > 70+startOfTOC {
+ peekEnd = 70 + startOfTOC
+ }
- if startOfTOC < 0 {
- return stripEmptyNav(content), toc
- }
- // Need to peek ahead to see if this nav element is actually the right one.
- correctNav := bytes.Index(content[startOfTOC:peekEnd], []byte(`#toc_0`))
- if correctNav < 0 { // no match found
- return content, toc
- }
- lengthOfTOC := bytes.Index(content[startOfTOC:], last) + len(last)
- endOfTOC := startOfTOC + lengthOfTOC
+ if startOfTOC < 0 {
+ return stripEmptyNav(content), toc
+ }
+ // Need to peek ahead to see if this nav element is actually the right one.
+ correctNav := bytes.Index(content[startOfTOC:peekEnd], []byte(`#toc_0`))
+ if correctNav < 0 { // no match found
+ return content, toc
+ }
+ lengthOfTOC := bytes.Index(content[startOfTOC:], last) + len(last)
+ endOfTOC := startOfTOC + lengthOfTOC
- newcontent = append(content[:startOfTOC], content[endOfTOC:]...)
- toc = append(replacement, origContent[startOfTOC+len(first):endOfTOC]...)
- return
+ newcontent = append(content[:startOfTOC], content[endOfTOC:]...)
+ toc = append(replacement, origContent[startOfTOC+len(first):endOfTOC]...)
+ return
}
func ReaderToBytes(lines io.Reader) []byte {
- b := new(bytes.Buffer)
- b.ReadFrom(lines)
- return b.Bytes()
+ b := new(bytes.Buffer)
+ b.ReadFrom(lines)
+ return b.Bytes()
}
func (p *Page) TargetPath() (outfile string) {
- // Always use Url if it's specified
- if len(strings.TrimSpace(p.Url)) > 2 {
- outfile = strings.TrimSpace(p.Url)
+ // Always use Url if it's specified
+ if len(strings.TrimSpace(p.Url)) > 2 {
+ outfile = strings.TrimSpace(p.Url)
- if strings.HasSuffix(outfile, "/") {
- outfile = outfile + "index.html"
- }
- return
- }
+ if strings.HasSuffix(outfile, "/") {
+ outfile = outfile + "index.html"
+ }
+ return
+ }
- // If there's a Permalink specification, we use that
- if override, ok := p.Site.Permalinks[p.Section]; ok {
- var err error
- outfile, err = override.Expand(p)
- if err == nil {
- if strings.HasSuffix(outfile, "/") {
- outfile += "index.html"
- }
- return
- }
- }
+ // If there's a Permalink specification, we use that
+ if override, ok := p.Site.Permalinks[p.Section]; ok {
+ var err error
+ outfile, err = override.Expand(p)
+ if err == nil {
+ if strings.HasSuffix(outfile, "/") {
+ outfile += "index.html"
+ }
+ return
+ }
+ }
- if len(strings.TrimSpace(p.Slug)) > 0 {
- outfile = strings.TrimSpace(p.Slug) + "." + p.Extension
- } else {
- // Fall back to filename
- _, t := path.Split(p.FileName)
- outfile = replaceExtension(strings.TrimSpace(t), p.Extension)
- }
+ if len(strings.TrimSpace(p.Slug)) > 0 {
+ outfile = strings.TrimSpace(p.Slug) + "." + p.Extension
+ } else {
+ // Fall back to filename
+ _, t := path.Split(p.FileName)
+ outfile = replaceExtension(strings.TrimSpace(t), p.Extension)
+ }
- return path.Join(p.Dir, strings.TrimSpace(outfile))
+ return path.Join(p.Dir, strings.TrimSpace(outfile))
}
--- a/hugolib/pageSort.go
+++ b/hugolib/pageSort.go
@@ -14,7 +14,7 @@
package hugolib
import (
- "sort"
+ "sort"
)
/*
@@ -23,8 +23,8 @@
// A type to implement the sort interface for Pages
type PageSorter struct {
- pages Pages
- by PageBy
+ pages Pages
+ by PageBy
}
// Closure used in the Sort.Less method.
@@ -31,19 +31,19 @@
type PageBy func(p1, p2 *Page) bool
func (by PageBy) Sort(pages Pages) {
- ps := &PageSorter{
- pages: pages,
- by: by, // The Sort method's receiver is the function (closure) that defines the sort order.
- }
- sort.Sort(ps)
+ ps := &PageSorter{
+ pages: pages,
+ by: by, // The Sort method's receiver is the function (closure) that defines the sort order.
+ }
+ sort.Sort(ps)
}
var DefaultPageSort = func(p1, p2 *Page) bool {
- if p1.Weight == p2.Weight {
- return p1.Date.Unix() > p2.Date.Unix()
- } else {
- return p1.Weight < p2.Weight
- }
+ if p1.Weight == p2.Weight {
+ return p1.Date.Unix() > p2.Date.Unix()
+ } else {
+ return p1.Weight < p2.Weight
+ }
}
func (ps *PageSorter) Len() int { return len(ps.pages) }
@@ -53,44 +53,44 @@
func (ps *PageSorter) Less(i, j int) bool { return ps.by(ps.pages[i], ps.pages[j]) }
func (p Pages) Sort() {
- PageBy(DefaultPageSort).Sort(p)
+ PageBy(DefaultPageSort).Sort(p)
}
func (p Pages) Limit(n int) Pages {
- if len(p) < n {
- return p[0:n]
- } else {
- return p
- }
+ if len(p) < n {
+ return p[0:n]
+ } else {
+ return p
+ }
}
func (p Pages) ByWeight() Pages {
- PageBy(DefaultPageSort).Sort(p)
- return p
+ PageBy(DefaultPageSort).Sort(p)
+ return p
}
func (p Pages) ByDate() Pages {
- date := func(p1, p2 *Page) bool {
- return p1.Date.Unix() < p2.Date.Unix()
- }
+ date := func(p1, p2 *Page) bool {
+ return p1.Date.Unix() < p2.Date.Unix()
+ }
- PageBy(date).Sort(p)
- return p
+ PageBy(date).Sort(p)
+ return p
}
func (p Pages) ByLength() Pages {
- length := func(p1, p2 *Page) bool {
- return len(p1.Content) < len(p2.Content)
- }
+ length := func(p1, p2 *Page) bool {
+ return len(p1.Content) < len(p2.Content)
+ }
- PageBy(length).Sort(p)
- return p
+ PageBy(length).Sort(p)
+ return p
}
func (p Pages) Reverse() Pages {
- for i, j := 0, len(p)-1; i < j; i, j = i+1, j-1 {
- p[i], p[j] = p[j], p[i]
- }
+ for i, j := 0, len(p)-1; i < j; i, j = i+1, j-1 {
+ p[i], p[j] = p[j], p[i]
+ }
- return p
+ return p
}
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -1,20 +1,20 @@
package hugolib
import (
- "html/template"
- "path"
- "strings"
- "testing"
- "time"
+ "html/template"
+ "path"
+ "strings"
+ "testing"
+ "time"
)
var EMPTY_PAGE = ""
const (
- SIMPLE_PAGE = "---\ntitle: Simple\n---\nSimple Page\n"
- INVALID_FRONT_MATTER_MISSING = "This is a test"
- RENDER_NO_FRONT_MATTER = "<!doctype><html><head></head><body>This is a test</body></html>"
- INVALID_FRONT_MATTER_SHORT_DELIM = `
+ SIMPLE_PAGE = "---\ntitle: Simple\n---\nSimple Page\n"
+ INVALID_FRONT_MATTER_MISSING = "This is a test"
+ RENDER_NO_FRONT_MATTER = "<!doctype><html><head></head><body>This is a test</body></html>"
+ INVALID_FRONT_MATTER_SHORT_DELIM = `
--
title: Short delim start
---
@@ -21,7 +21,7 @@
Short Delim
`
- INVALID_FRONT_MATTER_SHORT_DELIM_ENDING = `
+ INVALID_FRONT_MATTER_SHORT_DELIM_ENDING = `
---
title: Short delim ending
--
@@ -28,7 +28,7 @@
Short Delim
`
- INVALID_FRONT_MATTER_LEADING_WS = `
+ INVALID_FRONT_MATTER_LEADING_WS = `
---
title: Leading WS
@@ -36,7 +36,7 @@
Leading
`
- SIMPLE_PAGE_JSON = `
+ SIMPLE_PAGE_JSON = `
{
"title": "spf13-vim 3.0 release and new website",
"description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim.",
@@ -51,7 +51,7 @@
Content of the file goes Here
`
- SIMPLE_PAGE_JSON_LOOSE = `
+ SIMPLE_PAGE_JSON_LOOSE = `
{
"title": "spf13-vim 3.0 release and new website"
"description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim."
@@ -66,8 +66,8 @@
Content of the file goes Here
`
- SIMPLE_PAGE_RFC3339_DATE = "---\ntitle: RFC3339 Date\ndate: \"2013-05-17T16:59:30Z\"\n---\nrfc3339 content"
- SIMPLE_PAGE_JSON_MULTIPLE = `
+ SIMPLE_PAGE_RFC3339_DATE = "---\ntitle: RFC3339 Date\ndate: \"2013-05-17T16:59:30Z\"\n---\nrfc3339 content"
+ SIMPLE_PAGE_JSON_MULTIPLE = `
{
"title": "foobar",
"customData": { "foo": "bar" },
@@ -76,34 +76,34 @@
Some text
`
- SIMPLE_PAGE_JSON_COMPACT = `
+ SIMPLE_PAGE_JSON_COMPACT = `
{"title":"foobar","customData":{"foo":"bar"},"date":"2012-08-06"}
Text
`
- SIMPLE_PAGE_NOLAYOUT = `---
+ SIMPLE_PAGE_NOLAYOUT = `---
title: simple_no_layout
---
No Layout called out`
- SIMPLE_PAGE_LAYOUT_FOOBAR = `---
+ SIMPLE_PAGE_LAYOUT_FOOBAR = `---
title: simple layout foobar
layout: foobar
---
Layout foobar`
- SIMPLE_PAGE_TYPE_FOOBAR = `---
+ SIMPLE_PAGE_TYPE_FOOBAR = `---
type: foobar
---
type foobar`
- SIMPLE_PAGE_TYPE_LAYOUT = `---
+ SIMPLE_PAGE_TYPE_LAYOUT = `---
type: barfoo
layout: buzfoo
---
type and layout set`
- SIMPLE_PAGE_WITH_SUMMARY_DELIMITER = `---
+ SIMPLE_PAGE_WITH_SUMMARY_DELIMITER = `---
title: Simple
---
Summary Next Line
@@ -111,7 +111,7 @@
<!--more-->
Some more text
`
- SIMPLE_PAGE_WITH_SHORTCODE_IN_SUMMARY = `---
+ SIMPLE_PAGE_WITH_SHORTCODE_IN_SUMMARY = `---
title: Simple
---
Summary Next Line. {{% img src="/not/real" %}}.
@@ -120,7 +120,7 @@
Some more text
`
- SIMPLE_PAGE_WITH_SUMMARY_DELIMITER_SAME_LINE = `---
+ SIMPLE_PAGE_WITH_SUMMARY_DELIMITER_SAME_LINE = `---
title: Simple
---
Summary Same Line<!--more-->
@@ -128,7 +128,7 @@
Some more text
`
- SIMPLE_PAGE_WITH_LONG_CONTENT = `---
+ SIMPLE_PAGE_WITH_LONG_CONTENT = `---
title: Simple
---
@@ -174,7 +174,7 @@
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.`
- PAGE_WITH_TOC = `---
+ PAGE_WITH_TOC = `---
title: TOC
---
For some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.
@@ -215,330 +215,330 @@
Front Matter with various frontmatter types`
func checkError(t *testing.T, err error, expected string) {
- if err == nil {
- t.Fatalf("err is nil. Expected: %s", expected)
- }
- if err.Error() != expected {
- t.Errorf("err.Error() returned: '%s'. Expected: '%s'", err.Error(), expected)
- }
+ if err == nil {
+ t.Fatalf("err is nil. Expected: %s", expected)
+ }
+ if err.Error() != expected {
+ t.Errorf("err.Error() returned: '%s'. Expected: '%s'", err.Error(), expected)
+ }
}
func TestDegenerateEmptyPageZeroLengthName(t *testing.T) {
- _, err := ReadFrom(strings.NewReader(EMPTY_PAGE), "")
- if err == nil {
- t.Fatalf("A zero length page name must return an error")
- }
+ _, err := ReadFrom(strings.NewReader(EMPTY_PAGE), "")
+ if err == nil {
+ t.Fatalf("A zero length page name must return an error")
+ }
- checkError(t, err, "Zero length page name")
+ checkError(t, err, "Zero length page name")
}
func TestDegenerateEmptyPage(t *testing.T) {
- _, err := ReadFrom(strings.NewReader(EMPTY_PAGE), "test")
- if err != nil {
- t.Fatalf("Empty files should not trigger an error. Should be able to touch a file while watching without erroring out.")
- }
+ _, err := ReadFrom(strings.NewReader(EMPTY_PAGE), "test")
+ if err != nil {
+ t.Fatalf("Empty files should not trigger an error. Should be able to touch a file while watching without erroring out.")
+ }
- //checkError(t, err, "EOF")
+ //checkError(t, err, "EOF")
}
func checkPageTitle(t *testing.T, page *Page, title string) {
- if page.Title != title {
- t.Fatalf("Page title is: %s. Expected %s", page.Title, title)
- }
+ if page.Title != title {
+ t.Fatalf("Page title is: %s. Expected %s", page.Title, title)
+ }
}
func checkPageContent(t *testing.T, page *Page, content string) {
- if page.Content != template.HTML(content) {
- t.Fatalf("Page content is: %q\nExpected: %q", page.Content, content)
- }
+ if page.Content != template.HTML(content) {
+ t.Fatalf("Page content is: %q\nExpected: %q", page.Content, content)
+ }
}
func checkPageTOC(t *testing.T, page *Page, toc string) {
- if page.TableOfContents != template.HTML(toc) {
- t.Fatalf("Page TableOfContents is: %q.\nExpected %q", page.TableOfContents, toc)
- }
+ if page.TableOfContents != template.HTML(toc) {
+ t.Fatalf("Page TableOfContents is: %q.\nExpected %q", page.TableOfContents, toc)
+ }
}
func checkPageSummary(t *testing.T, page *Page, summary string) {
- if page.Summary != template.HTML(summary) {
- t.Fatalf("Page summary is: %q.\nExpected %q", page.Summary, summary)
- }
+ if page.Summary != template.HTML(summary) {
+ t.Fatalf("Page summary is: %q.\nExpected %q", page.Summary, summary)
+ }
}
func checkPageType(t *testing.T, page *Page, pageType string) {
- if page.Type() != pageType {
- t.Fatalf("Page type is: %s. Expected: %s", page.Type(), pageType)
- }
+ if page.Type() != pageType {
+ t.Fatalf("Page type is: %s. Expected: %s", page.Type(), pageType)
+ }
}
func checkPageLayout(t *testing.T, page *Page, layout ...string) {
- if !listEqual(page.Layout(), layout) {
- t.Fatalf("Page layout is: %s. Expected: %s", page.Layout(), layout)
- }
+ if !listEqual(page.Layout(), layout) {
+ t.Fatalf("Page layout is: %s. Expected: %s", page.Layout(), layout)
+ }
}
func checkPageDate(t *testing.T, page *Page, time time.Time) {
- if page.Date != time {
- t.Fatalf("Page date is: %s. Expected: %s", page.Date, time)
- }
+ if page.Date != time {
+ t.Fatalf("Page date is: %s. Expected: %s", page.Date, time)
+ }
}
func checkTruncation(t *testing.T, page *Page, shouldBe bool, msg string) {
- if page.Summary == "" {
- t.Fatal("page has no summary, can not check truncation")
- }
- if page.Truncated != shouldBe {
- if shouldBe {
- t.Fatalf("page wasn't truncated: %s", msg)
- } else {
- t.Fatalf("page was truncated: %s", msg)
- }
- }
+ if page.Summary == "" {
+ t.Fatal("page has no summary, can not check truncation")
+ }
+ if page.Truncated != shouldBe {
+ if shouldBe {
+ t.Fatalf("page wasn't truncated: %s", msg)
+ } else {
+ t.Fatalf("page was truncated: %s", msg)
+ }
+ }
}
func TestCreateNewPage(t *testing.T) {
- p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE), "simple.md")
- p.Convert()
+ p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE), "simple.md")
+ p.Convert()
- if err != nil {
- t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
- }
- checkPageTitle(t, p, "Simple")
- checkPageContent(t, p, "<p>Simple Page</p>\n")
- checkPageSummary(t, p, "Simple Page")
- checkPageType(t, p, "page")
- checkPageLayout(t, p, "page/single.html", "single.html")
- checkTruncation(t, p, false, "simple short page")
+ if err != nil {
+ t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+ }
+ checkPageTitle(t, p, "Simple")
+ checkPageContent(t, p, "<p>Simple Page</p>\n")
+ checkPageSummary(t, p, "Simple Page")
+ checkPageType(t, p, "page")
+ checkPageLayout(t, p, "page/single.html", "single.html")
+ checkTruncation(t, p, false, "simple short page")
}
func TestPageWithDelimiter(t *testing.T) {
- p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SUMMARY_DELIMITER), "simple.md")
- p.Convert()
- if err != nil {
- t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
- }
- checkPageTitle(t, p, "Simple")
- checkPageContent(t, p, "<p>Summary Next Line</p>\n\n<p>Some more text</p>\n")
- checkPageSummary(t, p, "<p>Summary Next Line</p>\n")
- checkPageType(t, p, "page")
- checkPageLayout(t, p, "page/single.html", "single.html")
- checkTruncation(t, p, true, "page with summary delimiter")
+ p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SUMMARY_DELIMITER), "simple.md")
+ p.Convert()
+ if err != nil {
+ t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+ }
+ checkPageTitle(t, p, "Simple")
+ checkPageContent(t, p, "<p>Summary Next Line</p>\n\n<p>Some more text</p>\n")
+ checkPageSummary(t, p, "<p>Summary Next Line</p>\n")
+ checkPageType(t, p, "page")
+ checkPageLayout(t, p, "page/single.html", "single.html")
+ checkTruncation(t, p, true, "page with summary delimiter")
}
func TestPageWithShortCodeInSummary(t *testing.T) {
- p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SHORTCODE_IN_SUMMARY), "simple.md")
- p.Convert()
- if err != nil {
- t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
- }
- checkPageTitle(t, p, "Simple")
- checkPageContent(t, p, "<p>Summary Next Line. {{% img src=“/not/real” %}}.\nMore text here.</p>\n\n<p>Some more text</p>\n")
- checkPageSummary(t, p, "Summary Next Line. . More text here. Some more text")
- checkPageType(t, p, "page")
- checkPageLayout(t, p, "page/single.html", "single.html")
+ p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SHORTCODE_IN_SUMMARY), "simple.md")
+ p.Convert()
+ if err != nil {
+ t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+ }
+ checkPageTitle(t, p, "Simple")
+ checkPageContent(t, p, "<p>Summary Next Line. {{% img src=“/not/real” %}}.\nMore text here.</p>\n\n<p>Some more text</p>\n")
+ checkPageSummary(t, p, "Summary Next Line. . More text here. Some more text")
+ checkPageType(t, p, "page")
+ checkPageLayout(t, p, "page/single.html", "single.html")
}
func TestTableOfContents(t *testing.T) {
- p, err := ReadFrom(strings.NewReader(PAGE_WITH_TOC), "tocpage.md")
- p.Convert()
- if err != nil {
- t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
- }
- checkPageContent(t, p, "\n\n<p>For some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.</p>\n\n<h2 id=\"toc_0\">AA</h2>\n\n<p>I have no idea, of course, how long it took me to reach the limit of the plain,\nbut at last I entered the foothills, following a pretty little canyon upward\ntoward the mountains. Beside me frolicked a laughing brooklet, hurrying upon\nits noisy way down to the silent sea. In its quieter pools I discovered many\nsmall fish, of four-or five-pound weight I should imagine. In appearance,\nexcept as to size and color, they were not unlike the whale of our own seas. As\nI watched them playing about I discovered, not only that they suckled their\nyoung, but that at intervals they rose to the surface to breathe as well as to\nfeed upon certain grasses and a strange, scarlet lichen which grew upon the\nrocks just above the water line.</p>\n\n<h3 id=\"toc_1\">AAA</h3>\n\n<p>I remember I felt an extraordinary persuasion that I was being played with,\nthat presently, when I was upon the very verge of safety, this mysterious\ndeath—as swift as the passage of light—would leap after me from the pit about\nthe cylinder and strike me down. ## BB</p>\n\n<h3 id=\"toc_2\">BBB</h3>\n\n<p>“You’re a great Granser,” he cried delightedly, “always making believe them little marks mean something.”</p>\n")
- checkPageTOC(t, p, "<nav id=\"TableOfContents\">\n<ul>\n<li>\n<ul>\n<li><a href=\"#toc_0\">AA</a>\n<ul>\n<li><a href=\"#toc_1\">AAA</a></li>\n<li><a href=\"#toc_2\">BBB</a></li>\n</ul></li>\n</ul></li>\n</ul>\n</nav>")
+ p, err := ReadFrom(strings.NewReader(PAGE_WITH_TOC), "tocpage.md")
+ p.Convert()
+ if err != nil {
+ t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+ }
+ checkPageContent(t, p, "\n\n<p>For some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.</p>\n\n<h2 id=\"toc_0\">AA</h2>\n\n<p>I have no idea, of course, how long it took me to reach the limit of the plain,\nbut at last I entered the foothills, following a pretty little canyon upward\ntoward the mountains. Beside me frolicked a laughing brooklet, hurrying upon\nits noisy way down to the silent sea. In its quieter pools I discovered many\nsmall fish, of four-or five-pound weight I should imagine. In appearance,\nexcept as to size and color, they were not unlike the whale of our own seas. As\nI watched them playing about I discovered, not only that they suckled their\nyoung, but that at intervals they rose to the surface to breathe as well as to\nfeed upon certain grasses and a strange, scarlet lichen which grew upon the\nrocks just above the water line.</p>\n\n<h3 id=\"toc_1\">AAA</h3>\n\n<p>I remember I felt an extraordinary persuasion that I was being played with,\nthat presently, when I was upon the very verge of safety, this mysterious\ndeath—as swift as the passage of light—would leap after me from the pit about\nthe cylinder and strike me down. ## BB</p>\n\n<h3 id=\"toc_2\">BBB</h3>\n\n<p>“You’re a great Granser,” he cried delightedly, “always making believe them little marks mean something.”</p>\n")
+ checkPageTOC(t, p, "<nav id=\"TableOfContents\">\n<ul>\n<li>\n<ul>\n<li><a href=\"#toc_0\">AA</a>\n<ul>\n<li><a href=\"#toc_1\">AAA</a></li>\n<li><a href=\"#toc_2\">BBB</a></li>\n</ul></li>\n</ul></li>\n</ul>\n</nav>")
}
func TestPageWithMoreTag(t *testing.T) {
- p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SUMMARY_DELIMITER_SAME_LINE), "simple.md")
- p.Convert()
- if err != nil {
- t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
- }
- checkPageTitle(t, p, "Simple")
- checkPageContent(t, p, "<p>Summary Same Line</p>\n\n<p>Some more text</p>\n")
- checkPageSummary(t, p, "<p>Summary Same Line</p>\n")
- checkPageType(t, p, "page")
- checkPageLayout(t, p, "page/single.html", "single.html")
+ p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SUMMARY_DELIMITER_SAME_LINE), "simple.md")
+ p.Convert()
+ if err != nil {
+ t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+ }
+ checkPageTitle(t, p, "Simple")
+ checkPageContent(t, p, "<p>Summary Same Line</p>\n\n<p>Some more text</p>\n")
+ checkPageSummary(t, p, "<p>Summary Same Line</p>\n")
+ checkPageType(t, p, "page")
+ checkPageLayout(t, p, "page/single.html", "single.html")
}
func TestPageWithDate(t *testing.T) {
- p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_RFC3339_DATE), "simple")
- p.Convert()
- if err != nil {
- t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
- }
- d, err := time.Parse(time.RFC3339, "2013-05-17T16:59:30Z")
- if err != nil {
- t.Fatalf("Unable to prase page.")
- }
- checkPageDate(t, p, d)
+ p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_RFC3339_DATE), "simple")
+ p.Convert()
+ if err != nil {
+ t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+ }
+ d, err := time.Parse(time.RFC3339, "2013-05-17T16:59:30Z")
+ if err != nil {
+ t.Fatalf("Unable to prase page.")
+ }
+ checkPageDate(t, p, d)
}
func TestWordCount(t *testing.T) {
- p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_LONG_CONTENT), "simple.md")
- p.Convert()
- p.analyzePage()
- if err != nil {
- t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
- }
+ p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_LONG_CONTENT), "simple.md")
+ p.Convert()
+ p.analyzePage()
+ if err != nil {
+ t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+ }
- if p.WordCount != 483 {
- t.Fatalf("incorrect word count. expected %v, got %v", 483, p.WordCount)
- }
+ if p.WordCount != 483 {
+ t.Fatalf("incorrect word count. expected %v, got %v", 483, p.WordCount)
+ }
- if p.FuzzyWordCount != 500 {
- t.Fatalf("incorrect word count. expected %v, got %v", 500, p.WordCount)
- }
+ if p.FuzzyWordCount != 500 {
+ t.Fatalf("incorrect word count. expected %v, got %v", 500, p.WordCount)
+ }
- if p.ReadingTime != 3 {
- t.Fatalf("incorrect min read. expected %v, got %v", 3, p.ReadingTime)
- }
+ if p.ReadingTime != 3 {
+ t.Fatalf("incorrect min read. expected %v, got %v", 3, p.ReadingTime)
+ }
- checkTruncation(t, p, true, "long page")
+ checkTruncation(t, p, true, "long page")
}
func TestCreatePage(t *testing.T) {
- var tests = []struct {
- r string
- }{
- {SIMPLE_PAGE_JSON},
- {SIMPLE_PAGE_JSON_LOOSE},
- {SIMPLE_PAGE_JSON_MULTIPLE},
- //{strings.NewReader(SIMPLE_PAGE_JSON_COMPACT)},
- }
+ var tests = []struct {
+ r string
+ }{
+ {SIMPLE_PAGE_JSON},
+ {SIMPLE_PAGE_JSON_LOOSE},
+ {SIMPLE_PAGE_JSON_MULTIPLE},
+ //{strings.NewReader(SIMPLE_PAGE_JSON_COMPACT)},
+ }
- for _, test := range tests {
- if _, err := ReadFrom(strings.NewReader(test.r), "page"); err != nil {
- t.Errorf("Unable to parse page: %s", err)
- }
- }
+ for _, test := range tests {
+ if _, err := ReadFrom(strings.NewReader(test.r), "page"); err != nil {
+ t.Errorf("Unable to parse page: %s", err)
+ }
+ }
}
func TestDegenerateInvalidFrontMatterShortDelim(t *testing.T) {
- var tests = []struct {
- r string
- err string
- }{
- {INVALID_FRONT_MATTER_SHORT_DELIM_ENDING, "Unable to read frontmatter at filepos 45: EOF"},
- }
- for _, test := range tests {
- _, err := ReadFrom(strings.NewReader(test.r), "invalid/front/matter/short/delim")
- checkError(t, err, test.err)
- }
+ var tests = []struct {
+ r string
+ err string
+ }{
+ {INVALID_FRONT_MATTER_SHORT_DELIM_ENDING, "Unable to read frontmatter at filepos 45: EOF"},
+ }
+ for _, test := range tests {
+ _, err := ReadFrom(strings.NewReader(test.r), "invalid/front/matter/short/delim")
+ checkError(t, err, test.err)
+ }
}
func TestShouldRenderContent(t *testing.T) {
- var tests = []struct {
- text string
- render bool
- }{
- {INVALID_FRONT_MATTER_MISSING, true},
- // TODO how to deal with malformed frontmatter. In this case it'll be rendered as markdown.
- {INVALID_FRONT_MATTER_SHORT_DELIM, true},
- {RENDER_NO_FRONT_MATTER, false},
- }
+ var tests = []struct {
+ text string
+ render bool
+ }{
+ {INVALID_FRONT_MATTER_MISSING, true},
+ // TODO how to deal with malformed frontmatter. In this case it'll be rendered as markdown.
+ {INVALID_FRONT_MATTER_SHORT_DELIM, true},
+ {RENDER_NO_FRONT_MATTER, false},
+ }
- for _, test := range tests {
- p := pageMust(ReadFrom(strings.NewReader(test.text), "render/front/matter"))
- if p.IsRenderable() != test.render {
- t.Errorf("expected p.IsRenderable() == %t, got %t", test.render, p.IsRenderable())
- }
- }
+ for _, test := range tests {
+ p := pageMust(ReadFrom(strings.NewReader(test.text), "render/front/matter"))
+ if p.IsRenderable() != test.render {
+ t.Errorf("expected p.IsRenderable() == %t, got %t", test.render, p.IsRenderable())
+ }
+ }
}
func TestDifferentFrontMatterVarTypes(t *testing.T) {
- page, _ := ReadFrom(strings.NewReader(PAGE_WITH_VARIOUS_FRONTMATTER_TYPES), "test/file1.md")
+ page, _ := ReadFrom(strings.NewReader(PAGE_WITH_VARIOUS_FRONTMATTER_TYPES), "test/file1.md")
- dateval, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z")
- if page.GetParam("a_string") != "bar" {
- t.Errorf("frontmatter not handling strings correctly should be %s, got: %s", "bar", page.GetParam("a_string"))
- }
- if page.GetParam("an_integer") != 1 {
- t.Errorf("frontmatter not handling ints correctly should be %s, got: %s", "1", page.GetParam("an_integer"))
- }
- if page.GetParam("a_float") != 1.3 {
- t.Errorf("frontmatter not handling floats correctly should be %s, got: %s", 1.3, page.GetParam("a_float"))
- }
- if page.GetParam("a_bool") != false {
- t.Errorf("frontmatter not handling bools correctly should be %s, got: %s", false, page.GetParam("a_bool"))
- }
- if page.GetParam("a_date") != dateval {
- t.Errorf("frontmatter not handling dates correctly should be %s, got: %s", dateval, page.GetParam("a_date"))
- }
+ dateval, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z")
+ if page.GetParam("a_string") != "bar" {
+ t.Errorf("frontmatter not handling strings correctly should be %s, got: %s", "bar", page.GetParam("a_string"))
+ }
+ if page.GetParam("an_integer") != 1 {
+ t.Errorf("frontmatter not handling ints correctly should be %s, got: %s", "1", page.GetParam("an_integer"))
+ }
+ if page.GetParam("a_float") != 1.3 {
+ t.Errorf("frontmatter not handling floats correctly should be %s, got: %s", 1.3, page.GetParam("a_float"))
+ }
+ if page.GetParam("a_bool") != false {
+ t.Errorf("frontmatter not handling bools correctly should be %s, got: %s", false, page.GetParam("a_bool"))
+ }
+ if page.GetParam("a_date") != dateval {
+ t.Errorf("frontmatter not handling dates correctly should be %s, got: %s", dateval, page.GetParam("a_date"))
+ }
}
func TestDegenerateInvalidFrontMatterLeadingWhitespace(t *testing.T) {
- _, err := ReadFrom(strings.NewReader(INVALID_FRONT_MATTER_LEADING_WS), "invalid/front/matter/leading/ws")
- if err != nil {
- t.Fatalf("Unable to parse front matter given leading whitespace: %s", err)
- }
+ _, err := ReadFrom(strings.NewReader(INVALID_FRONT_MATTER_LEADING_WS), "invalid/front/matter/leading/ws")
+ if err != nil {
+ t.Fatalf("Unable to parse front matter given leading whitespace: %s", err)
+ }
}
func TestSectionEvaluation(t *testing.T) {
- page, _ := ReadFrom(strings.NewReader(SIMPLE_PAGE), "blue/file1.md")
- if page.Section != "blue" {
- t.Errorf("Section should be %s, got: %s", "blue", page.Section)
- }
+ page, _ := ReadFrom(strings.NewReader(SIMPLE_PAGE), "blue/file1.md")
+ if page.Section != "blue" {
+ t.Errorf("Section should be %s, got: %s", "blue", page.Section)
+ }
}
func L(s ...string) []string {
- return s
+ return s
}
func TestLayoutOverride(t *testing.T) {
- var (
- path_content_two_dir = path.Join("content", "dub", "sub", "file1.md")
- path_content_one_dir = path.Join("content", "gub", "file1.md")
- path_content_no_dir = path.Join("content", "file1")
- path_one_directory = path.Join("fub", "file1.md")
- path_no_directory = path.Join("file1.md")
- )
- tests := []struct {
- content string
- path string
- expectedLayout []string
- }{
- {SIMPLE_PAGE_NOLAYOUT, path_content_two_dir, L("dub/sub/single.html", "dub/single.html", "single.html")},
- {SIMPLE_PAGE_NOLAYOUT, path_content_one_dir, L("gub/single.html", "single.html")},
- {SIMPLE_PAGE_NOLAYOUT, path_content_no_dir, L("page/single.html", "single.html")},
- {SIMPLE_PAGE_NOLAYOUT, path_one_directory, L("fub/single.html", "single.html")},
- {SIMPLE_PAGE_NOLAYOUT, path_no_directory, L("page/single.html", "single.html")},
- {SIMPLE_PAGE_LAYOUT_FOOBAR, path_content_two_dir, L("dub/sub/foobar.html", "dub/foobar.html", "foobar.html")},
- {SIMPLE_PAGE_LAYOUT_FOOBAR, path_content_one_dir, L("gub/foobar.html", "foobar.html")},
- {SIMPLE_PAGE_LAYOUT_FOOBAR, path_one_directory, L("fub/foobar.html", "foobar.html")},
- {SIMPLE_PAGE_LAYOUT_FOOBAR, path_no_directory, L("page/foobar.html", "foobar.html")},
- {SIMPLE_PAGE_TYPE_FOOBAR, path_content_two_dir, L("foobar/single.html", "single.html")},
- {SIMPLE_PAGE_TYPE_FOOBAR, path_content_one_dir, L("foobar/single.html", "single.html")},
- {SIMPLE_PAGE_TYPE_FOOBAR, path_content_no_dir, L("foobar/single.html", "single.html")},
- {SIMPLE_PAGE_TYPE_FOOBAR, path_one_directory, L("foobar/single.html", "single.html")},
- {SIMPLE_PAGE_TYPE_FOOBAR, path_no_directory, L("foobar/single.html", "single.html")},
- {SIMPLE_PAGE_TYPE_LAYOUT, path_content_two_dir, L("barfoo/buzfoo.html", "buzfoo.html")},
- {SIMPLE_PAGE_TYPE_LAYOUT, path_content_one_dir, L("barfoo/buzfoo.html", "buzfoo.html")},
- {SIMPLE_PAGE_TYPE_LAYOUT, path_content_no_dir, L("barfoo/buzfoo.html", "buzfoo.html")},
- {SIMPLE_PAGE_TYPE_LAYOUT, path_one_directory, L("barfoo/buzfoo.html", "buzfoo.html")},
- {SIMPLE_PAGE_TYPE_LAYOUT, path_no_directory, L("barfoo/buzfoo.html", "buzfoo.html")},
- }
- for _, test := range tests {
- p, err := ReadFrom(strings.NewReader(test.content), test.path)
- if err != nil {
- t.Fatalf("Unable to parse content:\n%s\n", test.content)
- }
- if !listEqual(p.Layout(), test.expectedLayout) {
- t.Errorf("Layout mismatch. Expected: %s, got: %s", test.expectedLayout, p.Layout())
- }
- }
+ var (
+ path_content_two_dir = path.Join("content", "dub", "sub", "file1.md")
+ path_content_one_dir = path.Join("content", "gub", "file1.md")
+ path_content_no_dir = path.Join("content", "file1")
+ path_one_directory = path.Join("fub", "file1.md")
+ path_no_directory = path.Join("file1.md")
+ )
+ tests := []struct {
+ content string
+ path string
+ expectedLayout []string
+ }{
+ {SIMPLE_PAGE_NOLAYOUT, path_content_two_dir, L("dub/sub/single.html", "dub/single.html", "single.html")},
+ {SIMPLE_PAGE_NOLAYOUT, path_content_one_dir, L("gub/single.html", "single.html")},
+ {SIMPLE_PAGE_NOLAYOUT, path_content_no_dir, L("page/single.html", "single.html")},
+ {SIMPLE_PAGE_NOLAYOUT, path_one_directory, L("fub/single.html", "single.html")},
+ {SIMPLE_PAGE_NOLAYOUT, path_no_directory, L("page/single.html", "single.html")},
+ {SIMPLE_PAGE_LAYOUT_FOOBAR, path_content_two_dir, L("dub/sub/foobar.html", "dub/foobar.html", "foobar.html")},
+ {SIMPLE_PAGE_LAYOUT_FOOBAR, path_content_one_dir, L("gub/foobar.html", "foobar.html")},
+ {SIMPLE_PAGE_LAYOUT_FOOBAR, path_one_directory, L("fub/foobar.html", "foobar.html")},
+ {SIMPLE_PAGE_LAYOUT_FOOBAR, path_no_directory, L("page/foobar.html", "foobar.html")},
+ {SIMPLE_PAGE_TYPE_FOOBAR, path_content_two_dir, L("foobar/single.html", "single.html")},
+ {SIMPLE_PAGE_TYPE_FOOBAR, path_content_one_dir, L("foobar/single.html", "single.html")},
+ {SIMPLE_PAGE_TYPE_FOOBAR, path_content_no_dir, L("foobar/single.html", "single.html")},
+ {SIMPLE_PAGE_TYPE_FOOBAR, path_one_directory, L("foobar/single.html", "single.html")},
+ {SIMPLE_PAGE_TYPE_FOOBAR, path_no_directory, L("foobar/single.html", "single.html")},
+ {SIMPLE_PAGE_TYPE_LAYOUT, path_content_two_dir, L("barfoo/buzfoo.html", "buzfoo.html")},
+ {SIMPLE_PAGE_TYPE_LAYOUT, path_content_one_dir, L("barfoo/buzfoo.html", "buzfoo.html")},
+ {SIMPLE_PAGE_TYPE_LAYOUT, path_content_no_dir, L("barfoo/buzfoo.html", "buzfoo.html")},
+ {SIMPLE_PAGE_TYPE_LAYOUT, path_one_directory, L("barfoo/buzfoo.html", "buzfoo.html")},
+ {SIMPLE_PAGE_TYPE_LAYOUT, path_no_directory, L("barfoo/buzfoo.html", "buzfoo.html")},
+ }
+ for _, test := range tests {
+ p, err := ReadFrom(strings.NewReader(test.content), test.path)
+ if err != nil {
+ t.Fatalf("Unable to parse content:\n%s\n", test.content)
+ }
+ if !listEqual(p.Layout(), test.expectedLayout) {
+ t.Errorf("Layout mismatch. Expected: %s, got: %s", test.expectedLayout, p.Layout())
+ }
+ }
}
func listEqual(left, right []string) bool {
- if len(left) != len(right) {
- return false
- }
+ if len(left) != len(right) {
+ return false
+ }
- for i := range left {
- if left[i] != right[i] {
- return false
- }
- }
+ for i := range left {
+ if left[i] != right[i] {
+ return false
+ }
+ }
- return true
+ return true
}
--- a/hugolib/shortcode.go
+++ b/hugolib/shortcode.go
@@ -14,12 +14,12 @@
package hugolib
import (
- "bytes"
- "fmt"
- "github.com/spf13/hugo/template/bundle"
- "html/template"
- "strings"
- "unicode"
+ "bytes"
+ "fmt"
+ "github.com/spf13/hugo/template/bundle"
+ "html/template"
+ "strings"
+ "unicode"
)
var _ = fmt.Println
@@ -27,201 +27,201 @@
type ShortcodeFunc func([]string) string
type Shortcode struct {
- Name string
- Func ShortcodeFunc
+ Name string
+ Func ShortcodeFunc
}
type ShortcodeWithPage struct {
- Params interface{}
- Inner template.HTML
- Page *Page
+ Params interface{}
+ Inner template.HTML
+ Page *Page
}
type Shortcodes map[string]ShortcodeFunc
func ShortcodesHandle(stringToParse string, p *Page, t bundle.Template) string {
- leadStart := strings.Index(stringToParse, `{{%`)
- if leadStart >= 0 {
- leadEnd := strings.Index(stringToParse[leadStart:], `%}}`) + leadStart
- if leadEnd > leadStart {
- name, par := SplitParams(stringToParse[leadStart+3 : leadEnd])
- tmpl := GetTemplate(name, t)
- if tmpl == nil {
- return stringToParse
- }
- params := Tokenize(par)
- // Always look for closing tag.
- endStart, endEnd := FindEnd(stringToParse[leadEnd:], name)
- var data = &ShortcodeWithPage{Params: params, Page: p}
- if endStart > 0 {
- s := stringToParse[leadEnd+3 : leadEnd+endStart]
- data.Inner = template.HTML(CleanP(ShortcodesHandle(s, p, t)))
- remainder := CleanP(stringToParse[leadEnd+endEnd:])
+ leadStart := strings.Index(stringToParse, `{{%`)
+ if leadStart >= 0 {
+ leadEnd := strings.Index(stringToParse[leadStart:], `%}}`) + leadStart
+ if leadEnd > leadStart {
+ name, par := SplitParams(stringToParse[leadStart+3 : leadEnd])
+ tmpl := GetTemplate(name, t)
+ if tmpl == nil {
+ return stringToParse
+ }
+ params := Tokenize(par)
+ // Always look for closing tag.
+ endStart, endEnd := FindEnd(stringToParse[leadEnd:], name)
+ var data = &ShortcodeWithPage{Params: params, Page: p}
+ if endStart > 0 {
+ s := stringToParse[leadEnd+3 : leadEnd+endStart]
+ data.Inner = template.HTML(CleanP(ShortcodesHandle(s, p, t)))
+ remainder := CleanP(stringToParse[leadEnd+endEnd:])
- return CleanP(stringToParse[:leadStart]) +
- ShortcodeRender(tmpl, data) +
- CleanP(ShortcodesHandle(remainder, p, t))
- }
- return CleanP(stringToParse[:leadStart]) +
- ShortcodeRender(tmpl, data) +
- CleanP(ShortcodesHandle(stringToParse[leadEnd+3:], p,
- t))
- }
- }
- return stringToParse
+ return CleanP(stringToParse[:leadStart]) +
+ ShortcodeRender(tmpl, data) +
+ CleanP(ShortcodesHandle(remainder, p, t))
+ }
+ return CleanP(stringToParse[:leadStart]) +
+ ShortcodeRender(tmpl, data) +
+ CleanP(ShortcodesHandle(stringToParse[leadEnd+3:], p,
+ t))
+ }
+ }
+ return stringToParse
}
// Clean up odd behavior when closing tag is on first line
// or opening tag is on the last line due to extra line in markdown file
func CleanP(str string) string {
- if strings.HasSuffix(strings.TrimSpace(str), "<p>") {
- idx := strings.LastIndex(str, "<p>")
- str = str[:idx]
- }
+ if strings.HasSuffix(strings.TrimSpace(str), "<p>") {
+ idx := strings.LastIndex(str, "<p>")
+ str = str[:idx]
+ }
- if strings.HasPrefix(strings.TrimSpace(str), "</p>") {
- str = str[strings.Index(str, "</p>")+5:]
- }
+ if strings.HasPrefix(strings.TrimSpace(str), "</p>") {
+ str = str[strings.Index(str, "</p>")+5:]
+ }
- return str
+ return str
}
func FindEnd(str string, name string) (int, int) {
- var endPos int
- var startPos int
- var try []string
+ var endPos int
+ var startPos int
+ var try []string
- try = append(try, "{{% /"+name+" %}}")
- try = append(try, "{{% /"+name+"%}}")
- try = append(try, "{{%/"+name+"%}}")
- try = append(try, "{{%/"+name+" %}}")
+ try = append(try, "{{% /"+name+" %}}")
+ try = append(try, "{{% /"+name+"%}}")
+ try = append(try, "{{%/"+name+"%}}")
+ try = append(try, "{{%/"+name+" %}}")
- lowest := len(str)
- for _, x := range try {
- start := strings.Index(str, x)
- if start < lowest && start > 0 {
- startPos = start
- endPos = startPos + len(x)
- }
- }
+ lowest := len(str)
+ for _, x := range try {
+ start := strings.Index(str, x)
+ if start < lowest && start > 0 {
+ startPos = start
+ endPos = startPos + len(x)
+ }
+ }
- return startPos, endPos
+ return startPos, endPos
}
func GetTemplate(name string, t bundle.Template) *template.Template {
- if x := t.Lookup("shortcodes/" + name + ".html"); x != nil {
- return x
- }
- return t.Lookup("_internal/shortcodes/" + name + ".html")
+ if x := t.Lookup("shortcodes/" + name + ".html"); x != nil {
+ return x
+ }
+ return t.Lookup("_internal/shortcodes/" + name + ".html")
}
func StripShortcodes(stringToParse string) string {
- posStart := strings.Index(stringToParse, "{{%")
- if posStart > 0 {
- posEnd := strings.Index(stringToParse[posStart:], "%}}") + posStart
- if posEnd > posStart {
- newString := stringToParse[:posStart] + StripShortcodes(stringToParse[posEnd+3:])
- return newString
- }
- }
- return stringToParse
+ posStart := strings.Index(stringToParse, "{{%")
+ if posStart > 0 {
+ posEnd := strings.Index(stringToParse[posStart:], "%}}") + posStart
+ if posEnd > posStart {
+ newString := stringToParse[:posStart] + StripShortcodes(stringToParse[posEnd+3:])
+ return newString
+ }
+ }
+ return stringToParse
}
func Tokenize(in string) interface{} {
- first := strings.Fields(in)
- var final = make([]string, 0)
+ first := strings.Fields(in)
+ var final = make([]string, 0)
- // if don't need to parse, don't parse.
- if strings.Index(in, " ") < 0 && strings.Index(in, "=") < 1 {
- return append(final, in)
- }
+ // if don't need to parse, don't parse.
+ if strings.Index(in, " ") < 0 && strings.Index(in, "=") < 1 {
+ return append(final, in)
+ }
- var keys = make([]string, 0)
- inQuote := false
- start := 0
+ var keys = make([]string, 0)
+ inQuote := false
+ start := 0
- for i, v := range first {
- index := strings.Index(v, "=")
+ for i, v := range first {
+ index := strings.Index(v, "=")
- if !inQuote {
- if index > 1 {
- keys = append(keys, v[:index])
- v = v[index+1:]
- }
- }
+ if !inQuote {
+ if index > 1 {
+ keys = append(keys, v[:index])
+ v = v[index+1:]
+ }
+ }
- // Adjusted to handle htmlencoded and non htmlencoded input
- if !strings.HasPrefix(v, "“") && !strings.HasPrefix(v, "\"") && !inQuote {
- final = append(final, v)
- } else if inQuote && (strings.HasSuffix(v, "”") ||
- strings.HasSuffix(v, "\"")) && !strings.HasSuffix(v, "\\\"") {
- if strings.HasSuffix(v, "\"") {
- first[i] = v[:len(v)-1]
- } else {
- first[i] = v[:len(v)-7]
- }
- final = append(final, strings.Join(first[start:i+1], " "))
- inQuote = false
- } else if (strings.HasPrefix(v, "“") ||
- strings.HasPrefix(v, "\"")) && !inQuote {
- if strings.HasSuffix(v, "”") || strings.HasSuffix(v,
- "\"") {
- if strings.HasSuffix(v, "\"") {
- if len(v) > 1 {
- final = append(final, v[1:len(v)-1])
- } else {
- final = append(final, "")
- }
- } else {
- final = append(final, v[7:len(v)-7])
- }
- } else {
- start = i
- if strings.HasPrefix(v, "\"") {
- first[i] = v[1:]
- } else {
- first[i] = v[7:]
- }
- inQuote = true
- }
- }
+ // Adjusted to handle htmlencoded and non htmlencoded input
+ if !strings.HasPrefix(v, "“") && !strings.HasPrefix(v, "\"") && !inQuote {
+ final = append(final, v)
+ } else if inQuote && (strings.HasSuffix(v, "”") ||
+ strings.HasSuffix(v, "\"")) && !strings.HasSuffix(v, "\\\"") {
+ if strings.HasSuffix(v, "\"") {
+ first[i] = v[:len(v)-1]
+ } else {
+ first[i] = v[:len(v)-7]
+ }
+ final = append(final, strings.Join(first[start:i+1], " "))
+ inQuote = false
+ } else if (strings.HasPrefix(v, "“") ||
+ strings.HasPrefix(v, "\"")) && !inQuote {
+ if strings.HasSuffix(v, "”") || strings.HasSuffix(v,
+ "\"") {
+ if strings.HasSuffix(v, "\"") {
+ if len(v) > 1 {
+ final = append(final, v[1:len(v)-1])
+ } else {
+ final = append(final, "")
+ }
+ } else {
+ final = append(final, v[7:len(v)-7])
+ }
+ } else {
+ start = i
+ if strings.HasPrefix(v, "\"") {
+ first[i] = v[1:]
+ } else {
+ first[i] = v[7:]
+ }
+ inQuote = true
+ }
+ }
- // No closing "... just make remainder the final token
- if inQuote && i == len(first) {
- final = append(final, first[start:]...)
- }
- }
+ // No closing "... just make remainder the final token
+ if inQuote && i == len(first) {
+ final = append(final, first[start:]...)
+ }
+ }
- if len(keys) > 0 && (len(keys) != len(final)) {
- panic("keys and final different lengths")
- }
+ if len(keys) > 0 && (len(keys) != len(final)) {
+ panic("keys and final different lengths")
+ }
- if len(keys) > 0 {
- var m = make(map[string]string)
- for i, k := range keys {
- m[k] = final[i]
- }
+ if len(keys) > 0 {
+ var m = make(map[string]string)
+ for i, k := range keys {
+ m[k] = final[i]
+ }
- return m
- }
+ return m
+ }
- return final
+ return final
}
func SplitParams(in string) (name string, par2 string) {
- i := strings.IndexFunc(strings.TrimSpace(in), unicode.IsSpace)
- if i < 1 {
- return strings.TrimSpace(in), ""
- }
+ i := strings.IndexFunc(strings.TrimSpace(in), unicode.IsSpace)
+ if i < 1 {
+ return strings.TrimSpace(in), ""
+ }
- return strings.TrimSpace(in[:i+1]), strings.TrimSpace(in[i+1:])
+ return strings.TrimSpace(in[:i+1]), strings.TrimSpace(in[i+1:])
}
func ShortcodeRender(tmpl *template.Template, data *ShortcodeWithPage) string {
- buffer := new(bytes.Buffer)
- err := tmpl.Execute(buffer, data)
- if err != nil {
- fmt.Println("error processing shortcode", tmpl.Name(), "\n ERR:", err)
- }
- return buffer.String()
+ buffer := new(bytes.Buffer)
+ err := tmpl.Execute(buffer, data)
+ if err != nil {
+ fmt.Println("error processing shortcode", tmpl.Name(), "\n ERR:", err)
+ }
+ return buffer.String()
}
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -14,21 +14,21 @@
package hugolib
import (
- "bitbucket.org/pkg/inflect"
- "bytes"
- "fmt"
- "github.com/spf13/hugo/helpers"
- "github.com/spf13/hugo/source"
- "github.com/spf13/hugo/target"
- "github.com/spf13/hugo/template/bundle"
- "github.com/spf13/hugo/transform"
- "github.com/spf13/nitro"
- "html/template"
- "io"
- "net/url"
- "os"
- "strings"
- "time"
+ "bitbucket.org/pkg/inflect"
+ "bytes"
+ "fmt"
+ "github.com/spf13/hugo/helpers"
+ "github.com/spf13/hugo/source"
+ "github.com/spf13/hugo/target"
+ "github.com/spf13/hugo/template/bundle"
+ "github.com/spf13/hugo/transform"
+ "github.com/spf13/nitro"
+ "html/template"
+ "io"
+ "net/url"
+ "os"
+ "strings"
+ "time"
)
var _ = transform.AbsURL
@@ -36,7 +36,7 @@
var DefaultTimer *nitro.B
func MakePermalink(base *url.URL, path *url.URL) *url.URL {
- return base.ResolveReference(path)
+ return base.ResolveReference(path)
}
// Site contains all the information relevant for constructing a static
@@ -57,621 +57,621 @@
//
// 5. The entire collection of files is written to disk.
type Site struct {
- Config Config
- Pages Pages
- Tmpl bundle.Template
- Indexes IndexList
- Source source.Input
- Sections Index
- Info SiteInfo
- Shortcodes map[string]ShortcodeFunc
- timer *nitro.B
- Target target.Output
- Alias target.AliasPublisher
- Completed chan bool
- RunMode runmode
- params map[string]interface{}
+ Config Config
+ Pages Pages
+ Tmpl bundle.Template
+ Indexes IndexList
+ Source source.Input
+ Sections Index
+ Info SiteInfo
+ Shortcodes map[string]ShortcodeFunc
+ timer *nitro.B
+ Target target.Output
+ Alias target.AliasPublisher
+ Completed chan bool
+ RunMode runmode
+ params map[string]interface{}
}
type SiteInfo struct {
- BaseUrl template.URL
- Indexes IndexList
- Recent *Pages
- LastChange time.Time
- Title string
- Config *Config
- Permalinks PermalinkOverrides
- Params map[string]interface{}
+ BaseUrl template.URL
+ Indexes IndexList
+ Recent *Pages
+ LastChange time.Time
+ Title string
+ Config *Config
+ Permalinks PermalinkOverrides
+ Params map[string]interface{}
}
type runmode struct {
- Watching bool
+ Watching bool
}
func (s *Site) Running() bool {
- return s.RunMode.Watching
+ return s.RunMode.Watching
}
func init() {
- DefaultTimer = nitro.Initalize()
+ DefaultTimer = nitro.Initalize()
}
func (s *Site) timerStep(step string) {
- if s.timer == nil {
- s.timer = DefaultTimer
- }
- s.timer.Step(step)
+ if s.timer == nil {
+ s.timer = DefaultTimer
+ }
+ s.timer.Step(step)
}
func (s *Site) Build() (err error) {
- if err = s.Process(); err != nil {
- return
- }
- if err = s.Render(); err != nil {
- fmt.Printf("Error rendering site: %s\nAvailable templates:\n", err)
- for _, template := range s.Tmpl.Templates() {
- fmt.Printf("\t%s\n", template.Name())
- }
- return
- }
- return nil
+ if err = s.Process(); err != nil {
+ return
+ }
+ if err = s.Render(); err != nil {
+ fmt.Printf("Error rendering site: %s\nAvailable templates:\n", err)
+ for _, template := range s.Tmpl.Templates() {
+ fmt.Printf("\t%s\n", template.Name())
+ }
+ return
+ }
+ return nil
}
func (s *Site) Analyze() {
- s.Process()
- s.initTarget()
- s.Alias = &target.HTMLRedirectAlias{
- PublishDir: s.absPublishDir(),
- }
- s.ShowPlan(os.Stdout)
+ s.Process()
+ s.initTarget()
+ s.Alias = &target.HTMLRedirectAlias{
+ PublishDir: s.absPublishDir(),
+ }
+ s.ShowPlan(os.Stdout)
}
func (s *Site) prepTemplates() {
- s.Tmpl = bundle.NewTemplate()
- s.Tmpl.LoadTemplates(s.absLayoutDir())
+ s.Tmpl = bundle.NewTemplate()
+ s.Tmpl.LoadTemplates(s.absLayoutDir())
}
func (s *Site) addTemplate(name, data string) error {
- return s.Tmpl.AddTemplate(name, data)
+ return s.Tmpl.AddTemplate(name, data)
}
func (s *Site) Process() (err error) {
- if err = s.initialize(); err != nil {
- return
- }
- s.prepTemplates()
- s.timerStep("initialize & template prep")
- if err = s.CreatePages(); err != nil {
- return
- }
- s.setupPrevNext()
- s.timerStep("import pages")
- if err = s.BuildSiteMeta(); err != nil {
- return
- }
- s.timerStep("build indexes")
- return
+ if err = s.initialize(); err != nil {
+ return
+ }
+ s.prepTemplates()
+ s.timerStep("initialize & template prep")
+ if err = s.CreatePages(); err != nil {
+ return
+ }
+ s.setupPrevNext()
+ s.timerStep("import pages")
+ if err = s.BuildSiteMeta(); err != nil {
+ return
+ }
+ s.timerStep("build indexes")
+ return
}
func (s *Site) setupPrevNext() {
- for i, page := range s.Pages {
- if i < len(s.Pages)-1 {
- page.Next = s.Pages[i+1]
- }
+ for i, page := range s.Pages {
+ if i < len(s.Pages)-1 {
+ page.Next = s.Pages[i+1]
+ }
- if i > 0 {
- page.Prev = s.Pages[i-1]
- }
- }
+ if i > 0 {
+ page.Prev = s.Pages[i-1]
+ }
+ }
}
func (s *Site) Render() (err error) {
- if err = s.RenderAliases(); err != nil {
- return
- }
- s.timerStep("render and write aliases")
- if err = s.RenderIndexes(); err != nil {
- return
- }
- s.timerStep("render and write indexes")
- s.RenderIndexesIndexes()
- s.timerStep("render & write index indexes")
- if err = s.RenderLists(); err != nil {
- return
- }
- s.timerStep("render and write lists")
- if err = s.RenderPages(); err != nil {
- return
- }
- s.timerStep("render and write pages")
- if err = s.RenderHomePage(); err != nil {
- return
- }
- s.timerStep("render and write homepage")
- return
+ if err = s.RenderAliases(); err != nil {
+ return
+ }
+ s.timerStep("render and write aliases")
+ if err = s.RenderIndexes(); err != nil {
+ return
+ }
+ s.timerStep("render and write indexes")
+ s.RenderIndexesIndexes()
+ s.timerStep("render & write index indexes")
+ if err = s.RenderLists(); err != nil {
+ return
+ }
+ s.timerStep("render and write lists")
+ if err = s.RenderPages(); err != nil {
+ return
+ }
+ s.timerStep("render and write pages")
+ if err = s.RenderHomePage(); err != nil {
+ return
+ }
+ s.timerStep("render and write homepage")
+ return
}
func (s *Site) checkDescriptions() {
- for _, p := range s.Pages {
- if len(p.Description) < 60 {
- fmt.Println(p.FileName + " ")
- }
- }
+ for _, p := range s.Pages {
+ if len(p.Description) < 60 {
+ fmt.Println(p.FileName + " ")
+ }
+ }
}
func (s *Site) initialize() (err error) {
- if err = s.checkDirectories(); err != nil {
- return err
- }
+ if err = s.checkDirectories(); err != nil {
+ return err
+ }
- staticDir := s.Config.GetAbsPath(s.Config.StaticDir + "/")
+ staticDir := s.Config.GetAbsPath(s.Config.StaticDir + "/")
- s.Source = &source.Filesystem{
- AvoidPaths: []string{staticDir},
- Base: s.absContentDir(),
- }
+ s.Source = &source.Filesystem{
+ AvoidPaths: []string{staticDir},
+ Base: s.absContentDir(),
+ }
- s.initializeSiteInfo()
+ s.initializeSiteInfo()
- s.Shortcodes = make(map[string]ShortcodeFunc)
- return
+ s.Shortcodes = make(map[string]ShortcodeFunc)
+ return
}
func (s *Site) initializeSiteInfo() {
- s.Info = SiteInfo{
- BaseUrl: template.URL(s.Config.BaseUrl),
- Title: s.Config.Title,
- Recent: &s.Pages,
- Config: &s.Config,
- Params: s.Config.Params,
- Permalinks: s.Config.Permalinks,
- }
+ s.Info = SiteInfo{
+ BaseUrl: template.URL(s.Config.BaseUrl),
+ Title: s.Config.Title,
+ Recent: &s.Pages,
+ Config: &s.Config,
+ Params: s.Config.Params,
+ Permalinks: s.Config.Permalinks,
+ }
}
// Check if File / Directory Exists
func exists(path string) (bool, error) {
- _, err := os.Stat(path)
- if err == nil {
- return true, nil
- }
- if os.IsNotExist(err) {
- return false, nil
- }
- return false, err
+ _, err := os.Stat(path)
+ if err == nil {
+ return true, nil
+ }
+ if os.IsNotExist(err) {
+ return false, nil
+ }
+ return false, err
}
func (s *Site) absLayoutDir() string {
- return s.Config.GetAbsPath(s.Config.LayoutDir)
+ return s.Config.GetAbsPath(s.Config.LayoutDir)
}
func (s *Site) absContentDir() string {
- return s.Config.GetAbsPath(s.Config.ContentDir)
+ return s.Config.GetAbsPath(s.Config.ContentDir)
}
func (s *Site) absPublishDir() string {
- return s.Config.GetAbsPath(s.Config.PublishDir)
+ return s.Config.GetAbsPath(s.Config.PublishDir)
}
func (s *Site) checkDirectories() (err error) {
- /*
- if b, _ := dirExists(s.absLayoutDir()); !b {
- return fmt.Errorf("No layout directory found, expecting to find it at " + s.absLayoutDir())
- }
- */
- if b, _ := dirExists(s.absContentDir()); !b {
- return fmt.Errorf("No source directory found, expecting to find it at " + s.absContentDir())
- }
- return
+ /*
+ if b, _ := dirExists(s.absLayoutDir()); !b {
+ return fmt.Errorf("No layout directory found, expecting to find it at " + s.absLayoutDir())
+ }
+ */
+ if b, _ := dirExists(s.absContentDir()); !b {
+ return fmt.Errorf("No source directory found, expecting to find it at " + s.absContentDir())
+ }
+ return
}
func (s *Site) CreatePages() (err error) {
- if s.Source == nil {
- panic(fmt.Sprintf("s.Source not set %s", s.absContentDir()))
- }
- if len(s.Source.Files()) < 1 {
- return fmt.Errorf("No source files found in %s", s.absContentDir())
- }
- for _, file := range s.Source.Files() {
- page, err := ReadFrom(file.Contents, file.LogicalName)
- if err != nil {
- return err
- }
- page.Site = s.Info
- page.Tmpl = s.Tmpl
- page.Section = file.Section
- page.Dir = file.Dir
+ if s.Source == nil {
+ panic(fmt.Sprintf("s.Source not set %s", s.absContentDir()))
+ }
+ if len(s.Source.Files()) < 1 {
+ return fmt.Errorf("No source files found in %s", s.absContentDir())
+ }
+ for _, file := range s.Source.Files() {
+ page, err := ReadFrom(file.Contents, file.LogicalName)
+ if err != nil {
+ return err
+ }
+ page.Site = s.Info
+ page.Tmpl = s.Tmpl
+ page.Section = file.Section
+ page.Dir = file.Dir
- //Handling short codes prior to Conversion to HTML
- page.ProcessShortcodes(s.Tmpl)
+ //Handling short codes prior to Conversion to HTML
+ page.ProcessShortcodes(s.Tmpl)
- err = page.Convert()
- if err != nil {
- return err
- }
+ err = page.Convert()
+ if err != nil {
+ return err
+ }
- if s.Config.BuildDrafts || !page.Draft {
- s.Pages = append(s.Pages, page)
- }
- }
+ if s.Config.BuildDrafts || !page.Draft {
+ s.Pages = append(s.Pages, page)
+ }
+ }
- s.Pages.Sort()
- return
+ s.Pages.Sort()
+ return
}
func (s *Site) BuildSiteMeta() (err error) {
- s.Indexes = make(IndexList)
- s.Sections = make(Index)
+ s.Indexes = make(IndexList)
+ s.Sections = make(Index)
- for _, plural := range s.Config.Indexes {
- s.Indexes[plural] = make(Index)
- for _, p := range s.Pages {
- vals := p.GetParam(plural)
- weight := p.GetParam(plural + "_weight")
- if weight == nil {
- weight = 0
- }
+ for _, plural := range s.Config.Indexes {
+ s.Indexes[plural] = make(Index)
+ for _, p := range s.Pages {
+ vals := p.GetParam(plural)
+ weight := p.GetParam(plural + "_weight")
+ if weight == nil {
+ weight = 0
+ }
- if vals != nil {
- v, ok := vals.([]string)
- if ok {
- for _, idx := range v {
- x := WeightedPage{weight.(int), p}
+ if vals != nil {
+ v, ok := vals.([]string)
+ if ok {
+ for _, idx := range v {
+ x := WeightedPage{weight.(int), p}
- s.Indexes[plural].Add(idx, x)
- }
- } else {
- if s.Config.Verbose {
- fmt.Fprintf(os.Stderr, "Invalid %s in %s\n", plural, p.File.FileName)
- }
- }
- }
- }
- for k := range s.Indexes[plural] {
- s.Indexes[plural][k].Sort()
- }
- }
+ s.Indexes[plural].Add(idx, x)
+ }
+ } else {
+ if s.Config.Verbose {
+ fmt.Fprintf(os.Stderr, "Invalid %s in %s\n", plural, p.File.FileName)
+ }
+ }
+ }
+ }
+ for k := range s.Indexes[plural] {
+ s.Indexes[plural][k].Sort()
+ }
+ }
- for i, p := range s.Pages {
- s.Sections.Add(p.Section, WeightedPage{s.Pages[i].Weight, s.Pages[i]})
- }
+ for i, p := range s.Pages {
+ s.Sections.Add(p.Section, WeightedPage{s.Pages[i].Weight, s.Pages[i]})
+ }
- for k := range s.Sections {
- s.Sections[k].Sort()
- }
+ for k := range s.Sections {
+ s.Sections[k].Sort()
+ }
- s.Info.Indexes = s.Indexes
+ s.Info.Indexes = s.Indexes
- if len(s.Pages) == 0 {
- return
- }
- s.Info.LastChange = s.Pages[0].Date
+ if len(s.Pages) == 0 {
+ return
+ }
+ s.Info.LastChange = s.Pages[0].Date
- // populate pages with site metadata
- for _, p := range s.Pages {
- p.Site = s.Info
- }
+ // populate pages with site metadata
+ for _, p := range s.Pages {
+ p.Site = s.Info
+ }
- return
+ return
}
func (s *Site) possibleIndexes() (indexes []string) {
- for _, p := range s.Pages {
- for k := range p.Params {
- if !inStringArray(indexes, k) {
- indexes = append(indexes, k)
- }
- }
- }
- return
+ for _, p := range s.Pages {
+ for k := range p.Params {
+ if !inStringArray(indexes, k) {
+ indexes = append(indexes, k)
+ }
+ }
+ }
+ return
}
func inStringArray(arr []string, el string) bool {
- for _, v := range arr {
- if v == el {
- return true
- }
- }
- return false
+ for _, v := range arr {
+ if v == el {
+ return true
+ }
+ }
+ return false
}
func (s *Site) RenderAliases() error {
- for _, p := range s.Pages {
- for _, a := range p.Aliases {
- plink, err := p.Permalink()
- if err != nil {
- return err
- }
- if err := s.WriteAlias(a, template.HTML(plink)); err != nil {
- return err
- }
- }
- }
- return nil
+ for _, p := range s.Pages {
+ for _, a := range p.Aliases {
+ plink, err := p.Permalink()
+ if err != nil {
+ return err
+ }
+ if err := s.WriteAlias(a, template.HTML(plink)); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
}
func (s *Site) RenderPages() (err error) {
- for _, p := range s.Pages {
- var layout []string
+ for _, p := range s.Pages {
+ var layout []string
- if !p.IsRenderable() {
- self := "__" + p.TargetPath()
- _, err := s.Tmpl.New(self).Parse(string(p.Content))
- if err != nil {
- return err
- }
- layout = append(layout, self)
- } else {
- layout = append(layout, p.Layout()...)
- layout = append(layout, "_default/single.html")
- }
+ if !p.IsRenderable() {
+ self := "__" + p.TargetPath()
+ _, err := s.Tmpl.New(self).Parse(string(p.Content))
+ if err != nil {
+ return err
+ }
+ layout = append(layout, self)
+ } else {
+ layout = append(layout, p.Layout()...)
+ layout = append(layout, "_default/single.html")
+ }
- err := s.render(p, p.TargetPath(), layout...)
- if err != nil {
- return err
- }
- }
- return nil
+ err := s.render(p, p.TargetPath(), layout...)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
}
func (s *Site) RenderIndexes() error {
- for singular, plural := range s.Config.Indexes {
- for k, o := range s.Indexes[plural] {
- n := s.NewNode()
- n.Title = strings.Title(k)
- url := helpers.Urlize(plural + "/" + k)
- n.Url = url + ".html"
- plink := n.Url
- n.Permalink = permalink(s, plink)
- n.RSSLink = permalink(s, url+".xml")
- n.Date = o[0].Page.Date
- n.Data[singular] = o
- n.Data["Pages"] = o.Pages()
- layout := "indexes/" + singular + ".html"
+ for singular, plural := range s.Config.Indexes {
+ for k, o := range s.Indexes[plural] {
+ n := s.NewNode()
+ n.Title = strings.Title(k)
+ url := helpers.Urlize(plural + "/" + k)
+ n.Url = url + ".html"
+ plink := n.Url
+ n.Permalink = permalink(s, plink)
+ n.RSSLink = permalink(s, url+".xml")
+ n.Date = o[0].Page.Date
+ n.Data[singular] = o
+ n.Data["Pages"] = o.Pages()
+ layout := "indexes/" + singular + ".html"
- var base string
- base = plural + "/" + k
- err := s.render(n, base+".html", layout)
- if err != nil {
- return err
- }
+ var base string
+ base = plural + "/" + k
+ err := s.render(n, base+".html", layout)
+ if err != nil {
+ return err
+ }
- if a := s.Tmpl.Lookup("rss.xml"); a != nil {
- // XML Feed
- n.Url = helpers.Urlize(plural + "/" + k + ".xml")
- n.Permalink = permalink(s, n.Url)
- err := s.render(n, base+".xml", "rss.xml")
- if err != nil {
- return err
- }
- }
- }
- }
- return nil
-}
+ if a := s.Tmpl.Lookup("rss.xml"); a != nil {
+ // XML Feed
+ n.Url = helpers.Urlize(plural + "/" + k + ".xml")
+ n.Permalink = permalink(s, n.Url)
+ err := s.render(n, base+".xml", "rss.xml")
+ if err != nil {
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
func (s *Site) RenderIndexesIndexes() (err error) {
- layout := "indexes/indexes.html"
- if s.Tmpl.Lookup(layout) != nil {
- for singular, plural := range s.Config.Indexes {
- n := s.NewNode()
- n.Title = strings.Title(plural)
- url := helpers.Urlize(plural)
- n.Url = url + "/index.html"
- n.Permalink = permalink(s, n.Url)
- n.Data["Singular"] = singular
- n.Data["Plural"] = plural
- n.Data["Index"] = s.Indexes[plural]
- // keep the following just for legacy reasons
- n.Data["OrderedIndex"] = s.Indexes[plural]
+ layout := "indexes/indexes.html"
+ if s.Tmpl.Lookup(layout) != nil {
+ for singular, plural := range s.Config.Indexes {
+ n := s.NewNode()
+ n.Title = strings.Title(plural)
+ url := helpers.Urlize(plural)
+ n.Url = url + "/index.html"
+ n.Permalink = permalink(s, n.Url)
+ n.Data["Singular"] = singular
+ n.Data["Plural"] = plural
+ n.Data["Index"] = s.Indexes[plural]
+ // keep the following just for legacy reasons
+ n.Data["OrderedIndex"] = s.Indexes[plural]
- err := s.render(n, plural+"/index.html", layout)
- if err != nil {
- return err
- }
- }
- }
- return
+ err := s.render(n, plural+"/index.html", layout)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return
}
func (s *Site) RenderLists() error {
- for section, data := range s.Sections {
- n := s.NewNode()
- n.Title = strings.Title(inflect.Pluralize(section))
- n.Url = helpers.Urlize(section + "/" + "index.html")
- n.Permalink = permalink(s, n.Url)
- n.RSSLink = permalink(s, section+".xml")
- n.Date = data[0].Page.Date
- n.Data["Pages"] = data.Pages()
- layout := "indexes/" + section + ".html"
+ for section, data := range s.Sections {
+ n := s.NewNode()
+ n.Title = strings.Title(inflect.Pluralize(section))
+ n.Url = helpers.Urlize(section + "/" + "index.html")
+ n.Permalink = permalink(s, n.Url)
+ n.RSSLink = permalink(s, section+".xml")
+ n.Date = data[0].Page.Date
+ n.Data["Pages"] = data.Pages()
+ layout := "indexes/" + section + ".html"
- err := s.render(n, section, layout, "_default/indexes.html")
- if err != nil {
- return err
- }
+ err := s.render(n, section, layout, "_default/indexes.html")
+ if err != nil {
+ return err
+ }
- if a := s.Tmpl.Lookup("rss.xml"); a != nil {
- // XML Feed
- n.Url = helpers.Urlize(section + ".xml")
- n.Permalink = template.HTML(string(n.Site.BaseUrl) + n.Url)
- err = s.render(n, section+".xml", "rss.xml")
- if err != nil {
- return err
- }
- }
- }
- return nil
+ if a := s.Tmpl.Lookup("rss.xml"); a != nil {
+ // XML Feed
+ n.Url = helpers.Urlize(section + ".xml")
+ n.Permalink = template.HTML(string(n.Site.BaseUrl) + n.Url)
+ err = s.render(n, section+".xml", "rss.xml")
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
}
func (s *Site) RenderHomePage() error {
- n := s.NewNode()
- n.Title = n.Site.Title
- n.Url = helpers.Urlize(string(n.Site.BaseUrl))
- n.RSSLink = permalink(s, "index.xml")
- n.Permalink = permalink(s, "")
- n.Data["Pages"] = s.Pages
- err := s.render(n, "/", "index.html")
- if err != nil {
- return err
- }
+ n := s.NewNode()
+ n.Title = n.Site.Title
+ n.Url = helpers.Urlize(string(n.Site.BaseUrl))
+ n.RSSLink = permalink(s, "index.xml")
+ n.Permalink = permalink(s, "")
+ n.Data["Pages"] = s.Pages
+ err := s.render(n, "/", "index.html")
+ if err != nil {
+ return err
+ }
- if a := s.Tmpl.Lookup("rss.xml"); a != nil {
- // XML Feed
- n.Url = helpers.Urlize("index.xml")
- n.Title = "Recent Content"
- n.Permalink = permalink(s, "index.xml")
- high := 50
- if len(s.Pages) < high {
- high = len(s.Pages)
- }
- n.Data["Pages"] = s.Pages[:high]
- if len(s.Pages) > 0 {
- n.Date = s.Pages[0].Date
- }
- err := s.render(n, ".xml", "rss.xml")
- if err != nil {
- return err
- }
- }
+ if a := s.Tmpl.Lookup("rss.xml"); a != nil {
+ // XML Feed
+ n.Url = helpers.Urlize("index.xml")
+ n.Title = "Recent Content"
+ n.Permalink = permalink(s, "index.xml")
+ high := 50
+ if len(s.Pages) < high {
+ high = len(s.Pages)
+ }
+ n.Data["Pages"] = s.Pages[:high]
+ if len(s.Pages) > 0 {
+ n.Date = s.Pages[0].Date
+ }
+ err := s.render(n, ".xml", "rss.xml")
+ if err != nil {
+ return err
+ }
+ }
- if a := s.Tmpl.Lookup("404.html"); a != nil {
- n.Url = helpers.Urlize("404.html")
- n.Title = "404 Page not found"
- n.Permalink = permalink(s, "404.html")
- return s.render(n, "404.html", "404.html")
- }
+ if a := s.Tmpl.Lookup("404.html"); a != nil {
+ n.Url = helpers.Urlize("404.html")
+ n.Title = "404 Page not found"
+ n.Permalink = permalink(s, "404.html")
+ return s.render(n, "404.html", "404.html")
+ }
- return nil
+ return nil
}
func (s *Site) Stats() {
- fmt.Printf("%d pages created \n", len(s.Pages))
- for _, pl := range s.Config.Indexes {
- fmt.Printf("%d %s index created\n", len(s.Indexes[pl]), pl)
- }
+ fmt.Printf("%d pages created \n", len(s.Pages))
+ for _, pl := range s.Config.Indexes {
+ fmt.Printf("%d %s index created\n", len(s.Indexes[pl]), pl)
+ }
}
func permalink(s *Site, plink string) template.HTML {
- base, err := url.Parse(string(s.Config.BaseUrl))
- if err != nil {
- panic(err)
- }
+ base, err := url.Parse(string(s.Config.BaseUrl))
+ if err != nil {
+ panic(err)
+ }
- path, err := url.Parse(plink)
- if err != nil {
- panic(err)
- }
+ path, err := url.Parse(plink)
+ if err != nil {
+ panic(err)
+ }
- return template.HTML(MakePermalink(base, path).String())
+ return template.HTML(MakePermalink(base, path).String())
}
func (s *Site) NewNode() *Node {
- return &Node{
- Data: make(map[string]interface{}),
- Site: s.Info,
- }
+ return &Node{
+ Data: make(map[string]interface{}),
+ Site: s.Info,
+ }
}
func (s *Site) render(d interface{}, out string, layouts ...string) (err error) {
- layout := s.findFirstLayout(layouts...)
- if layout == "" {
- if s.Config.Verbose {
- fmt.Printf("Unable to locate layout: %s\n", layouts)
- }
- return
- }
+ layout := s.findFirstLayout(layouts...)
+ if layout == "" {
+ if s.Config.Verbose {
+ fmt.Printf("Unable to locate layout: %s\n", layouts)
+ }
+ return
+ }
- transformLinks := transform.NewEmptyTransforms()
+ transformLinks := transform.NewEmptyTransforms()
- if s.Config.CanonifyUrls {
- absURL, err := transform.AbsURL(s.Config.BaseUrl)
- if err != nil {
- return err
- }
- transformLinks = append(transformLinks, absURL...)
- }
+ if s.Config.CanonifyUrls {
+ absURL, err := transform.AbsURL(s.Config.BaseUrl)
+ if err != nil {
+ return err
+ }
+ transformLinks = append(transformLinks, absURL...)
+ }
- transformer := transform.NewChain(transformLinks...)
+ transformer := transform.NewChain(transformLinks...)
- var renderBuffer *bytes.Buffer
+ var renderBuffer *bytes.Buffer
- if strings.HasSuffix(out, ".xml") {
- renderBuffer = s.NewXMLBuffer()
- } else {
- renderBuffer = new(bytes.Buffer)
- }
+ if strings.HasSuffix(out, ".xml") {
+ renderBuffer = s.NewXMLBuffer()
+ } else {
+ renderBuffer = new(bytes.Buffer)
+ }
- err = s.renderThing(d, layout, renderBuffer)
- if err != nil {
- // Behavior here should be dependent on if running in server or watch mode.
- fmt.Println(fmt.Errorf("Rendering error: %v", err))
- if !s.Running() {
- os.Exit(-1)
- }
- }
+ err = s.renderThing(d, layout, renderBuffer)
+ if err != nil {
+ // Behavior here should be dependent on if running in server or watch mode.
+ fmt.Println(fmt.Errorf("Rendering error: %v", err))
+ if !s.Running() {
+ os.Exit(-1)
+ }
+ }
- var outBuffer = new(bytes.Buffer)
- if strings.HasSuffix(out, ".xml") {
- outBuffer = renderBuffer
- } else {
- transformer.Apply(outBuffer, renderBuffer)
- }
+ var outBuffer = new(bytes.Buffer)
+ if strings.HasSuffix(out, ".xml") {
+ outBuffer = renderBuffer
+ } else {
+ transformer.Apply(outBuffer, renderBuffer)
+ }
- return s.WritePublic(out, outBuffer)
+ return s.WritePublic(out, outBuffer)
}
func (s *Site) findFirstLayout(layouts ...string) (layout string) {
- for _, layout = range layouts {
- if s.Tmpl.Lookup(layout) != nil {
- return
- }
- }
- return ""
+ for _, layout = range layouts {
+ if s.Tmpl.Lookup(layout) != nil {
+ return
+ }
+ }
+ return ""
}
func (s *Site) renderThing(d interface{}, layout string, w io.Writer) error {
- // If the template doesn't exist, then return, but leave the Writer open
- if s.Tmpl.Lookup(layout) == nil {
- return fmt.Errorf("Layout not found: %s", layout)
- }
- //defer w.Close()
- return s.Tmpl.ExecuteTemplate(w, layout, d)
+ // If the template doesn't exist, then return, but leave the Writer open
+ if s.Tmpl.Lookup(layout) == nil {
+ return fmt.Errorf("Layout not found: %s", layout)
+ }
+ //defer w.Close()
+ return s.Tmpl.ExecuteTemplate(w, layout, d)
}
func (s *Site) NewXMLBuffer() *bytes.Buffer {
- header := "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n"
- return bytes.NewBufferString(header)
+ header := "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n"
+ return bytes.NewBufferString(header)
}
func (s *Site) initTarget() {
- if s.Target == nil {
- s.Target = &target.Filesystem{
- PublishDir: s.absPublishDir(),
- UglyUrls: s.Config.UglyUrls,
- }
- }
+ if s.Target == nil {
+ s.Target = &target.Filesystem{
+ PublishDir: s.absPublishDir(),
+ UglyUrls: s.Config.UglyUrls,
+ }
+ }
}
func (s *Site) WritePublic(path string, reader io.Reader) (err error) {
- s.initTarget()
+ s.initTarget()
- if s.Config.Verbose {
- fmt.Println(path)
- }
- return s.Target.Publish(path, reader)
+ if s.Config.Verbose {
+ fmt.Println(path)
+ }
+ return s.Target.Publish(path, reader)
}
func (s *Site) WriteAlias(path string, permalink template.HTML) (err error) {
- if s.Alias == nil {
- s.initTarget()
- s.Alias = &target.HTMLRedirectAlias{
- PublishDir: s.absPublishDir(),
- }
- }
+ if s.Alias == nil {
+ s.initTarget()
+ s.Alias = &target.HTMLRedirectAlias{
+ PublishDir: s.absPublishDir(),
+ }
+ }
- if s.Config.Verbose {
- fmt.Println(path)
- }
+ if s.Config.Verbose {
+ fmt.Println(path)
+ }
- return s.Alias.Publish(path, permalink)
+ return s.Alias.Publish(path, permalink)
}
--- a/hugolib/site_test.go
+++ b/hugolib/site_test.go
@@ -1,37 +1,37 @@
package hugolib
import (
- "bytes"
- "fmt"
- "github.com/spf13/hugo/source"
- "github.com/spf13/hugo/target"
- "html/template"
- "io"
- "strings"
- "testing"
+ "bytes"
+ "fmt"
+ "github.com/spf13/hugo/source"
+ "github.com/spf13/hugo/target"
+ "html/template"
+ "io"
+ "strings"
+ "testing"
)
const (
- TEMPLATE_TITLE = "{{ .Title }}"
- PAGE_SIMPLE_TITLE = `---
+ TEMPLATE_TITLE = "{{ .Title }}"
+ PAGE_SIMPLE_TITLE = `---
title: simple template
---
content`
- TEMPLATE_MISSING_FUNC = "{{ .Title | funcdoesnotexists }}"
- TEMPLATE_FUNC = "{{ .Title | urlize }}"
- TEMPLATE_CONTENT = "{{ .Content }}"
- TEMPLATE_DATE = "{{ .Date }}"
- INVALID_TEMPLATE_FORMAT_DATE = "{{ .Date.Format time.RFC3339 }}"
- TEMPLATE_WITH_URL_REL = "<a href=\"foobar.jpg\">Going</a>"
- TEMPLATE_WITH_URL_ABS = "<a href=\"/foobar.jpg\">Going</a>"
- PAGE_URL_SPECIFIED = `---
+ TEMPLATE_MISSING_FUNC = "{{ .Title | funcdoesnotexists }}"
+ TEMPLATE_FUNC = "{{ .Title | urlize }}"
+ TEMPLATE_CONTENT = "{{ .Content }}"
+ TEMPLATE_DATE = "{{ .Date }}"
+ INVALID_TEMPLATE_FORMAT_DATE = "{{ .Date.Format time.RFC3339 }}"
+ TEMPLATE_WITH_URL_REL = "<a href=\"foobar.jpg\">Going</a>"
+ TEMPLATE_WITH_URL_ABS = "<a href=\"/foobar.jpg\">Going</a>"
+ PAGE_URL_SPECIFIED = `---
title: simple template
url: "mycategory/my-whatever-content/"
---
content`
- PAGE_WITH_MD = `---
+ PAGE_WITH_MD = `---
title: page with md
---
# heading 1
@@ -42,306 +42,306 @@
)
func pageMust(p *Page, err error) *Page {
- if err != nil {
- panic(err)
- }
- return p
+ if err != nil {
+ panic(err)
+ }
+ return p
}
func TestDegenerateRenderThingMissingTemplate(t *testing.T) {
- p, _ := ReadFrom(strings.NewReader(PAGE_SIMPLE_TITLE), "content/a/file.md")
- p.Convert()
- s := new(Site)
- s.prepTemplates()
- err := s.renderThing(p, "foobar", nil)
- if err == nil {
- t.Errorf("Expected err to be returned when missing the template.")
- }
+ p, _ := ReadFrom(strings.NewReader(PAGE_SIMPLE_TITLE), "content/a/file.md")
+ p.Convert()
+ s := new(Site)
+ s.prepTemplates()
+ err := s.renderThing(p, "foobar", nil)
+ if err == nil {
+ t.Errorf("Expected err to be returned when missing the template.")
+ }
}
func TestAddInvalidTemplate(t *testing.T) {
- s := new(Site)
- s.prepTemplates()
- err := s.addTemplate("missing", TEMPLATE_MISSING_FUNC)
- if err == nil {
- t.Fatalf("Expecting the template to return an error")
- }
+ s := new(Site)
+ s.prepTemplates()
+ err := s.addTemplate("missing", TEMPLATE_MISSING_FUNC)
+ if err == nil {
+ t.Fatalf("Expecting the template to return an error")
+ }
}
type nopCloser struct {
- io.Writer
+ io.Writer
}
func (nopCloser) Close() error { return nil }
func NopCloser(w io.Writer) io.WriteCloser {
- return nopCloser{w}
+ return nopCloser{w}
}
func matchRender(t *testing.T, s *Site, p *Page, tmplName string, expected string) {
- content := new(bytes.Buffer)
- err := s.renderThing(p, tmplName, NopCloser(content))
- if err != nil {
- t.Fatalf("Unable to render template.")
- }
+ content := new(bytes.Buffer)
+ err := s.renderThing(p, tmplName, NopCloser(content))
+ if err != nil {
+ t.Fatalf("Unable to render template.")
+ }
- if string(content.Bytes()) != expected {
- t.Fatalf("Content did not match expected: %s. got: %s", expected, content)
- }
+ if string(content.Bytes()) != expected {
+ t.Fatalf("Content did not match expected: %s. got: %s", expected, content)
+ }
}
func TestRenderThing(t *testing.T) {
- tests := []struct {
- content string
- template string
- expected string
- }{
- {PAGE_SIMPLE_TITLE, TEMPLATE_TITLE, "simple template"},
- {PAGE_SIMPLE_TITLE, TEMPLATE_FUNC, "simple-template"},
- {PAGE_WITH_MD, TEMPLATE_CONTENT, "\n\n<h1 id=\"toc_0\">heading 1</h1>\n\n<p>text</p>\n\n<h2 id=\"toc_1\">heading 2</h2>\n\n<p>more text</p>\n"},
- {SIMPLE_PAGE_RFC3339_DATE, TEMPLATE_DATE, "2013-05-17 16:59:30 +0000 UTC"},
- }
+ tests := []struct {
+ content string
+ template string
+ expected string
+ }{
+ {PAGE_SIMPLE_TITLE, TEMPLATE_TITLE, "simple template"},
+ {PAGE_SIMPLE_TITLE, TEMPLATE_FUNC, "simple-template"},
+ {PAGE_WITH_MD, TEMPLATE_CONTENT, "\n\n<h1 id=\"toc_0\">heading 1</h1>\n\n<p>text</p>\n\n<h2 id=\"toc_1\">heading 2</h2>\n\n<p>more text</p>\n"},
+ {SIMPLE_PAGE_RFC3339_DATE, TEMPLATE_DATE, "2013-05-17 16:59:30 +0000 UTC"},
+ }
- s := new(Site)
- s.prepTemplates()
+ s := new(Site)
+ s.prepTemplates()
- for i, test := range tests {
- p, err := ReadFrom(strings.NewReader(test.content), "content/a/file.md")
- p.Convert()
- if err != nil {
- t.Fatalf("Error parsing buffer: %s", err)
- }
- templateName := fmt.Sprintf("foobar%d", i)
- err = s.addTemplate(templateName, test.template)
- if err != nil {
- t.Fatalf("Unable to add template")
- }
+ for i, test := range tests {
+ p, err := ReadFrom(strings.NewReader(test.content), "content/a/file.md")
+ p.Convert()
+ if err != nil {
+ t.Fatalf("Error parsing buffer: %s", err)
+ }
+ templateName := fmt.Sprintf("foobar%d", i)
+ err = s.addTemplate(templateName, test.template)
+ if err != nil {
+ t.Fatalf("Unable to add template")
+ }
- p.Content = template.HTML(p.Content)
- html := new(bytes.Buffer)
- err = s.renderThing(p, templateName, NopCloser(html))
- if err != nil {
- t.Errorf("Unable to render html: %s", err)
- }
+ p.Content = template.HTML(p.Content)
+ html := new(bytes.Buffer)
+ err = s.renderThing(p, templateName, NopCloser(html))
+ if err != nil {
+ t.Errorf("Unable to render html: %s", err)
+ }
- if string(html.Bytes()) != test.expected {
- t.Errorf("Content does not match.\nExpected\n\t'%q'\ngot\n\t'%q'", test.expected, html)
- }
- }
+ if string(html.Bytes()) != test.expected {
+ t.Errorf("Content does not match.\nExpected\n\t'%q'\ngot\n\t'%q'", test.expected, html)
+ }
+ }
}
func HTML(in string) string {
- return in
+ return in
}
func TestRenderThingOrDefault(t *testing.T) {
- tests := []struct {
- content string
- missing bool
- template string
- expected string
- }{
- {PAGE_SIMPLE_TITLE, true, TEMPLATE_TITLE, HTML("simple template")},
- {PAGE_SIMPLE_TITLE, true, TEMPLATE_FUNC, HTML("simple-template")},
- {PAGE_SIMPLE_TITLE, false, TEMPLATE_TITLE, HTML("simple template")},
- {PAGE_SIMPLE_TITLE, false, TEMPLATE_FUNC, HTML("simple-template")},
- }
+ tests := []struct {
+ content string
+ missing bool
+ template string
+ expected string
+ }{
+ {PAGE_SIMPLE_TITLE, true, TEMPLATE_TITLE, HTML("simple template")},
+ {PAGE_SIMPLE_TITLE, true, TEMPLATE_FUNC, HTML("simple-template")},
+ {PAGE_SIMPLE_TITLE, false, TEMPLATE_TITLE, HTML("simple template")},
+ {PAGE_SIMPLE_TITLE, false, TEMPLATE_FUNC, HTML("simple-template")},
+ }
- files := make(map[string][]byte)
- target := &target.InMemoryTarget{Files: files}
- s := &Site{
- Target: target,
- }
- s.prepTemplates()
+ files := make(map[string][]byte)
+ target := &target.InMemoryTarget{Files: files}
+ s := &Site{
+ Target: target,
+ }
+ s.prepTemplates()
- for i, test := range tests {
- p, err := ReadFrom(strings.NewReader(PAGE_SIMPLE_TITLE), "content/a/file.md")
- if err != nil {
- t.Fatalf("Error parsing buffer: %s", err)
- }
- templateName := fmt.Sprintf("default%d", i)
- err = s.addTemplate(templateName, test.template)
- if err != nil {
- t.Fatalf("Unable to add template")
- }
+ for i, test := range tests {
+ p, err := ReadFrom(strings.NewReader(PAGE_SIMPLE_TITLE), "content/a/file.md")
+ if err != nil {
+ t.Fatalf("Error parsing buffer: %s", err)
+ }
+ templateName := fmt.Sprintf("default%d", i)
+ err = s.addTemplate(templateName, test.template)
+ if err != nil {
+ t.Fatalf("Unable to add template")
+ }
- var err2 error
- if test.missing {
- err2 = s.render(p, "out", "missing", templateName)
- } else {
- err2 = s.render(p, "out", templateName, "missing_default")
- }
+ var err2 error
+ if test.missing {
+ err2 = s.render(p, "out", "missing", templateName)
+ } else {
+ err2 = s.render(p, "out", templateName, "missing_default")
+ }
- if err2 != nil {
- t.Errorf("Unable to render html: %s", err)
- }
+ if err2 != nil {
+ t.Errorf("Unable to render html: %s", err)
+ }
- if string(files["out"]) != test.expected {
- t.Errorf("Content does not match. Expected '%s', got '%s'", test.expected, files["out"])
- }
- }
+ if string(files["out"]) != test.expected {
+ t.Errorf("Content does not match. Expected '%s', got '%s'", test.expected, files["out"])
+ }
+ }
}
func TestTargetPath(t *testing.T) {
- tests := []struct {
- doc string
- content string
- expectedOutFile string
- expectedSection string
- }{
- {"content/a/file.md", PAGE_URL_SPECIFIED, "mycategory/my-whatever-content/index.html", "a"},
- {"content/x/y/deepfile.md", SIMPLE_PAGE, "x/y/deepfile.html", "x/y"},
- {"content/x/y/z/deeperfile.md", SIMPLE_PAGE, "x/y/z/deeperfile.html", "x/y/z"},
- {"content/b/file.md", SIMPLE_PAGE, "b/file.html", "b"},
- {"a/file.md", SIMPLE_PAGE, "a/file.html", "a"},
- {"file.md", SIMPLE_PAGE, "file.html", ""},
- }
+ tests := []struct {
+ doc string
+ content string
+ expectedOutFile string
+ expectedSection string
+ }{
+ {"content/a/file.md", PAGE_URL_SPECIFIED, "mycategory/my-whatever-content/index.html", "a"},
+ {"content/x/y/deepfile.md", SIMPLE_PAGE, "x/y/deepfile.html", "x/y"},
+ {"content/x/y/z/deeperfile.md", SIMPLE_PAGE, "x/y/z/deeperfile.html", "x/y/z"},
+ {"content/b/file.md", SIMPLE_PAGE, "b/file.html", "b"},
+ {"a/file.md", SIMPLE_PAGE, "a/file.html", "a"},
+ {"file.md", SIMPLE_PAGE, "file.html", ""},
+ }
- if true {
- return
- }
- for _, test := range tests {
- s := &Site{
- Config: Config{ContentDir: "content"},
- }
- p := pageMust(ReadFrom(strings.NewReader(test.content), s.Config.GetAbsPath(test.doc)))
+ if true {
+ return
+ }
+ for _, test := range tests {
+ s := &Site{
+ Config: Config{ContentDir: "content"},
+ }
+ p := pageMust(ReadFrom(strings.NewReader(test.content), s.Config.GetAbsPath(test.doc)))
- expected := test.expectedOutFile
+ expected := test.expectedOutFile
- if p.TargetPath() != expected {
- t.Errorf("%s => OutFile expected: '%s', got: '%s'", test.doc, expected, p.TargetPath())
- }
+ if p.TargetPath() != expected {
+ t.Errorf("%s => OutFile expected: '%s', got: '%s'", test.doc, expected, p.TargetPath())
+ }
- if p.Section != test.expectedSection {
- t.Errorf("%s => p.Section expected: %s, got: %s", test.doc, test.expectedSection, p.Section)
- }
- }
+ if p.Section != test.expectedSection {
+ t.Errorf("%s => p.Section expected: %s, got: %s", test.doc, test.expectedSection, p.Section)
+ }
+ }
}
func TestSkipRender(t *testing.T) {
- files := make(map[string][]byte)
- target := &target.InMemoryTarget{Files: files}
- sources := []source.ByteSource{
- {"sect/doc1.html", []byte("---\nmarkup: markdown\n---\n# title\nsome *content*"), "sect"},
- {"sect/doc2.html", []byte("<!doctype html><html><body>more content</body></html>"), "sect"},
- {"sect/doc3.md", []byte("# doc3\n*some* content"), "sect"},
- {"sect/doc4.md", []byte("---\ntitle: doc4\n---\n# doc4\n*some content*"), "sect"},
- {"sect/doc5.html", []byte("<!doctype html><html>{{ template \"head\" }}<body>body5</body></html>"), "sect"},
- {"sect/doc6.html", []byte("<!doctype html><html>{{ template \"head_abs\" }}<body>body5</body></html>"), "sect"},
- {"doc7.html", []byte("<html><body>doc7 content</body></html>"), ""},
- {"sect/doc8.html", []byte("---\nmarkup: md\n---\n# title\nsome *content*"), "sect"},
- }
+ files := make(map[string][]byte)
+ target := &target.InMemoryTarget{Files: files}
+ sources := []source.ByteSource{
+ {"sect/doc1.html", []byte("---\nmarkup: markdown\n---\n# title\nsome *content*"), "sect"},
+ {"sect/doc2.html", []byte("<!doctype html><html><body>more content</body></html>"), "sect"},
+ {"sect/doc3.md", []byte("# doc3\n*some* content"), "sect"},
+ {"sect/doc4.md", []byte("---\ntitle: doc4\n---\n# doc4\n*some content*"), "sect"},
+ {"sect/doc5.html", []byte("<!doctype html><html>{{ template \"head\" }}<body>body5</body></html>"), "sect"},
+ {"sect/doc6.html", []byte("<!doctype html><html>{{ template \"head_abs\" }}<body>body5</body></html>"), "sect"},
+ {"doc7.html", []byte("<html><body>doc7 content</body></html>"), ""},
+ {"sect/doc8.html", []byte("---\nmarkup: md\n---\n# title\nsome *content*"), "sect"},
+ }
- s := &Site{
- Target: target,
- Config: Config{
- Verbose: true,
- BaseUrl: "http://auth/bub",
- CanonifyUrls: true,
- },
- Source: &source.InMemorySource{sources},
- }
+ s := &Site{
+ Target: target,
+ Config: Config{
+ Verbose: true,
+ BaseUrl: "http://auth/bub",
+ CanonifyUrls: true,
+ },
+ Source: &source.InMemorySource{sources},
+ }
- s.initializeSiteInfo()
- s.prepTemplates()
+ s.initializeSiteInfo()
+ s.prepTemplates()
- must(s.addTemplate("_default/single.html", "{{.Content}}"))
- must(s.addTemplate("head", "<head><script src=\"script.js\"></script></head>"))
- must(s.addTemplate("head_abs", "<head><script src=\"/script.js\"></script></head>"))
+ must(s.addTemplate("_default/single.html", "{{.Content}}"))
+ must(s.addTemplate("head", "<head><script src=\"script.js\"></script></head>"))
+ must(s.addTemplate("head_abs", "<head><script src=\"/script.js\"></script></head>"))
- if err := s.CreatePages(); err != nil {
- t.Fatalf("Unable to create pages: %s", err)
- }
+ if err := s.CreatePages(); err != nil {
+ t.Fatalf("Unable to create pages: %s", err)
+ }
- if err := s.BuildSiteMeta(); err != nil {
- t.Fatalf("Unable to build site metadata: %s", err)
- }
+ if err := s.BuildSiteMeta(); err != nil {
+ t.Fatalf("Unable to build site metadata: %s", err)
+ }
- if err := s.RenderPages(); err != nil {
- t.Fatalf("Unable to render pages. %s", err)
- }
+ if err := s.RenderPages(); err != nil {
+ t.Fatalf("Unable to render pages. %s", err)
+ }
- tests := []struct {
- doc string
- expected string
- }{
- {"sect/doc1.html", "\n\n<h1 id=\"toc_0\">title</h1>\n\n<p>some <em>content</em></p>\n"},
- {"sect/doc2.html", "<!doctype html><html><body>more content</body></html>"},
- {"sect/doc3.html", "\n\n<h1 id=\"toc_0\">doc3</h1>\n\n<p><em>some</em> content</p>\n"},
- {"sect/doc4.html", "\n\n<h1 id=\"toc_0\">doc4</h1>\n\n<p><em>some content</em></p>\n"},
- {"sect/doc5.html", "<!doctype html><html><head><script src=\"script.js\"></script></head><body>body5</body></html>"},
- {"sect/doc6.html", "<!doctype html><html><head><script src=\"http://auth/bub/script.js\"></script></head><body>body5</body></html>"},
- {"doc7.html", "<html><body>doc7 content</body></html>"},
- {"sect/doc8.html", "\n\n<h1 id=\"toc_0\">title</h1>\n\n<p>some <em>content</em></p>\n"},
- }
+ tests := []struct {
+ doc string
+ expected string
+ }{
+ {"sect/doc1.html", "\n\n<h1 id=\"toc_0\">title</h1>\n\n<p>some <em>content</em></p>\n"},
+ {"sect/doc2.html", "<!doctype html><html><body>more content</body></html>"},
+ {"sect/doc3.html", "\n\n<h1 id=\"toc_0\">doc3</h1>\n\n<p><em>some</em> content</p>\n"},
+ {"sect/doc4.html", "\n\n<h1 id=\"toc_0\">doc4</h1>\n\n<p><em>some content</em></p>\n"},
+ {"sect/doc5.html", "<!doctype html><html><head><script src=\"script.js\"></script></head><body>body5</body></html>"},
+ {"sect/doc6.html", "<!doctype html><html><head><script src=\"http://auth/bub/script.js\"></script></head><body>body5</body></html>"},
+ {"doc7.html", "<html><body>doc7 content</body></html>"},
+ {"sect/doc8.html", "\n\n<h1 id=\"toc_0\">title</h1>\n\n<p>some <em>content</em></p>\n"},
+ }
- for _, test := range tests {
- content, ok := target.Files[test.doc]
- if !ok {
- t.Fatalf("Did not find %s in target. %v", test.doc, target.Files)
- }
+ for _, test := range tests {
+ content, ok := target.Files[test.doc]
+ if !ok {
+ t.Fatalf("Did not find %s in target. %v", test.doc, target.Files)
+ }
- if !bytes.Equal(content, []byte(test.expected)) {
- t.Errorf("%s content expected:\n%q\ngot:\n%q", test.doc, test.expected, string(content))
- }
- }
+ if !bytes.Equal(content, []byte(test.expected)) {
+ t.Errorf("%s content expected:\n%q\ngot:\n%q", test.doc, test.expected, string(content))
+ }
+ }
}
func TestAbsUrlify(t *testing.T) {
- files := make(map[string][]byte)
- target := &target.InMemoryTarget{Files: files}
- sources := []source.ByteSource{
- {"sect/doc1.html", []byte("<!doctype html><html><head></head><body><a href=\"#frag1\">link</a></body></html>"), "sect"},
- {"content/blue/doc2.html", []byte("---\nf: t\n---\n<!doctype html><html><body>more content</body></html>"), "blue"},
- }
- for _, canonify := range []bool{true, false} {
- s := &Site{
- Target: target,
- Config: Config{
- BaseUrl: "http://auth/bub",
- CanonifyUrls: canonify,
- },
- Source: &source.InMemorySource{sources},
- }
- t.Logf("Rendering with BaseUrl %q and CanonifyUrls set %v", s.Config.BaseUrl, canonify)
- s.initializeSiteInfo()
- s.prepTemplates()
- must(s.addTemplate("blue/single.html", TEMPLATE_WITH_URL_ABS))
+ files := make(map[string][]byte)
+ target := &target.InMemoryTarget{Files: files}
+ sources := []source.ByteSource{
+ {"sect/doc1.html", []byte("<!doctype html><html><head></head><body><a href=\"#frag1\">link</a></body></html>"), "sect"},
+ {"content/blue/doc2.html", []byte("---\nf: t\n---\n<!doctype html><html><body>more content</body></html>"), "blue"},
+ }
+ for _, canonify := range []bool{true, false} {
+ s := &Site{
+ Target: target,
+ Config: Config{
+ BaseUrl: "http://auth/bub",
+ CanonifyUrls: canonify,
+ },
+ Source: &source.InMemorySource{sources},
+ }
+ t.Logf("Rendering with BaseUrl %q and CanonifyUrls set %v", s.Config.BaseUrl, canonify)
+ s.initializeSiteInfo()
+ s.prepTemplates()
+ must(s.addTemplate("blue/single.html", TEMPLATE_WITH_URL_ABS))
- if err := s.CreatePages(); err != nil {
- t.Fatalf("Unable to create pages: %s", err)
- }
+ if err := s.CreatePages(); err != nil {
+ t.Fatalf("Unable to create pages: %s", err)
+ }
- if err := s.BuildSiteMeta(); err != nil {
- t.Fatalf("Unable to build site metadata: %s", err)
- }
+ if err := s.BuildSiteMeta(); err != nil {
+ t.Fatalf("Unable to build site metadata: %s", err)
+ }
- if err := s.RenderPages(); err != nil {
- t.Fatalf("Unable to render pages. %s", err)
- }
+ if err := s.RenderPages(); err != nil {
+ t.Fatalf("Unable to render pages. %s", err)
+ }
- tests := []struct {
- file, expected string
- }{
- {"content/blue/doc2.html", "<a href=\"http://auth/bub/foobar.jpg\">Going</a>"},
- {"sect/doc1.html", "<!doctype html><html><head></head><body><a href=\"#frag1\">link</a></body></html>"},
- }
+ tests := []struct {
+ file, expected string
+ }{
+ {"content/blue/doc2.html", "<a href=\"http://auth/bub/foobar.jpg\">Going</a>"},
+ {"sect/doc1.html", "<!doctype html><html><head></head><body><a href=\"#frag1\">link</a></body></html>"},
+ }
- for _, test := range tests {
- content, ok := target.Files[test.file]
- if !ok {
- t.Fatalf("Unable to locate rendered content: %s", test.file)
- }
+ for _, test := range tests {
+ content, ok := target.Files[test.file]
+ if !ok {
+ t.Fatalf("Unable to locate rendered content: %s", test.file)
+ }
- expected := test.expected
- if !canonify {
- expected = strings.Replace(expected, s.Config.BaseUrl, "", -1)
- }
- if string(content) != expected {
- t.Errorf("AbsUrlify content expected:\n%q\ngot\n%q", expected, string(content))
- }
- }
- }
+ expected := test.expected
+ if !canonify {
+ expected = strings.Replace(expected, s.Config.BaseUrl, "", -1)
+ }
+ if string(content) != expected {
+ t.Errorf("AbsUrlify content expected:\n%q\ngot\n%q", expected, string(content))
+ }
+ }
+ }
}
var WEIGHTED_PAGE_1 = []byte(`+++
@@ -371,58 +371,58 @@
Front Matter with Ordered Pages 4. This is longer content`)
var WEIGHTED_SOURCES = []source.ByteSource{
- {"sect/doc1.md", WEIGHTED_PAGE_1, "sect"},
- {"sect/doc2.md", WEIGHTED_PAGE_2, "sect"},
- {"sect/doc3.md", WEIGHTED_PAGE_3, "sect"},
- {"sect/doc4.md", WEIGHTED_PAGE_4, "sect"},
+ {"sect/doc1.md", WEIGHTED_PAGE_1, "sect"},
+ {"sect/doc2.md", WEIGHTED_PAGE_2, "sect"},
+ {"sect/doc3.md", WEIGHTED_PAGE_3, "sect"},
+ {"sect/doc4.md", WEIGHTED_PAGE_4, "sect"},
}
func TestOrderedPages(t *testing.T) {
- files := make(map[string][]byte)
- target := &target.InMemoryTarget{Files: files}
- s := &Site{
- Target: target,
- Config: Config{BaseUrl: "http://auth/bub/"},
- Source: &source.InMemorySource{WEIGHTED_SOURCES},
- }
- s.initializeSiteInfo()
+ files := make(map[string][]byte)
+ target := &target.InMemoryTarget{Files: files}
+ s := &Site{
+ Target: target,
+ Config: Config{BaseUrl: "http://auth/bub/"},
+ Source: &source.InMemorySource{WEIGHTED_SOURCES},
+ }
+ s.initializeSiteInfo()
- if err := s.CreatePages(); err != nil {
- t.Fatalf("Unable to create pages: %s", err)
- }
+ if err := s.CreatePages(); err != nil {
+ t.Fatalf("Unable to create pages: %s", err)
+ }
- if err := s.BuildSiteMeta(); err != nil {
- t.Fatalf("Unable to build site metadata: %s", err)
- }
+ if err := s.BuildSiteMeta(); err != nil {
+ t.Fatalf("Unable to build site metadata: %s", err)
+ }
- if s.Sections["sect"][0].Weight != 2 || s.Sections["sect"][3].Weight != 6 {
- t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", 2, s.Sections["sect"][0].Weight)
- }
+ if s.Sections["sect"][0].Weight != 2 || s.Sections["sect"][3].Weight != 6 {
+ t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", 2, s.Sections["sect"][0].Weight)
+ }
- if s.Sections["sect"][1].Page.Title != "Three" || s.Sections["sect"][2].Page.Title != "Four" {
- t.Errorf("Pages in unexpected order. Second should be '%s', got '%s'", "Three", s.Sections["sect"][1].Page.Title)
- }
+ if s.Sections["sect"][1].Page.Title != "Three" || s.Sections["sect"][2].Page.Title != "Four" {
+ t.Errorf("Pages in unexpected order. Second should be '%s', got '%s'", "Three", s.Sections["sect"][1].Page.Title)
+ }
- bydate := s.Pages.ByDate()
+ bydate := s.Pages.ByDate()
- if bydate[0].Title != "One" {
- t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "One", bydate[0].Title)
- }
+ if bydate[0].Title != "One" {
+ t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "One", bydate[0].Title)
+ }
- rev := bydate.Reverse()
- if rev[0].Title != "Three" {
- t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "Three", rev[0].Title)
- }
+ rev := bydate.Reverse()
+ if rev[0].Title != "Three" {
+ t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "Three", rev[0].Title)
+ }
- bylength := s.Pages.ByLength()
- if bylength[0].Title != "One" {
- t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "One", bylength[0].Title)
- }
+ bylength := s.Pages.ByLength()
+ if bylength[0].Title != "One" {
+ t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "One", bylength[0].Title)
+ }
- rbylength := bylength.Reverse()
- if rbylength[0].Title != "Four" {
- t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "Four", rbylength[0].Title)
- }
+ rbylength := bylength.Reverse()
+ if rbylength[0].Title != "Four" {
+ t.Errorf("Pages in unexpected order. First should be '%s', got '%s'", "Four", rbylength[0].Title)
+ }
}
var PAGE_WITH_WEIGHTED_INDEXES_2 = []byte(`+++
@@ -455,41 +455,41 @@
Front Matter with weighted tags and categories`)
func TestWeightedIndexes(t *testing.T) {
- files := make(map[string][]byte)
- target := &target.InMemoryTarget{Files: files}
- sources := []source.ByteSource{
- {"sect/doc1.md", PAGE_WITH_WEIGHTED_INDEXES_1, "sect"},
- {"sect/doc2.md", PAGE_WITH_WEIGHTED_INDEXES_2, "sect"},
- {"sect/doc3.md", PAGE_WITH_WEIGHTED_INDEXES_3, "sect"},
- }
- indexes := make(map[string]string)
+ files := make(map[string][]byte)
+ target := &target.InMemoryTarget{Files: files}
+ sources := []source.ByteSource{
+ {"sect/doc1.md", PAGE_WITH_WEIGHTED_INDEXES_1, "sect"},
+ {"sect/doc2.md", PAGE_WITH_WEIGHTED_INDEXES_2, "sect"},
+ {"sect/doc3.md", PAGE_WITH_WEIGHTED_INDEXES_3, "sect"},
+ }
+ indexes := make(map[string]string)
- indexes["tag"] = "tags"
- indexes["category"] = "categories"
- s := &Site{
- Target: target,
- Config: Config{BaseUrl: "http://auth/bub/", Indexes: indexes},
- Source: &source.InMemorySource{sources},
- }
- s.initializeSiteInfo()
+ indexes["tag"] = "tags"
+ indexes["category"] = "categories"
+ s := &Site{
+ Target: target,
+ Config: Config{BaseUrl: "http://auth/bub/", Indexes: indexes},
+ Source: &source.InMemorySource{sources},
+ }
+ s.initializeSiteInfo()
- if err := s.CreatePages(); err != nil {
- t.Fatalf("Unable to create pages: %s", err)
- }
+ if err := s.CreatePages(); err != nil {
+ t.Fatalf("Unable to create pages: %s", err)
+ }
- if err := s.BuildSiteMeta(); err != nil {
- t.Fatalf("Unable to build site metadata: %s", err)
- }
+ if err := s.BuildSiteMeta(); err != nil {
+ t.Fatalf("Unable to build site metadata: %s", err)
+ }
- if s.Indexes["tags"]["a"][0].Page.Title != "foo" {
- t.Errorf("Pages in unexpected order, 'foo' expected first, got '%v'", s.Indexes["tags"]["a"][0].Page.Title)
- }
+ if s.Indexes["tags"]["a"][0].Page.Title != "foo" {
+ t.Errorf("Pages in unexpected order, 'foo' expected first, got '%v'", s.Indexes["tags"]["a"][0].Page.Title)
+ }
- if s.Indexes["categories"]["d"][0].Page.Title != "bar" {
- t.Errorf("Pages in unexpected order, 'bar' expected first, got '%v'", s.Indexes["categories"]["d"][0].Page.Title)
- }
+ if s.Indexes["categories"]["d"][0].Page.Title != "bar" {
+ t.Errorf("Pages in unexpected order, 'bar' expected first, got '%v'", s.Indexes["categories"]["d"][0].Page.Title)
+ }
- if s.Indexes["categories"]["e"][0].Page.Title != "bza" {
- t.Errorf("Pages in unexpected order, 'bza' expected first, got '%v'", s.Indexes["categories"]["e"][0].Page.Title)
- }
+ if s.Indexes["categories"]["e"][0].Page.Title != "bza" {
+ t.Errorf("Pages in unexpected order, 'bza' expected first, got '%v'", s.Indexes["categories"]["e"][0].Page.Title)
+ }
}
--- a/template/bundle/embedded.go
+++ b/template/bundle/embedded.go
@@ -14,16 +14,16 @@
package bundle
type Tmpl struct {
- Name string
- Data string
+ Name string
+ Data string
}
func (t *GoHtmlTemplate) EmbedShortcodes() {
- const k = "shortcodes"
+ const k = "shortcodes"
- t.AddInternalTemplate(k, "highlight.html", `{{ $lang := index .Params 0 }}{{ highlight .Inner $lang }}`)
- t.AddInternalTemplate(k, "test.html", `This is a simple Test`)
- t.AddInternalTemplate(k, "figure.html", `<!-- image -->
+ t.AddInternalTemplate(k, "highlight.html", `{{ $lang := index .Params 0 }}{{ highlight .Inner $lang }}`)
+ t.AddInternalTemplate(k, "test.html", `This is a simple Test`)
+ t.AddInternalTemplate(k, "figure.html", `<!-- image -->
<figure {{ if isset .Params "class" }}class="{{ index .Params "class" }}"{{ end }}>
{{ if isset .Params "link"}}<a href="{{ index .Params "link"}}">{{ end }}
<img src="{{ index .Params "src" }}" {{ if or (isset .Params "alt") (isset .Params "caption") }}alt="{{ if isset .Params "alt"}}{{ index .Params "alt"}}{{else}}{{ index .Params "caption" }}{{ end }}"{{ end }} />
--- a/template/bundle/template.go
+++ b/template/bundle/template.go
@@ -1,254 +1,254 @@
package bundle
import (
- "errors"
- "github.com/eknkc/amber"
- "github.com/spf13/hugo/helpers"
- "html"
- "html/template"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "reflect"
- "strconv"
- "strings"
+ "errors"
+ "github.com/eknkc/amber"
+ "github.com/spf13/hugo/helpers"
+ "html"
+ "html/template"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "reflect"
+ "strconv"
+ "strings"
)
func Gt(a interface{}, b interface{}) bool {
- var left, right int64
- av := reflect.ValueOf(a)
+ var left, right int64
+ av := reflect.ValueOf(a)
- switch av.Kind() {
- case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
- left = int64(av.Len())
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- left = av.Int()
- case reflect.String:
- left, _ = strconv.ParseInt(av.String(), 10, 64)
- }
+ switch av.Kind() {
+ case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+ left = int64(av.Len())
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ left = av.Int()
+ case reflect.String:
+ left, _ = strconv.ParseInt(av.String(), 10, 64)
+ }
- bv := reflect.ValueOf(b)
+ bv := reflect.ValueOf(b)
- switch bv.Kind() {
- case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
- right = int64(bv.Len())
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- right = bv.Int()
- case reflect.String:
- right, _ = strconv.ParseInt(bv.String(), 10, 64)
- }
+ switch bv.Kind() {
+ case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+ right = int64(bv.Len())
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ right = bv.Int()
+ case reflect.String:
+ right, _ = strconv.ParseInt(bv.String(), 10, 64)
+ }
- return left > right
+ return left > right
}
// First is exposed to templates, to iterate over the first N items in a
// rangeable list.
func First(limit int, seq interface{}) (interface{}, error) {
- if limit < 1 {
- return nil, errors.New("can't return negative/empty count of items from sequence")
- }
+ if limit < 1 {
+ return nil, errors.New("can't return negative/empty count of items from sequence")
+ }
- seqv := reflect.ValueOf(seq)
- // this is better than my first pass; ripped from text/template/exec.go indirect():
- for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() {
- if seqv.IsNil() {
- return nil, errors.New("can't iterate over a nil value")
- }
- if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 {
- break
- }
- }
+ seqv := reflect.ValueOf(seq)
+ // this is better than my first pass; ripped from text/template/exec.go indirect():
+ for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() {
+ if seqv.IsNil() {
+ return nil, errors.New("can't iterate over a nil value")
+ }
+ if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 {
+ break
+ }
+ }
- switch seqv.Kind() {
- case reflect.Array, reflect.Slice, reflect.String:
- // okay
- default:
- return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
- }
- if limit > seqv.Len() {
- limit = seqv.Len()
- }
- return seqv.Slice(0, limit).Interface(), nil
+ switch seqv.Kind() {
+ case reflect.Array, reflect.Slice, reflect.String:
+ // okay
+ default:
+ return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
+ }
+ if limit > seqv.Len() {
+ limit = seqv.Len()
+ }
+ return seqv.Slice(0, limit).Interface(), nil
}
func IsSet(a interface{}, key interface{}) bool {
- av := reflect.ValueOf(a)
- kv := reflect.ValueOf(key)
+ av := reflect.ValueOf(a)
+ kv := reflect.ValueOf(key)
- switch av.Kind() {
- case reflect.Array, reflect.Chan, reflect.Slice:
- if int64(av.Len()) > kv.Int() {
- return true
- }
- case reflect.Map:
- if kv.Type() == av.Type().Key() {
- return av.MapIndex(kv).IsValid()
- }
- }
+ switch av.Kind() {
+ case reflect.Array, reflect.Chan, reflect.Slice:
+ if int64(av.Len()) > kv.Int() {
+ return true
+ }
+ case reflect.Map:
+ if kv.Type() == av.Type().Key() {
+ return av.MapIndex(kv).IsValid()
+ }
+ }
- return false
+ return false
}
func ReturnWhenSet(a interface{}, index int) interface{} {
- av := reflect.ValueOf(a)
+ av := reflect.ValueOf(a)
- switch av.Kind() {
- case reflect.Array, reflect.Slice:
- if av.Len() > index {
+ switch av.Kind() {
+ case reflect.Array, reflect.Slice:
+ if av.Len() > index {
- avv := av.Index(index)
- switch avv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return avv.Int()
- case reflect.String:
- return avv.String()
- }
- }
- }
+ avv := av.Index(index)
+ switch avv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return avv.Int()
+ case reflect.String:
+ return avv.String()
+ }
+ }
+ }
- return ""
+ return ""
}
func Highlight(in interface{}, lang string) template.HTML {
- var str string
- av := reflect.ValueOf(in)
- switch av.Kind() {
- case reflect.String:
- str = av.String()
- }
+ var str string
+ av := reflect.ValueOf(in)
+ switch av.Kind() {
+ case reflect.String:
+ str = av.String()
+ }
- if strings.HasPrefix(strings.TrimSpace(str), "<pre><code>") {
- str = str[strings.Index(str, "<pre><code>")+11:]
- }
- if strings.HasSuffix(strings.TrimSpace(str), "</code></pre>") {
- str = str[:strings.LastIndex(str, "</code></pre>")]
- }
- return template.HTML(helpers.Highlight(html.UnescapeString(str), lang))
+ if strings.HasPrefix(strings.TrimSpace(str), "<pre><code>") {
+ str = str[strings.Index(str, "<pre><code>")+11:]
+ }
+ if strings.HasSuffix(strings.TrimSpace(str), "</code></pre>") {
+ str = str[:strings.LastIndex(str, "</code></pre>")]
+ }
+ return template.HTML(helpers.Highlight(html.UnescapeString(str), lang))
}
func SafeHtml(text string) template.HTML {
- return template.HTML(text)
+ return template.HTML(text)
}
type Template interface {
- ExecuteTemplate(wr io.Writer, name string, data interface{}) error
- Lookup(name string) *template.Template
- Templates() []*template.Template
- New(name string) *template.Template
- LoadTemplates(absPath string)
- AddTemplate(name, tpl string) error
+ ExecuteTemplate(wr io.Writer, name string, data interface{}) error
+ Lookup(name string) *template.Template
+ Templates() []*template.Template
+ New(name string) *template.Template
+ LoadTemplates(absPath string)
+ AddTemplate(name, tpl string) error
}
type templateErr struct {
- name string
- err error
+ name string
+ err error
}
type GoHtmlTemplate struct {
- template.Template
- errors []*templateErr
+ template.Template
+ errors []*templateErr
}
func NewTemplate() Template {
- var templates = &GoHtmlTemplate{
- Template: *template.New(""),
- errors: make([]*templateErr, 0),
- }
+ var templates = &GoHtmlTemplate{
+ Template: *template.New(""),
+ errors: make([]*templateErr, 0),
+ }
- funcMap := template.FuncMap{
- "urlize": helpers.Urlize,
- "gt": Gt,
- "isset": IsSet,
- "echoParam": ReturnWhenSet,
- "safeHtml": SafeHtml,
- "first": First,
- "highlight": Highlight,
- "add": func(a, b int) int { return a + b },
- "sub": func(a, b int) int { return a - b },
- "div": func(a, b int) int { return a / b },
- "mod": func(a, b int) int { return a % b },
- "mul": func(a, b int) int { return a * b },
- "modBool": func(a, b int) bool { return a%b == 0 },
- "lower": func(a string) string { return strings.ToLower(a) },
- "upper": func(a string) string { return strings.ToUpper(a) },
- "title": func(a string) string { return strings.Title(a) },
- }
+ funcMap := template.FuncMap{
+ "urlize": helpers.Urlize,
+ "gt": Gt,
+ "isset": IsSet,
+ "echoParam": ReturnWhenSet,
+ "safeHtml": SafeHtml,
+ "first": First,
+ "highlight": Highlight,
+ "add": func(a, b int) int { return a + b },
+ "sub": func(a, b int) int { return a - b },
+ "div": func(a, b int) int { return a / b },
+ "mod": func(a, b int) int { return a % b },
+ "mul": func(a, b int) int { return a * b },
+ "modBool": func(a, b int) bool { return a%b == 0 },
+ "lower": func(a string) string { return strings.ToLower(a) },
+ "upper": func(a string) string { return strings.ToUpper(a) },
+ "title": func(a string) string { return strings.Title(a) },
+ }
- templates.Funcs(funcMap)
+ templates.Funcs(funcMap)
- templates.LoadEmbedded()
- return templates
+ templates.LoadEmbedded()
+ return templates
}
func (t *GoHtmlTemplate) LoadEmbedded() {
- t.EmbedShortcodes()
+ t.EmbedShortcodes()
}
func (t *GoHtmlTemplate) AddInternalTemplate(prefix, name, tpl string) error {
- return t.AddTemplate("_internal/"+prefix+"/"+name, tpl)
+ return t.AddTemplate("_internal/"+prefix+"/"+name, tpl)
}
func (t *GoHtmlTemplate) AddTemplate(name, tpl string) error {
- _, err := t.New(name).Parse(tpl)
- if err != nil {
- t.errors = append(t.errors, &templateErr{name: name, err: err})
- }
- return err
+ _, err := t.New(name).Parse(tpl)
+ if err != nil {
+ t.errors = append(t.errors, &templateErr{name: name, err: err})
+ }
+ return err
}
func (t *GoHtmlTemplate) AddTemplateFile(name, path string) error {
- b, err := ioutil.ReadFile(path)
- if err != nil {
- return err
- }
- s := string(b)
- _, err = t.New(name).Parse(s)
- if err != nil {
- t.errors = append(t.errors, &templateErr{name: name, err: err})
- }
- return err
+ b, err := ioutil.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ s := string(b)
+ _, err = t.New(name).Parse(s)
+ if err != nil {
+ t.errors = append(t.errors, &templateErr{name: name, err: err})
+ }
+ return err
}
func (t *GoHtmlTemplate) generateTemplateNameFrom(base, path string) string {
- return filepath.ToSlash(path[len(base)+1:])
+ return filepath.ToSlash(path[len(base)+1:])
}
func ignoreDotFile(path string) bool {
- return filepath.Base(path)[0] == '.'
+ return filepath.Base(path)[0] == '.'
}
func (t *GoHtmlTemplate) LoadTemplates(absPath string) {
- walker := func(path string, fi os.FileInfo, err error) error {
- if err != nil {
- return nil
- }
+ walker := func(path string, fi os.FileInfo, err error) error {
+ if err != nil {
+ return nil
+ }
- if !fi.IsDir() {
- if ignoreDotFile(path) {
- return nil
- }
+ if !fi.IsDir() {
+ if ignoreDotFile(path) {
+ return nil
+ }
- tplName := t.generateTemplateNameFrom(absPath, path)
+ tplName := t.generateTemplateNameFrom(absPath, path)
- if strings.HasSuffix(path, ".amber") {
- compiler := amber.New()
- // Parse the input file
- if err := compiler.ParseFile(path); err != nil {
- return nil
- }
+ if strings.HasSuffix(path, ".amber") {
+ compiler := amber.New()
+ // Parse the input file
+ if err := compiler.ParseFile(path); err != nil {
+ return nil
+ }
- // note t.New(tplName)
- if _, err := compiler.CompileWithTemplate(t.New(tplName)); err != nil {
- return err
- }
+ // note t.New(tplName)
+ if _, err := compiler.CompileWithTemplate(t.New(tplName)); err != nil {
+ return err
+ }
- } else {
- t.AddTemplateFile(tplName, path)
- }
- }
- return nil
- }
+ } else {
+ t.AddTemplateFile(tplName, path)
+ }
+ }
+ return nil
+ }
- filepath.Walk(absPath, walker)
+ filepath.Walk(absPath, walker)
}
--- a/watcher/batcher.go
+++ b/watcher/batcher.go
@@ -1,56 +1,56 @@
-package watcher
-
-import (
- "github.com/howeyc/fsnotify"
- "time"
-)
-
-type Batcher struct {
- *fsnotify.Watcher
- interval time.Duration
- done chan struct{}
-
- Event chan []*fsnotify.FileEvent // Events are returned on this channel
-}
-
-func New(interval time.Duration) (*Batcher, error) {
- watcher, err := fsnotify.NewWatcher()
-
- batcher := &Batcher{}
- batcher.Watcher = watcher
- batcher.interval = interval
- batcher.done = make(chan struct{}, 1)
- batcher.Event = make(chan []*fsnotify.FileEvent, 1)
-
- if err == nil {
- go batcher.run()
- }
-
- return batcher, err
-}
-
-func (b *Batcher) run() {
- tick := time.Tick(b.interval)
- evs := make([]*fsnotify.FileEvent, 0)
-OuterLoop:
- for {
- select {
- case ev := <-b.Watcher.Event:
- evs = append(evs, ev)
- case <-tick:
- if len(evs) == 0 {
- continue
- }
- b.Event <- evs
- evs = make([]*fsnotify.FileEvent, 0)
- case <-b.done:
- break OuterLoop
- }
- }
- close(b.done)
-}
-
-func (b *Batcher) Close() {
- b.done <- struct{}{}
- b.Watcher.Close()
-}
+package watcher
+
+import (
+ "github.com/howeyc/fsnotify"
+ "time"
+)
+
+type Batcher struct {
+ *fsnotify.Watcher
+ interval time.Duration
+ done chan struct{}
+
+ Event chan []*fsnotify.FileEvent // Events are returned on this channel
+}
+
+func New(interval time.Duration) (*Batcher, error) {
+ watcher, err := fsnotify.NewWatcher()
+
+ batcher := &Batcher{}
+ batcher.Watcher = watcher
+ batcher.interval = interval
+ batcher.done = make(chan struct{}, 1)
+ batcher.Event = make(chan []*fsnotify.FileEvent, 1)
+
+ if err == nil {
+ go batcher.run()
+ }
+
+ return batcher, err
+}
+
+func (b *Batcher) run() {
+ tick := time.Tick(b.interval)
+ evs := make([]*fsnotify.FileEvent, 0)
+OuterLoop:
+ for {
+ select {
+ case ev := <-b.Watcher.Event:
+ evs = append(evs, ev)
+ case <-tick:
+ if len(evs) == 0 {
+ continue
+ }
+ b.Event <- evs
+ evs = make([]*fsnotify.FileEvent, 0)
+ case <-b.done:
+ break OuterLoop
+ }
+ }
+ close(b.done)
+}
+
+func (b *Batcher) Close() {
+ b.done <- struct{}{}
+ b.Watcher.Close()
+}