feat(writer): add renderer (ChapterContent -> DocxInjector.Block)
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
"""渲染:ChapterContent 的 ContentBlock 序列 → DocxInjector.Block 序列(Phase 5)。
|
||||
|
||||
字段塌缩(外视 #6):table.headers/caption、list.items/style 在渲染时显式丢弃,
|
||||
仅保留 DocxInjector.Block 支持的 (kind, text, level, rows)。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from genesis.writer.docx_injector import Block
|
||||
from genesis.writer.models import ChapterContent
|
||||
|
||||
|
||||
def render_chapter_blocks(content: ChapterContent) -> list[Block]:
|
||||
out: list[Block] = []
|
||||
for b in content.blocks:
|
||||
if b.type == "heading":
|
||||
out.append(Block(kind="heading", text=b.text or b.caption or "", level=b.level or 1))
|
||||
elif b.type == "table":
|
||||
out.append(Block(kind="table", text=b.caption or "", rows=b.rows or []))
|
||||
elif b.type == "list":
|
||||
out.append(Block(kind="list", text="\n".join(b.items or [])))
|
||||
elif b.type == "note":
|
||||
out.append(Block(kind="note", text=b.text or b.caption or ""))
|
||||
else: # paragraph 及未知类型
|
||||
out.append(Block(kind="paragraph", text=b.text or b.caption or ""))
|
||||
return out
|
||||
@@ -87,3 +87,11 @@ def test_original_content_style_preserved(tmp_path):
|
||||
|
||||
# 模板原有段落(尾部固定内容)在注入后仍存在且未被破坏
|
||||
assert any("尾部固定内容" in p.text for p in out.paragraphs)
|
||||
|
||||
|
||||
# ---------- Block 支持 table/list/note 等 kind(renderer 依赖) ----------
|
||||
|
||||
def test_block_accepts_table_list_note():
|
||||
assert Block(kind="table", text="t", rows=[["x"]]).kind == "table"
|
||||
assert Block(kind="list", text="a\nb").kind == "list"
|
||||
assert Block(kind="note", text="n").kind == "note"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
from genesis.writer.renderer import render_chapter_blocks
|
||||
from genesis.writer.models import ChapterContent, ContentBlock
|
||||
|
||||
|
||||
def _content():
|
||||
blocks = [
|
||||
ContentBlock(block_id="1", type="heading", level=2, text="小節"),
|
||||
ContentBlock(block_id="2", type="paragraph", text="正文"),
|
||||
ContentBlock(block_id="3", type="table", caption="表1", rows=[["a", "b"], ["1", "2"]]),
|
||||
ContentBlock(block_id="4", type="list", items=["項目一", "項目二"]),
|
||||
ContentBlock(block_id="5", type="note", text="注意"),
|
||||
]
|
||||
return ChapterContent(chapter_id="db_design", version=1, title="DB 設計", blocks=blocks)
|
||||
|
||||
|
||||
def test_render_maps_all_block_types():
|
||||
out = render_chapter_blocks(_content())
|
||||
kinds = [b.kind for b in out]
|
||||
assert kinds == ["heading", "paragraph", "table", "list", "note"]
|
||||
# 表:rows 透传
|
||||
table = out[2]
|
||||
assert table.kind == "table"
|
||||
assert table.rows == [["a", "b"], ["1", "2"]]
|
||||
# 列表:items 拼接进 text
|
||||
assert "項目一" in out[3].text and "項目二" in out[3].text
|
||||
Reference in New Issue
Block a user