From c3931ef748d1bb0ec60e45e1cecdfc1bde850bfc Mon Sep 17 00:00:00 2001 From: Andrew Brampton Date: Wed, 8 Jul 2015 18:51:54 -0700 Subject: [PATCH] Add PygmentsOptions option This allows default pygments settings to be used, if none are explictly set per shortcode. Fixes #1260 --- commands/hugo.go | 3 +- helpers/content_renderer.go | 3 +- helpers/pygments.go | 87 +++++++++++++++++++++++-------------- helpers/pygments_test.go | 40 ++++++++++++++++- 4 files changed, 98 insertions(+), 35 deletions(-) diff --git a/commands/hugo.go b/commands/hugo.go index 3420fc52..f9780a1d 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -159,10 +159,11 @@ func LoadDefaultSettings() { viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"}) viper.SetDefault("Permalinks", make(hugolib.PermalinkOverrides, 0)) viper.SetDefault("Sitemap", hugolib.Sitemap{Priority: -1}) - viper.SetDefault("PygmentsStyle", "monokai") viper.SetDefault("DefaultExtension", "html") + viper.SetDefault("PygmentsStyle", "monokai") viper.SetDefault("PygmentsUseClasses", false) viper.SetDefault("PygmentsCodeFences", false) + viper.SetDefault("PygmentsOptions", "") viper.SetDefault("DisableLiveReload", false) viper.SetDefault("PluralizeListTitles", true) viper.SetDefault("PreserveTaxonomyNames", false) diff --git a/helpers/content_renderer.go b/helpers/content_renderer.go index 93556e7d..f7023f8d 100644 --- a/helpers/content_renderer.go +++ b/helpers/content_renderer.go @@ -17,8 +17,9 @@ type HugoHtmlRenderer struct { func (renderer *HugoHtmlRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) { if viper.GetBool("PygmentsCodeFences") { + opts := viper.GetString("PygmentsOptions") str := html.UnescapeString(string(text)) - out.WriteString(Highlight(str, lang, "")) + out.WriteString(Highlight(str, lang, opts)) } else { renderer.Renderer.BlockCode(out, text, lang) } diff --git a/helpers/pygments.go b/helpers/pygments.go index 17c30ee0..7d62fa0e 100644 --- a/helpers/pygments.go +++ b/helpers/pygments.go @@ -139,59 +139,82 @@ func init() { pygmentsKeywords["hl_lines"] = true pygmentsKeywords["linenos"] = true pygmentsKeywords["classprefix"] = true + pygmentsKeywords["startinline"] = true } -func parsePygmentsOpts(in string) (string, error) { - +func parseOptions(options map[string]string, in string) error { in = strings.Trim(in, " ") + if in != "" { + for _, v := range strings.Split(in, ",") { + keyVal := strings.Split(v, "=") + key := strings.ToLower(strings.Trim(keyVal[0], " ")) + if len(keyVal) != 2 || !pygmentsKeywords[key] { + return fmt.Errorf("invalid Pygments option: %s", key) + } + options[key] = keyVal[1] + } + } - style := viper.GetString("PygmentsStyle") + return nil +} - noclasses := "true" - if viper.GetBool("PygmentsUseClasses") { - noclasses = "false" +func createOptionsString(options map[string]string) string { + var keys []string + for k := range options { + keys = append(keys, k) } + sort.Strings(keys) - if len(in) == 0 { - return fmt.Sprintf("style=%s,noclasses=%s,encoding=utf8", style, noclasses), nil + var optionsStr string + for i, k := range keys { + optionsStr += fmt.Sprintf("%s=%s", k, options[k]) + if i < len(options)-1 { + optionsStr += "," + } } - options := make(map[string]string) + return optionsStr +} - o := strings.Split(in, ",") - for _, v := range o { - keyVal := strings.Split(v, "=") - key := strings.ToLower(strings.Trim(keyVal[0], " ")) - if len(keyVal) != 2 || !pygmentsKeywords[key] { - return "", fmt.Errorf("invalid Pygments option: %s", key) - } - options[key] = keyVal[1] +func parseDefaultPygmentsOpts() (map[string]string, error) { + + options := make(map[string]string) + err := parseOptions(options, viper.GetString("PygmentsOptions")) + if err != nil { + return nil, err } - if _, ok := options["style"]; !ok { - options["style"] = style + if viper.IsSet("PygmentsStyle") { + options["style"] = viper.GetString("PygmentsStyle") } - if _, ok := options["noclasses"]; !ok { - options["noclasses"] = noclasses + if viper.IsSet("PygmentsUseClasses") { + if viper.GetBool("PygmentsUseClasses") { + options["noclasses"] = "false" + } else { + options["noclasses"] = "true" + } + } if _, ok := options["encoding"]; !ok { options["encoding"] = "utf8" } - var keys []string - for k := range options { - keys = append(keys, k) + return options, nil +} + +func parsePygmentsOpts(in string) (string, error) { + + options, err := parseDefaultPygmentsOpts() + if err != nil { + return "", err } - sort.Strings(keys) - var optionsStr string - for i, k := range keys { - optionsStr += fmt.Sprintf("%s=%s", k, options[k]) - if i < len(options)-1 { - optionsStr += "," - } + err = parseOptions(options, in) + if err != nil { + return "", err } - return optionsStr, nil + + return createOptionsString(options), nil } diff --git a/helpers/pygments_test.go b/helpers/pygments_test.go index ba42adc1..9e91b813 100644 --- a/helpers/pygments_test.go +++ b/helpers/pygments_test.go @@ -13,7 +13,7 @@ func TestParsePygmentsArgs(t *testing.T) { pygmentsUseClasses bool expect1 interface{} }{ - {"", "foo", true, "style=foo,noclasses=false,encoding=utf8"}, + {"", "foo", true, "encoding=utf8,noclasses=false,style=foo"}, {"style=boo,noclasses=true", "foo", true, "encoding=utf8,noclasses=true,style=boo"}, {"Style=boo, noClasses=true", "foo", true, "encoding=utf8,noclasses=true,style=boo"}, {"noclasses=true", "foo", true, "encoding=utf8,noclasses=true,style=foo"}, @@ -42,3 +42,41 @@ func TestParsePygmentsArgs(t *testing.T) { } } } + +func TestParseDefaultPygmentsArgs(t *testing.T) { + expect := "encoding=utf8,noclasses=false,style=foo" + + for i, this := range []struct { + in string + pygmentsStyle interface{} + pygmentsUseClasses interface{} + pygmentsOptions string + }{ + {"", "foo", true, "style=override,noclasses=override"}, + {"", nil, nil, "style=foo,noclasses=false"}, + {"style=foo,noclasses=false", nil, nil, "style=override,noclasses=override"}, + {"style=foo,noclasses=false", "override", false, "style=override,noclasses=override"}, + + } { + viper.Reset() + + viper.Set("PygmentsOptions", this.pygmentsOptions) + + if s, ok := this.pygmentsStyle.(string); ok { + viper.Set("PygmentsStyle", s) + } + + if b, ok := this.pygmentsUseClasses.(bool); ok { + viper.Set("PygmentsUseClasses", b) + } + + result, err := parsePygmentsOpts(this.in) + if err != nil { + t.Errorf("[%d] parsePygmentArgs failed: %s", i, err) + continue + } + if result != expect { + t.Errorf("[%d] parsePygmentArgs got %v but expected %v", i, result, expect) + } + } +} -- 2.30.2