Pandoc系列 - 2. tex → docx 常见问题与解决方案

在处理 tex 文件转换为 docx 文件时,可能会遇到一些问题。

下面是对于一些情况的讨论以及解决方案。

1. 文献问题

1.1 生成参考文献 --citeproc--bibliography

【问题描述】tex 文件使用 bibtex 格式引用文献:

1
2
\bibliographystyle{plain}  % 参考文献格式
\bibliography{bibfile} % bib文件名
执行以下指令进行 texdocx 转换:
1
pandoc -s input.tex -o output.docx
生成的 word 文档中,既没有参考文献列表,正文中的引用 \cite{XXX} 也没有显示

【解决方案】进行 texdocx 转换时添加以下指令:

1
pandoc -s template.tex --citeproc --bibliography=template.bib -o template.docx

说明:

  • --citeproc:让 Pandoc 内置的 “citation processor” 工作:
    • 识别文中的引用(比如 [@Smith2020] 这种 pandoc-style 引用)
    • 按照引用样式把它们排版成真正的引文格式
    • 自动生成文末参考文献列表(bibliography)
  • --bibliography=template.bib:指定参考文献数据库文件。
    • citeproc 会从这个 .bib 里按键值(key)查文献条目。
    • 文献格式和引用格式还有问题,还需进一步调整

1.2 调整文献格式 --csl

  • 不做任何设置的前提下,Pandoc 会使用默认的参考文献格式 Chicago author-date。如下图所示
Chicago author-date 参考文献格式
  • 在使用 Pandoc 进行 texdocx 转换时,可以任意指定 docx 的参考文献格式,并且 docx 的参考文献格式不需要和 tex 中的参考文献格式相同

步骤如下

  • 去 Zotero Style Repository 下载一个数字型样式:在浏览器访问以下网址
    1
    https://www.zotero.org/styles
    搜索 numeric 或 ieee 或 7714 之类,点进去后点击 “Download Style”,保存为本地文件,这里我们将 7714 存为 china.csl。
zotero 下载 GB/T7714 样式
  • meta.yaml 添加

    1
    2
    bibliography: template.bib
    csl: numeric.csl # 或你下载的那个 csl 文件名

  • 执行以下指令进行 texdocx 转换:

    1
    pandoc -s template.tex --citeproc --metadata-file=meta.yaml -o template.docx
    注意,这里指令不再需要

    • --bibliography=template.bib
    • --csl=china.csl

    因为已经在 meta.yaml 中指定了。最后参考文献列表和文章中 \cite 引用效果如下

docx 中 GB/T7714 样式的参考文献 docx 中 \cite 引用样式

2. 字体问题

数学字体

  • ❌:\({\rm d}\) ${\rm d}$ 无法处理,Pandoc 会报错
  • ✅:\(\mathrm{d}\) $\mathrm{d}$ 可以处理,Pandoc 不报错

latex 公式

  • ❌:\(\mathop {\lim }\limits_{t \to \infty } \dot V(e,\tilde \theta )\)$\mathop {\lim }\limits_{t \to \infty } \dot V(e,\tilde \theta )$
  • ✅:\(\lim_{t\to\infty} \dot V(e,\tilde\theta)\)$\lim_{t\to\infty} \dot V(e,\tilde\theta)$

3. 公式问题

3.1 安装 pandoc-tex-numbering 滤波器

【问题描述】章节、公式都没有编号

  • \section{XXX}\subsection{XXX} 等章节编号,在 word 中不显示
  • eqnarray 环境中的公式没有自动编号

【解决方案】安装 pandoc-tex-numbering 滤波器

  1. conda 创建 python 环境

    1
    conda create -n pandoc_py310 python=3.10

  2. 激活环境

    1
    conda activate pandoc_py310
    接下来的操作都在 pandoc_py310 环境下进行。

  3. pip 安装 pandoc-tex-numbering 插件

    1
    pip install pandoc-tex-numbering

  4. 进行 texdocx 转换时使用以下指令:

    1
    pandoc template.tex --citeproc --bibliography=template.bib -F pandoc-tex-numbering -o tempalte.docx

说明:

  • 只改命令行参数是解决不了“自动编号”的问题的
  • 必须加一个专门的 pandoc 过滤器,在 LaTeX→Word 的转换过程中,把 eqnarray 等环境里的编号“补”出来。
  • pandoc-tex-numbering:这个过滤器就是处理从 LaTeX 转成 docx 时【自动编号】的问题。
  • --filter / -F (二者等价):调用外部可执行程序作为过滤器(这里是 pandoc-tex-numbering,所以可以推测:pip 安装 pandoc-tex-numbering 插件后,提供了一个可执行程序)

3.2 eqnarray 环境慎用(这里只是讲解 Pandoc 转换 tex 文件时与 eqnarray 环境不兼容的解决方案,eqnarrayPandoc 结合会有很多问题,本节方案只能解决一部分问题,不能都完美解决,完美方案可以直接阅读 3.2.5 节)

3.2.1 eqnarray 环境中 \nonumber 失效

【问题描述】Pandoc 进行 texdocx 转换时,直接使用eqnarray 环境主要有两个问题:

  • Pandoc 会将 eqnarray 环境中的公式整块处理,不能实现在最后一行添加自动编号
  • eqnarray 环境中的 \nonumber 指令在 Pandoc 中失效

具体见下图 eqnarray 环境中 \nonumber 指令不能正常工作

根本原因:

  • pandoc-tex-numbering 只在multiline-environments 环境,才会识别 \nonumber
  • multiline-environments 环境包括
    • cases
    • align
    • aligned
    • gather
    • gathered
    • multline
    • flalign
  • 注意:multiline-environments 环境不包括 eqnarray 环境

【解决方案1】(☆推荐这种方案) Latex中 eqnarray 环境都替换为 align 环境,这样 \nonumber 指令才可以正常工作

【解决方案2】 把 eqnarray 环境加入 multiline-environments,具体操作有两种途径(以下方案二选一即可)

  • 直接命令行添加 -M

    1
    2
    3
    4
    5
    pandoc template.tex \
    --citeproc --bibliography=template.bib \
    -F pandoc-tex-numbering \
    -M multiline-environments="cases,align,aligned,gather,gathered,multline,flalign,eqnarray" \
    -o template.docx

  • 用 meta.yaml:tex 文件同目录新建一个 meta.yaml

    1
    multiline-environments: "cases,align,aligned,gather,gathered,multline,flalign,eqnarray"
    然后执行以下指令进行转换:
    1
    2
    3
    4
    5
    pandoc template.tex \
    --citeproc --bibliography=template.bib \
    -F pandoc-tex-numbering \
    --metadata-file=meta.yaml \
    -o template.docx

  • 配置好以后,eqnarray 就会像 align 一样按行处理,这一行末尾有 \nonumber 就不会编号。

  • 如果想整个 eqnarray 都不要编号,那就给每一行都加上 \nonumber(包括最后一行)。

  • 如果只想让中间几步不编号,就只在这些行后面写 \nonumber

  • 进行上述操作后,eqnarray 环境中 \nonumber 指令就可以正常工作了,见下图。

eqnarray 环境中 \nonumber 指令正常工作

3.2.2 行间公式环境:默认强制编号

这里行间公式环境指的是 $$...$$\[...\]

  • Pandoc 就是会为 $$...$$\[...\] 这些环境中的公式添加编号。
  • Pandoc 没有办法彻底取消 $$...$$\[...\] 这些环境中的编号

【解决方案】

  • Latex中 $$...$$\[...\] 环境都替换为 align 环境(或者 eqnarray 环境,但是需要进行 3.3 节中的【解决方案2】操作)

  • 然后添加 \nonumber 指令,即可取消编号。

3.2.3 Pandoc 进行 texdocx 转换时,支持用户自定义指令,前提是用户自定义指令需要合法

下面这种自定义指令是可以的

1
\newcommand{\rmd}{{\mathrm{d}}}
下面这种自定义指令不可以(不可以的原因是因为\rm而不是因为自定义)
1
\newcommand{\rmd}{{\rm{d}}}

3.2.4 公式编号含有章节编号

【问题描述】pandoc-tex-numbering 可以为章节和公式添加编号,但是公式编号包含章节编号,但是我们希望全文公式统一编号,不附带章节信息

上述问题具体见下图 公式编号含有章节编号

【解决方案】

  • pandoc-tex-numbering 里有个总的参数 number-reset-level,意思是 在哪一级 section 时把计数器归零

  • 默认 number-reset-level: 1:在每个一级标题(section/chapter)处重置,所以会得到 (6.1)、(6.2) 这种风格;

  • 如果想“永远不重置”,可以设成 0 或一个非常大的数。

  • 具体操作:新建一个 meta.yaml,内容如下

    1
    2
    3
    4
    number-reset-level: 0        # 不随 section 重置
    equation-src-format: "\\qquad({this_num})"
    equation-ref-format: "{this_num}"
    equation-cref-format: "({this_num})"
    然后命令行:
    1
    2
    3
    4
    5
    pandoc template.tex \
    --citeproc --bibliography=template.bib \
    -F pandoc-tex-numbering \
    --metadata-file=meta.yaml \
    -o template.docx

上述方案效果如下 公式编号不包含章节编号

3.2.5 公式引用问题:最好还是禁用 eqnarray

【问题描述】eqnarray 环境经过前面的方案,可以解决一些问题,但在引用上还是会有很多奇怪的问题。比如

  • eqnarray 环境添加 \label 后,其他位置引用公式时用 \eqref 指令,虽然引用标号可以正确显示,但是引用不会自动添加括号
  • 多个 \eqref 公式引用只能保证最后一个有显示,前面的 \eqref 都没有显示

【解决方案】

  • 彻底禁用 eqnarray 环境

    • 彻底放弃 eqnarray,只用 amsmathequation / align / split / aligned 环境
    • 多行只打一 个编号:用 equation + (split / aligned) 套娃写法 (equation 在外层)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      \begin{equation}
      \begin{aligned}
      f(x) &= x^2 + 2x + 1 \\
      g(x) &= \sin(x)
      \end{aligned}
      \label{eq:quadratic}
      \end{equation}

      \begin{align}
      a &= b + c \label{eq:align1} \\
      d &= e - f \label{eq:align2} \\
      g &= h \nonumber \\
      i &= j + k \label{eq:align3}
      \end{align}
    • 不想编号的多行:老老实实在每行加 \nonumber
    • \label + \eqref,括号交给 pandoc-tex-numberingmetadata 控制
  • 创建 meta.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    # Pandoc-TeX-Numbering 过滤器设置
    number-reset-level: 1 # 编号随 section 重置,不重置设为 0

    # 公式编号设置
    number-equations: true # 让过滤器接管所有公式编号
    equation-src-format: "\\qquad({num})" # 公式右侧显示:(1)
    equation-ref-format: "({num})" # \ref / \eqref 显示:(1)
    equation-cref-format: "({num})" # 若将来用 \cref 也是加括号

  • 执行

    1
    2
    3
    4
    5
    pandoc template.tex \
    --citeproc --bibliography=template.bib \
    -F pandoc-tex-numbering \
    --metadata-file=meta.yaml \
    -o template.docx

4. 交叉引用编号问题

4.1 公式引用

以 “公式 (3.1)” 为例:

  • {num} = 完整编号串:“3.1”
  • {this_num} = 当前层的编号:“1”
  • {parent_num} = 上一层编号(就是章节号):“3”

所以:

  • 要 3.1 这种编号 → 用 number-reset-level: 1 控制,按 section 重置
  • 想在 中只要 “3.1” → {num};
  • “{prefix}{num}” → “3.1” (默认 “.” 连接)
  • “{prefix}-{num}” → “3-1”

4.2 定理引用

1
2
3
4
\usepackage{amsthm}
\newtheorem{thm}{定理}
\newtheorem{lem}[thm]{引理}
\numberwithin{thm}{section} % thm 计数器随\section重置

创建 meta.yaml

1
2
3
4
5
6
7
8
# 定理编号设置
number-theorems: true # 让过滤器接管所有定理编号
prefix-space: true # “定理 3.1”中“定理”和“3.1”之间空格
theorem-names: "thm,lem" # 告诉过滤器:有 \begin{thm} 和 \begin{lem} 环境
theorem-thm-prefix: "定理" # 前缀文字(引用时显示)
theorem-lem-prefix: "定理" # 前缀文字(引用时显示)
thm-thm-src-format: "定理 {parent_num}.{this_num}" # 源位置的格式:“定理 3.1”
thm-thm-ref-format: "{num}" # \ref{thm:stab} 的显示:“3.1”

然并卵

【Pandoc的局限】

  • 定理编号和引用强制从 1 开始
  • {parent_num}.{this_num} 对于定理环境失效

4.3 图片引用

创建 meta.yaml

1
2
3
4
5
6
# 图片编号设置
number-figures: true
figure-prefix: "图"
fig-src-format: "{prefix}{parent_num}-{this_num}" # “图 3-1”
fig-cref-format: "{prefix}{parent_num}-{this_num}" # \cref 同样样式
fig-ref-format: "{parent_num}-{this_num}" # \ref 只要数字
执行
1
2
3
4
5
pandoc template.tex \
--citeproc --bibliography=template.bib \
-F pandoc-tex-numbering \
--metadata-file=meta.yaml \
-o template.docx

4.4 表格引用

Latex 中表格建议这样写(因为下面方式与Pandoc兼容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
\begin{table}[htbp]
\centering
\caption{控制器参数整定结果}
\label{tab:ctrl-params}
\begin{tabular}{ccc}
\hline
参数 & 数值 & 说明 \\
\hline
$K_p$ & 1.2 & 比例系数 \\
$K_i$ & 0.5 & 积分系数 \\
$K_d$ & 0.01 & 微分系数 \\
\hline
\end{tabular}
\end{table}

创建 meta.yaml

1
2
3
4
5
6
# 表格编号设置
number-tables: true
table-prefix: "表"
table-src-format: "{prefix}{num}" # 出现在 caption 里的格式:表3.1 控制器参数整定结果
table-ref-format: "{num}" # \ref{tab:...} 输出:3.1
table-cref-format: "{prefix}{num}" # \cref{tab:...} 输出:表3.1
执行
1
2
3
4
5
pandoc template.tex \
--citeproc --bibliography=template.bib \
-F pandoc-tex-numbering \
--metadata-file=meta.yaml \
-o template.docx


Pandoc系列 - 2. tex → docx 常见问题与解决方案
http://yylustb.github.io/2025/11/19/software/Pandoc/Pandoc_2/
作者
yylustb
发布于
2025年11月19日
许可协议