From fbf8bcacc464e9bfbc816fa6d097e6371662ce02 Mon Sep 17 00:00:00 2001 From: bep Date: Fri, 28 Nov 2014 21:16:57 +0100 Subject: [PATCH] Add configurable support for angled quotes The flag `HTML_SMARTYPANTS_ANGLED_QUOTES` was added to Blackfriday on Black Friday. This configures rendering of double quotes as angled left and right quotes (« »). Typical use cases would be either or, or combined, but never in the same document. As an example would be a person from Norway; he has a blog in both English and Norwegian (his native tongue); he would then configure Blackfriday to use angled quotes for the Norwegian section, but keep them as reqular double quotes for the English. This commit adds configuration support for this new flag, configuration that can be set in the site configuration, but overridden in page front matter. Fixes #605 --- commands/hugo.go | 1 + helpers/content.go | 55 +++++++++++++++++++++++++++++--------------- hugolib/page.go | 32 ++++++++++++++++++++++---- hugolib/shortcode.go | 4 +++- tpl/template.go | 2 +- 5 files changed, 69 insertions(+), 25 deletions(-) diff --git a/commands/hugo.go b/commands/hugo.go index d43bb0ac0..ca7caf090 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -136,6 +136,7 @@ func InitializeConfig() { viper.SetDefault("FootnoteAnchorPrefix", "") viper.SetDefault("FootnoteReturnLinkContents", "") viper.SetDefault("NewContentEditor", "") + viper.SetDefault("Blackfriday", map[string]bool{"angledQuotes": false}) if hugoCmdV.PersistentFlags().Lookup("buildDrafts").Changed { viper.Set("BuildDrafts", Draft) diff --git a/helpers/content.go b/helpers/content.go index d5e507dae..a32245ae3 100644 --- a/helpers/content.go +++ b/helpers/content.go @@ -77,15 +77,15 @@ func BytesToHTML(b []byte) template.HTML { return template.HTML(string(b)) } -func GetHtmlRenderer(defaultFlags int, documentId string) blackfriday.Renderer { +func GetHtmlRenderer(defaultFlags int, ctx RenderingContext) blackfriday.Renderer { renderParameters := blackfriday.HtmlRendererParameters{ FootnoteAnchorPrefix: viper.GetString("FootnoteAnchorPrefix"), FootnoteReturnLinkContents: viper.GetString("FootnoteReturnLinkContents"), } - if len(documentId) != 0 { - renderParameters.FootnoteAnchorPrefix = documentId + ":" + renderParameters.FootnoteAnchorPrefix - renderParameters.HeaderIDSuffix = ":" + documentId + if len(ctx.DocumentId) != 0 { + renderParameters.FootnoteAnchorPrefix = ctx.DocumentId + ":" + renderParameters.FootnoteAnchorPrefix + renderParameters.HeaderIDSuffix = ":" + ctx.DocumentId } htmlFlags := defaultFlags @@ -95,6 +95,16 @@ func GetHtmlRenderer(defaultFlags int, documentId string) blackfriday.Renderer { htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES htmlFlags |= blackfriday.HTML_FOOTNOTE_RETURN_LINKS + var angledQuotes bool + + if m, ok := ctx.ConfigFlags["angledQuotes"]; ok { + angledQuotes = m + } + + if angledQuotes { + htmlFlags |= blackfriday.HTML_SMARTYPANTS_ANGLED_QUOTES + } + return blackfriday.HtmlRendererWithParameters(htmlFlags, "", "", renderParameters) } @@ -106,14 +116,14 @@ func GetMarkdownExtensions() int { blackfriday.EXTENSION_HEADER_IDS | blackfriday.EXTENSION_AUTO_HEADER_IDS } -func MarkdownRender(content []byte, documentId string) []byte { - return blackfriday.Markdown(content, GetHtmlRenderer(0, documentId), +func MarkdownRender(ctx RenderingContext) []byte { + return blackfriday.Markdown(ctx.Content, GetHtmlRenderer(0, ctx), GetMarkdownExtensions()) } -func MarkdownRenderWithTOC(content []byte, documentId string) []byte { - return blackfriday.Markdown(content, - GetHtmlRenderer(blackfriday.HTML_TOC, documentId), +func MarkdownRenderWithTOC(ctx RenderingContext) []byte { + return blackfriday.Markdown(ctx.Content, + GetHtmlRenderer(blackfriday.HTML_TOC, ctx), GetMarkdownExtensions()) } @@ -153,25 +163,32 @@ func ExtractTOC(content []byte) (newcontent []byte, toc []byte) { return } -func RenderBytesWithTOC(content []byte, pagefmt string, documentId string) []byte { - switch pagefmt { +type RenderingContext struct { + Content []byte + PageFmt string + DocumentId string + ConfigFlags map[string]bool +} + +func RenderBytesWithTOC(ctx RenderingContext) []byte { + switch ctx.PageFmt { default: - return MarkdownRenderWithTOC(content, documentId) + return MarkdownRenderWithTOC(ctx) case "markdown": - return MarkdownRenderWithTOC(content, documentId) + return MarkdownRenderWithTOC(ctx) case "rst": - return []byte(GetRstContent(content)) + return []byte(GetRstContent(ctx.Content)) } } -func RenderBytes(content []byte, pagefmt string, documentId string) []byte { - switch pagefmt { +func RenderBytes(ctx RenderingContext) []byte { + switch ctx.PageFmt { default: - return MarkdownRender(content, documentId) + return MarkdownRender(ctx) case "markdown": - return MarkdownRender(content, documentId) + return MarkdownRender(ctx) case "rst": - return []byte(GetRstContent(content)) + return []byte(GetRstContent(ctx.Content)) } } diff --git a/hugolib/page.go b/hugolib/page.go index 7eda69589..7c189ca28 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -17,10 +17,11 @@ import ( "bytes" "errors" "fmt" - "github.com/spf13/cast" "github.com/spf13/hugo/helpers" - "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/parser" + + "github.com/spf13/cast" + "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/source" "github.com/spf13/hugo/tpl" jww "github.com/spf13/jwalterweatherman" @@ -173,11 +174,32 @@ func (p *Page) setSummary() { } func (p *Page) renderBytes(content []byte) []byte { - return helpers.RenderBytes(content, p.guessMarkupType(), p.UniqueId()) + return helpers.RenderBytes( + helpers.RenderingContext{Content: content, PageFmt: p.guessMarkupType(), + DocumentId: p.UniqueId(), ConfigFlags: p.getRenderingConfigFlags()}) } func (p *Page) renderContent(content []byte) []byte { - return helpers.RenderBytesWithTOC(content, p.guessMarkupType(), p.UniqueId()) + return helpers.RenderBytesWithTOC(helpers.RenderingContext{Content: content, PageFmt: p.guessMarkupType(), + DocumentId: p.UniqueId(), ConfigFlags: p.getRenderingConfigFlags()}) +} + +func (p *Page) getRenderingConfigFlags() map[string]bool { + flags := make(map[string]bool) + + pageParam := p.GetParam("blackfriday") + siteParam := viper.GetStringMap("blackfriday") + + flags = cast.ToStringMapBool(siteParam) + + if pageParam != nil { + pageFlags := cast.ToStringMapBool(pageParam) + for key, value := range pageFlags { + flags[key] = value + } + } + + return flags } func newPage(filename string) *Page { @@ -472,6 +494,8 @@ func (page *Page) GetParam(key string) interface{} { return cast.ToTime(v) case []string: return helpers.SliceToLower(v.([]string)) + case map[interface{}]interface{}: + return v } return nil } diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index 9f7508e12..4cf2f84c0 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -212,7 +212,9 @@ func renderShortcode(sc shortcode, tokenizedShortcodes map[string](string), cnt } if sc.doMarkup { - newInner := helpers.RenderBytes([]byte(inner), p.guessMarkupType(), p.UniqueId()) + newInner := helpers.RenderBytes(helpers.RenderingContext{ + Content: []byte(inner), PageFmt: p.guessMarkupType(), + DocumentId: p.UniqueId(), ConfigFlags: p.getRenderingConfigFlags()}) // If the type is “unknown” or “markdown”, we assume the markdown // generation has been performed. Given the input: `a line`, markdown diff --git a/tpl/template.go b/tpl/template.go index daa8d7dd8..aef6c3ba6 100644 --- a/tpl/template.go +++ b/tpl/template.go @@ -618,7 +618,7 @@ func Highlight(in interface{}, lang string) template.HTML { } func Markdownify(text string) template.HTML { - return template.HTML(helpers.RenderBytes([]byte(text), "markdown", "")) + return template.HTML(helpers.RenderBytes(helpers.RenderingContext{Content: []byte(text), PageFmt: "markdown"})) } func refPage(page interface{}, ref, methodName string) template.HTML {