Use Node.ID for anchor ID - hugo - [fork] hugo port for 9front
HTML git clone git@git.drkhsh.at/hugo.git
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
DIR commit cd558958a0c0ecd06f7560a38e27334fe983e0de
DIR parent 5ef52294f90c51697bd3f918b3c3ed83baff657a
HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date: Mon, 11 Apr 2016 13:17:25 +0200
Use Node.ID for anchor ID
Fixes #2057
Diffstat:
M helpers/content.go | 19 ++++++++++---------
M helpers/content_test.go | 10 +++++-----
M hugolib/handler_test.go | 10 +++++-----
A hugolib/hugolib_test.go | 34 +++++++++++++++++++++++++++++++
M hugolib/node.go | 12 ++++++++++--
M hugolib/node_test.go | 17 +++++++----------
M hugolib/page.go | 4 ++--
M hugolib/page_test.go | 7 +++++--
M hugolib/shortcode.go | 2 +-
M hugolib/shortcode_test.go | 9 +++++++--
M hugolib/site_test.go | 17 ++++++++++-------
11 files changed, 96 insertions(+), 45 deletions(-)
---
DIR diff --git a/helpers/content.go b/helpers/content.go
@@ -23,6 +23,10 @@ import (
"os/exec"
"unicode/utf8"
+ "fmt"
+ "strings"
+ "sync"
+
"github.com/miekg/mmark"
"github.com/mitchellh/mapstructure"
"github.com/russross/blackfriday"
@@ -30,9 +34,6 @@ 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.
@@ -167,11 +168,11 @@ func getHTMLRenderer(defaultFlags int, ctx *RenderingContext) blackfriday.Render
FootnoteReturnLinkContents: viper.GetString("FootnoteReturnLinkContents"),
}
- b := len(ctx.DocumentID) != 0
+ b := ctx.DocumentID != 0
if b && !ctx.getConfig().PlainIDAnchors {
- renderParameters.FootnoteAnchorPrefix = ctx.DocumentID + ":" + renderParameters.FootnoteAnchorPrefix
- renderParameters.HeaderIDSuffix = ":" + ctx.DocumentID
+ renderParameters.FootnoteAnchorPrefix = fmt.Sprintf("%d:%s", ctx.DocumentID, renderParameters.FootnoteAnchorPrefix)
+ renderParameters.HeaderIDSuffix = fmt.Sprintf(":%d", ctx.DocumentID)
}
htmlFlags := defaultFlags
@@ -258,10 +259,10 @@ func getMmarkHTMLRenderer(defaultFlags int, ctx *RenderingContext) mmark.Rendere
FootnoteReturnLinkContents: viper.GetString("FootnoteReturnLinkContents"),
}
- b := len(ctx.DocumentID) != 0
+ b := ctx.DocumentID != 0
if b && !ctx.getConfig().PlainIDAnchors {
- renderParameters.FootnoteAnchorPrefix = ctx.DocumentID + ":" + renderParameters.FootnoteAnchorPrefix
+ renderParameters.FootnoteAnchorPrefix = fmt.Sprintf("%d:%s", ctx.DocumentID, renderParameters.FootnoteAnchorPrefix)
// renderParameters.HeaderIDSuffix = ":" + ctx.DocumentId
}
@@ -343,7 +344,7 @@ func ExtractTOC(content []byte) (newcontent []byte, toc []byte) {
type RenderingContext struct {
Content []byte
PageFmt string
- DocumentID string
+ DocumentID int
Config *Blackfriday
FileResolver FileResolverFunc
LinkResolver LinkResolverFunc
DIR diff --git 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 = "testid"
+ ctx.DocumentID = 123
ctx.Config = ctx.getConfig()
ctx.Config.PlainIDAnchors = false
actualRenderer := getHTMLRenderer(0, ctx)
headerBuffer := &bytes.Buffer{}
footnoteBuffer := &bytes.Buffer{}
- expectedFootnoteHref := []byte("href=\"#fn:testid:href\"")
- expectedHeaderID := []byte("<h1 id=\"id:testid\"></h1>\n")
+ expectedFootnoteHref := []byte("href=\"#fn:123:href\"")
+ expectedHeaderID := []byte("<h1 id=\"id:123\"></h1>\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 = "testid"
+ ctx.DocumentID = 321
ctx.Config = ctx.getConfig()
ctx.Config.PlainIDAnchors = false
actualRenderer := getMmarkHTMLRenderer(0, ctx)
headerBuffer := &bytes.Buffer{}
footnoteBuffer := &bytes.Buffer{}
- expectedFootnoteHref := []byte("href=\"#fn:testid:href\"")
+ expectedFootnoteHref := []byte("href=\"#fn:321:href\"")
expectedHeaderID := []byte("<h1 id=\"id\"></h1>")
actualRenderer.FootnoteRef(footnoteBuffer, []byte("href"), 1)
DIR diff --git a/hugolib/handler_test.go b/hugolib/handler_test.go
@@ -25,8 +25,8 @@ import (
)
func TestDefaultHandler(t *testing.T) {
- viper.Reset()
- defer viper.Reset()
+ setUp()
+ defer tearDown()
hugofs.InitMemFs()
sources := []source.ByteSource{
@@ -63,14 +63,14 @@ func TestDefaultHandler(t *testing.T) {
doc string
expected string
}{
- {filepath.FromSlash("sect/doc1.html"), "\n\n<h1 id=\"title:5d74edbb89ef198cd37882b687940cda\">title</h1>\n\n<p>some <em>content</em></p>\n"},
+ {filepath.FromSlash("sect/doc1.html"), "\n\n<h1 id=\"title:42\">title</h1>\n\n<p>some <em>content</em></p>\n"},
{filepath.FromSlash("sect/doc2.html"), "<!doctype html><html><body>more content</body></html>"},
- {filepath.FromSlash("sect/doc3.html"), "\n\n<h1 id=\"doc3:28c75a9e2162b8eccda73a1ab9ce80b4\">doc3</h1>\n\n<p><em>some</em> content</p>\n"},
+ {filepath.FromSlash("sect/doc3.html"), "\n\n<h1 id=\"doc3:42\">doc3</h1>\n\n<p><em>some</em> content</p>\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"), "<html><body>doc7 content</body></html>"},
- {filepath.FromSlash("sect/doc8.html"), "\n\n<h1 id=\"title:0ae308ad73e2f37bd09874105281b5d8\">title</h1>\n\n<p>some <em>content</em></p>\n"},
+ {filepath.FromSlash("sect/doc8.html"), "\n\n<h1 id=\"title:42\">title</h1>\n\n<p>some <em>content</em></p>\n"},
}
for _, test := range tests {
DIR diff --git a/hugolib/hugolib_test.go b/hugolib/hugolib_test.go
@@ -0,0 +1,34 @@
+// 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
+}
DIR diff --git a/hugolib/node.go b/hugolib/node.go
@@ -47,6 +47,15 @@ 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))
}
@@ -55,8 +64,7 @@ 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 {
- n.idInit.Do(func() { n.id = nextNodeID() })
- return n.id
+ return nodeIDProvider(n)
}
func (n *Node) Now() time.Time {
DIR diff --git a/hugolib/node_test.go b/hugolib/node_test.go
@@ -43,14 +43,6 @@ 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
@@ -58,8 +50,13 @@ func TestNodeID(t *testing.T) {
wg.Add(1)
go func(j int) {
for k := 0; k < 10; k++ {
- n := &Node{}
- assert.True(t, n.ID() > 0)
+ n1 := &Node{}
+ n2 := &Node{}
+
+ assert.True(t, n1.ID() > 0)
+ assert.Equal(t, n1.ID(), n1.ID())
+ assert.True(t, n2.ID() > n1.ID())
+
}
wg.Done()
}(i)
DIR diff --git 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.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn})
+ DocumentID: p.ID(), 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.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn})
+ DocumentID: p.ID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn})
}
func (p *Page) getRenderingConfig() *helpers.Blackfriday {
DIR diff --git a/hugolib/page_test.go b/hugolib/page_test.go
@@ -605,14 +605,17 @@ 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)
}
drkhsh.at:70 /scm/hugo/commit/cd558958a0c0ecd06f7560a38e27334fe983e0de.gph:288: line too long