阿拉伯文、波斯文导出 PDF 后字母断开、顺序颠倒

简短回答

阿拉伯字母的形状随前后字母变化,并且从右往左书写。如果 PDF 工具按从左到右排版,或逐个字母绘制,就会出现孤立的字母和颠倒的顺序。Pandoc 中加上 -V dir=rtl -V lang=ar(波斯文用 lang=fa)并选用支持阿拉伯文的字体;HTML 类工具中设置 dir="rtl",不要对阿拉伯文使用 letter-spacing。

症状复现

Pandoc xelatex 输出的阿拉伯文顺序颠倒
Pandoc 3.5 + xelatex,只设置 -V mainfont="Segoe UI":单词顺序颠倒,波斯文一行完全错乱。
Pandoc lualatex 输出的阿拉伯文顺序错误
Pandoc 3.5 + lualatex(默认渲染器):同一份文档,仍然是从左到右。

原因

  • 书写方向(双向文本):没有设置从右到左时,整行按从左到右排列,单词和字母就会颠倒。
  • 字形拼合:阿拉伯字母有独立、词首、词中、词尾四种形式。不做字形拼合(或逐字绘制)的渲染器只会显示独立形式。
  • letter-spacing 与 html2canvas:Chrome 本身在有字间距时仍保持阿拉伯文连写,但 html2canvas(很多“HTML 转 PDF”按钮用它)会改为逐个绘制字形,字母随即散开(见下图)。
阿拉伯文在有无字间距时,Chrome 与 html2canvas 的渲染对比
实测:letter-spacing: 0.05em 在 Chrome 中仍保持连写,在 html2canvas 1.4.1 中则断开。

打开一份阿拉伯文示例

打开阿拉伯文示例

Pandoc 中的修法(实测有效)

pandoc input.md -o output.pdf \
  --pdf-engine=xelatex \
  -V mainfont="Segoe UI" \
  -V dir=rtl -V lang=ar
Pandoc xelatex 输出的正确阿拉伯文
同一份文档加上 -V dir=rtl -V lang=ar 后:字母连写,从右到左。

波斯文用 lang=fa,乌尔都文用 lang=ur。任何包含阿拉伯字形的字体都可以;Linux 上可用 Noto Sans Arabic 或 Noto Naskh Arabic。

HTML / Chromium 类工具中的修法

md-to-pdf 输出的阿拉伯文段落左对齐
md-to-pdf 5.2.5:字母能连写,但段落按从左到右排列,句末标点和英文单词的位置不对。
  • 设置方向:把 RTL 段落放进 <div dir="rtl">…</div>,或使用 <p dir="auto"> 让每段自动判断方向。
  • 在自定义 CSS 中去掉正文的 letter-spacing。
  • 在服务器和 Docker 镜像中安装阿拉伯文字体(Debian/Ubuntu 可装 fonts-noto-core)。
<div dir="rtl">

مرحبا بالعالم. هذا نص عربي.

</div>

在 MarkPDF 中

MarkPDF 自动识别阿拉伯文、波斯文和乌尔都文:加载对应的 Noto 字体,每个段落、列表、引用和表格按自身内容确定方向。英文与阿拉伯文混排也不需要额外标记。

常见问题

为什么在编辑器里正常,导出 PDF 就不对?

编辑器和浏览器会自动处理阿拉伯文的字形和方向;很多 PDF 流程需要明确设置方向和语言。

需要特殊字体吗?

需要包含阿拉伯字形和 OpenType 拼合表的字体,Noto Sans Arabic、Noto Naskh Arabic、Segoe UI、Tahoma 都可以。

阿拉伯文中夹杂数字和英文怎么办?

方向设为 RTL 后,双向文本算法会让数字和拉丁单词在行内保持从左到右的顺序。

相关指南