- fix Не появляется пустая странициа перед названием таблицы - fix Не появляется пустая страница перед альбомной ориентацией - fix При отказе от изменений создаётся новый файл - fix Замена "..." на «...» больше не затрагивает uml и mermaid блоки
This commit is contained in:
@@ -156,6 +156,86 @@ def test_landscape_places_figure_inside_landscape_section(tmp_path, monkeypatch)
|
||||
assert image_section == 1
|
||||
|
||||
|
||||
W_NS = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}"
|
||||
|
||||
|
||||
def _is_break_paragraph(el) -> bool:
|
||||
"""Empty paragraph that is a page break and/or hosts a section break."""
|
||||
if el.tag != f"{W_NS}p":
|
||||
return False
|
||||
texts = [t.text or "" for t in el.findall(f".//{W_NS}t")]
|
||||
if any(t.strip() for t in texts):
|
||||
return False
|
||||
pPr = el.find(f"{W_NS}pPr")
|
||||
has_sect = pPr is not None and pPr.find(f"{W_NS}sectPr") is not None
|
||||
has_br = any(br.get(f"{W_NS}type") == "page" for br in el.findall(f".//{W_NS}br"))
|
||||
return has_sect or has_br
|
||||
|
||||
|
||||
def _breaks_between_last_text_and_table(doc) -> int:
|
||||
"""Empty page/section-break paras between the last body sentence and the table."""
|
||||
children = list(doc.element.body)
|
||||
table_i = next(i for i, el in enumerate(children) if el.tag == f"{W_NS}tbl")
|
||||
j = table_i - 1
|
||||
breaks = 0
|
||||
while j >= 0:
|
||||
el = children[j]
|
||||
if _is_break_paragraph(el):
|
||||
breaks += 1
|
||||
j -= 1
|
||||
continue
|
||||
if el.tag == f"{W_NS}p":
|
||||
text = "".join(t.text or "" for t in el.findall(f".//{W_NS}t")).strip()
|
||||
if text.startswith("Таблица") or text.startswith("Продолжение"):
|
||||
j -= 1
|
||||
continue
|
||||
break
|
||||
return breaks
|
||||
|
||||
|
||||
def test_portrait_to_landscape_is_single_section_break():
|
||||
"""Text then +landscape: one next-page section, no extra blank portrait page."""
|
||||
doc = Document(os.path.join(package_dir(), "Template.docx"))
|
||||
body = doc._body._element
|
||||
for child in list(body):
|
||||
if child.tag.endswith("}sectPr"):
|
||||
continue
|
||||
body.remove(child)
|
||||
|
||||
from md2gost.renderable.heading import Heading
|
||||
from md2gost.renderable.paragraph import Paragraph
|
||||
from md2gost.renderable.toc import ToC
|
||||
|
||||
h = Heading(doc._body, 1, False)
|
||||
h.add_run("СОДЕРЖАНИЕ")
|
||||
toc = ToC(doc._body, toc_mode="native")
|
||||
para = Paragraph(doc._body)
|
||||
para.add_run("Текст перед широкой таблицей.")
|
||||
table = Table(doc._body, 2, 3, CaptionInfo("wide", "Карта", landscape=True))
|
||||
for r in range(2):
|
||||
for c in range(3):
|
||||
table.add_paragraph_to_cell(r, c).add_run(f"{r}{c}")
|
||||
|
||||
Renderer(doc, skip_numbering=True).process([h, toc, para, table])
|
||||
assert _breaks_between_last_text_and_table(doc) == 1
|
||||
|
||||
# Same without TOC — still a single break, not page-break + section-break.
|
||||
doc2 = Document(os.path.join(package_dir(), "Template.docx"))
|
||||
body2 = doc2._body._element
|
||||
for child in list(body2):
|
||||
if child.tag.endswith("}sectPr"):
|
||||
continue
|
||||
body2.remove(child)
|
||||
para2 = Paragraph(doc2._body)
|
||||
para2.add_run("Текст перед широкой таблицей.")
|
||||
table2 = Table(doc2._body, 2, 3, CaptionInfo("wide2", "Карта", landscape=True))
|
||||
for r in range(2):
|
||||
for c in range(3):
|
||||
table2.add_paragraph_to_cell(r, c).add_run(f"{r}{c}")
|
||||
Renderer(doc2, skip_numbering=True).process([para2, table2])
|
||||
assert _breaks_between_last_text_and_table(doc2) == 1
|
||||
|
||||
|
||||
def test_landscape_listing_deferred_after_section(tmp_path, monkeypatch):
|
||||
"""+landscape +listing → listing must not sit in the landscape section."""
|
||||
from unittest.mock import patch
|
||||
|
||||
Reference in New Issue
Block a user