Skip to content

fix(parser): stop section extraction at any heading or thematic break (#2555 task 2) - #2557

Merged
jung-thomas merged 1 commit into
DEVfrom
fix/extract-section-boundary-2555
Sep 30, 2026
Merged

jung-thomas merged 1 commit into
DEVfrom
fix/extract-section-boundary-2555

Conversation

@jung-thomas

Copy link
Copy Markdown
Contributor

Follow-up to #2556. Addresses the second, rarer parse-time issue in #2555.

Problem

extractSection and extractBulletList (scripts/parsers/frontmatter.ts) bounded a section only at the next ## /### heading:

(?=\n## |\n### |$)

So a ## Prerequisites / ## You will learn block over-captured everything down to EOF whenever the content that followed it had no h2/h3 — e.g. an #### sub-heading, a # H1, or a bare ----separated intro paragraph. Rare in practice because authors almost always put ## Steps or a ### Step 1 right after, which correctly bounds the section.

Distinct from #2556, which was a render-time heading duplication; this is a parse-time boundary in the frontmatter extractor.

Fix

Widen the boundary to stop at any ATX heading (#..######) or a thematic break (---/***/___ alone on a line):

(?=\n#{1,6} |\n(?:---|\*\*\*|___)\s*(?:\n|$)|$)

Applied to both extractors via a shared SECTION_END constant.

Safety invariant: every new alternative is an earlier-or-equal stop point, so the change can only ever shrink an over-capturing section, never grow one. A section correctly bounded by ## Steps today still stops there — no correctly-rendering tutorial can regress.

Testing

npx vitest run — 19/19 pass:

  • New extract-section-boundary.test.ts (5 cases): stops at ####, at bare ---, at # H1, a control proving ## Steps-bounded prereqs still capture fully, and the same boundary honoured by extractBulletList.
  • Existing comment-aware-extraction.test.ts + frontmatter-utils.test.ts stay green.

No local corpus diff was possible (no .tutorial-cache/ present); the "can only shrink" invariant plus CI + the post-DEV e2e job are the backstop.

…#2555)

extractSection / extractBulletList bounded a section only at the next
`## `/`### ` heading, so a Prerequisites or You-will-learn block
over-captured everything down to EOF when the following content was an
`#### ` sub-heading, a `# H1`, or a bare `---`-separated intro paragraph
with no h2/h3 after it.

Widen the boundary lookahead to stop at any ATX heading (`#`..`######`)
or a thematic break (`---`/`***`/`___` alone on a line). Every added
alternative is an earlier-or-equal stop point, so the change can only
shrink an over-capturing section, never grow one — sections correctly
bounded by `## Steps` are unaffected (covered by a control test).

Follow-up to #2556 (task 2 of #2555).
@jung-thomas
jung-thomas merged commit f54735c into DEV Sep 30, 2026
4 checks passed
@jung-thomas
jung-thomas deleted the fix/extract-section-boundary-2555 branch September 30, 2026 17:52
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.

1 participant