Deterministically repair an UNBALANCED code fence (odd fence-line count). Fences
strictly alternate open/close, so an odd count means the LAST fence line is an
opener that is never closed and swallows everything after it. The repair closes
(or strips) that dangling fence so trailing headings stop being read as code:
prefer to CLOSE the fence right before the first ##-style heading the fence
would otherwise swallow (rescuing ## References / ## See also);
if the dangling open has only blank lines before that heading (or before
EOF), it is a SPURIOUS stray fence — strip the line instead of wrapping an
empty block;
with no heading to protect, close at EOF (or strip when the tail is blank).
A balanced article is returned byte-identical (changed: false); after a repair
the count is even, so a second pass is a no-op (idempotent). Pure.
Deterministically repair an UNBALANCED code fence (odd fence-line count). Fences strictly alternate open/close, so an odd count means the LAST fence line is an opener that is never closed and swallows everything after it. The repair closes (or strips) that dangling fence so trailing headings stop being read as code:
A balanced article is returned byte-identical (changed: false); after a repair the count is even, so a second pass is a no-op (idempotent). Pure.