Spec: Table of Contents

Continuing the discussion from Is there markdown for creating a table of contents in a topic?:

Ok, I’d really like to see this happen, so here’s my attempt at making a spec for it.

This feature allows the automatic creation of a table of contents for any post (although it’s best suited to Wiki posts).

Details

  • To invoke the feature, add the [contents] markup to a post.
  • After cooking the markdown, the code scans the post below the [contents] markup and adds an anchor before each Header element (this allows for a preamble or top-level title to be excluded from the contents).
  • The text and anchor of those Header elements are then composed into a <ul> and inserted at the location of the [contents] markup.
  • Each sub-list should be indented by relative hierarchy, not Header size. This allows for “jumps” in Header size to produce a tidily indented list.
  • List item styling, however, is applied based on the Header level it refers to.

Examples with the list item styles H1 H2 and H3:

H1
  H2
  H2
  H2

H1
  H3
  H3
  H3

H2
  H3
  H3
  H3

H1
  H3
  H3
  H2
    H3
    H3

H1
  H2
    H3
    H3
  H2
    H3
    H3

Options

[contents min=1 max=3]

where min and max are the limits of H elements to index. I suppose it should support up to H6 given that those can be generated with HTML. 1 and 3 are the default if left unspecified.

I toyed with a style= parameter for bullets or numbers, but I think numbers will be misleading because the contents of the post are subject to change, making the numbering inconsistent over time.

Example output

Pay close attention to the numbers!

<div class="toc-wrapper">
  <ul class ="toc-h1">
  <li><a href="#h1-1">Header text</a></li>
  <li><a href="#h1-2">Header text</a></li>
  <li><a href="#h1-3">Header text</a></li>
    <ul class="toc-h2">
    <li><a href="#h2-1">Subheader text</a></li>
    <li><a href="#h2-2">Subheader text</a></li>
      <ul class="toc-h3>
      <li>a href="#h3-1">Sub-subheader text</a>
      <li>a href="#h3-2">Sub-subheader text</a>
      <li>a href="#h3-3">Sub-subheader text</a>
     </ul>
    <li><a href="#h2-3">Subheader text</a></li>
    </ul>
  <li><a href="#h1-4">Header text</a></li>
  <li><a href="#h1-3">Header text</a></li>
    <ul class="toc-h3">
    <li><a href="#h3-4">Sub-subheader text</a></li>
    <li><a href="#h3-5">Sub-subheader text</a></li>
    </ul>
  </ul>
</div>

Where “h1-3” is the anchor of the third H1 element in the topic etc.

I suppose you could generate random strings if you want to reduce the chances of clashing with a user-generated Anchor somewhere else in the post.

##Mockup

This post: Laser Cutter - Trotec Speedy 300 - Tools - Discourse – South London Makerspace

Makes his sort of thing, only prettier because I’m just slapping this together in Paint. If I have time later, I might do a more carefully designed mockup.

##Thoughts

It takes up a lot of vertical space. Maybe it could be pushed into one of the gutters at wider window sizes? Or even float over the gutter as you scroll, so you can always access it from all points in the post?

13 Likes

For readability, I’d not call the anchors 1-1 and so on, but generate a URL-compatible slug just as for topics.

This would result in nice URLs like https://meta.discourse.org/t/spec-table-of-contents/32248#details. :smiley:

The danger comes when you have identically titled sub-headers in different locations.

Whatever method is chosen, you have to guarantee unique anchor URLs.

EDIT: oh and what if multiple posts in a topic have a Contents?

3 Likes

Good point, this could clash. Some ideas:

  • Always concatenate all higher-level headings, like in #about-details?
  • Check for clashes and append a number?
  • Use both your number and a slug, e.g. https://meta.discourse.org/t/spec-table-of-contents/32248#1-1-details?

Supporting multiple posts in a topic having contents is awful if you want to guarantee clash-freeness, because it means that a post cannot be baked without knowing about the other posts in the same topic. My only (awful) idea to avoid this would be to also add the post number to the anchor.

1 Like

Not so awful IMO.

https://meta.discourse.org/t/spec-table-of-contents/322481#1-H1-1-details

Yeah it’s full of numbers, but it begins and ends with the human-readable bits.

2 Likes

HTML anchor support should be part of the 1.4 release. I’d say let the team worry about solving those problems. :wink:

3 Likes

It’s possible this will get pushed to a future release, though.

Adding for posterity that this is something that we’d also love. We’re having to use a separate wiki platform in the mean time to get around the current lack of TOC functionality.

3 Likes

I created a TOC manually recently for a FAQ on my discourse - it’s fairly time consuming to create but looks awesome!

This would have saved me some time if the TOC were generated automagically, but today I am not sure it’s really so important for a discussion platform, esp as long as wiki topics lack other essential wiki functionality anyway. Like @HAWK we’ve moved our wiki content elsewhere. But perhaps that’s a topic for another day.

All that said if this is developed I like this @Tom_Newsom idea for naming anchors and would love to see it implemented this way.

5 Likes

Automated TOC, is a most requested feature for many of our users.
It would be great to have this implemented as we try to get away from the old conventional wikis

Thanks!

3 Likes

This just came up on my site again - we have a program update that is sent out once every few months via a discourse topic and it gets quite long. Having the ability to add a [toc] shortcode at the top and have it automagically generate a table of contents at the top of the post is thus an important priority again.

1 Like

We do have heading anchor link support in 1.6 now.

6 Likes

Can we automatically create a TOC easily now? Or do we have to do it manually?

2 Likes

I haven’t found a way to do it automatically yet, but I would love to be able to do so! We’re using Discourse at my work as a knowledge base, and certain articles are very long it would be great to have this generated (like MediaWiki does).

1 Like

TOC is one of the mandatory features useful to use Discourse as a wiki. I don’t need fancy things :slight_smile:

1 Like

Automatic TOC generation is a difficult problem to solve. There’s more discussion about this in the aforementioned feature topic:

1 Like