Skip to content

Commit 257ea84

Browse files
author
cobyfrombrooklyn-bot
committed
Fix duplicated TOC entries when chapter starts with h2+
When a chapter's markdown file starts with an h2 or lower heading (e.g. `## Section Title`), the 'on this page' sidebar feature would add it as a sub-entry, duplicating the chapter's existing SUMMARY.md sidebar link. This skips the first heading in the on-this-page list when its text matches the active sidebar link, preventing the duplication. Fixes #2995
1 parent 424d6a4 commit 257ea84

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

crates/mdbook-html/front-end/templates/toc.js.hbs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,16 @@ window.customElements.define('mdbook-sidebar-scrollbox', MDBookSidebarScrollbox)
356356
headers = Array.from(main.querySelectorAll('h2, h3, h4, h5, h6'))
357357
.filter(h => h.id !== '' && h.children.length && h.children[0].tagName === 'A');
358358
359+
// Skip the first heading if its text matches the active sidebar link.
360+
// This avoids duplicating the chapter title in the "on this page" list
361+
// when a chapter's markdown starts with a heading (e.g. `## Section Title`)
362+
// that matches its SUMMARY.md entry.
363+
// See https://github.com/rust-lang/mdBook/issues/2995
364+
if (headers.length > 0
365+
&& activeSection.textContent.trim() === headers[0].textContent.trim()) {
366+
headers.shift();
367+
}
368+
359369
if (headers.length === 0) {
360370
return;
361371
}

tests/testsuite/toc.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ fn check_link_target_fallback() {
141141
);
142142
}
143143

144+
/// The "on this page" feature should skip the first heading if it matches
145+
/// the active sidebar link text, to avoid duplicating the chapter title
146+
/// when a chapter starts with an h2+ heading.
147+
/// See <https://github.com/rust-lang/mdBook/issues/2995>.
148+
#[test]
149+
fn toc_js_deduplicates_first_heading() {
150+
BookTest::from_dir("toc/basic_toc")
151+
.check_file_contains("book/toc*.js", "activeSection.textContent.trim() === headers[0].textContent.trim()")
152+
.check_file_contains("book/toc*.js", "headers.shift()");
153+
}
154+
144155
// Checks formatting of summary names with inline elements.
145156
#[test]
146157
fn summary_with_markdown_formatting() {

0 commit comments

Comments
 (0)