markup: Rename Header(s) to Heading(s) in ToC struct

Because that is what it is.
This commit is contained in:
Bjørn Erik Pedersen 2021-06-19 18:19:46 +02:00
parent b70a12ec45
commit a7e3da242f
No known key found for this signature in database
GPG key ID: 330E6E2BD4859D8F
5 changed files with 74 additions and 74 deletions

View file

@ -276,7 +276,7 @@ func parseTOC(doc *html.Node) tableofcontents.Root {
continue continue
} }
href := attr(c, "href")[1:] href := attr(c, "href")[1:]
toc.AddAt(tableofcontents.Header{ toc.AddAt(tableofcontents.Heading{
Text: nodeContent(c), Text: nodeContent(c),
ID: href, ID: href,
}, row, level) }, row, level)

View file

@ -340,42 +340,42 @@ testContent
toc, ok := r.(converter.TableOfContentsProvider) toc, ok := r.(converter.TableOfContentsProvider)
c.Assert(ok, qt.Equals, true) c.Assert(ok, qt.Equals, true)
expected := tableofcontents.Root{ expected := tableofcontents.Root{
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "", ID: "",
Text: "", Text: "",
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "_introduction", ID: "_introduction",
Text: "Introduction", Text: "Introduction",
Headers: nil, Headings: nil,
}, },
{ {
ID: "_section_1", ID: "_section_1",
Text: "Section 1", Text: "Section 1",
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "_section_1_1", ID: "_section_1_1",
Text: "Section 1.1", Text: "Section 1.1",
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "_section_1_1_1", ID: "_section_1_1_1",
Text: "Section 1.1.1", Text: "Section 1.1.1",
Headers: nil, Headings: nil,
}, },
}, },
}, },
{ {
ID: "_section_1_2", ID: "_section_1_2",
Text: "Section 1.2", Text: "Section 1.2",
Headers: nil, Headings: nil,
}, },
}, },
}, },
{ {
ID: "_section_2", ID: "_section_2",
Text: "Section 2", Text: "Section 2",
Headers: nil, Headings: nil,
}, },
}, },
}, },
@ -408,15 +408,15 @@ func TestTableOfContentsWithCode(t *testing.T) {
toc, ok := r.(converter.TableOfContentsProvider) toc, ok := r.(converter.TableOfContentsProvider)
c.Assert(ok, qt.Equals, true) c.Assert(ok, qt.Equals, true)
expected := tableofcontents.Root{ expected := tableofcontents.Root{
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "", ID: "",
Text: "", Text: "",
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "_some_code_in_the_title", ID: "_some_code_in_the_title",
Text: "Some <code>code</code> in the title", Text: "Some <code>code</code> in the title",
Headers: nil, Headings: nil,
}, },
}, },
}, },
@ -452,15 +452,15 @@ func TestTableOfContentsPreserveTOC(t *testing.T) {
toc, ok := r.(converter.TableOfContentsProvider) toc, ok := r.(converter.TableOfContentsProvider)
c.Assert(ok, qt.Equals, true) c.Assert(ok, qt.Equals, true)
expected := tableofcontents.Root{ expected := tableofcontents.Root{
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "", ID: "",
Text: "", Text: "",
Headers: tableofcontents.Headers{ Headings: tableofcontents.Headings{
{ {
ID: "some-title", ID: "some-title",
Text: "Some title", Text: "Some title",
Headers: nil, Headings: nil,
}, },
}, },
}, },

View file

@ -42,7 +42,7 @@ func (t *tocTransformer) Transform(n *ast.Document, reader text.Reader, pc parse
var ( var (
toc tableofcontents.Root toc tableofcontents.Root
header tableofcontents.Header tocHeading tableofcontents.Heading
level int level int
row = -1 row = -1
inHeading bool inHeading bool
@ -53,10 +53,10 @@ func (t *tocTransformer) Transform(n *ast.Document, reader text.Reader, pc parse
s := ast.WalkStatus(ast.WalkContinue) s := ast.WalkStatus(ast.WalkContinue)
if n.Kind() == ast.KindHeading { if n.Kind() == ast.KindHeading {
if inHeading && !entering { if inHeading && !entering {
header.Text = headingText.String() tocHeading.Text = headingText.String()
headingText.Reset() headingText.Reset()
toc.AddAt(header, row, level-1) toc.AddAt(tocHeading, row, level-1)
header = tableofcontents.Header{} tocHeading = tableofcontents.Heading{}
inHeading = false inHeading = false
return s, nil return s, nil
} }
@ -79,7 +79,7 @@ func (t *tocTransformer) Transform(n *ast.Document, reader text.Reader, pc parse
id, found := heading.AttributeString("id") id, found := heading.AttributeString("id")
if found { if found {
header.ID = string(id.([]byte)) tocHeading.ID = string(id.([]byte))
} }
case case
ast.KindCodeSpan, ast.KindCodeSpan,

View file

@ -17,55 +17,55 @@ import (
"strings" "strings"
) )
// Headers holds the top level (h1) headers. // Headings holds the top level headings.
type Headers []Header type Headings []Heading
// Header holds the data about a header and its children. // Heading holds the data about a heading and its children.
type Header struct { type Heading struct {
ID string ID string
Text string Text string
Headers Headers Headings Headings
} }
// IsZero is true when no ID or Text is set. // IsZero is true when no ID or Text is set.
func (h Header) IsZero() bool { func (h Heading) IsZero() bool {
return h.ID == "" && h.Text == "" return h.ID == "" && h.Text == ""
} }
// Root implements AddAt, which can be used to build the // Root implements AddAt, which can be used to build the
// data structure for the ToC. // data structure for the ToC.
type Root struct { type Root struct {
Headers Headers Headings Headings
} }
// AddAt adds the header into the given location. // AddAt adds the heading into the given location.
func (toc *Root) AddAt(h Header, row, level int) { func (toc *Root) AddAt(h Heading, row, level int) {
for i := len(toc.Headers); i <= row; i++ { for i := len(toc.Headings); i <= row; i++ {
toc.Headers = append(toc.Headers, Header{}) toc.Headings = append(toc.Headings, Heading{})
} }
if level == 0 { if level == 0 {
toc.Headers[row] = h toc.Headings[row] = h
return return
} }
header := &toc.Headers[row] heading := &toc.Headings[row]
for i := 1; i < level; i++ { for i := 1; i < level; i++ {
if len(header.Headers) == 0 { if len(heading.Headings) == 0 {
header.Headers = append(header.Headers, Header{}) heading.Headings = append(heading.Headings, Heading{})
} }
header = &header.Headers[len(header.Headers)-1] heading = &heading.Headings[len(heading.Headings)-1]
} }
header.Headers = append(header.Headers, h) heading.Headings = append(heading.Headings, h)
} }
// ToHTML renders the ToC as HTML. // 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) string {
b := &tocBuilder{ b := &tocBuilder{
s: strings.Builder{}, s: strings.Builder{},
h: toc.Headers, h: toc.Headings,
startLevel: startLevel, startLevel: startLevel,
stopLevel: stopLevel, stopLevel: stopLevel,
ordered: ordered, ordered: ordered,
@ -76,7 +76,7 @@ func (toc Root) ToHTML(startLevel, stopLevel int, ordered bool) string {
type tocBuilder struct { type tocBuilder struct {
s strings.Builder s strings.Builder
h Headers h Headings
startLevel int startLevel int
stopLevel int stopLevel int
@ -87,16 +87,16 @@ func (b *tocBuilder) Build() {
b.writeNav(b.h) b.writeNav(b.h)
} }
func (b *tocBuilder) writeNav(h Headers) { func (b *tocBuilder) writeNav(h Headings) {
b.s.WriteString("<nav id=\"TableOfContents\">") b.s.WriteString("<nav id=\"TableOfContents\">")
b.writeHeaders(1, 0, b.h) b.writeHeadings(1, 0, b.h)
b.s.WriteString("</nav>") b.s.WriteString("</nav>")
} }
func (b *tocBuilder) writeHeaders(level, indent int, h Headers) { func (b *tocBuilder) writeHeadings(level, indent int, h Headings) {
if level < b.startLevel { if level < b.startLevel {
for _, h := range h { for _, h := range h {
b.writeHeaders(level+1, indent, h.Headers) b.writeHeadings(level+1, indent, h.Headings)
} }
return return
} }
@ -118,7 +118,7 @@ func (b *tocBuilder) writeHeaders(level, indent int, h Headers) {
} }
for _, h := range h { for _, h := range h {
b.writeHeader(level+1, indent+2, h) b.writeHeading(level+1, indent+2, h)
} }
if hasChildren { if hasChildren {
@ -133,13 +133,13 @@ func (b *tocBuilder) writeHeaders(level, indent int, h Headers) {
} }
} }
func (b *tocBuilder) writeHeader(level, indent int, h Header) { func (b *tocBuilder) writeHeading(level, indent int, h Heading) {
b.indent(indent) b.indent(indent)
b.s.WriteString("<li>") b.s.WriteString("<li>")
if !h.IsZero() { if !h.IsZero() {
b.s.WriteString("<a href=\"#" + h.ID + "\">" + h.Text + "</a>") b.s.WriteString("<a href=\"#" + h.ID + "\">" + h.Text + "</a>")
} }
b.writeHeaders(level, indent, h.Headers) b.writeHeadings(level, indent, h.Headings)
b.s.WriteString("</li>\n") b.s.WriteString("</li>\n")
} }

View file

@ -24,16 +24,16 @@ func TestToc(t *testing.T) {
toc := &Root{} toc := &Root{}
toc.AddAt(Header{Text: "Header 1", ID: "h1-1"}, 0, 0) toc.AddAt(Heading{Text: "Heading 1", ID: "h1-1"}, 0, 0)
toc.AddAt(Header{Text: "1-H2-1", ID: "1-h2-1"}, 0, 1) toc.AddAt(Heading{Text: "1-H2-1", ID: "1-h2-1"}, 0, 1)
toc.AddAt(Header{Text: "1-H2-2", ID: "1-h2-2"}, 0, 1) toc.AddAt(Heading{Text: "1-H2-2", ID: "1-h2-2"}, 0, 1)
toc.AddAt(Header{Text: "1-H3-1", ID: "1-h2-2"}, 0, 2) toc.AddAt(Heading{Text: "1-H3-1", ID: "1-h2-2"}, 0, 2)
toc.AddAt(Header{Text: "Header 2", ID: "h1-2"}, 1, 0) toc.AddAt(Heading{Text: "Heading 2", ID: "h1-2"}, 1, 0)
got := toc.ToHTML(1, -1, false) got := toc.ToHTML(1, -1, false)
c.Assert(got, qt.Equals, `<nav id="TableOfContents"> c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul> <ul>
<li><a href="#h1-1">Header 1</a> <li><a href="#h1-1">Heading 1</a>
<ul> <ul>
<li><a href="#1-h2-1">1-H2-1</a></li> <li><a href="#1-h2-1">1-H2-1</a></li>
<li><a href="#1-h2-2">1-H2-2</a> <li><a href="#1-h2-2">1-H2-2</a>
@ -43,28 +43,28 @@ func TestToc(t *testing.T) {
</li> </li>
</ul> </ul>
</li> </li>
<li><a href="#h1-2">Header 2</a></li> <li><a href="#h1-2">Heading 2</a></li>
</ul> </ul>
</nav>`, qt.Commentf(got)) </nav>`, qt.Commentf(got))
got = toc.ToHTML(1, 1, false) got = toc.ToHTML(1, 1, false)
c.Assert(got, qt.Equals, `<nav id="TableOfContents"> c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul> <ul>
<li><a href="#h1-1">Header 1</a></li> <li><a href="#h1-1">Heading 1</a></li>
<li><a href="#h1-2">Header 2</a></li> <li><a href="#h1-2">Heading 2</a></li>
</ul> </ul>
</nav>`, qt.Commentf(got)) </nav>`, qt.Commentf(got))
got = toc.ToHTML(1, 2, false) got = toc.ToHTML(1, 2, false)
c.Assert(got, qt.Equals, `<nav id="TableOfContents"> c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ul> <ul>
<li><a href="#h1-1">Header 1</a> <li><a href="#h1-1">Heading 1</a>
<ul> <ul>
<li><a href="#1-h2-1">1-H2-1</a></li> <li><a href="#1-h2-1">1-H2-1</a></li>
<li><a href="#1-h2-2">1-H2-2</a></li> <li><a href="#1-h2-2">1-H2-2</a></li>
</ul> </ul>
</li> </li>
<li><a href="#h1-2">Header 2</a></li> <li><a href="#h1-2">Heading 2</a></li>
</ul> </ul>
</nav>`, qt.Commentf(got)) </nav>`, qt.Commentf(got))
@ -79,7 +79,7 @@ func TestToc(t *testing.T) {
got = toc.ToHTML(1, -1, true) got = toc.ToHTML(1, -1, true)
c.Assert(got, qt.Equals, `<nav id="TableOfContents"> c.Assert(got, qt.Equals, `<nav id="TableOfContents">
<ol> <ol>
<li><a href="#h1-1">Header 1</a> <li><a href="#h1-1">Heading 1</a>
<ol> <ol>
<li><a href="#1-h2-1">1-H2-1</a></li> <li><a href="#1-h2-1">1-H2-1</a></li>
<li><a href="#1-h2-2">1-H2-2</a> <li><a href="#1-h2-2">1-H2-2</a>
@ -89,7 +89,7 @@ func TestToc(t *testing.T) {
</li> </li>
</ol> </ol>
</li> </li>
<li><a href="#h1-2">Header 2</a></li> <li><a href="#h1-2">Heading 2</a></li>
</ol> </ol>
</nav>`, qt.Commentf(got)) </nav>`, qt.Commentf(got))
} }
@ -99,9 +99,9 @@ func TestTocMissingParent(t *testing.T) {
toc := &Root{} toc := &Root{}
toc.AddAt(Header{Text: "H2", ID: "h2"}, 0, 1) toc.AddAt(Heading{Text: "H2", ID: "h2"}, 0, 1)
toc.AddAt(Header{Text: "H3", ID: "h3"}, 1, 2) toc.AddAt(Heading{Text: "H3", ID: "h3"}, 1, 2)
toc.AddAt(Header{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)
c.Assert(got, qt.Equals, `<nav id="TableOfContents"> c.Assert(got, qt.Equals, `<nav id="TableOfContents">