TOC: Edit the HTML

I need to modify the TableOfContents HTML that is generated by the Markdownify tool. Yes, I am able to css the ul/li portions as need be.

But, I am trying to use it with Bootstrap - which requires me to add a few css classes onto the UL element to properly track navigation within the page.

There is a Feature Request asking for the TableOfContents to be put into a collection: that would work too as I could iterate over the collection:

I was able to hack this:

{{ with .TableOfContents }}
  {{ replace . "id=\"TableOfContents\"" "id='TableOfContents' class='nav nav-stacked'" | safeHtml }}
{{ end }}

And using CSS3 assignments of what is parent > first child, starting from #TableOfContents, I can hack it together. But, it just seems like a lot more work for a non-designer guy like me. :slight_smile:

But it doesn’t help organizing the embedded ul/li/ul/li (and the first one is empty, keeping H1 via the title and all).

This is in Blackfriday land (the Markdown parser used in Hugo).

If I understand you correctly, what you want COULD be done by implementing this:

And provide a custom Renderer like this:

This shouldn’t be hard to do, but it should be “important enough” to add to Hugo – and someone should sketch out a “api” of such (what should be modified by what). We might get bitten by this once people expect similar hacks in the other rendering engines provided.

Interesting suggestion. I didn’t know Blackfriday exposed those commands. But, since we can’t extend Hugo (without forking), we can’t access those APIs, right? Hugo would need to be extended to access those APIs I believe.

So yes, there are two code paths here to explorer:

Option 1) Hugo parse the HTML output (it’s a simple format) to build a collection, and expose that TOC collection to the Page object. Something like:

type TocNode struct {
  HasChildren bool
  Childrent *TocNode  // note recursive property
  Depth int  // H1, H2, H3 and so on
  Anchor string  // <a href=""> link
  Text string  // <a>...</a> inner text
}

Then expose this as a single property of TocNode on the page struct.

or Option 2) Expose all Blackfriday TOC APi functions in the page’s Frontmatter. And there’s a lot of options here:

That could clutter up the frontmatter. Maybe look at a new struct for this, Toc, and expose all wrapper methods on that, which calls the Blickfriday API before rendering the markdown for that page. That’s one option.

My opinion:
Considering how messy the frontmatter can get with exposing those TOC API functions (the Menu feature is a clear example of how messy the frontmatter can get - it’s just barely livable), I would vote for option 1.

I say this assuming that Blackfriday has been versioned at Hugo (godep, for example). By locking in a version, and writing a few tests using Blackfriday, we can write a parser to parse the HTML into the struct I wrote above. The output of Blackfriday’s TOC structure is simple enough:

<nav id="TableOfContents">
  <ul>
    <li><h1><a href="#abc">My Text</a></h1></li>
    <li>
      <ul>
        <li><h2><a href="#abc">My Text</a></h2></li>
      </ul>
    </li>
  </ul>
</nav>

Where the contents of <li> can either be an <h1><a>... header and anchor combination with text, or another <ul><li><h2><a> combination signifying a child node of H2, and so on (stop at H6?).

As long as the unit tests pass, that would be good enough for me.

For backwards compability, leave the .TableOfContents raw HTML currently. Just create a new single property on the Page struct for the TocNode, which encloses all child nodes as well. Maybe Page.TocNode?