演示文稿上线前,多查一层结构:用 python-pptx 审计标题与阅读顺序
很多 PPT 检查只看两件事:页面有没有内容、文字有没有溢出。但演示文稿并不只是图片集合,它还包含标题层级、形状顺序和占位符语义。标题丢失、同一标题重复或正文排在标题之前,可能不会影响“看起来能看到”,却会影响后续的大纲提取、自动摘要、无障碍阅读以及模板复用。
本文用一个只读审计脚本,演示如何在上传或交付前检查这些结构问题。脚本不会修改原文件,只输出 JSON 报告和退出码。
一、检查哪些结构
原型先覆盖四类确定性规则:
- 缺少标题占位符;
- 标题占位符存在但文本为空;
- 正文文本框在形状顺序中早于标题;
- 多页使用完全相同的标题;
- 文本占位符存在但内容为空。
“标题”通过 slide.shapes.title 获取,而不是猜测第一个有文字的文本框。这样可以区分真正的结构标题和普通正文。标题比较前会去除首尾空白、压缩连续空白并做大小写归一化,避免只因为空格不同而漏掉重复标题。
二、核心检查逻辑
读取每一页时,先取得标题文本,再遍历全部形状:
title_shape = slide.shapes.title
title_text = title_shape.text.strip() if title_shape is not None else ""
text_shapes = []
for index, shape in enumerate(slide.shapes, start=1):
if shape.has_text_frame and shape.text.strip():
text_shapes.append((index, shape.text.strip()))
随后判断正文位置是否早于标题位置:
title_position = next((pos for pos, text in text_shapes
if text == title_text), None)
first_body = next((pos for pos, text in text_shapes
if text != title_text), None)
if title_position is not None and first_body is not None:
if first_body < title_position:
issues.append("title_after_body")
这里没有试图判断字体是否漂亮,也没有用大模型猜测语义。它只验证能从文件中确定的结构事实,因此结果可重复,也适合放入 CI 或交付检查脚本。
三、结构化报告
我用脚本生成了一个包含 4 页的测试文稿:正常页、无标题页、以及两页重复标题。实际运行后得到:
{
"ok": false,
"slide_count": 4,
"issue_count": 3,
"issue_counts": {
"duplicate_title": 2,
"missing_title_placeholder": 1
}
}
每页的 issues 还会给出更具体的说明,例如:
{
"slide": 2,
"title": null,
"issues": [
{
"code": "missing_title_placeholder",
"detail": "slide has no title placeholder"
}
]
}
命令行退出码分为:
0:没有发现问题;1:存在结构问题;2:文件读取或处理失败。
这样自动化流程可以先保存 JSON 报告,再只根据退出码决定是否阻断后续步骤。
四、测试结果
脚本使用 unittest 生成了临时 PPTX,覆盖以下场景:
test_clean_titled_slide_passes ok
test_missing_title_is_reported ok
test_title_after_body_is_reported ok
test_duplicate_titles_are_reported ok
Ran 4 tests in 0.044s
OK
其中“正文早于标题”的用例通过调整形状 XML 顺序构造,确保测试验证的是形状阅读顺序,而不只是视觉坐标。
五、适用边界
这种审计适合发现结构性问题,但不能单方面证明演示文稿已经满足所有无障碍规范。颜色对比、替代文本、字体可读性、语言标记和复杂图表说明仍然需要专门检查。
实际使用时,我更建议把这个脚本放在“生成或编辑 PPT”之后、“发布或交付”之前:先用脚本检查标题和顺序,再由渲染工具检查页面截图和溢出。结构验证与视觉验证是两层不同证据,不能互相替代。
工具的价值不一定在于规则数量多,而在于它把容易被人眼忽略、又会影响自动化处理的结构事实变成了可重复的检查结果。
- 点赞
- 收藏
- 关注作者
评论(0)