@@ -452,6 +452,22 @@ def parse_blocks(self, blocks: list[str], current_parent: etree.Element) -> None
452452 if self .stack :
453453 self .stack [- 1 ].hungry = True
454454
455+ def capture_leaked_content (self , parent : etree .Element , entry : BlockEntry ) -> None :
456+ """
457+ Capture leaked content.
458+
459+ Old school, non-block admonitions, details,
460+ and content tabs strongly control where there content is inserted and
461+ can cause content leakage outside of the Blocks container.
462+ Look for such content and pull it back into the container if found.
463+ """
464+
465+ last_child = self .lastChild (parent )
466+ if last_child is not None and last_child is not entry .el :
467+ target = entry .block .on_add (entry .el )
468+ parent .remove (last_child )
469+ target .append (last_child )
470+
455471 def run (self , parent : etree .Element , blocks : list [str ]) -> None :
456472 """Convert to details/summary block."""
457473
@@ -492,6 +508,10 @@ def run(self, parent: etree.Element, blocks: list[str]) -> None:
492508 for r in range (len (self .stack )):
493509 entry = self .stack [r ]
494510 if entry .hungry and parent is entry .parent :
511+
512+ # Capture leaked content from old-school extensions: admonition, details, tabbed, etc.
513+ self .capture_leaked_content (parent , entry )
514+
495515 # Get the target element and parse
496516 entry .hungry = False
497517 self .parse_blocks (blocks , parent )
0 commit comments