
pptx-html-fidelity-audit
热门将 python-pptx 导出的 PPT 演示文稿与源 HTML 幻灯片进行对比审计,识别布局与内容偏差(如页脚溢出、内容裁切、斜体/em 缺失、样式丢失、间距错乱等),并采用严格的“页脚轨界(footer-rail)+ 光标流(cursor-flow)”布局规范重新导出。当用户拥有由 HTML 幻灯片生成的 .pptx 文件,并要求对比、审计、校验或修复导出效果时使用此 Skill —— 包括“对比 ppt 和 html”、“还原度审计”、“修复 pptx”、“ppt 被截断”、“页脚重叠”、“pptx 缺少斜体”、“重新导出 PPT”、“pptx-html-fidelity-audit”,或任何需要对 python-pptx → HTML 流程进行校验与修复的场景。当用户同时展示 deck.html 和 deck.pptx 并调试视觉差异时,也应触发此 Skill。
将 python-pptx 导出的 PPT 演示文稿与源 HTML 幻灯片进行对比审计,识别布局与内容偏差(如页脚溢出、内容裁切、斜体/em 缺失、样式丢失、间距错乱等),并采用严格的“页脚轨界(footer-rail)+ 光标流(cursor-flow)”布局规范重新导出。当用户拥有由 HTML 幻灯片生成的 .pptx 文件,并要求对比、审计、校验或修复导出效果时使用此 Skill —— 包括“对比 ppt 和 html”、“还原度审计”、“修复 pptx”、“ppt 被截断”、“页脚重叠”、“pptx 缺少斜体”、“重新导出 PPT”、“pptx-html-fidelity-audit”,或任何需要对 python-pptx → HTML 流程进行校验与修复的场景。当用户同时展示 deck.html 和 deck.pptx 并调试视觉差异时,也应触发此 Skill。
PPTX ↔ HTML 还原度审计
一套可重复执行的工作流程,用于捕获 python-pptx 导出文件与 HTML 源文件之间发生的隐蔽布局偏差,并通过严格的布局规范加以修复,避免在后续导出中再次出现相同的回归问题。
适用场景
用户拥有:
-
一个 HTML 幻灯片源文件(通常是包含
<section class="slide">区块的单文件演示文稿):<section class="slide light"> <div class="chrome">2026 · Q2 review</div> <span class="kicker">Pillar 03</span> <h2 class="h-xl">Shipping <em>velocity</em> doubled</h2> <p class="lead">…</p> <div class="foot">page 5 / 14</div> </section> -
一个由该 HTML 幻灯片通过 python-pptx(或类似工具)生成的 PPTX 文件。
-
怀疑(或已观察到明显的视觉证据)PPTX 与 HTML 不匹配 —— 比如文字溢出到页脚、斜体变正体、Hero 居中幻灯片未居中、页面被截断、标签样式丢失等。
如果用户只有上述两者之一,则本 Skill 暂不适用 —— 请先生成缺失的文件,或提示用户提供。
为什么这很困难(以及为什么需要 Skill)
PPTX 是固定画布、绝对定位的介质;而 HTML 是弹性流式布局。天真的 python-pptx 导出逻辑往往硬编码每个元素的 (top, left) 坐标,这在最初测试的单张幻灯片上可行,但遇到内容固有高度不同的其他幻灯片时就会隐蔽地失效。这会导致最常见的几种偏差模式:
- 页脚溢出(Footer overflow) — 内容区底端(
top + height)穿透到页脚区域。 - 超出画布(Off-canvas content) — 最后一个区块的底部坐标超过了
7.5"(16:9 画布极限)。 - 斜体丢失(Italic loss) — HTML 中的
<em>标签在导出时未正确设置run.font.italic = True。 - Hero 幻灯片未居中(Hero slides not centered) — 垂直堆叠布局的幻灯片直接使用了固定
MARGIN_TOP,而非动态计算垂直居中。 - 框体边界侵入(Box bounds intruding) — 虽然文字装得下,但形状的文本框(bounding box)过大,视觉上跨越了轨界(rail)。
- 标签/样式丢失(Tag/styling loss) — 彩色顶栏行、kicker 标签的大写字间距、等宽/衬线字体映射暗中退化为默认样式。
上述每一个问题都是布局规范问题,而非内容本身的问题。只要采用统一的布局规范,这些问题就能迎刃而解。
工作流程
审计过程分为五个步骤。请勿跳过任何一步 —— 只有先输出具体的差异清单来驱动重新导出,布局规范才能发挥作用。未经审计直接修改往往会导致一半的问题遗漏。
步骤 1 — 从 PPTX 提取真实基准数据
运行 scripts/extract_pptx.py <path-to.pptx> > pptx_dump.json。该脚本会遍历每张幻灯片上的所有形状,转储文本、位置(top / left)、尺寸(width / height)以及具体的 TextRun 排版信息(字体名称、字号 pt、加粗、斜体、颜色)。这是导出文件的真实状态 —— 不要相信导出脚本的预期逻辑,而要相信 dump 出来的实际数据。
对于 14 页的 PPT,dump 出来的 JSON 大约 30–60 KB,非常易于人类阅读。
步骤 2 — 梳理 HTML 结构
阅读源 HTML,枚举所有的 <section class="slide"> 区块。针对每一页,记录以下内容:
- 幻灯片主题(
light/dark/hero light/hero dark)。 chrome顶栏文本(顶部元数据)。kicker标签(标题上方的小号大写眉题)。- 主标题(h-hero / h-xl 等)及副标题。
- 正文副本及任何结构化区块(流程步骤、卡片、柱状图、观察卡片等)。
foot页脚行(底部元数据)。- 任何
<em>或斜体样式的 span 标签 — 斜体是最容易被忽略的退化点。
将每个 HTML 幻灯片与 PPTX 幻灯片索引进行映射。如果演示文稿遵循“第 1 页 = 封面,第 N 页 = 结束页”的约定,映射方式即为按顺序一一对应。
步骤 3 — 构建审计表格
针对每张幻灯片,遍历 dump 中的形状并比对预期的布局规则。必须严格使用下述表格格式 —— 严重性(Severity)列将决定修复的优先顺序:
| 幻灯片 | 问题 | 严重性 |
|---|---|---|
| 1 cover | meta-row 底端 6.95" 蓋過 footer (6.7") | 🔴 |
| 5 checklist | row B 步驟描述底端 7.2" 切到 footer | 🔴 |
| 8 3E | 收束段落直接坐在 footer 起點 | 🔴 |
| 9 on-day | step 描述底端剛好碰 footer,無安全距 | 🟠 |
| 多處 | em (Playfair italic) 未保留 | 🟡 |
严重性评估标准(Severity rubric):
- 🔴 critical(致命) — 内容裁切、文本不可见、与页脚重叠、超出画布。必须修复。
- 🟠 high(高) — 内容可见但视觉层级破坏、缺少呼吸感、Hero 幻灯片未居中。应当修复。
- 🟡 medium(中) — 斜体/em 丢失、字体退化错误、颜色漂移。本次迭代中修复。
- 🟢 low(低) — 细微的间距/对齐偏差、亚像素偏移。记录即可,不阻塞发布。
表格下方请附上简短的根本原因分析(Root Cause):通常 90% 的问题都源于 2–3 个系统性原因(例如:“未实施页脚轨界限制”、“Hero 堆叠固定在 MARGIN_TOP 而非垂直居中”、“斜体未透传”)。明确系统性原因可以大幅精简重新导出脚本的代码,并提高准确度。
步骤 4 — 基于“页脚轨界 + 光标流”布局规范重新导出
这是最核心的技术方案。完整规则见 references/layout-discipline.md;以下为核心要点:
在全局最开始一次性定义轨界(Rails):
from pptx.util import Inches
CANVAS_W = Inches(13.333) # 16:9 画布
CANVAS_H = Inches(7.5)
MARGIN_X = Inches(0.6)
MARGIN_TOP = Inches(0.5)
CONTENT_MAX_Y = Inches(6.70) # 内容区域的任何元素绝不能越过此线
FOOTER_TOP = Inches(6.85) # 页脚行固定于此处,横跨两端
自定义轨界: 上述默认值适用于带有窄页脚的 16:9 画布。如果你的设计系统使用了更宽的页脚或 4:3 画布,请在导出脚本中覆盖这些常量,并通过
--content-max-y/--canvas-h/--canvas-w参数向verify_layout.py传递相同数值。完整常量表见references/layout-discipline.md§1。
对内容区块使用光标(Cursor)进行推进,而非写死绝对 Y 坐标:
class Cursor:
"""沿幻灯片向下推进;拒绝越过页脚轨界。"""
def __init__(self, y_start, cap=CONTENT_MAX_Y):
self.y = y_start
self.cap = cap
def take(self, h, gap=Inches(0.12)): # ~14pt 字号下的 1 行留白;根据设计系统灵活微调
top = self.y
self.y = top + h + gap
if self.y > self.cap:
raise OverflowError(
f"位于 {self.y} 的光标超出了页脚轨界 {self.cap};"
f"请减小区块高度或拆分幻灯片"
)
return top
针对每张幻灯片,初始化 Cursor(MARGIN_TOP),并按阅读顺序对每个区块调用 take(height)。如果任何区块越界,渲染逻辑将拒绝生成幻灯片,从而将隐蔽的视觉 Bug 转化为明确的构建报错。
Hero(垂直居中)幻灯片改用预算(Budget)机制而非光标:
def hero_layout(blocks):
"""blocks = 按阅读顺序排列的 (height, gap_after) 元组列表。"""
total = sum(h + g for h, g in blocks)
y_start = (CANVAS_H - total) / 2
return Cursor(y_start)
仅此一项改动即可根除“Hero 幻灯片内容顶格吸顶”这一最常见的缺陷。
精简文本框高度,使其精准贴合文本 + 最小内边距。 当形状发生重叠时,PowerPoint 会显示框体边缘(选中虚线、Z 轴层级冲突等),即便内部文字没有溢出,过大的文本框也可能在视觉上跨越页脚轨界。请根据文本度量加上约 0.05" 内边距来计算文本框高度,而不是直接给一个宽泛的包围框。
显式保留斜体 / em:
def add_run(p, text, font, size_pt, italic=False, bold=False, color=None):
r = p.add_run()
r.text = text
r.font.name = font
r.font.size = Pt(size_pt)
r.font.italic = italic
r.font.bold = bold
if color:
r.font.color.rgb = color
return r
解析 HTML 时,检测 <em> / <i> / 内联样式 font-style: italic,并传入 italic=True。对于斜体展示文本,请使用英文衬线字体(如 Playfair Display、Source Serif 或备用字体 Georgia)—— 中文字体通常没有原生斜体,强行倾斜效果极差。
对于布局轨界无法捕获的更深层次字体问题 —— 例如可变字体陷阱(PowerPoint 隐式静默替换为 Calibri / 微軟正黑體)、缺少 <a:ea> 标签槽导致中文字符回退、汉字伪斜体等 —— 请查阅 references/font-discipline.md。其中的五层防护体系涵盖了 verify_layout.py 无法检测到的所有细节。
步骤 5 — 导出后校验
生成新的 .pptx 后,运行 scripts/verify_layout.py <path-to.pptx>。脚本会执行:
- 遍历每张幻灯片上的所有形状。
- 对内容形状校验断言
top + height ≤ CONTENT_MAX_Y(允许页脚/页码形状低于此限制线)。 - 对所有形状校验断言
top + height ≤ CANVAS_H(防止超出画布)。 - 校验断言
left + width ≤ CANVAS_W以及left ≥ 0。 - 将违规项统一打印汇总:幻灯片索引、形状名称、观察到的底部坐标、轨界坐标。
只有零违规(Zero violations)才是“重新导出文件具备交付条件”的门槛。严禁在未经校验脚本验证的情况下声称已解决问题 —— 人眼在缩小预览时极易忽略 1–2 毫米的溢出,但脚本不会。
向用户输出结果
步骤 5 校验通过后,向用户汇报:
- 审计表格 — 步骤 3 中的表格。
- 根本原因 — 一段简短的系统性原因说明。
- 修复清单 — 简洁列出修改内容及原因(例如:“Hero 幻灯片切换为预算居中模式”、“所有内容区块均通过 Cursor 路由推进”、“em 文本显式设置为斜体”)。
- 校验结果 — “N 张幻灯片中共出现 0 次轨界违规,文件大小 X KB”。
- 文件路径 — 重新导出的
.pptx绝对路径。
用户阅读报告主要出于两个目的:确认可见 Bug 已得到修复,以及确认系统性方案正确可靠。请务必兼顾两者。
随附资源
scripts/extract_pptx.py— 将每张幻灯片上的每个形状转储为 JSON。在审计前运行。重要提示: 亦需在原始导出文件上运行以作对比,并在重新导出的文件上运行以确认修复效果。scripts/verify_layout.py— 导出后的轨界校验工具。存在违规时返回非零退出码,以便接入 CI 流水线。references/layout-discipline.md— 完整的“页脚轨界 + 光标流”规则集,包含各种常见幻灯片类型(Hero 居中页、内容页、流程页、双栏页、观察网格)的代码片段。references/font-discipline.md— 五层字体审计规范:字体映射、存在性检测、静态 vs 可变字体陷阱、三种 XML 语言槽(latin/ea/cs)、中英斜体混合处理。references/audit-table-template.md— 开箱即用的表格模板,内含严重性图例。
当遇到以下情况时请阅读参考文档:
- 演示文稿包含 SKILL.md 覆盖范围之外的幻灯片类型(多栏仪表盘、嵌入图片、图表等) → 查看
layout-discipline.md。 - 审计显示 🟡 排版问题 —— 斜体缺失、中文字体回退、XML 中出现意外的
Calibri/Microsoft JhengHei等 → 查看font-discipline.md。 - 需要将审计表格直接放入报告或 Markdown 交付物中 → 查看
audit-table-template.md。
应避免的反模式
- 未指出系统性原因就单点打补丁。 如果你仅靠将第 5 页的区块下移 0.2" 解决了问题,接下来第 9、11、14 页又会出现类似问题。必须找出引发这四个问题的共同规则。
- 盲目相信...



