试卷解析技能 (Exam Parser)
将 Word (.docx) 和 PDF 格式的数学试卷解析为树形结构化 JSON,
输出格式符合参考规范(参照 references/参考.json 和 references/json-format-spec.md)。
触发条件
当用户提出以下意图时主动调用:
- 将 Word/PDF 试卷转为 JSON
- 批量解析试卷文件
- 试题结构化处理
- 题干与答案解析匹配输出
工作流程
步骤 1:确认输入输出
与用户确认:
- 输入的 DOCX/PDF 文件路径(单个文件、多个文件或目录)
- 输出目录(默认为
./已生成文件/或./output/) - 是否需要同时处理题干文件和答案解析文件(如同一试卷拆分为题目 + 答案两个 PDF 的情况)
步骤 2:安装依赖(按需)
运行前确保 Python 虚拟环境安装了必需依赖:
<PYTHON> -m pip install python-docx pdfplumber PyMuPDF
其中 <PYTHON> 使用 managed Python 路径(如 C:\Users\lx\.workbuddy\binaries\python\versions\3.13.12\python.exe)。
步骤 3:解析文件
使用 scripts/main.py 作为入口。必须在 scripts/ 目录下执行,因为 main.py 依赖同级 exam_parser/ 包的相对导入:
cd <SKILL_DIR>/scripts
<PYTHON> main.py <输入文件或目录> -o <输出目录>
支持的命令行参数:
- 单文件:
python main.py 试卷.docx - 多文件:
python main.py 试卷1.docx 试卷2.pdf - 目录批量:
python main.py ./试卷目录/ -o ./output/ - 详细输出:添加
--verbose参数
步骤 4:LaTeX 公式转换(按需)
解析完成后,检查输出 JSON 中的数学公式是否已正确转换为 LaTeX $$...$$ 格式。
如果源文件是扫描版 PDF(图片型,非文字型),OCR 无法可靠识别数学公式,此时应:
- 使用
pypdfium2或PyMuPDF将 PDF 每页渲染为图片 - 手动读取每页图片内容
- 照常调用
scripts/main.py完成文本解析 - 手动将数学表达式转为
$$...$$LaTeX 格式
LaTeX 转换规则:
- 幂:
2^n→$$2^{n}$$ - 下标:
a_n→$$a_{n}$$ - 分数:
\dfrac{分子}{分母}或\frac{分子}{分母} - 求和:
\sum_{i=1}^{n} - 希腊字母:
α→\alpha,β→\beta - 集合:
{x | x > 0}→$$\{x \mid x>0\}$$ ∵→$$\because$$,∴→$$\therefore$$≥→\geqslant,≤→\leqslant- 包含中文的公式用
$$...$$包裹 - 仅包裹数学符号的可用
$$...$$包裹 - 已有 LaTeX 格式的不重复转换
- 保持非公式的中文文本不变
步骤 5:输出验证
确认输出 JSON:
- 树结构正确(L2 根 → L3 元信息/题型章节 → L4 题目)
node_id和parent_id对应关系正确- 各题型特有字段齐全(choice 有 choices/choice_count,blank 有 blank_count 等)
- 答案格式为数组(如
["B"]、["2", "3"]) - 数学公式使用
$$...$$ - body 字段包含正确格式的 HTML 段落
输出格式参考
完整的输出格式规范见 references/json-format-spec.md,参考样本见 references/参考.json。
树结构的核心要点:
- 顶层是数组,根节点 L2 chapter(parent_id 固定为
"n2ore0545") - L3 paragraph 放元信息("建议用时"、"满分"等)
- L3 chapter 放题型标题("一、选择题"、"二、填空题"等)
- L4 question 放具体题目
- 每个节点有唯一
node_id(10 位十六进制 MD5 生成)
代码结构
核心模块位于 scripts/exam_parser/:
| 模块 | 功能 |
|------|------|
| schema.py | 数据模型 + 正则模式(题型匹配、题号匹配等) |
| docx_parser.py | DOCX 解析,含 OMath→LaTeX 转换 |
| pdf_parser.py | PDF 解析,含 pdfplumber/PyMuPDF 双引擎 |
| analyzer.py | 核心分析引擎:识别标题→元信息→题型→题目 |
| formatter.py | JSON 序列化输出 |
| cli.py | 命令行接口 + 批量处理 |
常见问题处理
PDF 是扫描版图片
当 pdfplumber/PyMuPDF 提取不到文字时(输出 body 为空或乱码):
- 安装
pypdfium2:pip install pypdfium2 - 使用 pypdfium2 将 PDF 渲染为图片
- 手动读取每页内容后生成题目数据
- 不要尝试用 Tesseract OCR 处理数学公式(质量太差)
公式识别不完整
DOCX 中的 OMath 公式会被自动转为 LaTeX,但纯文本中的数学表达式(如 2^n)需要在步骤 4 中手动转换。
题型标题匹配失败
analyzer.py 的 SECTION_PATTERNS 支持以下中文格式:
一、选择题/一、单选题/一、多选题二、填空题三、判断题四、解答题/四、论述题/四、证明题/四、计算题五、材料题
如需扩展新的题型标题格式,修改 scripts/exam_parser/schema.py 中的 SECTION_PATTERNS。
Scan to join WeChat group