File tree Expand file tree Collapse file tree
_tests/src/infrastructure Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -42,7 +42,7 @@ module Infrastructure
4242 # to strip the preview when reusing rendered HTML (feeds, plain-text, etc).
4343 #
4444 # The full HTML string is never round-tripped through Nokogiri to avoid
45- # DOCTYPE mangling: Nokogiri::HTML is used read-only for extraction;
45+ # DOCTYPE mangling: Nokogiri::HTML5 is used read-only for extraction;
4646 # injection uses targeted string replacement on the original string.
4747 module FootnotePreviewInjector
4848 Text = Jekyll ::Infrastructure ::TextProcessingUtils
@@ -68,7 +68,7 @@ module FootnotePreviewInjector
6868 def self . inject ( html )
6969 return html unless html . include? ( 'class="footnote"' )
7070
71- doc = Nokogiri ::HTML ( html )
71+ doc = Nokogiri ::HTML5 ( html )
7272 footnote_map = build_footnote_map ( doc )
7373 return html if footnote_map . empty?
7474
Original file line number Diff line number Diff line change @@ -22,7 +22,7 @@ module TextProcessingUtils
2222 def self . clean_text_from_html ( html_content )
2323 return '' if html_content . nil? || html_content . strip . empty?
2424
25- doc = Nokogiri ::HTML ( html_content . to_s )
25+ doc = Nokogiri ::HTML5 ( html_content . to_s )
2626 doc . xpath ( '//script | //style' ) . remove # Remove script and style elements
2727 doc . text . gsub ( /\s +/ , ' ' ) . strip # Get text from remaining, normalize whitespace
2828 end
@@ -118,7 +118,7 @@ def self.slugify(text)
118118 # hidden preview text never leaks into plain-text output.
119119 def self . strip_tags ( html )
120120 cleaned = strip_link_previews ( strip_footnote_previews ( html ) )
121- Nokogiri ::HTML . fragment ( cleaned ) . text
121+ Nokogiri ::HTML5 . fragment ( cleaned ) . text
122122 end
123123
124124 # Removes book-link hover-preview markup (see BookPreviewRenderer), including
Original file line number Diff line number Diff line change @@ -120,7 +120,7 @@ def raw_title
120120 end
121121
122122 def decode_html_entities ( text )
123- Nokogiri ::HTML . fragment ( text . to_s ) . text
123+ Nokogiri ::HTML5 . fragment ( text . to_s ) . text
124124 end
125125
126126 def site_title
@@ -168,7 +168,7 @@ def site_description
168168
169169 def strip_html ( text )
170170 cleaned = Infrastructure ::TextProcessingUtils . strip_link_previews ( text )
171- Nokogiri ::HTML . fragment ( cleaned ) . text . gsub ( /\s +/ , ' ' ) . strip
171+ Nokogiri ::HTML5 . fragment ( cleaned ) . text . gsub ( /\s +/ , ' ' ) . strip
172172 end
173173
174174 # --- Image ---
Original file line number Diff line number Diff line change @@ -106,6 +106,23 @@ def test_inject_flattens_block_elements_to_classed_spans
106106 refute_match ( /<(?:figure|blockquote|figcaption|p)\b / , preview )
107107 end
108108
109+ def test_inject_figure_nested_in_paragraph
110+ # kramdown wraps cited-quote figures in a surrounding <p>. The HTML5
111+ # parser auto-closes the <p> before <figure> (per spec), ejecting it
112+ # as a sibling. flatten_blocks converts the resulting empty <p> tags
113+ # to empty fnp-p spans (harmless — they render nothing). Verify the
114+ # preview preserves all content regardless of the parse-tree shape.
115+ body = '<p><figure class="cited-quote">' \
116+ '<blockquote><p>The quote text.</p></blockquote>' \
117+ '<figcaption>—<span class="citation">Author.</span></figcaption>' \
118+ '</figure></p>'
119+ result = Injector . inject ( footnote_html ( id : 'note' , footnote_body : body ) )
120+ preview = extract_preview ( result ) . to_s
121+ refute_match ( /<(?:figure|blockquote|figcaption|p)\b / , preview )
122+ assert_includes preview , 'The quote text.'
123+ assert_includes preview , 'Author.'
124+ end
125+
109126 def test_inject_citedquote_full_fidelity
110127 # The real citedquote structure: figure > blockquote + figcaption,
111128 # where figcaption holds span.citation with <cite> and <a>. Existing
You can’t perform that action at this time.
0 commit comments