From 887820d7bd9da50d135de376a4808f05dd5aaf64 Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Fri, 30 Jun 2017 23:10:58 -0400 Subject: [PATCH] Lint --- README.md | 2 +- collections/collection.go | 2 ++ filters/filters.go | 67 ++++++++++++++++++++------------------- pipelines/pipeline.go | 2 ++ plugins/plugins.go | 9 ++++++ sites/site.go | 2 ++ tags/tags.go | 22 +++++++------ 7 files changed, 62 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 24d91a8..f7f8e4d 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ Gojekyll uses these libraries: | [gopkg.in/alecthomas/kingpin.v2](https://github.com/alecthomas/kingpin) | Alec Thomas | command line and flag parser | | [gopkg.in/yaml.v2](https://github.com/go-yaml) | Canonical | YAML support | -In addition to being totally and obviously inspired by the Jekyll Ruby implementation, Jekyll's solid documentation was indispensible. Many of the filter test cases are taken directly from the Jekyll documentation, and the [Jekyll docs](https://jekyllrb.com/docs/home/) were always open in at least one tab. +In addition to being totally and obviously inspired by the Jekyll, Jekyll's solid documentation was indispensible. Many of the filter test cases are taken directly from the Jekyll documentation, and the [Jekyll docs](https://jekyllrb.com/docs/home/) were always open in at least one tab. The gopher image in the test directory is from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Gophercolor.jpg). It is used under the [Creative Commons Attribution-Share Alike 3.0 Unported license](https://creativecommons.org/licenses/by-sa/3.0/deed.en). diff --git a/collections/collection.go b/collections/collection.go index 7122a84..f7c057d 100644 --- a/collections/collection.go +++ b/collections/collection.go @@ -134,6 +134,8 @@ func (c *Collection) ReadPages(sitePath string, frontMatterDefaults func(string, return filepath.Walk(filepath.Join(sitePath, c.PathPrefix()), walkFn) } +// DateFromFilename returns the date for a filename that uses Jekyll post convention. +// It also returns a bool indicating whether a date was found. func DateFromFilename(s string) (time.Time, bool) { layout := "2006-01-02-" t, err := time.Parse(layout, filepath.Base(s + layout)[:len(layout)]) diff --git a/filters/filters.go b/filters/filters.go index ded2cc7..97c488a 100644 --- a/filters/filters.go +++ b/filters/filters.go @@ -18,11 +18,12 @@ import ( "github.com/russross/blackfriday" ) -func AddJekyllFilters(engine liquid.Engine, config config.Config) { +// AddJekyllFilters adds the Jekyll filters to the Liquid engine. +func AddJekyllFilters(e liquid.Engine, c config.Config) { // array filters - engine.DefineFilter("array_to_sentence_string", arrayToSentenceStringFilter) + e.DefineFilter("array_to_sentence_string", arrayToSentenceStringFilter) // TODO neither Liquid nor Jekyll docs this, but it appears to be present - engine.DefineFilter("filter", func(values []map[string]interface{}, key string) []interface{} { + e.DefineFilter("filter", func(values []map[string]interface{}, key string) []interface{} { out := []interface{}{} for _, value := range values { if _, ok := value[key]; ok { @@ -31,62 +32,62 @@ func AddJekyllFilters(engine liquid.Engine, config config.Config) { } return out }) - engine.DefineFilter("group_by", groupByFilter) - engine.DefineFilter("group_by_exp", unimplementedFilter("group_by_exp")) - engine.DefineFilter("sample", func(array []interface{}) interface{} { + e.DefineFilter("group_by", groupByFilter) + e.DefineFilter("group_by_exp", unimplementedFilter("group_by_exp")) + e.DefineFilter("sample", func(array []interface{}) interface{} { if len(array) == 0 { return nil } return array[rand.Intn(len(array))] }) // sort overrides the Liquid filter with one that takes parameters - engine.DefineFilter("sort", sortFilter) - engine.DefineFilter("where", whereFilter) // TODO test case - engine.DefineFilter("where_exp", whereExpFilter) - engine.DefineFilter("xml_escape", xml.Marshal) + e.DefineFilter("sort", sortFilter) + e.DefineFilter("where", whereFilter) // TODO test case + e.DefineFilter("where_exp", whereExpFilter) + e.DefineFilter("xml_escape", xml.Marshal) - engine.DefineFilter("push", func(array []interface{}, item interface{}) interface{} { + e.DefineFilter("push", func(array []interface{}, item interface{}) interface{} { return append(array, generics.MustConvertItem(item, array)) }) - engine.DefineFilter("pop", unimplementedFilter("pop")) - engine.DefineFilter("shift", unimplementedFilter("shift")) - engine.DefineFilter("unshift", func(array []interface{}, item interface{}) interface{} { + e.DefineFilter("pop", unimplementedFilter("pop")) + e.DefineFilter("shift", unimplementedFilter("shift")) + e.DefineFilter("unshift", func(array []interface{}, item interface{}) interface{} { return append([]interface{}{generics.MustConvertItem(item, array)}, array...) }) // dates - engine.DefineFilter("date_to_rfc822", func(date time.Time) string { + e.DefineFilter("date_to_rfc822", func(date time.Time) string { return date.Format(time.RFC822) // Out: Mon, 07 Nov 2008 13:07:54 -0800 }) - engine.DefineFilter("date_to_string", func(date time.Time) string { + e.DefineFilter("date_to_string", func(date time.Time) string { return date.Format("02 Jan 2006") // Out: 07 Nov 2008 }) - engine.DefineFilter("date_to_long_string", func(date time.Time) string { + e.DefineFilter("date_to_long_string", func(date time.Time) string { return date.Format("02 January 2006") // Out: 07 November 2008 }) - engine.DefineFilter("date_to_xmlschema", func(date time.Time) string { + e.DefineFilter("date_to_xmlschema", func(date time.Time) string { return date.Format("2006-01-02T15:04:05-07:00") // Out: 2008-11-07T13:07:54-08:00 }) // strings - engine.DefineFilter("absolute_url", func(s string) string { - return config.AbsoluteURL + config.BaseURL + s + e.DefineFilter("absolute_url", func(s string) string { + return c.AbsoluteURL + c.BaseURL + s }) - engine.DefineFilter("relative_url", func(s string) string { - return config.BaseURL + s + e.DefineFilter("relative_url", func(s string) string { + return c.BaseURL + s }) - engine.DefineFilter("jsonify", json.Marshal) - engine.DefineFilter("markdownify", blackfriday.MarkdownCommon) - engine.DefineFilter("normalize_whitespace", func(s string) string { + e.DefineFilter("jsonify", json.Marshal) + e.DefineFilter("markdownify", blackfriday.MarkdownCommon) + e.DefineFilter("normalize_whitespace", func(s string) string { // s = strings.Replace(s, "n", "N", -1) wsPattern := regexp.MustCompile(`(?s:[\s\n]+)`) return wsPattern.ReplaceAllString(s, " ") }) - engine.DefineFilter("slugify", func(s, mode string) string { + e.DefineFilter("slugify", func(s, mode string) string { if mode == "" { mode = "default" } @@ -100,8 +101,8 @@ func AddJekyllFilters(engine liquid.Engine, config config.Config) { } return strings.ToLower(s) }) - engine.DefineFilter("to_integer", func(n int) int { return n }) - engine.DefineFilter("number_of_words", func(s string) int { + e.DefineFilter("to_integer", func(n int) int { return n }) + e.DefineFilter("number_of_words", func(s string) int { wordPattern := regexp.MustCompile(`\w+`) // TODO what's the Jekyll spec for a word? m := wordPattern.FindAllStringIndex(s, -1) if m == nil { @@ -119,11 +120,11 @@ func AddJekyllFilters(engine liquid.Engine, config config.Config) { // } // return strings.Join(parts, "?") // }) - engine.DefineFilter("cgi_escape", unimplementedFilter("cgi_escape")) - engine.DefineFilter("uri_escape", unimplementedFilter("uri_escape")) - engine.DefineFilter("scssify", unimplementedFilter("scssify")) - engine.DefineFilter("smartify", unimplementedFilter("smartify")) - engine.DefineFilter("xml_escape", func(s string) string { + e.DefineFilter("cgi_escape", unimplementedFilter("cgi_escape")) + e.DefineFilter("uri_escape", unimplementedFilter("uri_escape")) + e.DefineFilter("scssify", unimplementedFilter("scssify")) + e.DefineFilter("smartify", unimplementedFilter("smartify")) + e.DefineFilter("xml_escape", func(s string) string { // TODO can't handle maps // eval https://github.com/clbanning/mxj // adapt https://stackoverflow.com/questions/30928770/marshall-map-to-xml-in-go diff --git a/pipelines/pipeline.go b/pipelines/pipeline.go index a343845..778aeab 100644 --- a/pipelines/pipeline.go +++ b/pipelines/pipeline.go @@ -42,6 +42,8 @@ func NewPipeline(c config.Config, options PipelineOptions) (*Pipeline, error) { return &p, nil } +// SourceDir returns the site source directory. Seeing how far we can bend +// the Law of Demeter. func (p *Pipeline) SourceDir() string { return p.config.Source } diff --git a/plugins/plugins.go b/plugins/plugins.go index 417034d..e213cf1 100644 --- a/plugins/plugins.go +++ b/plugins/plugins.go @@ -1,3 +1,8 @@ +// Package plugins holds emulated Jekyll plugins. +// +// Unlike Jekyll, these are baked into the executable -- both because as of 2017.07 package "plugin' currently +// works only on Linux, but also because the gojekyll implementation is immature and any possible interfaces +// are far from baked. package plugins import ( @@ -9,10 +14,13 @@ import ( "github.com/osteele/liquid/chunks" ) +// PluginContext is the context for plugin initialization. +// Currently, the only thing a plugin can do is add filters and tags. type PluginContext interface { TemplateEngine() liquid.Engine } +// Install installs a plugin from the plugin directory. func Install(name string, ctx PluginContext) bool { p, found := plugins[name] if p != nil { @@ -25,6 +33,7 @@ func Install(name string, ctx PluginContext) bool { var plugins = map[string]func(PluginContext) error{} +// registerPlugin installs a plugin in the plugin directory. func registerPlugin(name string, fn func(PluginContext) error) { plugins[name] = fn } diff --git a/sites/site.go b/sites/site.go index 2757f35..1ca0f6b 100644 --- a/sites/site.go +++ b/sites/site.go @@ -29,8 +29,10 @@ type Site struct { siteVariables map[string]interface{} } +// SourceDir returns the site source directory. func (s *Site) SourceDir() string { return s.config.Source } +// DestDir returns the site destination directory. func (s *Site) DestDir() string { if filepath.IsAbs(s.config.Destination) { return s.config.Destination diff --git a/tags/tags.go b/tags/tags.go index 2cc1153..8401c6f 100644 --- a/tags/tags.go +++ b/tags/tags.go @@ -15,19 +15,20 @@ import ( // A LinkTagHandler given an include tag file name returns a URL. type LinkTagHandler func(string) (string, bool) -func AddJekyllTags(engine liquid.Engine, config config.Config, linkHandler LinkTagHandler) { - tc := tagContext{config, linkHandler} - engine.DefineTag("link", tc.linkTag) - engine.DefineTag("include", tc.includeTag) +// AddJekyllTags adds the Jekyll tags to the Liquid engine. +func AddJekyllTags(e liquid.Engine, c config.Config, lh LinkTagHandler) { + tc := tagContext{c, lh} + e.DefineTag("link", tc.linkTag) + e.DefineTag("include", tc.includeTag) // TODO unimplemented - engine.DefineTag("post_url", emptyTag) - engine.DefineStartTag("highlight", highlightTag) + e.DefineTag("post_url", emptyTag) + e.DefineStartTag("highlight", highlightTag) } type tagContext struct { - config config.Config - linkHandler LinkTagHandler + config config.Config + lh LinkTagHandler } func emptyTag(_ string) (func(io.Writer, chunks.RenderContext) error, error) { @@ -47,11 +48,12 @@ func highlightTag(w io.Writer, ctx chunks.RenderContext) error { if err != nil { return err } + // TODO this is disabled for performance; make it configurable instead. if true { _, err = w.Write([]byte(s)) return err } - cmd := exec.Command("pygmentize", cargs...) + cmd := exec.Command("pygmentize", cargs...) // nolint: gas cmd.Stdin = strings.NewReader(s) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -60,7 +62,7 @@ func highlightTag(w io.Writer, ctx chunks.RenderContext) error { func (tc tagContext) linkTag(filename string) (func(io.Writer, chunks.RenderContext) error, error) { return func(w io.Writer, _ chunks.RenderContext) error { - url, found := tc.linkHandler(filename) + url, found := tc.lh(filename) if !found { return fmt.Errorf("missing link filename: %s", filename) }