1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-27 13:24:41 +01:00
gojekyll/pipelines/pipeline.go

111 lines
3.0 KiB
Go
Raw Normal View History

2017-06-24 20:00:19 +02:00
package pipelines
2017-06-24 19:30:01 +02:00
import (
"io"
"github.com/osteele/gojekyll/config"
2017-07-01 01:40:52 +02:00
"github.com/osteele/gojekyll/filters"
2017-06-24 19:30:01 +02:00
"github.com/osteele/gojekyll/helpers"
2017-07-01 01:40:52 +02:00
"github.com/osteele/gojekyll/tags"
2017-06-24 19:30:01 +02:00
"github.com/osteele/gojekyll/templates"
2017-07-01 01:37:31 +02:00
"github.com/osteele/liquid"
2017-06-24 19:30:01 +02:00
"github.com/russross/blackfriday"
)
2017-06-24 20:00:19 +02:00
// PipelineInterface applies transformations to a document.
type PipelineInterface interface {
2017-07-01 05:56:29 +02:00
ApplyLayout(string, []byte, map[string]interface{}) ([]byte, error)
2017-06-24 20:00:19 +02:00
OutputExt(pathname string) string
2017-07-01 05:56:29 +02:00
Render(io.Writer, []byte, string, map[string]interface{}) ([]byte, error)
2017-06-24 20:00:19 +02:00
}
2017-06-24 19:30:01 +02:00
// Pipeline applies a rendering transformation to a file.
type Pipeline struct {
PipelineOptions
2017-06-24 19:30:01 +02:00
config config.Config
liquidEngine liquid.Engine
sassTempDir string
}
// PipelineOptions configures a pipeline.
type PipelineOptions struct {
2017-07-01 01:37:31 +02:00
RelativeFilenameToURL tags.LinkTagHandler
2017-06-24 19:30:01 +02:00
}
// NewPipeline makes a rendering pipeline.
func NewPipeline(c config.Config, options PipelineOptions) (*Pipeline, error) {
p := Pipeline{PipelineOptions: options, config: c}
2017-06-29 13:27:43 +02:00
p.liquidEngine = p.makeLiquidEngine()
2017-06-24 19:30:01 +02:00
if err := p.CopySassFileIncludes(); err != nil {
return nil, err
}
return &p, nil
}
2017-07-01 05:10:58 +02:00
// SourceDir returns the site source directory. Seeing how far we can bend
// the Law of Demeter.
2017-07-01 03:06:12 +02:00
func (p *Pipeline) SourceDir() string {
return p.config.Source
}
2017-07-01 01:40:52 +02:00
// TemplateEngine returns the Liquid engine.
2017-06-30 18:53:34 +02:00
func (p *Pipeline) TemplateEngine() liquid.Engine {
return p.liquidEngine
}
2017-06-24 19:30:01 +02:00
// OutputExt returns the output extension.
func (p *Pipeline) OutputExt(pathname string) string {
return p.config.OutputExt(pathname)
}
// Render returns nil iff it wrote to the writer
2017-07-01 05:56:29 +02:00
func (p *Pipeline) Render(w io.Writer, b []byte, filename string, e map[string]interface{}) ([]byte, error) {
2017-06-24 19:30:01 +02:00
if p.config.IsSassPath(filename) {
return nil, p.WriteSass(w, b)
}
b, err := p.renderTemplate(b, e, filename)
if err != nil {
return nil, err
}
if p.config.IsMarkdown(filename) {
b = blackfriday.MarkdownCommon(b)
}
return b, nil
}
2017-07-02 05:54:12 +02:00
func (p *Pipeline) renderTemplate(tpl []byte, b map[string]interface{}, filename string) ([]byte, error) {
out, err := p.liquidEngine.ParseAndRender(tpl, liquid.NewContext(b))
2017-06-24 19:30:01 +02:00
if err != nil {
2017-06-29 13:27:43 +02:00
return nil, helpers.PathError(err, "Liquid Error", filename)
2017-06-24 19:30:01 +02:00
}
2017-07-02 05:54:12 +02:00
return out, err
2017-06-24 19:30:01 +02:00
}
// ApplyLayout applies the named layout to the data.
2017-07-01 05:56:29 +02:00
func (p *Pipeline) ApplyLayout(name string, data []byte, e map[string]interface{}) ([]byte, error) {
2017-06-24 19:30:01 +02:00
for name != "" {
2017-07-01 05:56:29 +02:00
var lfm map[string]interface{}
2017-06-24 19:30:01 +02:00
t, err := p.FindLayout(name, &lfm)
if err != nil {
return nil, err
}
2017-07-02 05:54:12 +02:00
b := templates.MergeVariableMaps(e, map[string]interface{}{
"content": string(data),
2017-06-24 19:30:01 +02:00
"layout": lfm,
})
2017-07-02 05:54:12 +02:00
data, err = t.Render(liquid.NewContext(b))
2017-06-24 19:30:01 +02:00
if err != nil {
return nil, helpers.PathError(err, "render template", name)
2017-06-24 19:30:01 +02:00
}
2017-07-01 05:56:29 +02:00
name = templates.VariableMap(lfm).String("layout", "")
2017-06-24 19:30:01 +02:00
}
return data, nil
2017-06-24 19:30:01 +02:00
}
2017-06-29 13:27:43 +02:00
func (p *Pipeline) makeLiquidEngine() liquid.Engine {
engine := liquid.NewEngine()
2017-07-01 01:40:52 +02:00
filters.AddJekyllFilters(engine, p.config)
2017-07-01 03:06:12 +02:00
tags.AddJekyllTags(engine, p.config, p.RelativeFilenameToURL)
2017-06-24 19:30:01 +02:00
return engine
}