我正在尝试使用将 markdown 文件转换为 pdf pandoc
。由于我的markdown包含中文字符,我使用以下命令来生成pdf:
pandoc --pdf-engine=xelatex -V CJKmainfont=KaiTi test.md -o test.pdf
但是pandoc抱怨该文件包含它无法处理的非utf8字符,确切的错误消息是:
生成 PDF 时出错。
!未定义的控制序列。
pandoc.exe:无法解码字节 '\xbd':>Data.Text.Internal.Encoding.streamDecodeUtf8With:无效的 UTF-8 流
根据我在互联网上找到的信息。这很大程度上是由于markdown文件的编码造成的,可能与pandoc无关。我的文件包含很多汉字和英文字符。我已经将其转换为utf-8编码。
我尝试过但没有成功的事情
我尝试将文件传输到我的 CentOS 服务器并查找无效字符在哪里,或者只是删除无效字符。但没有成功。
Grep 查找非 utf8 字符
按照指示进行操作这里和这里(事实上,我在两篇文章中尝试了多个最佳答案,但它们不起作用)。我已验证系统区域设置设置为 UTF-8,输出为localectl status
:
System Locale: LANG=en_US.UTF-8
VC Keymap: us
X11 Layout: us
我尝试 grep 查找非 utf8 字符。使用的命令是grep -axv '.*' test.md
.但该命令没有输出任何内容。 (我认为这意味着不存在无法通过 utf-8 解码的无效字符。)
尝试丢弃无效字符
我按照说明进行操作这里尝试从我的文件中删除非 utf8 字符。我使用的命令是:
iconv -f utf-8 -t utf-8 -c test.md > output.md
之后,当我尝试output.md
使用pandoc
.我仍然遇到相同的错误消息,这表明该文件仍然包含非 utf8 字符。
我的问题
令我惊讶的是,上述方法不起作用。如何查明文件的哪个部分导致问题或如何解决真的从文件中删除非 utf8 字符以便编译时不会出现错误?
其他信息
你可以找到markdown文件这里。
如果您使用的是Linux系统,您可能需要设置
CJKmainfont
为系统中其他有效的中文字体名称。在Linux系统上,从Markdown生成带有中文文本的pdf的命令似乎应该是(将字体更改为有效字体):
pandoc --latex-engine=xelatex -V CJKmainfont=KaiTi test.md -o test.pdf
答案1
好吧,经过长时间的与问题的斗争和挖掘。我终于找到了问题的根本原因。
原因
问题是,在 中test.md
,以反斜杠开头的文本存在于多个位置,这些位置实际上应该被视为文字。例如,
* 一般现在时\过去时\将来时,simple present\past\future
* 现在(过去\将来)进行时,present(past\ future) continuous
* 现在(过去\将来)完成时,present(past\future) perfect
* 现在(过去\将来)完成进行时,present(past\future) perfect continuous
上段中的反斜杠只是作为不同情况的分隔符。这是有效的降价。但不幸的是它们是由 pandoc 命令处理的。
解决方案
请改用以下命令:
pandoc -f markdown-raw_tex --pdf-engine=xelatex -V CJKmainfont=KaiTi test.md -o test.pdf
或者使用反斜杠扭曲以反斜杠开头的文本(但这并不总是需要的)或仅使用两个反斜杠。
有些想法
Pandoc 的错误消息具有误导性,因为该问题与 UTF-8 解码无关。我不知道为什么错误信息是这样的。
另外,这个问题的错误消息似乎并不一致。例如,对于上面包含反斜杠的文本。如果你使用编译它
pandoc -f markdown --pdf-engine=xelatex -V CJKmainfont=KaiTi test.md -o test.pdf
错误消息将类似于:
生成 PDF 时出错。
!未定义的控制序列。
l.75 一般现在时间\过去时间
那么找到问题出在哪里就会容易很多,而不是去挖掘utf-8相关的问题。
后续行动
这确实是 xelatex 中的一个错误。当遇到无效的控制序列时,它可能会产生无效的 utf-8 字节。但 pandoc 只是假设它接收到的是有效的 utf-8 序列。因此出现了错误。更详细的解释请参见这个帖子。
更新2017.12.29
随着Pandoc 2.0.6 发布,这种行为处理得更恰当:
允许对 Latex 错误日志进行宽松的解码,这些日志并不总是正确的 UTF8 编码
现在,调试此类问题变得更加容易。
答案2
pandoc
抱怨字节\xbd
(十六进制“bd”),因此 grep 。例如
grep -n $'\xbd' file
例如,如果我创建一个包含 4 行的小文件,其中一行包含以下\xbd
字符:
a
b
c½
d
然后grep -n
会告诉我它在第 3 行:
$ grep -n $'\xbd' file
3:c½
注意:$'\xbd'
需要像 bash 这样的 UNIX shell。查看man bash
并搜索“报价”了解详情。
顺便说一句,该\xbd
字符是扩展的 ascii 字符。它可能是一个损坏的 unicode 序列(许多 unicode 字符都具有0xbd
其字节值之一)。在我的屏幕上,它显示为“1/2”分数。以下是ascii
对此的看法:
$ ascii bd
ASCII 11/13 is decimal 189, hex bd, octal 275, bits 10111101: meta-=