fix: Leerzeilenfolgen innerhalb von Codeblöcken erhalten (QA2-06)
render_chapter reduzierte mehrfache Leerzeilen im gesamten Kapiteltext, auch innerhalb von Codeblöcken (z. B. zwei Leerzeilen zwischen Python-Funktionen nach PEP 8). Im Python-Beispielbuch waren 54 von 746 Listings nicht mehr zeichengetreu. Die Normalisierung gilt jetzt nur außerhalb von Fences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e9120c84ef
commit
7de7efaaa2
2 changed files with 30 additions and 1 deletions
|
|
@ -152,6 +152,26 @@ def indent_block(text: str, first: str, rest: str) -> str:
|
||||||
return "\n".join(out)
|
return "\n".join(out)
|
||||||
|
|
||||||
|
|
||||||
|
def _collapse_blank_lines(text: str) -> str:
|
||||||
|
"""Reduce runs of blank lines to one, except inside fenced code blocks (also indented/quoted ones)."""
|
||||||
|
out: list[str] = []
|
||||||
|
fence = ""
|
||||||
|
for line in text.split("\n"):
|
||||||
|
bare = re.sub(r"^[ \t]*(?:>[ \t]?)*[ \t]*", "", line)
|
||||||
|
if fence:
|
||||||
|
if bare.rstrip() and set(bare.rstrip()) == {fence[0]} and len(bare.rstrip()) >= len(fence):
|
||||||
|
fence = ""
|
||||||
|
out.append(line)
|
||||||
|
continue
|
||||||
|
m = re.match(r"(`{3,}|~{3,})", bare)
|
||||||
|
if m:
|
||||||
|
fence = m.group(1)
|
||||||
|
elif not line.strip() and out and not out[-1].strip():
|
||||||
|
continue
|
||||||
|
out.append(line)
|
||||||
|
return "\n".join(out)
|
||||||
|
|
||||||
|
|
||||||
_BLOCK_SYNTAX = ("```", "~~~", "|", "<table", "- ", "> ", "#", "$$", "\\[", "* * *")
|
_BLOCK_SYNTAX = ("```", "~~~", "|", "<table", "- ", "> ", "#", "$$", "\\[", "* * *")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -251,7 +271,7 @@ class Renderer:
|
||||||
blocks.extend(self.render_items(ch.items))
|
blocks.extend(self.render_items(ch.items))
|
||||||
blocks.extend(self._chapter_note_definitions())
|
blocks.extend(self._chapter_note_definitions())
|
||||||
text = "\n\n".join(b for b in blocks if b.strip())
|
text = "\n\n".join(b for b in blocks if b.strip())
|
||||||
return re.sub(r"\n{3,}", "\n\n", text).strip() + "\n"
|
return _collapse_blank_lines(text).strip() + "\n"
|
||||||
|
|
||||||
def render_items(self, items: Sequence[tuple[str | None, Any]]) -> list[str]:
|
def render_items(self, items: Sequence[tuple[str | None, Any]]) -> list[str]:
|
||||||
blocks: list[str] = []
|
blocks: list[str] = []
|
||||||
|
|
|
||||||
|
|
@ -98,3 +98,12 @@ def test_inline_svg_inside_html_table_is_html_img(convert):
|
||||||
assert "![" not in table, table
|
assert "![" not in table, table
|
||||||
assert re.search(r'<img src="\.\./media/images/\d{4}-c-svg\.svg" alt="Kreis"/>', table), table
|
assert re.search(r'<img src="\.\./media/images/\d{4}-c-svg\.svg" alt="Kreis"/>', table), table
|
||||||
assert run.report["output_link_check"]["broken_count"] == 0
|
assert run.report["output_link_check"]["broken_count"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_multiple_blank_lines_inside_code_are_kept(convert):
|
||||||
|
"""QA2-06: runs of blank lines inside code blocks were collapsed to one (PEP 8: two between functions)."""
|
||||||
|
code = "def f():\n pass\n\n\nclass K:\n pass\n\n\n\nx = 1"
|
||||||
|
body = f"<h1>K</h1><p>Vorher</p><pre>{code}</pre><p>Nachher</p>"
|
||||||
|
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
|
||||||
|
assert f"```python\n{code}\n```" in text, text
|
||||||
|
assert "\n\n\n" not in text.replace(code, "") # outside code blank lines are still normalized
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue