mirror of
https://github.com/danog/gojekyll.git
synced 2024-11-26 17:24:42 +01:00
Use template.SetSourceLocation instead of adding fake whitespace
This commit is contained in:
parent
bec42f24d7
commit
ad59c0239d
@ -24,7 +24,7 @@ Gojekyll is a clone of the [Jekyll](https://jekyllrb.com) static site generator,
|
||||
|
||||
First-time install:
|
||||
|
||||
1. [Install go](https://golang.org/doc/install#install). On macOS running Homebrew, `brew install go` is easier than the linked instructions.
|
||||
1. [Install go](https://golang.org/doc/install#install). (On macOS running [Homebrew](https://brew.sh), `brew install go` is easier than the Install instructions on the Go site.)
|
||||
2. `go get osteele/gojekyll/cmd/gojekyll`
|
||||
3. To use the `{% highlight %}` tag, you need Pygments. `pip install Pygments`.
|
||||
|
||||
@ -36,7 +36,7 @@ Update to the latest version:
|
||||
|
||||
```bash
|
||||
gojekyll build # builds the site in the current directory into _site
|
||||
gojekyll serve # serve the app at http://localhost:4000
|
||||
gojekyll serve # serve the app at http://localhost:4000; reload on changes
|
||||
gojekyll help
|
||||
gojekyll help build
|
||||
```
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
// FrontMatter wraps a map to provide interface functions
|
||||
type FrontMatter map[string]interface{}
|
||||
|
||||
// The first four bytes of a file with front matter.
|
||||
const fmMagic = "---\n"
|
||||
|
||||
// FileHasFrontMatter returns a bool indicating whether the
|
||||
|
@ -1,9 +1,11 @@
|
||||
package templates
|
||||
package frontmatter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
|
||||
"github.com/osteele/gojekyll/templates"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
@ -12,13 +14,14 @@ var (
|
||||
emptyFontMatterMatcher = regexp.MustCompile(`(?s)^---\n+---\n`)
|
||||
)
|
||||
|
||||
// ReadFrontMatter reads the front matter from a document.
|
||||
func ReadFrontMatter(sourcePtr *[]byte) (frontMatter VariableMap, err error) {
|
||||
// Read reads the frontmatter from a document. It modifies srcPtr to point to the
|
||||
// content after the frontmatter, and sets firstLine to its 1-indexed line number.
|
||||
func Read(sourcePtr *[]byte, firstLine *int) (frontMatter templates.VariableMap, err error) {
|
||||
var (
|
||||
source = *sourcePtr
|
||||
start = 0
|
||||
)
|
||||
// Replace Windows linefeeds. This allows the following regular expressions to work.
|
||||
// Replace Windows line feeds. This allows the following regular expressions to work.
|
||||
source = bytes.Replace(source, []byte("\r\n"), []byte("\n"), -1)
|
||||
if match := frontMatterMatcher.FindSubmatchIndex(source); match != nil {
|
||||
start = match[1]
|
||||
@ -28,10 +31,9 @@ func ReadFrontMatter(sourcePtr *[]byte) (frontMatter VariableMap, err error) {
|
||||
} else if match := emptyFontMatterMatcher.FindSubmatchIndex(source); match != nil {
|
||||
start = match[1]
|
||||
}
|
||||
// This fixes the line numbers, so that template errors show with the correct line.
|
||||
// TODO find a less hack-ey solution
|
||||
*sourcePtr = append(
|
||||
regexp.MustCompile(`[^\n\r]+`).ReplaceAllLiteral(source[:start], []byte{}),
|
||||
source[start:]...)
|
||||
if firstLine != nil {
|
||||
*firstLine = 1 + bytes.Count(source[:start], []byte("\n"))
|
||||
}
|
||||
*sourcePtr = source[start:]
|
||||
return
|
||||
}
|
@ -7,6 +7,7 @@ import (
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/osteele/gojekyll/frontmatter"
|
||||
"github.com/osteele/gojekyll/templates"
|
||||
"github.com/osteele/liquid/evaluator"
|
||||
)
|
||||
@ -27,8 +28,9 @@ type Page interface {
|
||||
|
||||
type page struct {
|
||||
file
|
||||
raw []byte
|
||||
content *[]byte
|
||||
firstLine int
|
||||
raw []byte
|
||||
content *[]byte
|
||||
}
|
||||
|
||||
// Static is in the File interface.
|
||||
@ -39,15 +41,16 @@ func makePage(filename string, f file) (*page, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frontMatter, err := templates.ReadFrontMatter(&b)
|
||||
lineNo := 1
|
||||
frontMatter, err := frontmatter.Read(&b, &lineNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.frontMatter = templates.MergeVariableMaps(f.frontMatter, frontMatter)
|
||||
p := page{
|
||||
file: f,
|
||||
raw: b,
|
||||
file: f,
|
||||
firstLine: lineNo,
|
||||
raw: b,
|
||||
}
|
||||
if err = p.setPermalink(); err != nil {
|
||||
return nil, err
|
||||
@ -106,7 +109,7 @@ func (p *page) Content(rc RenderingContext) ([]byte, error) {
|
||||
if p.content == nil {
|
||||
rp := rc.RenderingPipeline()
|
||||
buf := new(bytes.Buffer)
|
||||
b, err := rp.Render(buf, p.raw, p.filename, p.TemplateContext(rc))
|
||||
b, err := rp.Render(buf, p.raw, p.filename, p.firstLine, p.TemplateContext(rc))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,14 +17,14 @@ type renderingContextFake struct {
|
||||
|
||||
func (c renderingContextFake) RenderingPipeline() pipelines.PipelineInterface { return c }
|
||||
func (c renderingContextFake) Config() config.Config { return c.cfg }
|
||||
func (c renderingContextFake) PathPrefix() string { return "." }
|
||||
func (c renderingContextFake) PathPrefix() string { return "." }
|
||||
func (c renderingContextFake) OutputExt(string) string { return ".html" }
|
||||
func (c renderingContextFake) Site() interface{} { return nil }
|
||||
func (c renderingContextFake) ApplyLayout(layout string, src []byte, vars map[string]interface{}) ([]byte, error) {
|
||||
require.Equal(c.t, "layout1", layout)
|
||||
return nil, nil
|
||||
}
|
||||
func (c renderingContextFake) Render(w io.Writer, src []byte, filename string, vars map[string]interface{}) ([]byte, error) {
|
||||
func (c renderingContextFake) Render(w io.Writer, src []byte, filename string, lineNo int, vars map[string]interface{}) ([]byte, error) {
|
||||
require.Equal(c.t, "testdata/page_with_layout.md", filename)
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -7,12 +7,12 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/osteele/gojekyll/templates"
|
||||
"github.com/osteele/gojekyll/frontmatter"
|
||||
"github.com/osteele/liquid"
|
||||
)
|
||||
|
||||
// FindLayout returns a template for the named layout.
|
||||
func (p *Pipeline) FindLayout(base string, fm *map[string]interface{}) (t liquid.Template, err error) {
|
||||
func (p *Pipeline) FindLayout(base string, fm *map[string]interface{}) (tpl liquid.Template, err error) {
|
||||
exts := []string{"", ".html"}
|
||||
for _, ext := range strings.SplitN(p.config.MarkdownExt, `,`, -1) {
|
||||
exts = append(exts, "."+ext)
|
||||
@ -37,15 +37,16 @@ func (p *Pipeline) FindLayout(base string, fm *map[string]interface{}) (t liquid
|
||||
if !found {
|
||||
return nil, fmt.Errorf("no template for %s", base)
|
||||
}
|
||||
*fm, err = templates.ReadFrontMatter(&content)
|
||||
lineNo := 1
|
||||
*fm, err = frontmatter.Read(&content, &lineNo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
t, err = p.liquidEngine.ParseTemplate(content)
|
||||
tpl, err = p.liquidEngine.ParseTemplate(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.SetSourcePath(filename)
|
||||
tpl.SetSourceLocation(filename, lineNo)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
type PipelineInterface interface {
|
||||
ApplyLayout(string, []byte, map[string]interface{}) ([]byte, error)
|
||||
OutputExt(pathname string) string
|
||||
Render(io.Writer, []byte, string, map[string]interface{}) ([]byte, error)
|
||||
Render(io.Writer, []byte, string, int, map[string]interface{}) ([]byte, error)
|
||||
}
|
||||
|
||||
// Pipeline applies a rendering transformation to a file.
|
||||
@ -59,11 +59,11 @@ func (p *Pipeline) OutputExt(pathname string) string {
|
||||
}
|
||||
|
||||
// Render returns nil iff it wrote to the writer
|
||||
func (p *Pipeline) Render(w io.Writer, b []byte, filename string, e map[string]interface{}) ([]byte, error) {
|
||||
func (p *Pipeline) Render(w io.Writer, b []byte, filename string, lineNo int, e map[string]interface{}) ([]byte, error) {
|
||||
if p.config.IsSASSPath(filename) {
|
||||
return nil, p.WriteSass(w, b)
|
||||
}
|
||||
b, err := p.renderTemplate(b, e, filename)
|
||||
b, err := p.renderTemplate(b, e, filename, lineNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -73,12 +73,12 @@ func (p *Pipeline) Render(w io.Writer, b []byte, filename string, e map[string]i
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (p *Pipeline) renderTemplate(src []byte, b map[string]interface{}, filename string) ([]byte, error) {
|
||||
func (p *Pipeline) renderTemplate(src []byte, b map[string]interface{}, filename string, lineNo int) ([]byte, error) {
|
||||
tpl, err := p.liquidEngine.ParseTemplate(src)
|
||||
if err != nil {
|
||||
return nil, helpers.PathError(err, "Liquid Error", filename)
|
||||
}
|
||||
tpl.SetSourcePath(filename)
|
||||
tpl.SetSourceLocation(filename, lineNo)
|
||||
out, err := tpl.Render(b)
|
||||
if err != nil {
|
||||
return nil, helpers.PathError(err, "Liquid Error", filename)
|
||||
@ -90,7 +90,7 @@ func (p *Pipeline) renderTemplate(src []byte, b map[string]interface{}, filename
|
||||
func (p *Pipeline) ApplyLayout(name string, data []byte, e map[string]interface{}) ([]byte, error) {
|
||||
for name != "" {
|
||||
var lfm map[string]interface{}
|
||||
t, err := p.FindLayout(name, &lfm)
|
||||
tpl, err := p.FindLayout(name, &lfm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -98,7 +98,7 @@ func (p *Pipeline) ApplyLayout(name string, data []byte, e map[string]interface{
|
||||
"content": string(data),
|
||||
"layout": lfm,
|
||||
})
|
||||
data, err = t.Render(b)
|
||||
data, err = tpl.Render(b)
|
||||
if err != nil {
|
||||
return nil, helpers.PathError(err, "render template", name)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user