diff --git a/helpers/content.go b/helpers/content.go index 3ac91b360..f60349055 100644 --- a/helpers/content.go +++ b/helpers/content.go @@ -23,10 +23,6 @@ import ( "os/exec" "unicode/utf8" - "fmt" - "strings" - "sync" - "github.com/miekg/mmark" "github.com/mitchellh/mapstructure" "github.com/russross/blackfriday" @@ -34,6 +30,9 @@ import ( bp "github.com/spf13/hugo/bufferpool" jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" + + "strings" + "sync" ) // SummaryLength is the length of the summary that Hugo extracts from a content. @@ -168,11 +167,11 @@ func getHTMLRenderer(defaultFlags int, ctx *RenderingContext) blackfriday.Render FootnoteReturnLinkContents: viper.GetString("FootnoteReturnLinkContents"), } - b := ctx.DocumentID != 0 + b := len(ctx.DocumentID) != 0 if b && !ctx.getConfig().PlainIDAnchors { - renderParameters.FootnoteAnchorPrefix = fmt.Sprintf("%d:%s", ctx.DocumentID, renderParameters.FootnoteAnchorPrefix) - renderParameters.HeaderIDSuffix = fmt.Sprintf(":%d", ctx.DocumentID) + renderParameters.FootnoteAnchorPrefix = ctx.DocumentID + ":" + renderParameters.FootnoteAnchorPrefix + renderParameters.HeaderIDSuffix = ":" + ctx.DocumentID } htmlFlags := defaultFlags @@ -259,10 +258,10 @@ func getMmarkHTMLRenderer(defaultFlags int, ctx *RenderingContext) mmark.Rendere FootnoteReturnLinkContents: viper.GetString("FootnoteReturnLinkContents"), } - b := ctx.DocumentID != 0 + b := len(ctx.DocumentID) != 0 if b && !ctx.getConfig().PlainIDAnchors { - renderParameters.FootnoteAnchorPrefix = fmt.Sprintf("%d:%s", ctx.DocumentID, renderParameters.FootnoteAnchorPrefix) + renderParameters.FootnoteAnchorPrefix = ctx.DocumentID + ":" + renderParameters.FootnoteAnchorPrefix // renderParameters.HeaderIDSuffix = ":" + ctx.DocumentId } @@ -344,7 +343,7 @@ func ExtractTOC(content []byte) (newcontent []byte, toc []byte) { type RenderingContext struct { Content []byte PageFmt string - DocumentID int + DocumentID string Config *Blackfriday FileResolver FileResolverFunc LinkResolver LinkResolverFunc diff --git a/helpers/content_test.go b/helpers/content_test.go index 347884f0a..a89b4992e 100644 --- a/helpers/content_test.go +++ b/helpers/content_test.go @@ -172,15 +172,15 @@ func TestGetHTMLRendererAllFlags(t *testing.T) { func TestGetHTMLRendererAnchors(t *testing.T) { ctx := &RenderingContext{} - ctx.DocumentID = 123 + ctx.DocumentID = "testid" ctx.Config = ctx.getConfig() ctx.Config.PlainIDAnchors = false actualRenderer := getHTMLRenderer(0, ctx) headerBuffer := &bytes.Buffer{} footnoteBuffer := &bytes.Buffer{} - expectedFootnoteHref := []byte("href=\"#fn:123:href\"") - expectedHeaderID := []byte("
\n") + expectedFootnoteHref := []byte("href=\"#fn:testid:href\"") + expectedHeaderID := []byte("\n") actualRenderer.Header(headerBuffer, func() bool { return true }, 1, "id") actualRenderer.FootnoteRef(footnoteBuffer, []byte("href"), 1) @@ -196,14 +196,14 @@ func TestGetHTMLRendererAnchors(t *testing.T) { func TestGetMmarkHTMLRenderer(t *testing.T) { ctx := &RenderingContext{} - ctx.DocumentID = 321 + ctx.DocumentID = "testid" ctx.Config = ctx.getConfig() ctx.Config.PlainIDAnchors = false actualRenderer := getMmarkHTMLRenderer(0, ctx) headerBuffer := &bytes.Buffer{} footnoteBuffer := &bytes.Buffer{} - expectedFootnoteHref := []byte("href=\"#fn:321:href\"") + expectedFootnoteHref := []byte("href=\"#fn:testid:href\"") expectedHeaderID := []byte("") actualRenderer.FootnoteRef(footnoteBuffer, []byte("href"), 1) diff --git a/hugolib/handler_test.go b/hugolib/handler_test.go index e48d26932..29b1161e4 100644 --- a/hugolib/handler_test.go +++ b/hugolib/handler_test.go @@ -25,8 +25,8 @@ import ( ) func TestDefaultHandler(t *testing.T) { - setUp() - defer tearDown() + viper.Reset() + defer viper.Reset() hugofs.InitMemFs() sources := []source.ByteSource{ @@ -63,14 +63,14 @@ func TestDefaultHandler(t *testing.T) { doc string expected string }{ - {filepath.FromSlash("sect/doc1.html"), "\n\nsome content
\n"}, + {filepath.FromSlash("sect/doc1.html"), "\n\nsome content
\n"}, {filepath.FromSlash("sect/doc2.html"), "more content"}, - {filepath.FromSlash("sect/doc3.html"), "\n\nsome content
\n"}, + {filepath.FromSlash("sect/doc3.html"), "\n\nsome content
\n"}, {filepath.FromSlash("sect/doc3/img1.png"), string([]byte("‰PNG ��� IHDR����������:~›U��� IDATWcø��ZMoñ����IEND®B`‚"))}, {filepath.FromSlash("sect/img2.gif"), string([]byte("GIF89a��€��ÿÿÿ���,�������D�;"))}, {filepath.FromSlash("sect/img2.spf"), string([]byte("****FAKE-FILETYPE****"))}, {filepath.FromSlash("doc7.html"), "doc7 content"}, - {filepath.FromSlash("sect/doc8.html"), "\n\nsome content
\n"}, + {filepath.FromSlash("sect/doc8.html"), "\n\nsome content
\n"}, } for _, test := range tests { diff --git a/hugolib/hugolib_test.go b/hugolib/hugolib_test.go deleted file mode 100644 index 8f17553df..000000000 --- a/hugolib/hugolib_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2016 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 hugolib - -import ( - "github.com/spf13/viper" -) - -var stableNodeIDProvider nodeIDProviderFunc = func(n *Node) int { - return 42 -} - -// common test setup. -func setUp() { - viper.Reset() - nodeIDProvider = stableNodeIDProvider -} - -// common test cleanup. -func tearDown() { - viper.Reset() - nodeIDProvider = defaultNodeIDProvider -} diff --git a/hugolib/node.go b/hugolib/node.go index dde1bd690..7e9ad7458 100644 --- a/hugolib/node.go +++ b/hugolib/node.go @@ -47,15 +47,6 @@ type Node struct { // but that would lead to massive changes; do it simple for now. var nodeIDCounter uint64 -type nodeIDProviderFunc func(n *Node) int - -var defaultNodeIDProvider nodeIDProviderFunc = func(n *Node) int { - n.idInit.Do(func() { n.id = nextNodeID() }) - return n.id -} - -var nodeIDProvider nodeIDProviderFunc = defaultNodeIDProvider - func nextNodeID() int { return int(atomic.AddUint64(&nodeIDCounter, 1)) } @@ -64,7 +55,8 @@ func nextNodeID() int { // This is unique for a given Hugo build, but must not be considered stable. // See UniqueID on Page for an identify that is stable for repeated builds. func (n *Node) ID() int { - return nodeIDProvider(n) + n.idInit.Do(func() { n.id = nextNodeID() }) + return n.id } func (n *Node) Now() time.Time { diff --git a/hugolib/node_test.go b/hugolib/node_test.go index a0d08ed07..5b83cc0ad 100644 --- a/hugolib/node_test.go +++ b/hugolib/node_test.go @@ -43,6 +43,14 @@ func TestNodeSimpleMethods(t *testing.T) { } func TestNodeID(t *testing.T) { + t.Parallel() + + n1 := &Node{} + n2 := &Node{} + + assert.True(t, n1.ID() > 0) + assert.Equal(t, n1.ID(), n1.ID()) + assert.True(t, n2.ID() > n1.ID()) var wg sync.WaitGroup @@ -50,13 +58,8 @@ func TestNodeID(t *testing.T) { wg.Add(1) go func(j int) { for k := 0; k < 10; k++ { - n1 := &Node{} - n2 := &Node{} - - assert.True(t, n1.ID() > 0) - assert.Equal(t, n1.ID(), n1.ID()) - assert.True(t, n2.ID() > n1.ID()) - + n := &Node{} + assert.True(t, n.ID() > 0) } wg.Done() }(i) diff --git a/hugolib/page.go b/hugolib/page.go index 9a9deecc1..cff84737b 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -265,7 +265,7 @@ func (p *Page) renderBytes(content []byte) []byte { } return helpers.RenderBytes( &helpers.RenderingContext{Content: content, PageFmt: p.determineMarkupType(), - DocumentID: p.ID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) + DocumentID: p.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) } func (p *Page) renderContent(content []byte) []byte { @@ -280,7 +280,7 @@ func (p *Page) renderContent(content []byte) []byte { } } return helpers.RenderBytesWithTOC(&helpers.RenderingContext{Content: content, PageFmt: p.determineMarkupType(), - DocumentID: p.ID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) + DocumentID: p.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) } func (p *Page) getRenderingConfig() *helpers.Blackfriday { diff --git a/hugolib/page_test.go b/hugolib/page_test.go index 6e636261d..b492bab2d 100644 --- a/hugolib/page_test.go +++ b/hugolib/page_test.go @@ -605,17 +605,14 @@ func TestPageWithAdditionalExtension(t *testing.T) { } func TestTableOfContents(t *testing.T) { - setUp() - defer tearDown() - p, _ := NewPage("tocpage.md") _, err := p.ReadFrom(strings.NewReader(pageWithToC)) p.Convert() if err != nil { t.Fatalf("Unable to create a page with frontmatter and body content: %s", err) } - checkPageContent(t, p, "\n\nFor some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.
\n\nI have no idea, of course, how long it took me to reach the limit of the plain,\nbut at last I entered the foothills, following a pretty little canyon upward\ntoward the mountains. Beside me frolicked a laughing brooklet, hurrying upon\nits noisy way down to the silent sea. In its quieter pools I discovered many\nsmall fish, of four-or five-pound weight I should imagine. In appearance,\nexcept as to size and color, they were not unlike the whale of our own seas. As\nI watched them playing about I discovered, not only that they suckled their\nyoung, but that at intervals they rose to the surface to breathe as well as to\nfeed upon certain grasses and a strange, scarlet lichen which grew upon the\nrocks just above the water line.
\n\nI remember I felt an extraordinary persuasion that I was being played with,\nthat presently, when I was upon the very verge of safety, this mysterious\ndeath–as swift as the passage of light–would leap after me from the pit about\nthe cylinder and strike me down. ## BB
\n\n“You’re a great Granser,” he cried delightedly, “always making believe them little marks mean something.”
\n") - checkPageTOC(t, p, "") + checkPageContent(t, p, "\n\nFor some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.
\n\nI have no idea, of course, how long it took me to reach the limit of the plain,\nbut at last I entered the foothills, following a pretty little canyon upward\ntoward the mountains. Beside me frolicked a laughing brooklet, hurrying upon\nits noisy way down to the silent sea. In its quieter pools I discovered many\nsmall fish, of four-or five-pound weight I should imagine. In appearance,\nexcept as to size and color, they were not unlike the whale of our own seas. As\nI watched them playing about I discovered, not only that they suckled their\nyoung, but that at intervals they rose to the surface to breathe as well as to\nfeed upon certain grasses and a strange, scarlet lichen which grew upon the\nrocks just above the water line.
\n\nI remember I felt an extraordinary persuasion that I was being played with,\nthat presently, when I was upon the very verge of safety, this mysterious\ndeath–as swift as the passage of light–would leap after me from the pit about\nthe cylinder and strike me down. ## BB
\n\n“You’re a great Granser,” he cried delightedly, “always making believe them little marks mean something.”
\n") + checkPageTOC(t, p, "") } func TestPageWithMoreTag(t *testing.T) { diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index dfe26d4d7..876e9293f 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -235,7 +235,7 @@ func renderShortcode(sc shortcode, parent *ShortcodeWithPage, p *Page, t tpl.Tem if sc.doMarkup { newInner := helpers.RenderBytes(&helpers.RenderingContext{ Content: []byte(inner), PageFmt: p.determineMarkupType(), - DocumentID: p.ID(), Config: p.getRenderingConfig()}) + DocumentID: p.UniqueID(), Config: p.getRenderingConfig()}) // If the type is “unknown” or “markdown”, we assume the markdown // generation has been performed. Given the input: `a line`, markdown diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go index 68c7f9220..ab764b845 100644 --- a/hugolib/shortcode_test.go +++ b/hugolib/shortcode_test.go @@ -168,9 +168,6 @@ func TestInnerSC(t *testing.T) { } func TestInnerSCWithMarkdown(t *testing.T) { - setUp() - defer tearDown() - tem := tpl.New() tem.AddInternalShortcode("inside.html", `link and text
\nlink and text
\nlink and text
\nlink and text
\ntext
\n\nmore text
\n"}, + {pageWithMd, templateContent, "\n\ntext
\n\nmore text
\n"}, {simplePageRFC3339Date, templateDate, "2013-05-17 16:59:30 +0000 UTC"}, } @@ -559,8 +556,8 @@ func doTestSectionNaming(t *testing.T, canonify, uglify, pluralize bool) { } func TestSkipRender(t *testing.T) { - setUp() - defer tearDown() + viper.Reset() + defer viper.Reset() hugofs.InitMemFs() sources := []source.ByteSource{ @@ -596,14 +593,14 @@ func TestSkipRender(t *testing.T) { doc string expected string }{ - {filepath.FromSlash("sect/doc1.html"), "\n\nsome content
\n"}, + {filepath.FromSlash("sect/doc1.html"), "\n\nsome content
\n"}, {filepath.FromSlash("sect/doc2.html"), "more content"}, - {filepath.FromSlash("sect/doc3.html"), "\n\nsome content
\n"}, - {filepath.FromSlash("sect/doc4.html"), "\n\nsome content
\n"}, + {filepath.FromSlash("sect/doc3.html"), "\n\nsome content
\n"}, + {filepath.FromSlash("sect/doc4.html"), "\n\nsome content
\n"}, {filepath.FromSlash("sect/doc5.html"), "body5"}, {filepath.FromSlash("sect/doc6.html"), "body5"}, {filepath.FromSlash("doc7.html"), "doc7 content"}, - {filepath.FromSlash("sect/doc8.html"), "\n\nsome content
\n"}, + {filepath.FromSlash("sect/doc8.html"), "\n\nsome content
\n"}, } for _, test := range tests {