Skip to content

Commit

Permalink
Reuse the BlackFriday instance when possible
Browse files Browse the repository at this point in the history
This is in heavy use in rendering, so this makes a difference:

```bash
benchmark                                                                                    old ns/op     new ns/op     delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_pages=500,tags_per_page=5,shortcodes,render-4     124551144     107743429     -13.49%

benchmark                                                                                    old allocs     new allocs     delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_pages=500,tags_per_page=5,shortcodes,render-4     528684         435118         -17.70%

benchmark                                                                                    old bytes     new bytes     delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_pages=500,tags_per_page=5,shortcodes,render-4     53306848      45147832      -15.31%
```
  • Loading branch information
bep committed Dec 16, 2017
1 parent 2511498 commit db4b7a5
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 33 deletions.
19 changes: 10 additions & 9 deletions helpers/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var SummaryDivider = []byte("<!--more-->")

// ContentSpec provides functionality to render markdown content.
type ContentSpec struct {
blackfriday map[string]interface{}
BlackFriday *BlackFriday
footnoteAnchorPrefix string
footnoteReturnLinkContents string
// SummaryLength is the length of the summary that Hugo extracts from a content.
Expand All @@ -56,8 +56,9 @@ type ContentSpec struct {
// NewContentSpec returns a ContentSpec initialized
// with the appropriate fields from the given config.Provider.
func NewContentSpec(cfg config.Provider) (*ContentSpec, error) {
bf := newBlackfriday(cfg.GetStringMap("blackfriday"))
spec := &ContentSpec{
blackfriday: cfg.GetStringMap("blackfriday"),
BlackFriday: bf,
footnoteAnchorPrefix: cfg.GetString("footnoteAnchorPrefix"),
footnoteReturnLinkContents: cfg.GetString("footnoteReturnLinkContents"),
summaryLength: cfg.GetInt("summaryLength"),
Expand Down Expand Up @@ -93,8 +94,8 @@ func NewContentSpec(cfg config.Provider) (*ContentSpec, error) {
return spec, nil
}

// Blackfriday holds configuration values for Blackfriday rendering.
type Blackfriday struct {
// BlackFriday holds configuration values for BlackFriday rendering.
type BlackFriday struct {
Smartypants bool
SmartypantsQuotesNBSP bool
AngledQuotes bool
Expand All @@ -109,7 +110,7 @@ type Blackfriday struct {
}

// NewBlackfriday creates a new Blackfriday filled with site config or some sane defaults.
func (c ContentSpec) NewBlackfriday() *Blackfriday {
func newBlackfriday(config map[string]interface{}) *BlackFriday {
defaultParam := map[string]interface{}{
"smartypants": true,
"angledQuotes": false,
Expand All @@ -130,13 +131,13 @@ func (c ContentSpec) NewBlackfriday() *Blackfriday {
siteConfig[k] = v
}

if c.blackfriday != nil {
for k, v := range c.blackfriday {
if config != nil {
for k, v := range config {
siteConfig[k] = v
}
}

combinedConfig := &Blackfriday{}
combinedConfig := &BlackFriday{}
if err := mapstructure.Decode(siteConfig, combinedConfig); err != nil {
jww.FATAL.Printf("Failed to get site rendering config\n%s", err.Error())
}
Expand Down Expand Up @@ -434,7 +435,7 @@ type RenderingContext struct {
PageFmt string
DocumentID string
DocumentName string
Config *Blackfriday
Config *BlackFriday
RenderTOC bool
Cfg config.Provider
}
Expand Down
6 changes: 3 additions & 3 deletions helpers/content_renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

// Renders a codeblock using Blackfriday
func (c ContentSpec) render(input string) string {
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
render := c.getHTMLRenderer(0, ctx)

buf := &bytes.Buffer{}
Expand All @@ -34,7 +34,7 @@ func (c ContentSpec) render(input string) string {

// Renders a codeblock using Mmark
func (c ContentSpec) renderWithMmark(input string) string {
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
render := c.getMmarkHTMLRenderer(0, ctx)

buf := &bytes.Buffer{}
Expand Down Expand Up @@ -128,7 +128,7 @@ END`, true, `<ul class="task-list">
<p>END</p>
`},
} {
blackFridayConfig := c.NewBlackfriday()
blackFridayConfig := c.BlackFriday
blackFridayConfig.TaskLists = this.taskListEnabled
ctx := &RenderingContext{Content: []byte(this.markdown), PageFmt: "markdown", Config: blackFridayConfig}

Expand Down
22 changes: 11 additions & 11 deletions helpers/content_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func TestTruncateWordsByRune(t *testing.T) {

func TestGetHTMLRendererFlags(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
renderer := c.getHTMLRenderer(blackfriday.HTML_USE_XHTML, ctx)
flags := renderer.GetFlags()
if flags&blackfriday.HTML_USE_XHTML != blackfriday.HTML_USE_XHTML {
Expand All @@ -186,7 +186,7 @@ func TestGetHTMLRendererAllFlags(t *testing.T) {
{blackfriday.HTML_SMARTYPANTS_LATEX_DASHES},
}
defaultFlags := blackfriday.HTML_USE_XHTML
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.Config.AngledQuotes = true
ctx.Config.Fractions = true
ctx.Config.HrefTargetBlank = true
Expand All @@ -209,7 +209,7 @@ func TestGetHTMLRendererAllFlags(t *testing.T) {

func TestGetHTMLRendererAnchors(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.DocumentID = "testid"
ctx.Config.PlainIDAnchors = false

Expand All @@ -233,7 +233,7 @@ func TestGetHTMLRendererAnchors(t *testing.T) {

func TestGetMmarkHTMLRenderer(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.DocumentID = "testid"
ctx.Config.PlainIDAnchors = false
actualRenderer := c.getMmarkHTMLRenderer(0, ctx)
Expand All @@ -257,7 +257,7 @@ func TestGetMmarkHTMLRenderer(t *testing.T) {

func TestGetMarkdownExtensionsMasksAreRemovedFromExtensions(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.Config.Extensions = []string{"headerId"}
ctx.Config.ExtensionsMask = []string{"noIntraEmphasis"}

Expand All @@ -272,7 +272,7 @@ func TestGetMarkdownExtensionsByDefaultAllExtensionsAreEnabled(t *testing.T) {
testFlag int
}
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.Config.Extensions = []string{""}
ctx.Config.ExtensionsMask = []string{""}
allExtensions := []data{
Expand Down Expand Up @@ -304,7 +304,7 @@ func TestGetMarkdownExtensionsByDefaultAllExtensionsAreEnabled(t *testing.T) {

func TestGetMarkdownExtensionsAddingFlagsThroughRenderingContext(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.Config.Extensions = []string{"definitionLists"}
ctx.Config.ExtensionsMask = []string{""}

Expand All @@ -316,7 +316,7 @@ func TestGetMarkdownExtensionsAddingFlagsThroughRenderingContext(t *testing.T) {

func TestGetMarkdownRenderer(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.Content = []byte("testContent")
actualRenderedMarkdown := c.markdownRender(ctx)
expectedRenderedMarkdown := []byte("<p>testContent</p>\n")
Expand All @@ -327,7 +327,7 @@ func TestGetMarkdownRenderer(t *testing.T) {

func TestGetMarkdownRendererWithTOC(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{RenderTOC: true, Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{RenderTOC: true, Cfg: c.cfg, Config: c.BlackFriday}
ctx.Content = []byte("testContent")
actualRenderedMarkdown := c.markdownRender(ctx)
expectedRenderedMarkdown := []byte("<nav>\n</nav>\n\n<p>testContent</p>\n")
Expand All @@ -342,7 +342,7 @@ func TestGetMmarkExtensions(t *testing.T) {
testFlag int
}
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.Config.Extensions = []string{"tables"}
ctx.Config.ExtensionsMask = []string{""}
allExtensions := []data{
Expand Down Expand Up @@ -371,7 +371,7 @@ func TestGetMmarkExtensions(t *testing.T) {

func TestMmarkRender(t *testing.T) {
c := newTestContentSpec()
ctx := &RenderingContext{Cfg: c.cfg, Config: c.NewBlackfriday()}
ctx := &RenderingContext{Cfg: c.cfg, Config: c.BlackFriday}
ctx.Content = []byte("testContent")
actualRenderedMarkdown := c.mmarkRender(ctx)
expectedRenderedMarkdown := []byte("<p>testContent</p>\n")
Expand Down
2 changes: 1 addition & 1 deletion hugolib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func loadDefaultSettingsFor(v *viper.Viper) error {
v.SetDefault("paginate", 10)
v.SetDefault("paginatePath", "page")
v.SetDefault("summaryLength", 70)
v.SetDefault("blackfriday", c.NewBlackfriday())
v.SetDefault("blackfriday", c.BlackFriday)
v.SetDefault("rSSUri", "index.xml")
v.SetDefault("rssLimit", -1)
v.SetDefault("sectionPagesMenu", "")
Expand Down
18 changes: 10 additions & 8 deletions hugolib/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ type Page struct {
plainWords []string

// rendering configuration
renderingConfig *helpers.Blackfriday
renderingConfig *helpers.BlackFriday

// menus
pageMenus PageMenus
Expand Down Expand Up @@ -700,18 +700,20 @@ func (p *Page) renderContent(content []byte) []byte {
Config: p.getRenderingConfig()})
}

func (p *Page) getRenderingConfig() *helpers.Blackfriday {
func (p *Page) getRenderingConfig() *helpers.BlackFriday {
p.renderingConfigInit.Do(func() {
p.renderingConfig = p.s.ContentSpec.NewBlackfriday()

if p.Language() == nil {
panic(fmt.Sprintf("nil language for %s with source lang %s", p.BaseFileName(), p.lang))
}

bfParam := p.GetParam("blackfriday")
if bfParam == nil {
p.renderingConfig = p.s.ContentSpec.BlackFriday
return
}
// Create a copy so we can modify it.
bf := *p.s.ContentSpec.BlackFriday
p.renderingConfig = &bf

if p.Language() == nil {
panic(fmt.Sprintf("nil language for %s with source lang %s", p.BaseFileName(), p.lang))
}

pageParam := cast.ToStringMap(bfParam)
if err := mapstructure.Decode(pageParam, &p.renderingConfig); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion tpl/transform/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (ns *Namespace) Markdownify(s interface{}) (template.HTML, error) {
Cfg: ns.deps.Cfg,
Content: []byte(ss),
PageFmt: "markdown",
Config: ns.deps.ContentSpec.NewBlackfriday(),
Config: ns.deps.ContentSpec.BlackFriday,
},
)

Expand Down

0 comments on commit db4b7a5

Please sign in to comment.