老师把一学期的课件丢在群里,十几份 docx 和 pptx。想在里头搜某个概念,翻半天找不到;复制进笔记软件更糟,编号全变成 1.,表格散成一行竖线,公式直接成了一张图。我用 pandoc 3.13 把这批讲义转成 Markdown,转了十几份,坑比预想的多。
装它只需要解压,但体积要有心理准备
Windows 包 pandoc-3.13-windows-x86_64.zip 是 43MB(42,983,200 字节),解压出来一共 4 个文件,其中 pandoc.exe 一个就 239MB——里面带着 Lua 5.4 引擎和几十种格式的读写器,不用另外装运行时,也不用改 PATH,放个固定目录用绝对路径调就行。
速度按三轮取样取中位数:5 页的 pptx 111ms,10 页左右的 docx 455ms,12 万字的讲义 804ms,峰值内存 90MB 上下。日常转一份课件基本是按下回车就完事,真正花时间的是后面改格式。
第一个坑:中文段落被按四十五个字折断
pandoc 默认按 72 列折行,它数的是字符不是显示宽度,一个汉字算一列,于是段落平均每 45 个字就被插一个换行。我把 12 万字的讲义转了两遍:加 --wrap=none 出来 3000 行,不加是 4200 行,多出来的 1200 个换行全在段落中间。那份 docx 只有 42KB,转出来的 md 是 117,358 字符,检索起来比在 Word 里翻页快得多。
Markdown 里单个换行是软换行,多数渲染器当空格处理,看不出问题。但只要你的笔记软件或博客把单换行当 <br>,每段中间就硬生生断一行。我用的这套渲染就是这样,第一版讲义在网页上像被人拿剪刀剪过。
这条没得商量,--wrap=none 永远加上。
同一个毛病还有个小号版本:docx 里每个项目符号都是独立段落,转出来项与项之间会多一个空行,渲染成三个彼此独立的小列表,间距拉得很开。想紧凑就手动把空行删掉,列表项之间不留空行。
第二个坑:表格格式选错,整张表报废
pandoc 有两个看着差不多的输出目标,-t markdown 和 -t gfm。前者出的表格是 grid table,用一串横线把单元格围起来;后者出的才是 | 分隔的管道表。
同一份讲义我两种都转了一遍,再拿自己这套渲染器跑:
| 输出格式 | table 标签 | 实际样子 |
|---|---|---|
-t markdown | 0 个 | 三行数据当普通段落,竖线横线糊成一片 |
-t gfm | 1 个 | 正常表格 |
Obsidian、Typora 对 grid table 是认的,所以不算绝对的错,问题在跨平台。要往博客、wiki、论坛贴,选 gfm;只在自己电脑上看,随便哪个都行。
第三个坑:图片出来的不是 Markdown 图片
这是最费时间的一处。同一份讲义,docx 里的图转出来是:
<img src="media/media/image1.png" style="width:3.93701in;height:2.46063in" />
一行 HTML。而 pptx 里的图转出来是 ,标准 Markdown,但尾巴上挂了个 title。
两种都可能坏。先整体转义 HTML 再解析的渲染器(不少论坛和 wiki 就这么干)会把第一行当文字原样显示出来;第二行的 title 会让一部分解析器匹配不上图片语法,我这边就是整行原文露在正文里。
还有个容易误会的地方:--extract-media=assets 抽图时会保留压缩包内的原路径。docx 的图落在 assets/media/image1.png,pptx 落在 assets/ppt/media/image1.png。看到 media/media 这种叠了两层的路径不是 bug,别去删它。
图抽出来后得自己改地址。我用一行正则把 HTML 换回 ,再把相对路径换成图床的绝对地址,改完渲染器能认出 1 个 img 标签。
第四个坑:公式能转,但转成什么方言看格式
Word 公式编辑器打的公式是 OMML,pandoc 认得,会转成 LaTeX。-t markdown 给的是标准的 $X(\omega) = \frac{1}{2\pi}\int_{-\infty} e^{j\omega t} dt$;-t gfm 给的是 $ + 反引号包起来的那版,美元符号里还裹一对反引号——这是防止正文里的美元金额被误认成公式。
但只要你贴的地方不渲染数学,两种都白搭:反引号那版会被当行内代码,页面上显示成一串等宽字体的 LaTeX 源码,比原来那张公式图还难看。我这份讲义公式不多,最后是把几个关键公式截图放进去的,比修语法省事。
第五个坑:pptx 的备注,转完一条都不剩
课件里最值钱的往往是备注。老师把"这里考试常考""这个推导不用背"写在备注里,投出来的幻灯片上看不见。
我做的测试 pptx 里写了 3 条备注,转成 gfm、markdown、纯文本三种,一条都没出现。pandoc 读 pptx 时只取幻灯片上的形状,备注页根本不读。要留备注只能在 PowerPoint 里另存讲义版,或者手动抄。
顺带一个:没有标题的页会被自动命名成 Slide 5 这类名字,转出来就成了一个叫「Slide 5」的小标题,得手动改。
第六个坑:参数错位时报错信息会骗人
--extract-media 后面如果直接跟 -o,它会把 -o 当成目录名吃掉,后面的输出路径就变成了输入文件。报错是:
z.md: withBinaryFile: does not exist (No such file or directory)
看着像"文件没找到",实际是参数错位,z.md 是它以为的输入文件名。第一次碰到这个,我以为是路径写错了,来回查了十分钟。
反过来,-o 指到一个不存在的目录,pandoc 会自己把目录建出来,退出码 0,什么都不提示。你还在找报错,文件已经躺在新建的目录里了。另外拿 -f docx 去读 pptx,报的是 couldn't parse docx file: DocxError,退出码 63,这两条命令的差别只在扩展名。
我最后用的命令
pandoc 讲义.docx -t gfm --wrap=none --extract-media=assets -o 讲义.md
然后一步后处理,把 HTML 图换成标准写法:
node -e "const s=require('fs').readFileSync('讲义.md','utf8').replace(/<img\s+src=\"([^\"]+)\"[^>]*>/g,(m,u)=>``);require('fs').writeFileSync('讲义.md',s)"
转完先看三件事:表格那几行是不是 | 开头;正文里还有没有 <img 残留在外面;每个段落是不是都只占一行。这三条过了,格式基本就干净了。
你们把课件转成笔记是用什么,还是干脆不转、直接在 PDF 上批注?