Skip to content

Commit e8994da

Browse files
schema: any markdown heading terminates a FAQ answer, not just "## " (#20841)
* schema: any markdown heading terminates a FAQ answer, not just "## " faq-entity.html previously ended a running FAQ answer only when it hit a line starting with "## ". A non-question "###"/"####" sub-heading, or a code fence / table / list nested under a question's answer, was NOT a boundary, so its text (including the literal "###"/"####" markdown prefix) got appended verbatim into acceptedAnswer.text. On pages with deep narrative structure under a question-shaped heading, this produced polluted FAQPage answers up to several thousand characters long. Now any line whose trimmed form starts with "#" ends the current answer, matching how a human reader would parse the section boundary. Verified with an isolated Hugo harness: a synthetic page with a clean question, a non-question H3 sub-heading, an H4 under that, and a final question, correctly stops each answer at the first heading of any level and no heading markdown leaks into acceptedAnswer.text. Also re-rendered the 5 real /what-is/ pages touched in the companion content PR (seo/what-is-faq-sweep-content): all 36 FAQ questions across those pages now have clean, bounded answers under 700 characters with zero markdown artifacts, down from several answers exceeding 4,000 characters pre-fix. * Guard FAQ heading terminator against code-fenced comment lines A heading-shaped comment line inside a fenced code sample (e.g. '# Install the CLI') was falsely terminating an FAQ answer early, truncating the emitted FAQPage structured data. Track fenced code blocks and require real heading syntax (1-6 '#' + space) rather than a bare leading '#'. --------- Co-authored-by: workprentice <257153108+workprentice@users.noreply.github.com>
1 parent cc3f6e6 commit e8994da

1 file changed

Lines changed: 27 additions & 6 deletions

File tree

layouts/partials/schema/collectors/faq-entity.html

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,33 @@
2424
{{ $currentQuestion := "" }}
2525
{{ $currentAnswer := slice }}
2626
{{ $inQuestion := false }}
27+
{{ $inCodeFence := false }}
2728

2829
{{ range $index, $line := $lines }}
30+
{{/* Track fenced code blocks so heading-shaped comment lines inside a
31+
code sample (e.g. "# Install the CLI") are never mistaken for a
32+
markdown heading or a question. */}}
33+
{{ $trimmedForFence := trim $line " \t" }}
34+
{{ $isFenceDelim := or (strings.HasPrefix $trimmedForFence "```") (strings.HasPrefix $trimmedForFence "~~~") }}
35+
{{ if $isFenceDelim }}
36+
{{ $inCodeFence = not $inCodeFence }}
37+
{{ end }}
2938
{{/* Check if this is a question (H2 ending with ? or context-aware H3) */}}
3039
{{/* Context-aware H3 detection:
3140
- In FAQ pages (/faq in URL): All H3s are treated as questions
3241
- Elsewhere: H3 must end with ? to be a question */}}
3342
{{ $isH3Question := false }}
34-
{{ if strings.Contains (lower $.RelPermalink) "/faq" }}
35-
{{ $isH3Question = strings.HasPrefix $line "### " }}
36-
{{ else }}
37-
{{ $isH3Question = and (strings.HasPrefix $line "### ") (strings.HasSuffix (trim $line " \t\n\r") "?") }}
43+
{{ if and (not $inCodeFence) (not $isFenceDelim) }}
44+
{{ if strings.Contains (lower $.RelPermalink) "/faq" }}
45+
{{ $isH3Question = strings.HasPrefix $line "### " }}
46+
{{ else }}
47+
{{ $isH3Question = and (strings.HasPrefix $line "### ") (strings.HasSuffix (trim $line " \t\n\r") "?") }}
48+
{{ end }}
49+
{{ end }}
50+
{{ $isH2Question := false }}
51+
{{ if and (not $inCodeFence) (not $isFenceDelim) }}
52+
{{ $isH2Question = and (strings.HasPrefix $line "## ") (strings.HasSuffix (trim $line " \t\n\r") "?") }}
3853
{{ end }}
39-
{{ $isH2Question := and (strings.HasPrefix $line "## ") (strings.HasSuffix (trim $line " \t\n\r") "?") }}
4054
{{ if or $isH3Question $isH2Question }}
4155
{{/* Save previous Q&A if exists */}}
4256
{{ if and $currentQuestion (gt (len $currentAnswer) 0) }}
@@ -64,7 +78,14 @@
6478
{{ $currentQuestion = $line }}
6579
{{ $currentAnswer = slice }}
6680
{{ $inQuestion = true }}
67-
{{ else if strings.HasPrefix $line "## " }}
81+
{{ else if and (not $inCodeFence) (not $isFenceDelim) (findRE "^#{1,6}[ \t]" $trimmedForFence) }}
82+
{{/* Any other markdown heading (## section break or a non-question ###/#### sub-heading)
83+
ends the current answer too, so narrative sub-headings inside an answer's
84+
span don't get swallowed verbatim into acceptedAnswer.text.
85+
Requires actual heading syntax (one to six "#" followed by a space) and
86+
excludes lines inside fenced code blocks, so a heading-shaped comment
87+
(e.g. "# Install the CLI") in a shell/YAML/Python sample is never
88+
mistaken for a markdown heading. */}}
6889
{{/* New section, save previous Q&A if exists */}}
6990
{{ if and $currentQuestion (gt (len $currentAnswer) 0) }}
7091
{{ $answerText := trim (delimit $currentAnswer " " | replaceRE "\\s+" " ") " \t\n\r" }}

0 commit comments

Comments
 (0)