Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pre and post fields for overriding ToC heading #8643

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/content/en/getting-started/configuration-markup.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ endLevel
ordered
: Whether or not to generate an ordered list instead of an unordered list.

pre
: HTML to immediately precede the outer list element. Default value is `<nav id="TableOfContents">`.

post
: HTML to immediately follow the outer list element. Default value is `</nav>`.


## Markdown Render Hooks

Expand Down
2 changes: 2 additions & 0 deletions hugolib/page__per_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err
cfg.TableOfContents.StartLevel,
cfg.TableOfContents.EndLevel,
cfg.TableOfContents.Ordered,
&cfg.TableOfContents.Pre,
&cfg.TableOfContents.Post,
),
)
} else {
Expand Down
2 changes: 1 addition & 1 deletion markup/goldmark/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ description

toc, ok := b.(converter.TableOfContentsProvider)
c.Assert(ok, qt.Equals, true)
tocHTML := toc.TableOfContents().ToHTML(1, 2, false)
tocHTML := toc.TableOfContents().ToHTML(1, 2, false, nil, nil)
c.Assert(tocHTML, qt.Contains, "TableOfContents")
}

Expand Down
6 changes: 3 additions & 3 deletions markup/goldmark/toc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ And then some.
c.Assert(err, qt.IsNil)
b, err := conv.Convert(converter.RenderContext{Src: []byte(content), RenderTOC: true})
c.Assert(err, qt.IsNil)
got := b.(converter.TableOfContentsProvider).TableOfContents().ToHTML(2, 3, false)
got := b.(converter.TableOfContentsProvider).TableOfContents().ToHTML(2, 3, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#first-h2---now-with-typography">First h2&mdash;now with typography!</a>
Expand Down Expand Up @@ -110,7 +110,7 @@ func TestEscapeToc(t *testing.T) {
// content := ""
b, err := safeConv.Convert(converter.RenderContext{Src: []byte(content), RenderTOC: true})
c.Assert(err, qt.IsNil)
got := b.(converter.TableOfContentsProvider).TableOfContents().ToHTML(1, 2, false)
got := b.(converter.TableOfContentsProvider).TableOfContents().ToHTML(1, 2, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#a--b--c--d">A &lt; B &amp; C &gt; D</a></li>
Expand All @@ -122,7 +122,7 @@ func TestEscapeToc(t *testing.T) {

b, err = unsafeConv.Convert(converter.RenderContext{Src: []byte(content), RenderTOC: true})
c.Assert(err, qt.IsNil)
got = b.(converter.TableOfContentsProvider).TableOfContents().ToHTML(1, 2, false)
got = b.(converter.TableOfContentsProvider).TableOfContents().ToHTML(1, 2, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#a--b--c--d">A &lt; B &amp; C &gt; D</a></li>
Expand Down
28 changes: 23 additions & 5 deletions markup/tableofcontents/tableofcontents.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ func (toc *Root) AddAt(h Heading, row, level int) {
}

// ToHTML renders the ToC as HTML.
func (toc Root) ToHTML(startLevel, stopLevel int, ordered bool) string {
func (toc Root) ToHTML(startLevel, stopLevel int, ordered bool, pre *string, post *string) string {
b := &tocBuilder{
s: strings.Builder{},
h: toc.Headings,
startLevel: startLevel,
stopLevel: stopLevel,
ordered: ordered,
pre: pre,
post: post,
}
b.Build()
return b.s.String()
Expand All @@ -81,16 +83,26 @@ type tocBuilder struct {
startLevel int
stopLevel int
ordered bool
pre *string
post *string
}

func (b *tocBuilder) Build() {
b.writeNav(b.h)
}

func (b *tocBuilder) writeNav(h Headings) {
b.s.WriteString("<nav id=\"TableOfContents\">")
b.writeHeadings(1, 0, b.h)
b.s.WriteString("</nav>")
func (b *tocBuilder) writeNav(h Headers) {
if b.pre != nil {
b.s.WriteString(*b.pre)
} else {
b.s.WriteString("<nav id=\"TableOfContents\">")
}
b.writeHeaders(1, 0, b.h)
if b.post != nil {
b.s.WriteString(*b.post)
} else {
b.s.WriteString("</nav>")
}
}

func (b *tocBuilder) writeHeadings(level, indent int, h Headings) {
Expand Down Expand Up @@ -154,6 +166,8 @@ var DefaultConfig = Config{
StartLevel: 2,
EndLevel: 3,
Ordered: false,
Pre: "<nav id=\"TableOfContents\">",
Post: "</nav>",
}

type Config struct {
Expand All @@ -167,4 +181,8 @@ type Config struct {

// Whether to produce a ordered list or not.
Ordered bool

// Override default behavior for ToC navigation heading.
Pre string
Post string
}
50 changes: 42 additions & 8 deletions markup/tableofcontents/tableofcontents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestToc(t *testing.T) {
toc.AddAt(Heading{Text: "1-H3-1", ID: "1-h2-2"}, 0, 2)
toc.AddAt(Heading{Text: "Heading 2", ID: "h1-2"}, 1, 0)

got := toc.ToHTML(1, -1, false)
got := toc.ToHTML(1, -1, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#h1-1">Heading 1</a>
Expand All @@ -47,15 +47,15 @@ func TestToc(t *testing.T) {
</ul>
</nav>`, qt.Commentf(got))

got = toc.ToHTML(1, 1, false)
got = toc.ToHTML(1, 1, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#h1-1">Heading 1</a></li>
<li><a href="#h1-2">Heading 2</a></li>
</ul>
</nav>`, qt.Commentf(got))

got = toc.ToHTML(1, 2, false)
got = toc.ToHTML(1, 2, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#h1-1">Heading 1</a>
Expand All @@ -68,15 +68,15 @@ func TestToc(t *testing.T) {
</ul>
</nav>`, qt.Commentf(got))

got = toc.ToHTML(2, 2, false)
got = toc.ToHTML(2, 2, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#1-h2-1">1-H2-1</a></li>
<li><a href="#1-h2-2">1-H2-2</a></li>
</ul>
</nav>`, qt.Commentf(got))

got = toc.ToHTML(1, -1, true)
got = toc.ToHTML(1, -1, true, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ol>
<li><a href="#h1-1">Heading 1</a>
Expand All @@ -94,6 +94,40 @@ func TestToc(t *testing.T) {
</nav>`, qt.Commentf(got))
}

func TestPrePostToc(t *testing.T) {
c := qt.New(t)

toc := &Root{}

pre := "<nav id=\"TableOfContents\"><h1>Woo</h1>"
post := "</nav>"
empty := ""

toc.AddAt(Header{Text: "Header 1", ID: "h1-1"}, 0, 0)

got := toc.ToHTML(1, -1, false, &pre, &post)
c.Assert(got, qt.Equals, `<nav id="TableOfContents"><h1>Woo</h1>
<ul>
<li><a href="#h1-1">Header 1</a></li>
</ul>
</nav>`, qt.Commentf(got))

got = toc.ToHTML(1, -1, false, &pre, &empty)
c.Assert(got, qt.Equals, `<nav id="TableOfContents"><h1>Woo</h1>
<ul>
<li><a href="#h1-1">Header 1</a></li>
</ul>
`, qt.Commentf(got))

got = toc.ToHTML(1, -1, false, &empty, &post)
c.Assert(got, qt.Equals, `
<ul>
<li><a href="#h1-1">Header 1</a></li>
</ul>
</nav>`, qt.Commentf(got))

}

func TestTocMissingParent(t *testing.T) {
c := qt.New(t)

Expand All @@ -103,7 +137,7 @@ func TestTocMissingParent(t *testing.T) {
toc.AddAt(Heading{Text: "H3", ID: "h3"}, 1, 2)
toc.AddAt(Heading{Text: "H3", ID: "h3"}, 1, 2)

got := toc.ToHTML(1, -1, false)
got := toc.ToHTML(1, -1, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li>
Expand All @@ -124,15 +158,15 @@ func TestTocMissingParent(t *testing.T) {
</ul>
</nav>`, qt.Commentf(got))

got = toc.ToHTML(3, 3, false)
got = toc.ToHTML(3, 3, false, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul>
<li><a href="#h3">H3</a></li>
<li><a href="#h3">H3</a></li>
</ul>
</nav>`, qt.Commentf(got))

got = toc.ToHTML(1, -1, true)
got = toc.ToHTML(1, -1, true, nil, nil)
c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ol>
<li>
Expand Down