pymdown-extensions icon indicating copy to clipboard operation
pymdown-extensions copied to clipboard

Add option to show Tabs within Table of Contents

Open ruralmeltdown opened this issue 5 months ago • 5 comments

Description

I created the following [1] issue over on the mkdocs-material repo, but it was suggested that I create an issue here, as it is out of scope for them. My request is that: I'm wondering, since Tabs work as URL slugs, is it possible to add them to the page Table of Contents, and, if possible switch to the tab? Obviously, some users may not want this, so having it as an option would probably be ideal, and/or if they are under a heading in the document, have them nest under that heading in the Table of Contents.

[1] https://github.com/squidfunk/mkdocs-material/issues/8400

Benefits

This should improve the navigation of a document, especially a longer one, that may have multiple tabs. Tabs allow a document to not appear as long when compared to a document that doesn't have the same information within tabs, but the navigation ability of the document is lost when the information is placed into tabs.

Solution Idea

Here is a visual of what I'm thinking (I would like to see the two tabs under 'Installation method' appear under that entry in the Table of Contents list): Image

ruralmeltdown avatar Aug 16 '25 21:08 ruralmeltdown

FWIW, I did ask Copilot if this was possible, and it suggested this change - but I have ZERO clue if this would even work, or be the change(s) needed; but sharing in case it helps:

Here’s a concrete proposal you could submit as a patch/PR against pymdown-extensions to make tab labels show up in the MkDocs‐Material TOC. The idea is to let users opt in to “exporting” each tab title as a hidden heading node in the Markdown AST, so that the standard toc extension picks it up automatically.


1. Add a new config flag

In TabbedTreeprocessor.__init__, add:

     def __init__(self, md, config):
         super().__init__(md)
         self.alternate     = config['alternate_style']
         self.slugify       = config['slugify']
         self.combine_header_slug = config['combine_header_slug']
         self.sep           = config["separator"]
+        self.add_tabs_to_toc = config.get("add_tabs_to_toc", False)

Also surface it in TabExtension.config:

     self.config = {
         'alternate_style': [False, "…"],
         'slugify':        [0,     "…"],
         'combine_header_slug': [False, "…"],
         'separator':      ['-',   "…"],
+        'add_tabs_to_toc': [False, "Add each tab title as an Hn for TOC generation"]
     }

2. Inject a hidden heading for each tab

In TabbedTreeprocessor.run(self, doc), right after you assign inpt.attrib["id"] = slug and label.attrib["for"] = slug, insert:

         inpt.attrib["id"] = slug
         label.attrib["for"] = slug

+        if self.add_tabs_to_toc:
+            # Create an H3 element (or choose level dynamically)
+            header = etree.Element("h3", {"id": slug})
+            # Use the label text as the heading content
+            header.text = innertext
+            # Insert it immediately after the label, so it appears
+            # before the content block in the AST
+            parent = el  # 'el' is the <div class="tabbed-set">
+            # find where the label lives, then insert after it
+            for idx, child in enumerate(list(parent)):
+                if child is label:
+                    parent.insert(idx + 1, header)
+                    break

What this does:

  • When add_tabs_to_toc=True, each tab label gets a real <h3 id="…">My Tab</h3> injected into the HTML tree.
  • The existing MkDocs Material TOC pipeline will now pick up those headings and insert them into the sidebar nav automatically.
  • You don’t need any custom JavaScript hacks, nor special Markdown slugs everywhere—you just flip on the option in your mkdocs.yml:
markdown_extensions:
  - pymdownx.blocks.tab:
      alternate_style: true
      combine_header_slug: false
      separator: '-'
      add_tabs_to_toc: true

Then rebuild your docs, and you’ll find each tab title nested right under its parent section in the “On this page” TOC.

Feel free to tweak the heading level (H3) or insertion point, but this minimal patch should give you exactly the up‐the‐pipeline support you’ve been craving.

ruralmeltdown avatar Aug 16 '25 21:08 ruralmeltdown

This may be beyond the scope of this project. This AI suggestion looks like it is assuming that it can just insert a header into the tab and it won't cause any issues. I don't know if this is true or not.

I also don't know if this is a direction we want to go in. I disagree that tabs should be added to the TOC, I think this desire is extremely niche. I think those who may desire this would be in a very small minority.

When I have some time to consider this more seriously, I'll make a decision.

facelessuser avatar Aug 16 '25 21:08 facelessuser

Thank you for the prompt response. Again, take the AI suggestion with a grain of salt, or not at all - I have no idea if it's even close to a solution.

I/we (working on RaspAP documentation at present) look forward to your decision. There are a number of discussions/issues in the mkdocs-material repo (some links below) that ask about adding headings that are within tabs to show in the Table of Contents; so I think this is a decent compromise that would likely be welcomed by many that didn't know it was something they wanted. Knowing what information is in a document is pretty priceless, and this would only help that. Let's say we have a document that doesn't use tabs, and is say 1,000 lines long, with 50 entries in the TOC. If we re-organize that document into tabs making it only a few hundred lines long, a good majority of those headings go away (and this won't fix that), but at least the parent demarc'ing tabs could be in the TOC.

Links to a handful of the issues: https://github.com/squidfunk/mkdocs-material/issues/3879 https://github.com/squidfunk/mkdocs-material/discussions/6217 https://github.com/squidfunk/mkdocs-material/issues/4828 https://github.com/squidfunk/mkdocs-material/issues/3376 https://github.com/squidfunk/mkdocs-material/issues/3527 https://github.com/squidfunk/mkdocs-material/issues/3376 https://github.com/squidfunk/mkdocs-material/discussions/3981

ruralmeltdown avatar Aug 16 '25 22:08 ruralmeltdown

It may be decided that this is something a TOC extension should do. I'm not sure I want to maintain an alternative TOC here, so keep that in mind. That's why I think it might be out of scope, but I'll wait to reserve judgement once I can properly investigate whether I'm interested in hacking something directly into tabs.

facelessuser avatar Aug 17 '25 00:08 facelessuser

Fully understood - I'm new to all of this, and am not sure where this belongs, so feel free to point me in a better direction if needed. Thank you again for your responses.

ruralmeltdown avatar Aug 17 '25 00:08 ruralmeltdown