从 Office 文档(PPT/PPTX/DOCX)和 ChemDraw 文件(CDX/CDXML)中提取化学结构,生成带分子表与反应步骤的 Markdown 摘要。
Extract chemical structures from Office documents and ChemDraw files, then generate Markdown summaries with molecule tables and reaction steps.
⚠️ 声明
- 本项目包含 AI 生成的代码。
- 部分功能正在开发中,敬请期待。
chem_summarizer 是一个面向化学/药物研发工作者的命令行工具,用于把含有 ChemDraw 嵌入对象的 Office 文档以及独立的 ChemDraw 文件批量转换成结构化的 Markdown 摘要。它直接解析 ChemDraw 的私有二进制格式(CDX),无需安装 ChemDraw、无需调用 COM 组件或 obabel,因此可以在没有 Chemistry 软件的环境下运行。
| 格式 | 处理路径 | 依赖 |
|---|---|---|
.cdx |
CDX 二进制解析器 → RDKit SMILES | rdkit |
.cdxml |
XML 解析 → RDKit SMILES | rdkit |
.pptx |
ZIP 解压 → OLE 提取嵌入 CDX | rdkit + olefile |
.docx |
ZIP 解压 → OLE 提取嵌入 CDX | rdkit + olefile |
.ppt |
PowerPoint COM 转 PPTX → 同 .pptx |
Windows + PowerPoint(见 .ppt 文件支持) |
- 自带 CDX 二进制解析器:直接读取 ChemDraw 二进制流(
VjCD标识),解码Document / Page / Fragment / Node / Bond / Text / Graphic / Scheme / Step等对象与属性标签,不依赖 ChemDraw COM。 - 零外部化学软件依赖:除 Python + RDKit + olefile 外不需要任何化学软件;CDX/CDXML 解析全部在进程内完成。
- 反应识别:解析 ChemDraw 的
Scheme / Step结构,提取原料、产物、箭头上方条件、下方产率,并通过箭头图形属性判断反应类型(done/retro/design/failed)。 - Morgan 指纹相似度过滤:对多片段反应使用 Morgan 半径 2、2048 位的 Tanimoto 相似度筛选最优原料-产物对,过滤标签展开产生的伪片段。
- 标签展开三级优先级:① 手工
LABEL_EXPAND_SMILES表(权威)→ ② CDX 内嵌Fragment→ ③ ChemDraw 官方nicknames.json(甲基帽约定)→ ④ 元素解析。 - 文献引用识别:基于 Endnote 风格期刊缩写关键词 + 4 位年份双重信号检测,自动插入
[引用]标签并汇总到“参考文献”小节。 - 跨平台路径处理:支持 WSL2 与 Windows 原生路径互转,
.ppt文件可从 WSL2 调用powershell.exe完成转换。
- Python ≥ 3.9(支持 3.9 / 3.10 / 3.11 / 3.12 / 3.13)
- rdkit ≥ 2022.03 — 分子图构建、SMILES/InChI 生成、Morgan 指纹
- olefile ≥ 0.46 — 从 Office ZIP 中解析 OLE 复合文档以提取嵌入的 CDX
.ppt转换(可选):需要 Windows + 已安装 PowerPoint,通过powershell.exe调用 PowerPoint COM 自动化(Presentations.Open/SaveAs(..., 24))完成.ppt → .pptx转换
非 Windows 环境(纯 Linux / macOS)不支持
.ppt输入;.cdx / .cdxml / .pptx / .docx均可正常使用。
源码托管于 GitHub。下面给出 Windows 原生与 WSL2 两种环境的安装方式。
在 PowerShell 或 cmd 中:
# 1. 克隆仓库
git clone https://github.com/HX0922/chem_summarizer.git
cd chem_summarizer
# 2. 创建虚拟环境(推荐)
python -m venv .venv
.venv\Scripts\activate
# 3. 安装 rdkit(rdkit 在 PyPI 上由 rdkit 轮子提供)
pip install rdkit>=2022.03 olefile>=0.46
# 4. 以可编辑模式安装本包(同时注册 chem-summarizer 命令)
pip install -e .安装完成后可直接调用:
chem-summarizer --version在 WSL2 的 bash 中:
# 1. 克隆仓库
git clone https://github.com/HX0922/chem_summarizer.git
cd chem_summarizer
# 若在 WSL2 ext4 开发(推荐,性能更好):
# cd ~/projects/chem_summarizer
# 2. 创建虚拟环境
python3 -m venv .venv
source .venv/bin/activate
# 3. 安装依赖与本包
pip install rdkit>=2022.03 olefile>=0.46
pip install -e .在 WSL2 中处理
.ppt文件时,本工具会自动通过wslpath -w/ UNC 路径 (\\wsl.localhost\<distro>\...) 把 Linux 路径转换为 Windows 路径,再调用powershell.exe启动 PowerPoint COM。要求 WSL2 所在的 Windows 主机已安装 PowerPoint。
通过 pyproject.toml 声明的 console_scripts,安装后提供 chem-summarizer 命令:
chem-summarizer file1.pptx file2.cdxml file3.docx file4.cdx也可以用模块方式调用(无需安装步骤,适合开发期):
python -m chem_summarizer.summarizer file.pptx命令行参数:
| 参数 | 说明 |
|---|---|
files |
一个或多个输入文件路径(.ppt / .pptx / .docx / .cdx / .cdxml) |
--version |
打印版本号 chem_summarizer 0.1.0 后退出 |
每个输入文件会在其同目录下生成 {原名}_summary.md(后缀由 config.py 中的 OUTPUT_SUFFIX 控制)。运行时会在临时目录 chem_summarizer_* 中暂存提取出的 CDX,处理完成后自动清理。
控制台示例输出:
=== report.pptx ===
→ /path/to/report_summary.md
Locations: 12, SMILES: 34 (unique: 21), Reactions: 5
核心函数均在 chem_summarizer 包中导出:
from chem_summarizer import (
process_file, # 处理单个文件并生成 Markdown
parse_cdx_binary, # 解析 CDX 二进制数据(返回文档对象树)
parse_cdxml, # 解析 CDXML 文件(返回 dict: text/molecules/reactions/fragment_count)
parse_reaction_steps, # 从 CDXML ElementTree 提取反应步骤
extract_cdx_from_zip, # 从 Office ZIP 中提取嵌入的 CDX 到指定目录
build_fragment_smiles, # 把单个 <fragment> 节点转换为 SMILES
)一键处理示例:
from chem_summarizer import process_file
# 在同目录下生成 report_summary.md
process_file("report.pptx")直接解析 CDX 二进制并拿到分子/反应:
from chem_summarizer import parse_cdx_binary
from chem_summarizer.summarizer import process_cdx_via_parser
result = process_cdx_via_parser("drawing.cdx")
print(result["molecules"]) # OrderedDict: {canonical_smiles: {"inchi": "..."}}
print(result["reactions"]) # list[dict]: reactants/products/conditions/yield_text/arrow_type
print(result["text"]) # 排除原子标签后的文本
print(result["fragment_count"]).ppt(旧版二进制格式)无法直接解析,需要先转换为 .pptx,由 ppt_to_pptx()(chem_summarizer/summarizer.py:779)完成:
- Windows:原生支持。直接调用本机的
powershell.exe启动 PowerPoint COM:$ppt = New-Object -ComObject PowerPoint.Application,打开后SaveAs($out, 24)另存为 PPTX,转换超时 120 秒。 - WSL2:支持。自动通过
wsl_to_win()把 WSL 路径转为 Windows 路径(/mnt/c/...→C:\...,必要时通过wslpath -w或\\wsl.localhost\<distro>\...UNC 路径),再调用宿主 Windows 上的powershell.exe。 - 非 Windows(纯 Linux / macOS):不支持
.ppt。请先在 Windows/PowerPoint 中另存为.pptx,或用 LibreOffice 等工具转换后再处理。
尝试在纯 Linux 上处理 .ppt 会得到 PPT conversion failed 的提示。
所有可调参数集中在 chem_summarizer/config.py,可直接编辑该文件,或通过环境变量覆盖 Nicknames 路径。
| 变量 | 作用 | 默认值 |
|---|---|---|
CHEM_SUMMARIZER_NICKNAMES_DIR |
覆盖 ChemDraw Nicknames 目录搜索路径(用于 generate_nicknames.py 重新生成 nicknames.json) |
未设置时使用 NICKNAMES_SEARCH_PATHS 中的两条默认路径 |
默认 Nicknames 搜索路径(config.py):
NICKNAMES_SEARCH_PATHS = [
Path("C:/ProgramData/RevvitySignalsSoftware/ChemDrawApplications/ChemDraw/ChemDraw Items/Nicknames"),
Path("/mnt/c/ProgramData/RevvitySignalsSoftware/ChemDrawApplications/ChemDraw/ChemDraw Items/Nicknames"),
]| 参数 | 默认值 | 作用 |
|---|---|---|
SIM_THRESHOLD_MULTI |
0.25 |
多对多反应步骤中,Morgan Tanimoto 相似度低于此值的原料-产物对会被丢弃 |
SIM_THRESHOLD_SINGLE |
0.15 |
1:1 反应步骤的结构相似度下限,低于此值视为误识别 |
HA_RATIO_MAX |
3.0 |
原料/产物重原子数比值上限,比值超过此值或低于 1/3 的反应被跳过 |
MIN_CARBONS |
6 |
碳原子数低于此值的片段不计入有效分子(过滤小分子/离子) |
OUTPUT_SUFFIX |
"_summary.md" |
输出 Markdown 文件名的后缀 |
CITATION_JOURNAL_KEYWORDS |
见源码 | 用于文献检测的 Endnote 风格期刊缩写关键词列表(ACS / RSC / Wiley / Nature / Cell / Elsevier / Springer / 中国化学期刊等) |
ELEMENT_SYMBOLS:周期表元素集合(大小写不敏感匹配)。EXPANDABLE_LABELS:标签 → 主元素映射(如OMe → O、NHBoc → N),用于 CDXML 解析器回退与 CDX 元素解析。包含占位符R/R1/R2/R3 → C、X/Y/Z → O、PG → C、LG → O。LABEL_EXPAND_SMILES:手工核对的标签 → SMILES 展开表(权威优先级最高),覆盖常见羰基/含硫/含硅/卤代/烷基/芳基/含氧/含氮/保护基/有机金属等缩写。nicknames.json:由generate_nicknames.py从 ChemDraw 官方 Nicknames 目录生成,运行时由get_nickname_table()懒加载。
生成的 *_summary.md 按以下顺序组织:
- 文件头:文件名、类型、大小、提取日期、CDX 对象数、分子片段数、有效分子数。
- 📄 文本内容(按位置):按 Slide / 段落 分组,包含 Office 原文与每个 CDX 对象的
[CDX]文本及[分子]SMILES 列表;文本中的文献会自动加[引用]标签。 - ⚗️ 反应 (N 步):四列表格,箭头类型映射为
done / retro / design / failed / -。 - ⚛️ 全分子对照表 (N 个):
SMILES | InChI两列表,按 SMILES 排序去重。 - 📚 参考文献 (N 条):从全部
[引用]文本中用正则抽取“期刊名 + 年份 + 卷 + 页码”,去重排序。
# report.pptx — 化学信息摘要
**文件类型**: .pptx | **大小**: 342 KB | **提取日期**: 2026-07-15
**CDX 对象**: 8 | **识别分子片段**: 23 | **有效分子**: 15
---
## 📄 文本内容(按位置)
### Slide 1
Suzuki 偶联合成苯联吡啶 [引用] J. Am. Chem. Soc. 2021, 143, 1024
[CDX] Pd(PPh3)4, K2CO3, dioxane/H2O, 80 °C
产率: 85%
[分子]
`c1ccc(-c2ccccc2)cc1`
---
## ⚗️ 反应 (2 步)
| 原料 | 条件 / 产率 | 产物 | 反应类型 |
|:--|:--|:--|:--:|
| `Brc1ccccc1` | Pd(PPh3)4, K2CO3<br>产率: 85% | `c1ccc(-c2ccccc2)cc1` | done |
---
## ⚛️ 全分子对照表 (15 个)
| SMILES | InChI |
|:--|:--|
| `Brc1ccccc1` | InChI=1S/C6H5Br/c7-6-4-2-1-3-5-6/h1-5H |
| `c1ccc(-c2ccccc2)cc1` | InChI=1S/C12H10/c1-3-7-11(8-4-1)12-9-5-2-6-10-12/h1-10H |
---
## 📚 参考文献 (1 条)
- J. Am. Chem. Soc. 2021, 143, 1024箭头类型映射:
Solid/FullHead/Bold → done、Hollow/RetroSynthetic → retro、Angle/Dashed/NoHead/Wavy/Equilibrium → design、Crossed → failed、Dipole → -。
chem_summarizer/
├── chem_summarizer/ # 主包
│ ├── __init__.py # 包入口,导出公共 API 与 __version__
│ ├── summarizer.py # 主逻辑:CDX 二进制解析、Office 提取、Markdown 生成、CLI main()
│ ├── config.py # 配置:Nicknames 路径、阈值、引用期刊关键词、OUTPUT_SUFFIX
│ ├── label_tables.py # 标签查找表(周期表、缩写→元素、缩写→SMILES、nickname 加载)
│ └── nicknames.json # ChemDraw 官方 nickname → SMILES 映射(运行时懒加载)
├── generate_nicknames.py # 从 ChemDraw Nicknames 目录重新生成 nicknames.json
├── pyproject.toml # 包元数据、依赖、console_scripts 入口
├── requirements.txt # pip 依赖(rdkit>=2022.03, olefile>=0.46)
├── LICENSE # MIT (Copyright (c) 2026 HX0922)
├── .gitignore # 忽略 __pycache__/、*_summary*.md 等
└── README.md
- CDX 解析:仅解码已知对象标签与属性(
0x0402元素、0x0600键级、0x0604/0x0605键端点、0x0700文本、0x0C0x反应引用、0x8021箭头等)。未知属性会被跳过;嵌套深度超过 1000 层会报错以防损坏文件。 .ppt输入:必须依赖 Windows + PowerPoint COM;纯 Linux/macOS 不支持。- 占位符标签回退:
EXPANDABLE_LABELS中的通用占位符X / Y / Z默认解析为O,R / R1 / R2 / R3 / PG默认解析为C,LG默认O。这些是启发式默认值,可能与作者本意不符。 - 反应识别:仅识别 ChemDraw 中显式绘制的
Scheme/Step;未绘制箭头/未分组到 Step 的结构不会进入反应表。重原子数比 >3.0或 Morgan 相似度 < 阈值的反应会被过滤。 - 最小分子过滤:碳原子数
< 6的片段(MIN_CARBONS)不计入分子表,可能导致小分子试剂/溶剂被忽略。 - 引用抽取:依赖正则
期刊名 + 4 位年份 + 卷 + 页码格式;不符合该格式的引用可能被遗漏或截断。
nicknames.json 由 generate_nicknames.py 从 ChemDraw 安装目录下的官方 Nicknames 文件夹(每个 .cdxml 对应一个 nickname 的 SMILES 定义)生成:
# 方式 A:使用 config.py 中的 NICKNAMES_SEARCH_PATHS 自动定位
python generate_nicknames.py
# 方式 B:显式指定 Nicknames 目录
python generate_nicknames.py "C:\ProgramData\RevvitySignalsSoftware\ChemDrawApplications\ChemDraw\ChemDraw Items\Nicknames"
# 方式 C:用环境变量覆盖搜索路径
CHEM_SUMMARIZER_NICKNAMES_DIR="/mnt/c/ProgramData/.../Nicknames" python generate_nicknames.py脚本会遍历目录下所有 *.cdxml,解析其中的 <fragment> 节点,调用 build_fragment_smiles() 生成 SMILES,写入 chem_summarizer/nicknames.json(与运行时 get_nickname_table() 读取的路径一致)。无法解析的条目会打印到 stderr(默认仅显示前 5 条错误)。
python -m chem_summarizer.label_tables
# LABEL_EXPAND_SMILES: N entries
# EXPANDABLE_LABELS: M entries
# NICKNAME_TABLE: K entries
# ELEMENT_SYMBOLS: 118 elementsMIT License — Copyright (c) 2026 HX0922。详见 LICENSE。