Skip to content

fix(llms): preserve heading section in llms-hidden conditional content#14571

Merged
cderv merged 2 commits into
mainfrom
fix/issue-14562
Jun 3, 2026
Merged

fix(llms): preserve heading section in llms-hidden conditional content#14571
cderv merged 2 commits into
mainfrom
fix/issue-14562

Conversation

@cderv
Copy link
Copy Markdown
Member

@cderv cderv commented Jun 3, 2026

When a heading is the first element inside ::: {.content-hidden when-format="llms-txt"} in a website with llms-txt: true, the heading renders in HTML as a bare <h2> with no <section id="..."> wrapper. The auto-generated TOC link points at an id that no longer exists, so clicking it does not scroll, and the heading's anchor and cross-references break too.

Root Cause

The llms conditional-content filter marks "visible in HTML, hidden from llms" blocks by wrapping them in <div class="llms-hidden-content">. When that block leads with a heading, Pandoc's --section-divs does not keep the heading nested in the div — it fuses the marker class onto the <section> it generates for the heading:

<section id="conditional-section" class="level2 llms-hidden-content">

cleanupConditionalContent in src/project/types/website/website-llms.ts then unwraps every .llms-hidden-content element. Since the class now rides on the <section>, unwrapping strips the section and its id, leaving the bare <h2>. Only the leading-heading shape is affected; with text before the heading or multiple headings, Pandoc keeps the wrapper div separate, so the unwrap is harmless.

Fix

When the marked element is a <section> (the marker fused onto it), keep the section and drop only the llms-hidden-content class; genuine wrapper divs are still unwrapped. Content stays excluded from the .llms.md output, which is generated before cleanup runs.

Test Plan

  • Render an llms-txt website with a heading inside content-hidden when-format="llms-txt" — heading keeps its <section id> and the TOC link scrolls
  • .llms.md still excludes the HTML-only content
  • content-visible when-format="llms-txt" (llms-only) content stays absent from HTML, present in .llms.md
  • section-divs: false documents still render the heading with its id

Fixes #14562

…al content (#14562)

A heading that leads a `content-hidden when-format="llms-txt"` block is
visible in HTML but lost its <section> wrapper and id. Pandoc's
--section-divs fuses the llms-hidden-content marker class onto the
<section> it generates for that heading; the HTML finalizer then unwrapped
every .llms-hidden-content, stripping that section and its id and breaking
the TOC link, anchors, and cross-references. Only the leading-heading shape
triggers it, since other shapes keep the wrapper div separate.

Keep the section when the marker fused onto it (dropping only the marker
class) and unwrap genuine wrapper divs as before.
@posit-snyk-bot
Copy link
Copy Markdown
Collaborator

posit-snyk-bot commented Jun 3, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

The conditional-headings regression test only exercised the
content-hidden (html-only) leading-heading shape. Extend coverage to the
two remaining cases from the fix's test plan:

- content-visible when-format="llms-txt": llms-only content is removed
  from the HTML body but kept in the .llms.md output.
- section-divs: false: the conditional block's leading heading still
  acquires a <section> wrapper independent of --section-divs, and the
  finalizer must keep its id intact while excluding the content from
  .llms.md.
@cderv cderv merged commit 35a8a77 into main Jun 3, 2026
51 checks passed
@cderv cderv deleted the fix/issue-14562 branch June 3, 2026 18:50
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.

Heading inside content-hidden when-format="llms-txt" loses its <section> and id, breaking TOC scroll

2 participants