_analyze_s1_style.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # -*- coding: utf-8 -*-
  2. """剖析 S1 模块四份交付文档的格式与风格特征,输出对比基线报告。"""
  3. from __future__ import annotations
  4. import sys
  5. from pathlib import Path
  6. from docx import Document
  7. from docx.shared import Pt
  8. BASE = Path(r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目管理\产互联项目管理\交付文档\Release产互联")
  9. S1 = [
  10. "S1产销协同业务需求描述-V0.4.docx",
  11. "S1产销协同模块蓝图设计方案-V2.2.docx",
  12. "S1产销协同模块详细设计说明书-V1.2.docx",
  13. "S1产销协同模块用户操作手册-V1.2.docx",
  14. ]
  15. MINE = Path(r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目管理\产互联项目管理\交付文档\Release产互联\待确认")
  16. MINE_UM = "系统集成-用户操作手册-V0.5.docx"
  17. def style_of(p):
  18. try:
  19. return p.style.name
  20. except Exception:
  21. return "?"
  22. def run_font(p):
  23. for r in p.runs:
  24. if r.text.strip():
  25. f = r.font
  26. sz = f.size.pt if f.size else None
  27. return f"{f.name}/{sz}/b={f.bold}"
  28. return "-"
  29. def dump_doc(path: Path, full: bool):
  30. d = Document(str(path))
  31. print(f"\n{'='*70}\nFILE {path.name}")
  32. # styles statistics
  33. from collections import Counter
  34. cnt = Counter(style_of(p) for p in d.paragraphs if p.text.strip())
  35. print("STYLE_STATS", dict(cnt))
  36. # Normal style font
  37. try:
  38. n = d.styles["Normal"]
  39. print("NORMAL_FONT", n.font.name, n.font.size.pt if n.font.size else None)
  40. except Exception as e:
  41. print("NORMAL_FONT ?", e)
  42. # core properties
  43. cp = d.core_properties
  44. print("CORE title=", cp.title, "| author=", cp.author)
  45. # headings outline
  46. print("--- HEADINGS ---")
  47. for p in d.paragraphs:
  48. s = style_of(p)
  49. if s.startswith(("Heading", "标题")) and p.text.strip():
  50. print(f" [{s}] {p.text.strip()}")
  51. print("--- TABLES ---", len(d.tables))
  52. for i, t in enumerate(d.tables[:6]):
  53. hdr = [c.text.strip().replace("\n", "/") for c in t.rows[0].cells]
  54. print(f" T{i} rows={len(t.rows)} hdr={hdr[:6]}")
  55. if full:
  56. print("--- FULL TEXT ---")
  57. for p in d.paragraphs:
  58. t = p.text.rstrip()
  59. if t:
  60. print(f"[{style_of(p)}|{run_font(p)}] {t}")
  61. for i, t in enumerate(d.tables):
  62. print(f"--- TABLE {i} ---")
  63. for r in t.rows:
  64. print(" | " + " | ".join(c.text.replace("\n", "⏎").strip() for c in r.cells))
  65. def main():
  66. which = sys.argv[1] if len(sys.argv) > 1 else "um"
  67. if which == "um":
  68. dump_doc(BASE / S1[3], full=True)
  69. print("\n\n########## 对比:本次生成的操作手册 ##########")
  70. dump_doc(MINE / MINE_UM, full=True)
  71. else:
  72. idx = {"brd": 0, "bbp": 1, "dds": 2}[which]
  73. dump_doc(BASE / idx if isinstance(idx, Path) else BASE / S1[idx], full=False)
  74. if __name__ == "__main__":
  75. main()