Skip to content

✨ NEW: Add section_ref syntax extension (§1.1 heading references)#1170

Draft
chrisjsewell wants to merge 4 commits into
masterfrom
claude/mdit-section-reference-plugin-yfvmtz
Draft

✨ NEW: Add section_ref syntax extension (§1.1 heading references)#1170
chrisjsewell wants to merge 4 commits into
masterfrom
claude/mdit-section-reference-plugin-yfvmtz

Conversation

@chrisjsewell

@chrisjsewell chrisjsewell commented Jul 16, 2026

Copy link
Copy Markdown
Member

What

Adds a new optional syntax extension section_ref, wiring in the new mdit-py-plugins section_ref plugin (executablebooks/mdit-py-plugins#144). It captures section-sign references — §1, §1.1, §2.3.4, the syntax LLMs commonly use to point at numbered headings — and resolves them to internal links targeting the correspondingly numbered heading of the current document:

# Title

See §1 and §1.1 for details.

## First Section

### Nested

⚠️ Draft / blocked on release: this depends on an unreleased mdit-py-plugins (the pyproject.toml and pre-commit pins are bumped to ~=0.7), so CI cannot install dependencies until executablebooks/mdit-py-plugins#144 is merged and 0.7.0 is released. All tests pass locally against the sibling branch (1167 passed).

How it works

  • The plugin emits section_ref tokens (with meta["numbers"], the parsed section number as a list of ints); render_section_ref produces an inert nodes.inline marker carrying it as a section_numbers attribute.
  • A new ResolveSectionRefs transform (priority 878 — deliberately before ResolveAnchorIds at 879 and Sphinx's DoctreeReadEvent at 880, so env.titles/toctree collectors see resolved references) resolves markers document-locally and structurally: with a single top-level heading (the common # Title layout) its subsections are §1, §2, …; otherwise top-level headings are numbered; nested levels are dot-separated. This gives identical results in docutils (doctitle promotion) and Sphinx (no promotion), independent of :numbered: toctrees.
  • Resolved markers become internal references (refid to the section, class section-ref), carrying the target heading's title as a reftitle — rendered by Sphinx HTML as a hover tooltip. Unresolved ones stay as styled text plus a suppressible myst.section_ref warning.
  • References inside headings or link text are deliberately left unlinked (styled text only): a reference there would produce nested <a> elements in the output — and, for headings, inside Sphinx toctree entry links and docutils contents entries.

Discussion points (why draft, beyond the release dependency)

  • Resolution semantics: document-local structural numbering is the simplest well-defined v1. A follow-up could resolve against Sphinx's env.toc_secnumbers for :numbered: toctrees (cross-document, matches displayed numbers), falling back to structural numbering.
  • Known docutils edge: a document consisting solely of # Title + one ## Section gets both promoted to title/subtitle by docutils in single-page mode, leaving no numbered sections (documented).

Testing

  • Docutils-mode: token/transform unit tests plus pseudo-XML regression fixtures (resolved, nested, multiple-H1, forward reference, unresolved + warning + suppression, in-link-text, in-heading).
  • Sphinx-mode: section_ref enabled in the extended_syntaxes regression build (heading ref stays inert in title/toc, body refs resolve with tooltips) — append-only fixture changes.
  • Adversarially probed with real Sphinx builds: no nested anchors, toctree/nav consistent with page bodies, doctree pickling and incremental rebuilds fine, cross-document isolation holds, no behavior change when the extension is disabled.
  • Full suite: 1167 passed; ruff + mypy (strict config) clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LwRkZLzpbHdb3pgmctmn6H

claude added 2 commits July 16, 2026 09:47
Wires the (unreleased) mdit-py-plugins section_ref plugin into
MyST-Parser as a new optional extension. §1 / §1.1 / §2.3.4 references
resolve, via a new ResolveSectionRefs transform, to internal links
targeting the correspondingly numbered heading of the current document.
Numbering is document-local and structural: with a single top-level
heading, its subsections are §1, §2, ...; nested levels dot-separated.

Unresolvable references stay as section-ref styled text and emit a
suppressible myst.section_ref warning. References inside headings or
link text are deliberately left unlinked, since a reference there would
nest anchors in the output and in sphinx toctree entries.

Requires mdit-py-plugins >= 0.7 (unreleased).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwRkZLzpbHdb3pgmctmn6H
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwRkZLzpbHdb3pgmctmn6H
claude added 2 commits July 16, 2026 14:09
The section_ref plugin now provides meta["numbers"] as a list of ints,
so the marker attribute becomes section_numbers and the transform no
longer parses the dotted string itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwRkZLzpbHdb3pgmctmn6H
Resolved §refs now carry the target section's title as reftitle,
rendered by Sphinx HTML as a hover tooltip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwRkZLzpbHdb3pgmctmn6H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants