| name | math-card-import |
| description | 数学 Anki 卡片导入。将 Markdown 格式的数学知识卡批量导入 Anki(通过 AnkiConnect),
自动处理 MathJax 公式渲染兼容性($...$ → \(...\) 转换)、配图复制、HTML 格式化。
触发条件:用户提到"导入anki"、"anki卡片"、"数学anki"、"牌组导入"、公式在
Anki 中显示不正确、$...$ 公式不渲染、MathJax 兼容性问题、创建/修改/完善 Anki
数学卡片、调整卡片格式。
也用于:已有 Anki 卡片公式显示异常的诊断和批量修复。
|
数学 Anki 卡片导入
将 Markdown 格式的数学知识卡批量导入 Anki,自动处理公式渲染兼容性。
前置条件
- Anki 已启动,AnkiConnect 插件可用(默认
localhost:8765)
- 卡片以 Markdown 文件编写,放在
G:/初中/数学/ 目录下
卡片 Markdown 格式
每张卡片用 ### 卡N 分隔,包含以下字段:
### 卡1
**配图:** 
**提问:** 同底数幂相乘的公式是什么?
**答案:** $a^m \cdot a^n = a^{m+n}$。
**易错分析:** 底数不变,指数相加。
**记忆钩子:** 底同指加,乘对加。(可选字段)
字段说明
| 字段 | 必须 | 说明 |
|---|
**配图:** | 否 | 图片路径,相对于 md 文件的子文件夹。支持 webp/png/jpg |
**提问:** | 是 | 卡片正面内容,支持行内公式 |
**答案:** | 是 | 卡片背面内容,支持行内和显示公式 |
**易错分析:** | 否 | 红色文字显示的易错提醒 |
**记忆钩子:** | 否 | 绿色文字显示的助记口诀 |
公式语法
在 Markdown 源文件中使用标准 LaTeX 语法:
- 行内公式:
$a^2 + b^2 = c^2$ — 导入时自动转为 \(...\) 格式
- 显示公式(块级):
\[ ... \] 或 $$ ... $$ — 保留原始格式
导入脚本位于 G:/初中/数学/import_math_to_anki.py。
MathJax 公式兼容性(关键知识点)
这是最容易出错的部分,务必理解。
问题
Anki(2.1.50+)内置 MathJax,但仅默认支持:
\(...\) 行内公式 ✅
\[...\] 显示公式 ✅
$...$ 行内公式 ❌ 不支持
如果直接将包含 $...$ 的文本导入 Anki,公式会显示为原始 $a^2$ 而不是渲染后的数学符号。
解决方案
导入脚本中的 convert_inline_math() 函数自动处理转换:
def convert_inline_math(text):
"""将 $...$ 行内公式转换为 Anki 支持的 \(...\) 格式。
跳过 $$...$$ 和 \[...\] 显示公式块。"""
return re.sub(
r'(?<!\$)\$(?!\$)(.*?)(?<!\$)\$(?!\$)',
r'\(\1\)',
text
)
转换规则:
$x^2$ → \(x^2\)(行内公式,转换为 \(...\))
$$x^2$$ → $$x^2$$(显示公式,不转换)
\[x^2\] → \[x^2\](显示公式,不转换)
显示公式的换行保护
preserve_display_math() 函数处理 \[...\] 和 $$...$$ 块:
- 块内的换行符替换为空格(防止被
html_field() 转成 <br>)
- 块外的换行符正常转为
<br>
两个字段的不同处理
| 字段 | 处理方式 | 原因 |
|---|
| Front | convert_inline_math() 仅转换公式 | 正面通常为单行文本,不需要 <br> |
| Back | html_field() 转换公式 + 换行转 <br> + 保护显示公式 | 背面可能有多行答案、易错分析、记忆钩子 |
导入流程
标准导入
cd G:\初中
python 数学/import_math_to_anki.py
这会:
- 清空现有"数学"牌组
- 扫描
数学/ 下所有 .md 文件
- 解析卡片、转换公式、复制配图
- 批量导入 Anki(每批 30 张)
仅导入特定文件
修改 import_math_to_anki.py 中的 md_files 路径过滤,或编写针对性的导入脚本。
修复已有卡片公式
当发现已导入的卡片公式不显示时:
批量修复(推荐)
for note in all_notes:
new_front = convert_inline_math(front)
new_back = convert_inline_math(back)
invoke_anki("updateNoteFields", {
"note": {"id": note_id, "fields": {
"Front": new_front, "Back": new_back
}}
})
然后重新导入整个牌组。
单张卡片修复
- 在 Anki 浏览器中找到卡片
- 修改字段中的
$...$ 为 \(...\)
- 保存
验证
检查卡片是否使用正确的格式:
"已知 \(a^2 + a - 1 = 0\),怎样处理含 \(a^3\) 的式子?"
"已知 $a^2 + a - 1 = 0$,怎样处理含 $a^3$ 的式子?"
AnkiConnect API 参考
导入脚本使用的关键 API:
| 操作 | action | 说明 |
|---|
| 检查连接 | version | 返回 AnkiConnect 版本号 |
| 获取牌组 | deckNames | 列出所有牌组 |
| 创建牌组 | createDeck | {"deck": "数学"} |
| 查询卡片 | findNotes | {"query": 'deck:"数学"'} |
| 批量导入 | addNotes | {"notes": [...]} |
| 删除卡片 | deleteNotes | {"notes": [id1, id2]} |
| 更新字段 | updateNoteFields | {"note": {"id": ..., "fields": {...}}} |
| 获取媒体路径 | getMediaDirPath | 返回 collection.media 目录 |
| 卡片详情 | notesInfo | {"notes": [id1, id2]} |
常见问题
Q: 卡片导入后公式显示为原始 $...$ 文本
原因:公式使用了 $...$ 格式,Anki 默认不支持。
解决:运行修复脚本转换所有 $...$ → \(...\),或重新导入(导入脚本已自动转换)。
Q: 显示公式 \[...\] 内部出现多余的 <br>
原因:html_field() 将显示公式块内的换行符错误地转成了 <br>。
解决:确保 preserve_display_math() 在 html_field() 中被优先调用。导入脚本 v2 已修复此问题。
Q: AnkiConnect 连接失败 "Connection refused"
原因:Anki 未启动或 AnkiConnect 插件未安装。
解决:
- 确保 Anki 正在运行
- 检查 AnkiConnect 插件是否已安装(工具 → 附加组件 → 搜索 AnkiConnect)
- 确认端口 8765 未被占用
Q: 配图不显示
原因:图片路径错误或未复制到 Anki 媒体文件夹。
解决:
- 检查 md 文件旁是否有同名子文件夹存放 webp 图片
- 路径格式:
**配图:** 
- 导入脚本会自动复制图片到 Anki 的
collection.media 目录
项目文件结构
G:/初中/数学/
├── import_math_to_anki.py # 主导入脚本
├── 七年级下册/
│ ├── 错题补充-代数易错记忆.md # 卡片源文件
│ ├── 错题补充-代数易错记忆/ # 配图文件夹(webp)
│ │ ├── 01.webp
│ │ └── ...
│ ├── 重要知识点补充-实数坐标系不等式统计.md
│ └── 重要知识点补充-实数坐标系不等式统计/
│ └── ...
添加新卡片
- 在对应的
.md 文件中按格式添加新的 ### 卡N 块
- 如果需要配图,将图片放入同名的子文件夹
- 公式统一使用
$...$ 写法(导入时自动转换)
- 运行
python 数学/import_math_to_anki.py 重新导入