summaryrefslogtreecommitdiffstats
path: root/helpers
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-02-05 10:20:06 +0700
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-02-17 17:15:26 +0100
commit93ca7c9e958e34469a337e4efcc7c75774ec50fd (patch)
tree5dfa296cfe74fd5ef8f0d41ea4078704f453aa04 /helpers
parente34af6ee30f70f5780a281e2fd8f4ed9b487ee61 (diff)
all: Refactor to nonglobal Viper, i18n etc.
This is a final rewrite that removes all the global state in Hugo, which also enables the use if `t.Parallel` in tests. Updates #2701 Fixes #3016
Diffstat (limited to 'helpers')
-rw-r--r--helpers/configProvider.go63
-rw-r--r--helpers/content.go74
-rw-r--r--helpers/content_renderer.go57
-rw-r--r--helpers/content_renderer_test.go34
-rw-r--r--helpers/content_test.go49
-rw-r--r--helpers/general.go5
-rw-r--r--helpers/language.go46
-rw-r--r--helpers/language_test.go7
-rw-r--r--helpers/path.go49
-rw-r--r--helpers/path_test.go44
-rw-r--r--helpers/pathspec.go54
-rw-r--r--helpers/pathspec_test.go38
-rw-r--r--helpers/pygments.go26
-rw-r--r--helpers/pygments_test.go19
-rw-r--r--helpers/testhelpers_test.go37
-rw-r--r--helpers/url.go7
-rw-r--r--helpers/url_test.go42
17 files changed, 348 insertions, 303 deletions
diff --git a/helpers/configProvider.go b/helpers/configProvider.go
deleted file mode 100644
index b96018257..000000000
--- a/helpers/configProvider.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2016-present The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package helpers implements general utility functions that work with
-// and on content. The helper functions defined here lay down the
-// foundation of how Hugo works with files and filepaths, and perform
-// string operations on content.
-package helpers
-
-import (
- "github.com/spf13/viper"
-)
-
-// A cached version of the current ConfigProvider (language) and relatives. These globals
-// are unfortunate, but we still have some places that needs this that does
-// not have access to the site configuration.
-// These values will be set on initialization when rendering a new language.
-//
-// TODO(bep) Get rid of these.
-var (
- currentConfigProvider ConfigProvider
-)
-
-// ConfigProvider provides the configuration settings for Hugo.
-type ConfigProvider interface {
- GetString(key string) string
- GetInt(key string) int
- GetBool(key string) bool
- GetStringMap(key string) map[string]interface{}
- GetStringMapString(key string) map[string]string
- Get(key string) interface{}
-}
-
-// Config returns the currently active Hugo config. This will be set
-// per site (language) rendered.
-func Config() ConfigProvider {
- if currentConfigProvider != nil {
- return currentConfigProvider
- }
- // Some tests rely on this. We will fix that, eventually.
- return viper.Get("currentContentLanguage").(ConfigProvider)
-}
-
-// InitConfigProviderForCurrentContentLanguage does what it says.
-func InitConfigProviderForCurrentContentLanguage() {
- currentConfigProvider = viper.Get("CurrentContentLanguage").(ConfigProvider)
-}
-
-// ResetConfigProvider is used in tests.
-func ResetConfigProvider() {
- currentConfigProvider = nil
-
-}
diff --git a/helpers/content.go b/helpers/content.go
index d8130e83f..0eb687af6 100644
--- a/helpers/content.go
+++ b/helpers/content.go
@@ -24,12 +24,13 @@ import (
"unicode"
"unicode/utf8"
+ "github.com/spf13/hugo/config"
+
"github.com/miekg/mmark"
"github.com/mitchellh/mapstructure"
"github.com/russross/blackfriday"
bp "github.com/spf13/hugo/bufferpool"
jww "github.com/spf13/jwalterweatherman"
- "github.com/spf13/viper"
"strings"
"sync"
@@ -41,6 +42,14 @@ var SummaryLength = 70
// SummaryDivider denotes where content summarization should end. The default is "<!--more-->".
var SummaryDivider = []byte("<!--more-->")
+type ContentSpec struct {
+ cfg config.Provider
+}
+
+func NewContentSpec(cfg config.Provider) *ContentSpec {
+ return &ContentSpec{cfg}
+}
+
// Blackfriday holds configuration values for Blackfriday rendering.
type Blackfriday struct {
Smartypants bool
@@ -58,7 +67,7 @@ type Blackfriday struct {
}
// NewBlackfriday creates a new Blackfriday filled with site config or some sane defaults.
-func NewBlackfriday(c ConfigProvider) *Blackfriday {
+func (c ContentSpec) NewBlackfriday() *Blackfriday {
defaultParam := map[string]interface{}{
"smartypants": true,
@@ -75,7 +84,7 @@ func NewBlackfriday(c ConfigProvider) *Blackfriday {
ToLowerMap(defaultParam)
- siteParam := c.GetStringMap("blackfriday")
+ siteParam := c.cfg.GetStringMap("blackfriday")
siteConfig := make(map[string]interface{})
@@ -187,10 +196,10 @@ func BytesToHTML(b []byte) template.HTML {
}
// getHTMLRenderer creates a new Blackfriday HTML Renderer with the given configuration.
-func getHTMLRenderer(defaultFlags int, ctx *RenderingContext) blackfriday.Renderer {
+func (c ContentSpec) getHTMLRenderer(defaultFlags int, ctx *RenderingContext) blackfriday.Renderer {
renderParameters := blackfriday.HtmlRendererParameters{
- FootnoteAnchorPrefix: viper.GetString("footnoteAnchorPrefix"),
- FootnoteReturnLinkContents: viper.GetString("footnoteReturnLinkContents"),
+ FootnoteAnchorPrefix: c.cfg.GetString("footnoteAnchorPrefix"),
+ FootnoteReturnLinkContents: c.cfg.GetString("footnoteReturnLinkContents"),
}
b := len(ctx.DocumentID) != 0
@@ -265,21 +274,21 @@ func getMarkdownExtensions(ctx *RenderingContext) int {
return flags
}
-func markdownRender(ctx *RenderingContext) []byte {
+func (c ContentSpec) markdownRender(ctx *RenderingContext) []byte {
if ctx.RenderTOC {
return blackfriday.Markdown(ctx.Content,
- getHTMLRenderer(blackfriday.HTML_TOC, ctx),
+ c.getHTMLRenderer(blackfriday.HTML_TOC, ctx),
getMarkdownExtensions(ctx))
}
- return blackfriday.Markdown(ctx.Content, getHTMLRenderer(0, ctx),
+ return blackfriday.Markdown(ctx.Content, c.getHTMLRenderer(0, ctx),
getMarkdownExtensions(ctx))
}
// getMmarkHTMLRenderer creates a new mmark HTML Renderer with the given configuration.
-func getMmarkHTMLRenderer(defaultFlags int, ctx *RenderingContext) mmark.Renderer {
+func (c ContentSpec) getMmarkHTMLRenderer(defaultFlags int, ctx *RenderingContext) mmark.Renderer {
renderParameters := mmark.HtmlRendererParameters{
- FootnoteAnchorPrefix: viper.GetString("footnoteAnchorPrefix"),
- FootnoteReturnLinkContents: viper.GetString("footnoteReturnLinkContents"),
+ FootnoteAnchorPrefix: c.cfg.GetString("footnoteAnchorPrefix"),
+ FootnoteReturnLinkContents: c.cfg.GetString("footnoteReturnLinkContents"),
}
b := len(ctx.DocumentID) != 0
@@ -294,6 +303,7 @@ func getMmarkHTMLRenderer(defaultFlags int, ctx *RenderingContext) mmark.Rendere
return &HugoMmarkHTMLRenderer{
mmark.HtmlRendererWithParameters(htmlFlags, "", "", renderParameters),
+ c.cfg,
}
}
@@ -321,8 +331,8 @@ func getMmarkExtensions(ctx *RenderingContext) int {
return flags
}
-func mmarkRender(ctx *RenderingContext) []byte {
- return mmark.Parse(ctx.Content, getMmarkHTMLRenderer(0, ctx),
+func (c ContentSpec) mmarkRender(ctx *RenderingContext) []byte {
+ return mmark.Parse(ctx.Content, c.getMmarkHTMLRenderer(0, ctx),
getMmarkExtensions(ctx)).Bytes()
}
@@ -365,42 +375,44 @@ func ExtractTOC(content []byte) (newcontent []byte, toc []byte) {
// RenderingContext holds contextual information, like content and configuration,
// for a given content rendering.
type RenderingContext struct {
- Content []byte
- PageFmt string
- DocumentID string
- DocumentName string
- Config *Blackfriday
- RenderTOC bool
- FileResolver FileResolverFunc
- LinkResolver LinkResolverFunc
- ConfigProvider ConfigProvider
- configInit sync.Once
+ Content []byte
+ PageFmt string
+ DocumentID string
+ DocumentName string
+ Config *Blackfriday
+ RenderTOC bool
+ FileResolver FileResolverFunc
+ LinkResolver LinkResolverFunc
+ Cfg config.Provider
+ configInit sync.Once
}
-func newViperProvidedRenderingContext() *RenderingContext {
- return &RenderingContext{ConfigProvider: viper.GetViper()}
+func newRenderingContext(cfg config.Provider) *RenderingContext {
+ return &RenderingContext{Cfg: cfg}
}
func (c *RenderingContext) getConfig() *Blackfriday {
+ // TODO(bep) get rid of this
c.configInit.Do(func() {
if c.Config == nil {
- c.Config = NewBlackfriday(c.ConfigProvider)
+ cs := NewContentSpec(c.Cfg)
+ c.Config = cs.NewBlackfriday()
}
})
return c.Config
}
// RenderBytes renders a []byte.
-func RenderBytes(ctx *RenderingContext) []byte {
+func (c ContentSpec) RenderBytes(ctx *RenderingContext) []byte {
switch ctx.PageFmt {
default:
- return markdownRender(ctx)
+ return c.markdownRender(ctx)
case "markdown":
- return markdownRender(ctx)
+ return c.markdownRender(ctx)
case "asciidoc":
return getAsciidocContent(ctx)
case "mmark":
- return mmarkRender(ctx)
+ return c.mmarkRender(ctx)
case "rst":
return getRstContent(ctx)
}
diff --git a/helpers/content_renderer.go b/helpers/content_renderer.go
index dbc29f431..6082ae945 100644
--- a/helpers/content_renderer.go
+++ b/helpers/content_renderer.go
@@ -19,8 +19,8 @@ import (
"github.com/miekg/mmark"
"github.com/russross/blackfriday"
+ "github.com/spf13/hugo/config"
jww "github.com/spf13/jwalterweatherman"
- "github.com/spf13/viper"
)
type LinkResolverFunc func(ref string) (string, error)
@@ -33,49 +33,49 @@ type HugoHTMLRenderer struct {
blackfriday.Renderer
}
-func (renderer *HugoHTMLRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
- if viper.GetBool("pygmentsCodeFences") && (lang != "" || viper.GetBool("pygmentsCodeFencesGuessSyntax")) {
- opts := viper.GetString("pygmentsOptions")
+func (r *HugoHTMLRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
+ if r.Cfg.GetBool("pygmentsCodeFences") && (lang != "" || r.Cfg.GetBool("pygmentsCodeFencesGuessSyntax")) {
+ opts := r.Cfg.GetString("pygmentsOptions")
str := html.UnescapeString(string(text))
- out.WriteString(Highlight(str, lang, opts))
+ out.WriteString(Highlight(r.RenderingContext.Cfg, str, lang, opts))
} else {
- renderer.Renderer.BlockCode(out, text, lang)
+ r.Renderer.BlockCode(out, text, lang)
}
}
-func (renderer *HugoHTMLRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
- if renderer.LinkResolver == nil || bytes.HasPrefix(link, []byte("HAHAHUGOSHORTCODE")) {
+func (r *HugoHTMLRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
+ if r.LinkResolver == nil || bytes.HasPrefix(link, []byte("HAHAHUGOSHORTCODE")) {
// Use the blackfriday built in Link handler
- renderer.Renderer.Link(out, link, title, content)
+ r.Renderer.Link(out, link, title, content)
} else {
// set by SourceRelativeLinksEval
- newLink, err := renderer.LinkResolver(string(link))
+ newLink, err := r.LinkResolver(string(link))
if err != nil {
newLink = string(link)
jww.ERROR.Printf("LinkResolver: %s", err)
}
- renderer.Renderer.Link(out, []byte(newLink), title, content)
+ r.Renderer.Link(out, []byte(newLink), title, content)
}
}
-func (renderer *HugoHTMLRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
- if renderer.FileResolver == nil || bytes.HasPrefix(link, []byte("HAHAHUGOSHORTCODE")) {
+func (r *HugoHTMLRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
+ if r.FileResolver == nil || bytes.HasPrefix(link, []byte("HAHAHUGOSHORTCODE")) {
// Use the blackfriday built in Image handler
- renderer.Renderer.Image(out, link, title, alt)
+ r.Renderer.Image(out, link, title, alt)
} else {
// set by SourceRelativeLinksEval
- newLink, err := renderer.FileResolver(string(link))
+ newLink, err := r.FileResolver(string(link))
if err != nil {
newLink = string(link)
jww.ERROR.Printf("FileResolver: %s", err)
}
- renderer.Renderer.Image(out, []byte(newLink), title, alt)
+ r.Renderer.Image(out, []byte(newLink), title, alt)
}
}
// ListItem adds task list support to the Blackfriday renderer.
-func (renderer *HugoHTMLRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
- if !renderer.Config.TaskLists {
- renderer.Renderer.ListItem(out, text, flags)
+func (r *HugoHTMLRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
+ if !r.Config.TaskLists {
+ r.Renderer.ListItem(out, text, flags)
return
}
@@ -87,17 +87,17 @@ func (renderer *HugoHTMLRenderer) ListItem(out *bytes.Buffer, text []byte, flags
text = append([]byte(`<input type="checkbox" checked disabled class="task-list-item">`), text[3:]...)
}
- renderer.Renderer.ListItem(out, text, flags)
+ r.Renderer.ListItem(out, text, flags)
}
// List adds task list support to the Blackfriday renderer.
-func (renderer *HugoHTMLRenderer) List(out *bytes.Buffer, text func() bool, flags int) {
- if !renderer.Config.TaskLists {
- renderer.Renderer.List(out, text, flags)
+func (r *HugoHTMLRenderer) List(out *bytes.Buffer, text func() bool, flags int) {
+ if !r.Config.TaskLists {
+ r.Renderer.List(out, text, flags)
return
}
marker := out.Len()
- renderer.Renderer.List(out, text, flags)
+ r.Renderer.List(out, text, flags)
if out.Len() > marker {
list := out.Bytes()[marker:]
if bytes.Contains(list, []byte("task-list-item")) {
@@ -114,13 +114,14 @@ func (renderer *HugoHTMLRenderer) List(out *bytes.Buffer, text func() bool, flag
// Enabling Hugo to customise the rendering experience
type HugoMmarkHTMLRenderer struct {
mmark.Renderer
+ Cfg config.Provider
}
-func (renderer *HugoMmarkHTMLRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string, caption []byte, subfigure bool, callouts bool) {
- if viper.GetBool("pygmentsCodeFences") && (lang != "" || viper.GetBool("pygmentsCodeFencesGuessSyntax")) {
+func (r *HugoMmarkHTMLRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string, caption []byte, subfigure bool, callouts bool) {
+ if r.Cfg.GetBool("pygmentsCodeFences") && (lang != "" || r.Cfg.GetBool("pygmentsCodeFencesGuessSyntax")) {
str := html.UnescapeString(string(text))
- out.WriteString(Highlight(str, lang, ""))
+ out.WriteString(Highlight(r.Cfg, str, lang, ""))
} else {
- renderer.Renderer.BlockCode(out, text, lang, caption, subfigure, callouts)
+ r.Renderer.BlockCode(out, text, lang, caption, subfigure, callouts)
}
}
diff --git a/helpers/content_renderer_test.go b/helpers/content_renderer_test.go
index 82168fcfd..ab663966b 100644
--- a/helpers/content_renderer_test.go
+++ b/helpers/content_renderer_test.go
@@ -22,9 +22,9 @@ import (
)
// Renders a codeblock using Blackfriday
-func render(input string) string {
- ctx := newViperProvidedRenderingContext()
- render := getHTMLRenderer(0, ctx)
+func (c ContentSpec) render(input string) string {
+ ctx := newRenderingContext(c.cfg)
+ render := c.getHTMLRenderer(0, ctx)
buf := &bytes.Buffer{}
render.BlockCode(buf, []byte(input), "html")
@@ -32,9 +32,9 @@ func render(input string) string {
}
// Renders a codeblock using Mmark
-func renderWithMmark(input string) string {
- ctx := newViperProvidedRenderingContext()
- render := getMmarkHTMLRenderer(0, ctx)
+func (c ContentSpec) renderWithMmark(input string) string {
+ ctx := newRenderingContext(c.cfg)
+ render := c.getMmarkHTMLRenderer(0, ctx)
buf := &bytes.Buffer{}
render.BlockCode(buf, []byte(input), "html", []byte(""), false, false)
@@ -59,16 +59,16 @@ func TestCodeFence(t *testing.T) {
{false, "<html></html>", `(?s)^<pre><code class="language-html">.*?</code></pre>\n$`},
}
- viper.Reset()
- defer viper.Reset()
+ for i, d := range data {
+ v := viper.New()
- viper.Set("pygmentsStyle", "monokai")
- viper.Set("pygmentsUseClasses", true)
+ v.Set("pygmentsStyle", "monokai")
+ v.Set("pygmentsUseClasses", true)
+ v.Set("pygmentsCodeFences", d.enabled)
- for i, d := range data {
- viper.Set("pygmentsCodeFences", d.enabled)
+ c := NewContentSpec(v)
- result := render(d.input)
+ result := c.render(d.input)
expectedRe, err := regexp.Compile(d.expected)
@@ -81,7 +81,7 @@ func TestCodeFence(t *testing.T) {
t.Errorf("Test %d failed. BlackFriday enabled:%t, Expected:\n%q got:\n%q", i, d.enabled, d.expected, result)
}
- result = renderWithMmark(d.input)
+ result = c.renderWithMmark(d.input)
matched = expectedRe.MatchString(result)
if !matched {
t.Errorf("Test %d failed. Mmark enabled:%t, Expected:\n%q got:\n%q", i, d.enabled, d.expected, result)
@@ -90,6 +90,8 @@ func TestCodeFence(t *testing.T) {
}
func TestBlackfridayTaskList(t *testing.T) {
+ c := newTestContentSpec()
+
for i, this := range []struct {
markdown string
taskListEnabled bool
@@ -118,11 +120,11 @@ END
</ul>
`},
} {
- blackFridayConfig := NewBlackfriday(viper.GetViper())
+ blackFridayConfig := c.NewBlackfriday()
blackFridayConfig.TaskLists = this.taskListEnabled
ctx := &RenderingContext{Content: []byte(this.markdown), PageFmt: "markdown", Config: blackFridayConfig}
- result := string(RenderBytes(ctx))
+ result := string(c.RenderBytes(ctx))
if result != this.expect {
t.Errorf("[%d] got \n%v but expected \n%v", i, result, this.expect)
diff --git a/helpers/content_test.go b/helpers/content_test.go
index 67c50f9d6..52bb85097 100644
--- a/helpers/content_test.go
+++ b/helpers/content_test.go
@@ -21,7 +21,6 @@ import (
"github.com/miekg/mmark"
"github.com/russross/blackfriday"
- "github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)
@@ -152,8 +151,9 @@ func TestTruncateWordsByRune(t *testing.T) {
}
func TestGetHTMLRendererFlags(t *testing.T) {
- ctx := newViperProvidedRenderingContext()
- renderer := getHTMLRenderer(blackfriday.HTML_USE_XHTML, ctx)
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
+ renderer := c.getHTMLRenderer(blackfriday.HTML_USE_XHTML, ctx)
flags := renderer.GetFlags()
if flags&blackfriday.HTML_USE_XHTML != blackfriday.HTML_USE_XHTML {
t.Errorf("Test flag: %d was not found amongs set flags:%d; Result: %d", blackfriday.HTML_USE_XHTML, flags, flags&blackfriday.HTML_USE_XHTML)
@@ -161,6 +161,8 @@ func TestGetHTMLRendererFlags(t *testing.T) {
}
func TestGetHTMLRendererAllFlags(t *testing.T) {
+ c := newTestContentSpec()
+
type data struct {
testFlag int
}
@@ -176,7 +178,7 @@ func TestGetHTMLRendererAllFlags(t *testing.T) {
{blackfriday.HTML_SMARTYPANTS_LATEX_DASHES},
}
defaultFlags := blackfriday.HTML_USE_XHTML
- ctx := newViperProvidedRenderingContext()
+ ctx := newRenderingContext(c.cfg)
ctx.Config = ctx.getConfig()
ctx.Config.AngledQuotes = true
ctx.Config.Fractions = true
@@ -186,7 +188,7 @@ func TestGetHTMLRendererAllFlags(t *testing.T) {
ctx.Config.SmartDashes = true
ctx.Config.Smartypants = true
ctx.Config.SourceRelativeLinksEval = true
- renderer := getHTMLRenderer(defaultFlags, ctx)
+ renderer := c.getHTMLRenderer(defaultFlags, ctx)
actualFlags := renderer.GetFlags()
var expectedFlags int
//OR-ing flags together...
@@ -199,12 +201,13 @@ func TestGetHTMLRendererAllFlags(t *testing.T) {
}
func TestGetHTMLRendererAnchors(t *testing.T) {
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.DocumentID = "testid"
ctx.Config = ctx.getConfig()
ctx.Config.PlainIDAnchors = false
- actualRenderer := getHTMLRenderer(0, ctx)
+ actualRenderer := c.getHTMLRenderer(0, ctx)
headerBuffer := &bytes.Buffer{}
footnoteBuffer := &bytes.Buffer{}
expectedFootnoteHref := []byte("href=\"#fn:testid:href\"")
@@ -223,11 +226,12 @@ func TestGetHTMLRendererAnchors(t *testing.T) {
}
func TestGetMmarkHTMLRenderer(t *testing.T) {
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.DocumentID = "testid"
ctx.Config = ctx.getConfig()
ctx.Config.PlainIDAnchors = false
- actualRenderer := getMmarkHTMLRenderer(0, ctx)
+ actualRenderer := c.getMmarkHTMLRenderer(0, ctx)
headerBuffer := &bytes.Buffer{}
footnoteBuffer := &bytes.Buffer{}
@@ -247,7 +251,8 @@ func TestGetMmarkHTMLRenderer(t *testing.T) {
}
func TestGetMarkdownExtensionsMasksAreRemovedFromExtensions(t *testing.T) {
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.Config = ctx.getConfig()
ctx.Config.Extensions = []string{"headerId"}
ctx.Config.ExtensionsMask = []string{"noIntraEmphasis"}
@@ -262,7 +267,8 @@ func TestGetMarkdownExtensionsByDefaultAllExtensionsAreEnabled(t *testing.T) {
type data struct {
testFlag int
}
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.Config = ctx.getConfig()
ctx.Config.Extensions = []string{""}
ctx.Config.ExtensionsMask = []string{""}
@@ -294,7 +300,8 @@ func TestGetMarkdownExtensionsByDefaultAllExtensionsAreEnabled(t *testing.T) {
}
func TestGetMarkdownExtensionsAddingFlagsThroughRenderingContext(t *testing.T) {
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.Config = ctx.getConfig()
ctx.Config.Extensions = []string{"definitionLists"}
ctx.Config.ExtensionsMask = []string{""}
@@ -306,10 +313,11 @@ func TestGetMarkdownExtensionsAddingFlagsThroughRenderingContext(t *testing.T) {
}
func TestGetMarkdownRenderer(t *testing.T) {
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.Content = []byte("testContent")
ctx.Config = ctx.getConfig()
- actualRenderedMarkdown := markdownRender(ctx)
+ actualRenderedMarkdown := c.markdownRender(ctx)
expectedRenderedMarkdown := []byte("<p>testContent</p>\n")
if !bytes.Equal(actualRenderedMarkdown, expectedRenderedMarkdown) {
t.Errorf("Actual rendered Markdown (%s) did not match expected markdown (%s)", actualRenderedMarkdown, expectedRenderedMarkdown)
@@ -317,10 +325,11 @@ func TestGetMarkdownRenderer(t *testing.T) {
}
func TestGetMarkdownRendererWithTOC(t *testing.T) {
- ctx := &RenderingContext{RenderTOC: true, ConfigProvider: viper.GetViper()}
+ c := newTestContentSpec()
+ ctx := &RenderingContext{RenderTOC: true, Cfg: c.cfg}
ctx.Content = []byte("testContent")
ctx.Config = ctx.getConfig()
- actualRenderedMarkdown := markdownRender(ctx)
+ actualRenderedMarkdown := c.markdownRender(ctx)
expectedRenderedMarkdown := []byte("<nav>\n</nav>\n\n<p>testContent</p>\n")
if !bytes.Equal(actualRenderedMarkdown, expectedRenderedMarkdown) {
t.Errorf("Actual rendered Markdown (%s) did not match expected markdown (%s)", actualRenderedMarkdown, expectedRenderedMarkdown)
@@ -332,7 +341,8 @@ func TestGetMmarkExtensions(t *testing.T) {
type data struct {
testFlag int
}
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.Config = ctx.getConfig()
ctx.Config.Extensions = []string{"tables"}
ctx.Config.ExtensionsMask = []string{""}
@@ -361,10 +371,11 @@ func TestGetMmarkExtensions(t *testing.T) {
}
func TestMmarkRender(t *testing.T) {
- ctx := newViperProvidedRenderingContext()
+ c := newTestContentSpec()
+ ctx := newRenderingContext(c.cfg)
ctx.Content = []byte("testContent")
ctx.Config = ctx.getConfig()
- actualRenderedMarkdown := mmarkRender(ctx)
+ actualRenderedMarkdown := c.mmarkRender(ctx)
expectedRenderedMarkdown := []byte("<p>testContent</p>\n")
if !bytes.Equal(actualRenderedMarkdown, expectedRenderedMarkdown) {
t.Errorf("Actual rendered Markdown (%s) did not match expected markdown (%s)", actualRenderedMarkdown, expectedRenderedMarkdown)
diff --git a/helpers/general.go b/helpers/general.go
index 1088d9dd1..91c25c04c 100644
--- a/helpers/general.go
+++ b/helpers/general.go
@@ -32,7 +32,6 @@ import (
bp "github.com/spf13/hugo/bufferpool"
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/pflag"
- "github.com/spf13/viper"
)
// FilePathSeparator as defined by os.Separator.
@@ -196,8 +195,8 @@ func ReaderContains(r io.Reader, subslice []byte) bool {
}
// ThemeSet checks whether a theme is in use or not.
-func ThemeSet() bool {
- return viper.GetString("theme") != ""
+func (p *PathSpec) ThemeSet() bool {
+ return p.theme != ""
}
type logPrinter interface {
diff --git a/helpers/language.go b/helpers/language.go
index 000c846b1..9b7136854 100644
--- a/helpers/language.go
+++ b/helpers/language.go
@@ -19,8 +19,7 @@ import (
"sync"
"github.com/spf13/cast"
-
- "github.com/spf13/viper"
+ "github.com/spf13/hugo/config"
)
// These are the settings that should only be looked up in the global Viper
@@ -41,26 +40,28 @@ type Language struct {
LanguageName string
Title string
Weight int
- params map[string]interface{}
- paramsInit sync.Once
+
+ Cfg config.Provider
+ params map[string]interface{}
+ paramsInit sync.Once
}
func (l *Language) String() string {
return l.Lang
}
-func NewLanguage(lang string) *Language {
- return &Language{Lang: lang, params: make(map[string]interface{})}
+func NewLanguage(lang string, cfg config.Provider) *Language {
+ return &Language{Lang: lang, Cfg: cfg, params: make(map[string]interface{})}
}
-func NewDefaultLanguage() *Language {
- defaultLang := viper.GetString("defaultContentLanguage")
+func NewDefaultLanguage(cfg config.Provider) *Language {
+ defaultLang := cfg.GetString("defaultContentLanguage")
if defaultLang == "" {
defaultLang = "en"
}
- return NewLanguage(defaultLang)
+ return NewLanguage(defaultLang, cfg)
}
type Languages []*Language
@@ -83,7 +84,7 @@ func (l *Language) Params() map[string]interface{} {
// Merge with global config.
// TODO(bep) consider making this part of a constructor func.
- globalParams := viper.GetStringMap("params")
+ globalParams := l.Cfg.GetStringMap("params")
for k, v := range globalParams {
if _, ok := l.params[k]; !ok {
l.params[k] = v
@@ -132,5 +133,28 @@ func (l *Language) Get(key string) interface{} {
return v
}
}
- return viper.Get(key)
+ return l.Cfg.Get(key)
+}
+
+// Set sets the value for the key in the language's params.
+func (l *Language) Set(key string, value interface{}) {
+ if l == nil {
+ panic("language not set")
+ }
+ key = strings.ToLower(key)
+ l.params[key] = value
+}
+
+// IsSet checks whether the key is set in the language or the related config store.
+func (l *Language) IsSet(key string) bool {
+ key = strings.ToLower(key)
+
+ key = strings.ToLower(key)
+ if !globalOnly