Files
md_to_gost/tests/test_page_geometry.py
Igor20264 510f7e7adf
Python application / build (push) Waiting to run
v0.5.2
Что то сделал
2026-09-08 19:37:54 +03:00

148 lines
4.3 KiB
Python

"""Page number start / offset helpers."""
from pathlib import Path
from zipfile import ZipFile
from docx import Document
from docx.oxml.ns import qn
from lxml import etree
from md2gost.page_geometry import (
apply_page_number_start,
apply_section_geometry,
clear_section_page_start,
patch_docx_page_starts,
set_section_page_start,
)
_W = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}"
def _pg_start(section):
pg = section._sectPr.find(qn("w:pgNumType"))
if pg is None:
return None
return pg.get(qn("w:start"))
def test_set_section_page_start():
doc = Document()
section = doc.sections[0]
set_section_page_start(section, 3)
pg = section._sectPr.find(qn("w:pgNumType"))
assert pg is not None
assert pg.get(qn("w:start")) == "3"
def test_apply_page_number_start_skips_front():
doc = Document()
doc.add_section() # front
doc.add_section() # body
apply_page_number_start(doc, 2, front_sections=1)
front = doc.sections[0]._sectPr.find(qn("w:pgNumType"))
body = doc.sections[1]._sectPr.find(qn("w:pgNumType"))
assert front is None or front.get(qn("w:start")) is None
assert body is not None
assert body.get(qn("w:start")) == "2"
def test_apply_page_number_start_none_strips():
doc = Document()
set_section_page_start(doc.sections[0], 5)
apply_page_number_start(doc, None)
pg = doc.sections[0]._sectPr.find(qn("w:pgNumType"))
assert pg is None or pg.get(qn("w:start")) is None
def test_apply_page_number_start_none_strips_all_four_sections():
doc = Document()
for _ in range(3):
doc.add_section()
for section in doc.sections:
set_section_page_start(section, 1)
assert all(_pg_start(s) == "1" for s in doc.sections)
apply_page_number_start(doc, None)
assert all(_pg_start(s) is None for s in doc.sections)
def test_apply_page_number_start_body_only_with_front():
doc = Document()
for _ in range(3):
doc.add_section() # front + body + landscape + portrait = 4
for section in doc.sections:
set_section_page_start(section, 1)
apply_page_number_start(doc, 1, front_sections=1)
assert _pg_start(doc.sections[0]) is None
assert _pg_start(doc.sections[1]) == "1"
assert _pg_start(doc.sections[2]) is None
assert _pg_start(doc.sections[3]) is None
def test_apply_section_geometry_strips_copied_start():
doc = Document()
set_section_page_start(doc.sections[0], 1)
apply_section_geometry(doc.sections[0], landscape=True)
assert _pg_start(doc.sections[0]) is None
def test_clear_section_page_start_removes_empty_element():
doc = Document()
set_section_page_start(doc.sections[0], 1)
clear_section_page_start(doc.sections[0])
assert doc.sections[0]._sectPr.find(qn("w:pgNumType")) is None
def test_patch_docx_page_starts_strips_and_restores(tmp_path: Path):
doc = Document()
for _ in range(3):
doc.add_section()
for section in doc.sections:
set_section_page_start(section, 1)
path = tmp_path / "pages.docx"
doc.save(path)
patch_docx_page_starts(path, None)
with ZipFile(path) as z:
root = etree.fromstring(z.read("word/document.xml"))
starts = [
el.get(f"{_W}start")
for el in root.findall(f".//{_W}pgNumType")
]
assert all(s is None for s in starts)
# Re-seed starts then restore body-only restart.
doc2 = Document(str(path))
for section in doc2.sections:
set_section_page_start(section, 1)
doc2.save(path)
patch_docx_page_starts(path, 2, front_sections=1)
with ZipFile(path) as z:
root = etree.fromstring(z.read("word/document.xml"))
body = root.find(f"{_W}body")
sects = []
for child in body:
if child.tag == f"{_W}sectPr":
sects.append(child)
continue
if child.tag != f"{_W}p":
continue
p_pr = child.find(f"{_W}pPr")
if p_pr is None:
continue
sect = p_pr.find(f"{_W}sectPr")
if sect is not None:
sects.append(sect)
assert len(sects) == 4
vals = [
(s.find(f"{_W}pgNumType").get(f"{_W}start")
if s.find(f"{_W}pgNumType") is not None else None)
for s in sects
]
assert vals[0] is None
assert vals[1] == "2"
assert vals[2] is None
assert vals[3] is None