Description
Auto-generate a table of contents (TOC) from post headings and make it available to themes as a template variable.
Split from #9 to keep scope manageable — #9 now covers RSS feed, meta tags, and reading time only.
Requirements
- Parse
h2 and h3 headings from rendered markdown to build a nested TOC
- Expose as
post.toc (HTML fragment) in Jinja2 templates
- Themes can render it wherever they choose (sidebar, inline, etc.)
- Support frontmatter flag
toc: false to disable per-post
- Optionally support a global config toggle in
config.yml
- Heading anchors should use slugified heading text (e.g.,
#my-heading)
Implementation Notes
- Option A: Use python-markdown's
toc extension (markdown.extensions.toc) — generates TOC and adds anchor IDs to headings in one pass
- Option B: Post-process rendered HTML with BeautifulSoup/regex to extract headings
- Option A is preferred — it integrates cleanly with the existing markdown pipeline in
src/squishmark/services/markdown.py
- Add
toc field to the Post model in src/squishmark/models/content.py
- Themes that don't use
post.toc are unaffected (variable is simply ignored)
Description
Auto-generate a table of contents (TOC) from post headings and make it available to themes as a template variable.
Split from #9 to keep scope manageable — #9 now covers RSS feed, meta tags, and reading time only.
Requirements
h2andh3headings from rendered markdown to build a nested TOCpost.toc(HTML fragment) in Jinja2 templatestoc: falseto disable per-postconfig.yml#my-heading)Implementation Notes
tocextension (markdown.extensions.toc) — generates TOC and adds anchor IDs to headings in one passsrc/squishmark/services/markdown.pytocfield to thePostmodel insrc/squishmark/models/content.pypost.tocare unaffected (variable is simply ignored)