| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- """投标函字段填充不得把混合格式段落压平到第一个 run。"""
- import os
- import tempfile
- import unittest
- import xml.etree.ElementTree as ET
- from docx import Document
- from docx.enum.text import WD_UNDERLINE
- from models import Chapter
- from step4_writing import _fill_docx_paragraph_text, _save_chapter_docx, _w_tag
- class Step4UnderlineTests(unittest.TestCase):
- def test_cross_run_placeholder_keeps_untouched_run_properties(self):
- doc = Document()
- p = doc.add_paragraph("参加")
- for value in ("%%项", "目名称%%"):
- run = p.add_run(value)
- run.underline = WD_UNDERLINE.DOUBLE
- run.bold = True
- p.add_run(",承诺")
- p.add_run("固定下划线文字").underline = True
- p.add_run("。")
- xml = ET.fromstring(p._p.xml)
- properties = [ET.tostring(r.find(_w_tag("rPr")))
- if r.find(_w_tag("rPr")) is not None else None
- for r in xml.iter(_w_tag("r"))]
- _fill_docx_paragraph_text(xml, "参加示例项目,承诺固定下划线文字。")
- texts = [t.text or "" for t in xml.iter(_w_tag("t"))]
- self.assertEqual(texts, ["参加", "示例项目", "", ",承诺", "固定下划线文字", "。"],
- "字段应在原下划线run内替换,禁止整段压平")
- self.assertEqual(properties, [ET.tostring(r.find(_w_tag("rPr")))
- if r.find(_w_tag("rPr")) is not None else None
- for r in xml.iter(_w_tag("r"))])
- def test_deletion_numeric_update_and_non_text_nodes_survive(self):
- p = Document().add_paragraph("比例")
- p.add_run("15%").underline = True
- p.add_run(",包号:%%包号%%")
- p.add_run().add_break()
- p.add_run("签署:____").italic = True
- xml = ET.fromstring(p._p.xml)
- _fill_docx_paragraph_text(xml, "比例20%签署:____")
- self.assertEqual("".join(t.text or "" for t in xml.iter(_w_tag("t"))),
- "比例20%签署:____")
- self.assertEqual(len(list(xml.iter(_w_tag("br")))), 1)
- underlined = [r for r in xml.iter(_w_tag("r"))
- if r.find(_w_tag("rPr") + '/' + _w_tag("u")) is not None]
- self.assertEqual("".join(t.text or "" for r in underlined for t in r.iter(_w_tag("t"))), "20%")
- def test_native_chapter_docx_preserves_letter_and_cell_underlines(self):
- with tempfile.TemporaryDirectory() as directory:
- template = Document()
- template.add_paragraph("第一章 投标人资格、资信证明", style="Heading 1")
- template.add_paragraph("投标函")
- paragraphs = [template.add_paragraph(), template.add_table(rows=1, cols=1).cell(0, 0).paragraphs[0]]
- for p in paragraphs:
- p.add_run("参加")
- p.add_run("%%项目").underline = True
- p.add_run("名称%%").underline = True
- p.add_run(",编号:")
- p.add_run("%%项目编号%%").underline = WD_UNDERLINE.DOUBLE
- p.add_run(";签署:")
- p.add_run(" ").underline = True
- p.add_run("。")
- template.add_paragraph("第二章 报价", style="Heading 1")
- template_path = os.path.join(directory, "template.docx")
- template.save(template_path)
- path = _save_chapter_docx(
- Chapter(id="1", title="投标人资格、资信证明", template_chapter_id="1"),
- directory, template_path=template_path,
- placeholder_map={"项目名称": "示例项目", "项目编号": "TEST-001"},
- )
- result = Document(path)
- paragraphs = [next(p for p in result.paragraphs if p.text.startswith("参加")),
- result.tables[0].cell(0, 0).paragraphs[0]]
- for p in paragraphs:
- self.assertEqual(p.text, "参加示例项目,编号:TEST-001;签署: 。")
- self.assertEqual([(r.text, r.underline) for r in p.runs if r.text], [
- ("参加", None), ("示例项目", True), (",编号:", None),
- ("TEST-001", WD_UNDERLINE.DOUBLE), (";签署:", None),
- (" ", True), ("。", None),
- ], "原生段落/单元格填充必须保留字段及签署空白下划线")
- if __name__ == "__main__":
- unittest.main()
|