Add workaround for TableOfContents h1/h2 hierarchy issue #34
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add workaround for TableOfContents h1/h2 hierarchy issue
First, some background is necessary. As noted at the hugo documentation site,
https://gohugo.io/content-management/toc/, the table of contents module does
not currently let you change which heading levels should be rendered. This
creates a slight issue as follows.
Let's say you have a markdown document and you use this template. The
<h1>
tag is the title for each page, as set in the frontmatter. In markdown, that's
also the single hash/octothorpe/number sign marker for a top level heading.
By convention, it's typical to have a single
<h1>
element of the same font sizeon each page. Naturally, the ideal behavior is to then make all elements
<h2>
or lower. As noted by Mozilla, this is even a loosely defined convention:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements
Now, this is all well and good, until you read more into the issue above.
Essentially, Hugo generates the table of contents starting with
<h1>
elementsfrom the markdown output. If you don't have an
<h1>
element, Hugo will renderthe level associated with
<h1>
anyway and then indent<h1>
all subsequent levelsbased on this non-existent hierarchy. You can make the table of contents look
better by adding an
<h1>
element to the page, but this creates the conflict asdescribed above. You end up with two
<h1>
elements, which is antithetical to thespec, only to create a correct looking table of contents. And one again, those
two
<h1>
elements will make your page look bad because they have the same fontsize.
This is easily shown graphically. Screenshots can be found at the bottom of this PR.
A discussion exists on gohugoio/hugo talking about the heading level issue
in the table of contents system, here:
gohugoio/hugo#1778
This is a slightly maddening issue, because it's closed, but in it many people
have identified this issue as a problem and patched it with one way or another.
My commit introduces the patch from @HenrySkup, which is located here:
gohugoio/hugo#1778 (comment)
This commit specifically will parse and remove empty headings in the generated
output from the
TableOfContents
module, thus creating the proper indentationlevel as expected, and not requiring breaking the html spec, nor making pages
look nasty. It's backwards compatible with existing markdown written under the
broken assumption, by way of rendering correctly with existing
<h1>
elements,while simultaneously fixing any table of contents generated with only
<h2>
andsubsequent heading levels by indenting them the correct amount each time.
This was tested against Hugo v0.58.0.
Screenshots of behavior without and with the patch, respectively
The first two images following this sentence are before
and after the patch with only
<h2>
elements in the markdown body and a title in thefrontmatter at the top. Note the spacing between the leftmost box border and the elements
generated by the
{{ .TableOfContents }}
directive in both images, and you'll spot the 1/2indentation difference.
The next two images depict the same before/after, this time with
<h1>
elements inthe body. This is used to demonstrate the backwards compatibility in this patch.
Finally, what it looks like with the patch using only
<h2>
elements withmore detail. Again, you can compare how indented the first level headings are between
the
<h2>
elements used in the markdown body with the above images, showing thatthe correct indentation level is present without a parent
<h1>
tag in the markdown body.As you can see, this is something that's very hard to describe the nuanced behavior of.
Naturally, the table of contents as created before this will look different than after, but
that's just because most of them will be made with only
<h2>
elements in the markdownbody, but they at least look correct and space evenly from then on.
This is trivially tested with markdown documents like so run through the toc generator: