Skip to content

Fall back to "section" id for punctuation-only headings#3092

Open
ChrisJr404 wants to merge 1 commit into
rust-lang:masterfrom
ChrisJr404:fix/punctuation-heading-id-3002
Open

Fall back to "section" id for punctuation-only headings#3092
ChrisJr404 wants to merge 1 commit into
rust-lang:masterfrom
ChrisJr404:fix/punctuation-heading-id-3002

Conversation

@ChrisJr404
Copy link
Copy Markdown

Fixes #3002.

A heading whose text is entirely stripped by id_from_content (e.g. ## ::, ## !!!) currently renders as <h2 id=""><a class="header" href="#"></a>. The empty id can't be linked to and breaks the in-page anchor.

When the generated slug is empty, fall back to "section". The existing unique_id helper then handles disambiguation, so two punctuation-only headings on the same page become section and section-1, matching what pandoc and kramdown do for the same case (thanks @stevecheckoway for pointing this out and providing the original sketch in the issue).

Changes:

  • crates/mdbook-html/src/utils.rs: when id_from_content would return an empty string, return "section" instead. Added a unit test that exercises the per-page counter end-to-end through unique_id (two punctuation-only headings + a normal heading + a third punctuation-only heading produce section, section-1, real-heading, section-2).
  • tests/testsuite/rendering/header_links/expected/header_links.html: the existing integration fixture already covers two empty-id headings (### and ####) and previously documented the broken output (id="", id="-1"); updated to the new section / section-1 output.

Tested locally:

  • cargo test --workspace — all green.
  • cargo clippy --workspace --all-targets -- -D warnings — clean.
  • cargo fmt --check — clean.

Headings like `## ::` produce an empty id and a useless `href="#"`
because every character gets stripped by `id_from_content`. When the
slug ends up empty, return `"section"` instead so that `unique_id` can
hand out `section`, `section-1`, `section-2`, ... — matching what
pandoc and kramdown do for the same case.

Updates the existing fixture in tests/testsuite/rendering/header_links
which previously documented the broken output.

Closes rust-lang#3002.
@rustbot rustbot added the S-waiting-on-review Status: waiting on a review label May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: waiting on a review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Headings with just punctuation do not generate a linkable ID

2 participants