shithub: hugo

Download patch

ref: c3931ef748d1bb0ec60e45e1cecdfc1bde850bfc
parent: 99acbb2eb273500596a0da5b51b490fefc0829c4
author: Andrew Brampton <[email protected]>
date: Wed Jul 8 14:51:54 EDT 2015

Add PygmentsOptions option

This allows default pygments settings to be used, if none are explictly set per shortcode.

Fixes #1260

--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -159,10 +159,11 @@
 	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)
--- a/helpers/content_renderer.go
+++ b/helpers/content_renderer.go
@@ -17,8 +17,9 @@
 
 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)
 	}
--- a/helpers/pygments.go
+++ b/helpers/pygments.go
@@ -139,41 +139,62 @@
 	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 {
@@ -180,18 +201,20 @@
 		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
 }
--- a/helpers/pygments_test.go
+++ b/helpers/pygments_test.go
@@ -13,7 +13,7 @@
 		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"},
@@ -39,6 +39,44 @@
 				t.Errorf("[%d] parsePygmentArgs got %v but expected %v", i, result1, this.expect1)
 			}
 
+		}
+	}
+}
+
+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)
 		}
 	}
 }