教程 · PDF → Markdown
PDF 转 Markdown,为什么结构是猜的
这儿别的转换器读的都是文件里真有的结构。这一个读不到,因为 PDF 里没有结构。
PDF 存的是带字号的字符和它们的坐标。「这是个标题」这句话不在文件里。所以结构是推断出来的 —— 知道它是怎么推的,就知道它什么时候会推错。
PDF 里没有结构
PDF 是个打印格式。它的活儿是把对的字形放到纸上对的位置,办法是存一段段带位置和字体的文字。文件里没有任何一处说哪一段是标题、哪儿是段落结尾、这六行是个项目符号列表。
所以 Word 文档是「转换」,PDF 是「重建」。下面写的每一条都是启发式规则,每条规则都有它判错的情况。这就是为什么无论看起来正不正常,每次转 PDF 都会在输出上方给出一条提示。
手上有原始的 .docx 就用它。那个能正经转,因为结构真在里面。
标题是怎么找出来的
先算正文字号:把每行的字号按它含多少字符加权统计一遍,最常见的那个胜出。按字符数而不是按行数加权是有讲究的 —— 一行长正文对「正文字号是多少」的说服力,比一行短标题大得多。
然后:明显比正文大、而且短的行算标题。字号比例定级别:1.6 倍以上是 #,1.35 倍是 ##,1.15 倍是 ###。原来的标题层级已经没了,所以留下来的只是相对关系 —— 这几个标题彼此是同一级。
长度上限是 120 个字符,它挡的是一种具体的判错:一份文档开头那段正文用大字排,那不是标题,而单看字号分不出来。长度能分出来。
这条也是最常猜漏的一条。用字重而不是字号做标题的文档 —— 加粗但和正文同样大 —— 完全没有字号信号,那些标题出来就是段落。
页眉页脚、分段和列表
页眉页脚在两个条件同时成立时被丢掉:比正文小,而且落在离上下边缘 9% 页高以内。用比例而不是固定值,所以 A4 和 Letter 表现一致。不然一个页码或者一个「机密」水印会在正文里打断你四十次。
分段看的是行间垂直空隙有没有超过这行自己字号的 1.8 倍。PDF 就是这么表达一次分段的,因为里面没有段落标记可读。
列表看行首字符:一个项目符号字形(•、·、▪、◦、‣、∙),或者最多三位数字后面跟一个点或者右括号。用别的方式画出来的列表,在转换器眼里不是列表。
被行尾断开的词
PDF 会在行尾用连字符断词,直接拼起来你会拿到「re- port」。规则是:一行以连字符结尾、下一行以小写字母开头,就把这两行拼回一个词 —— 这个组合几乎每次都是断行连字符。
下一行是大写字母的时候连字符留着。「state-of-the-art」在「state-」后面断开,连字符会保留,这是对的,因为那一个是词的一部分。
中文、日文、韩文的行之间不加空格。这些文字本来不用空格分词,每次断行插一个空格就是往句子中间塞一个缝。
The quarterly re-
port is attached.The quarterly report is attached.扫描件什么都出不来
如果一页是文字的图片 —— 扫描、拍照、传真 —— 文件里没有字符可读,只有一张位图。转换器会明说然后停下,而不是回一个空文档让你以为是 bug。
从那种页面里取文字要靠 OCR,这个工具没有这个能力。一份有些页是扫描、有些不是的 PDF,能转的页会转,出来是空的那些会列出页码,最多列六个。
两个上限:25 MB 和 500 页。都是为了不让浏览器标签页卡死 —— PDF 是在你的浏览器里渲染的,没有服务器参与。
多栏排版怎么办
双栏是最难的一种,只能尽力。文字按文件里存的顺序读,做得规矩的双栏 PDF 是一栏读完再读下一栏,做得不规矩的是两栏一行一行交替。读之前没有可靠的办法知道你手上是哪一种。
表格和公式是同一个故事:PDF 里的表格是几根线加摆在坐标上的文字,没有任何东西标明它是个表格。预期是拿到几行分开的文字,而不是一张竖线表格。
准备手工修的话把页标记打开。它会在每页前面插一个 HTML 注释,这样你能找到出问题那段来自第几页,回去对照原文。
…第一页结束。…第一页结束。
<!-- page 2 -->
## Method把 PDF 拖进来,然后读一下输出上方的提示 —— 它会说哪些页跳过了,也会提醒你结构是推断出来的。全程在你的浏览器里读,文件不上传。
PDF → MD