org-mode LaTeX 导出器:非 TEX 用户也能使用 LaTeX

作者:Pedro A. Aranda Gutiérrez。本文展示了如何配置和使用 Emacs 提供的 org-mode 来生成漂亮的文档。org 是一种多用途结构化文本文件格式,Emacs 可以将其转换为 LaTeX 文件,而 LaTeX 文件又可以转换为漂亮的 PDF 文档,从而充分利用 LaTeX 提供的所有排版功能。本文汇集了在使用 Emacs、org-mode 和 LaTeX 过程中积累的技巧。
1 简介
我在 20 世纪 90 年代接触到 Emacs,当时我在工作中使用 Unix 大型机和 VT220 终端。一开始,它只是我的程序员编辑器,当我习惯它后,我开始寻找可以在家使用的移植版本。最初这是一个梦想,但后来变成了现实,首先是移植版本 [10],然后当我安装了我的第一个 Linux(来自一套软盘)。很久以后,我开始接触 LaTeX。直到我攻读博士学位时,我才完全理解它的潜力,当时我的 Office 套件在会议的最后一刻模板更改时崩溃了。我花了更少的时间安装完整的 texlive 发行版,将我的论文导出为 LaTeX,清理结果并更改模板,而不是在更改模板后修复原始文档。我一直喜欢 LaTeX 的一点是,你写的就是你想要的。对我来说,标签的使用只是一个小小的麻烦。
在 LaTeX 之后,你写的就是你想要的路径中的下一步是 org-mode。最初是我的博士生导师提示说这是一种制作幻灯片的不错方式,但我花了一些时间才意识到它在演示文稿和文档方面的全部潜力。org-mode 包含在 Emacs 的库存代码中。
你始终可以站在最前沿,从存储库中获取最新公开版本的 org-mode,但相当新的 Emacs 版本可以保证 org-mode 中拥有出色且最新的功能集。就我而言,我使用 Emacs 28.0.9x,这是下一个稳定 Emacs 的预发布版本,我每周在 Ubuntu 20.04 和 macOS 上自行编译一次。如果你想从 org-mode 生成漂亮的 PDF 文件,你需要依赖其 LaTeX 导出器,并使用 TEX 发行版,例如 Linux 中的 texlive 或 macOS 中的 MacTeX 进行排版和输出生成。
为了证明我的观点,我将本文保存在 org 文件中,我用它来探索 org 模式的功能。这是一个生动的演示,展示了如何使用 org-mode 漂亮地编写内容,然后使用 LaTeX 生成 PDF。我的主要灵感来源是 org-mode 文档 [8] 和一本较旧的 Cookbook [4],以及所有那些我在处理文档时感觉缺少某些东西的时刻。
2 Emacs 调整
想象一下,你正在处理一个文档,并且可以直接隐藏节内容并处理文档结构以调整节的顺序等等。这证明了学习 org-mode1 的努力是值得的。现在,将 LaTeX 导出功能添加到使本文成为可能的等式中。我希望我已经证明了我的观点。为了体验 org-mode,我建议使用 Emacs27(或更新版本)。Emacs 的优点之一是我们能够根据自己的需要进行自定义。你可以通过将 Emacs Lisp 代码添加到你的 Emacs 初始化文件 2 或启动时将加载的文件中来完成此操作。让我们看看我们需要添加到其中以激活 org-mode 的内容。
2.1 激活 org-mode 和 LaTeX 导出
为了确保 org-mode 已加载,你需要添加以下内容
code (require 'org)
建议你使用以下代码自定义 org-mode 变量
(setq org-src-preserve-indentation t org-src-fontify-natively t org-export-latex-listings t org-latex-listings 'listings org-latex-prefer-user-labels t org-confirm-babel-evaluate nil org-latex-pdf-process '("latexmk -bibtex -f %f") org-babel-python-command "/usr/bin/env python3") (add-to-list 'org-latex-packages-alist '("" "listings"))
要激活 LaTeX 导出,你需要使用以下命令导入 ox-latex
(require 'ox-latex) in your .emacs.d/init.el file.
2.2 激活外部语言执行
为了能够在 org org 文件中执行 Python 代码,你需要在加载 org 模式后激活它。以下代码将完成这项工作(请注意,我们使用 (progn) 来允许在 =org-babel-do-languages" 调用之后跟随更多代码)
(eval-after-load "org" (progn (org-babel-do-load-languages 'Org-babel-load-languages '((python . t))) ) )
1 并添加导出到 LaTeX 功能(不,只是开玩笑)。
2 Emacs 初始化文件通常是 ~/.emacs.d/init.el
还有许多其他优秀的语言和程序可以与 org-mode 很好地集成。例如,ditaa [9] 用于快速图表,PlantUML [7] 用于更复杂的序列图和类图。它们不难集成,并且会为你的文档和演示文稿增添额外的亮点。
2.3 唾手可得的成果:本地文件变量
Emacs 不仅可以通过启动时加载的 Lisp 代码进行自定义。与大多数编辑器一样,它可以加载特定于正在编辑的文件的自定义设置,通过本地变量。
在 Emacs 中使用自动段落填充很容易。最初可以通过 # eval: (<elisp code>) 并将 fill-column 变量设置为例如 80,在文件末尾的本地变量块中完成此操作
# fill-column: 80 # eval: (auto-fill-mode t)
本地变量中的附加 eval 语句应有助于你设置 flyspell 的语言。建议你相信自己,并允许 eval: 继续进行,而无需询问是否应执行它。为此,请添加
;; Define safe local variables (setq enable-local-eval t)
到你的 Emacs 初始化代码。或者,在你的 org-mode-hook 中包含 (auto-fill-mode t)。我更喜欢在每个文件的基础上进行操作,因为我也使用 org-mode 来制作 Beamer 演示文稿,并且我不习惯在那里启用 auto-fill-mode。
2.4 直接保存和导出
Emacs 为你提供了 hooks 来扩展你执行许多操作的方式,包括保存文件。要进行操作,你需要编写一个函数来实现附加功能,并将其添加到 Emacs 初始化文件中的相应 hook。
如果我们希望在文件保存后自动添加导出到 LaTeX 功能,我们需要创建一个函数来调用导出器,并将其添加到 Emacs 初始化文件中的 after-save-hook 中。因为如果正在保存的文件是要导出到 LaTeX 的 org 文件,那么调用 LaTeX 导出器是有意义的。但这并非不言而喻,因为一旦你开始使用 org-mode,你可能希望在其他任务中使用它。检查当前缓冲区是否正在使用 org-mode 并查找指定 LATEX_CLASS3 的行的简单方法是
(defun org-mode-save-export () "Export the current buffer to latex if we are in org-mode and the file contents hints LaTeX" (interactive) (when (check-mode (list 'org-mode))
3 此函数仅在你只想让 org-mode 导出到 LaTeX 文档时才有效。它需要扩展以处理演示文稿。
(save-excursion (goto-char (point-min)) (when (re-search-forward "^#\\+LATEX_CLASS: \\([^ ]+\\)$" (point-max) t 1) (message "Exporting to LaTeX...") (org-latex-export-to-latex)))))
你需要将此函数添加到 Emacs 初始化文件中的 after-save-hook 中
(add-hook 'after-save-hook #'org-mode-save-export
2.5 PDF 预览
你可以使用键序列 C-c C-e l o 或从菜单中选择 Org → Export-publish,然后选择 [l] Export to LaTeX 和 [o] As PDF file and open,直接在 Emacs 上预览生成的 PDF。
或者使用外部 PDF 预览器查看结果。当使用外部预览器时,你可以依赖 latexmk [3] 和一个小脚本,在导出的输出可用后对其进行编译。latexmk 可以直接驱动你的 PDF 预览器。
#!/bin/bash filename="${1%.*}" while :; do [ -f ${filename}.tex ] && break sleep 1 done latexmk -pvc ${filename}
将此脚本作为起点,并根据你的需要进行扩展。你可能希望从中启动 Emacs 以编辑 org 文件,然后在退出脚本(或 Emacs)时自动清理你的目录。此外,请阅读 latexmk 文档,使其适应你的 PDF 预览器和你系统中的其他特性。
或者,探索在 Emacs 中查看 PDF 文件的其他方法。你可以从 PDF tools [6] 开始探索。
3 org 设置:文档序言
现在你已经为 org 准备好了 Emacs,你可以开始编辑了。调用 emacs 时,请确保你处理的文件具有 .org 扩展名。这将激活 Emacs 中的 org-mode。
为了激活 LaTeX 导出器,文档需要以序言开头来设置环境,其中包括你使用的 LaTeX 包,以及可能进行的一些调整以使其按你喜欢的方式工作。最常见的标头版本如下所示。
#+TITLE: <title here> #+SUBTITLE: <subtitle here> #+LATEX_CLASS: article #+LATEX_CLASS_OPTIONS: [a4paper,11pt,twoside] #+OPTIONS: toc:nil H:3
此处需要考虑的事项包括
-
标题限制: 将标题限制设置为 H:3 会将 org 中的所有 **** 标题(第 4 级及更高级别)转换为枚举,标题和文本作为 LaTeX 中的
\item
。我个人使用 org 列表代替。这使得文档更易于编辑。 -
目录: toc:t 将在文档开头,标题正下方添加目录。
-
要导出的 LaTeX 类: article 或 report 是不错的选择。选择将影响不同的标题级别如何转换为 LaTeX。article 将对所有级别依赖
\section{}
和 friends,而 report 将为 org 中的 1 级标题生成 \chapter{},默认情况下,这将在每个章节之前生成分页符。 -
文档类的选项:
#+LATEX_CLASS_OPTIONS:
行控制文档的排版方式。与示例中的#+LATEX_CLASS:
行一起,导出器创建以下 LaTeX 代码
\documentclass[a4paper,11pt,twoside]{article}
3.1 包含参考文献
我倾向于使用单个参考文献文件,其文件名与主 org 文件相同,扩展名为 .bib。我在 biblatex 中使用的参考文献包,以及我在 bibtex 中的后端,可以从我的参考文献文件中获益。
我在文档标题中的参考文献设置如下
# Bibliography #+LATEX_HEADER: \usepackage[backend=bibtex]{biblatex} #+LATEX_HEADER: \bibliography{\jobname.bib}
要打印参考文献,只需在文件末尾(或你想放置它们的位置)包含以下内容
#LATEX: \printbibliography
如果你需要参考文献部分出现在目录中(至少在 PDF 信息中),你需要包含
#+LATEX_HEADER: \defbibheading{bibliography}[\refname]{\section{#1}}
在上面的标题中 4。
3.2 使用 fancyvrb 格式化列表
使用 fancyvrb
包而不是默认的 listings。最好的方法是欺骗 org-mode,使其认为你确实正在使用 listings 包,然后重写所有内容以使用 fancyvrb
,如下所示
#+LATEX_HEADER: \RequirePackage{fancyvrb} #+LATEX_HEADER: \DefineVerbatimEnvironment{verbatim}{Verbatim}{fontsize=\scriptsize} #+LATEX_HEADER: \DefineVerbatimEnvironment{lstlisting}{Verbatim}{fontsize=\scriptsize}
4 参考文献标题的默认定义使用 \section*{#1}
,这排除了编号,因此也排除了添加到目录中。当使用 report 类时,请考虑使用 \chapter{}
代替。
或者,如果你想以不同的颜色(例如蓝色)获得结果
#+LATEX_HEADER: \usepackage{color} #+LATEX_HEADER: \RequirePackage{fancyvrb} #+LATEX_HEADER: \DefineVerbatimEnvironment{verbatim}{Verbatim}{fontsize=\scriptsize,formatcom=\color{blue}} #+LATEX_HEADER: \DefineVerbatimEnvironment{lstlisting}{Verbatim}{fontsize=\scriptsize}
使用 xcolor 包而不是 color 将允许你对颜色进行分级,例如 blue!50。此外,强烈建议你放置
#+LATEX_HEADER: \usepackage{upquote}
在配置列表后,以便在从生成的 PDF 文件复制和粘贴时获得正确的单引号和双引号字符。注意:如果你想包含代码并确保它永远不会执行,BEGIN_EXAMPLE=/=END_EXAMPLE 块非常方便。这些块将使用 LaTeX 中的 lstlisting 环境导出。
3.3 在文档中使用无衬线字体
你可以通过在标题中包含以下行,以无衬线字体(如 Helvetica)排版文档
#+LATEX_HEADER: \usepackage{helvet} #+LATEX_HEADER: \renewcommand\familydefault{\sfdefault}
3.4 更改文档的外观
你还可以将更改文档外观的指令放在标题中。在此示例中,我们在本文档中使用以下指标
#+LATEX_HEADER: \setlength{\textheight}{230mm} #+LATEX_HEADER: \setlength{\textwidth}{160mm} #+LATEX_HEADER: \setlength{\voffset}{-10mm} #+LATEX_HEADER: \setlength{\oddsidemargin}{0mm} #+LATEX_HEADER: \setlength{\evensidemargin}{0mm} #+LATEX_HEADER: \addtolength{\parskip}{0.33\baselineskip} #+LATEX_HEADER: \setlength\parindent{0pt}
3.5 org 列表
此行将允许你在文档中包含 org-mode 代码作为列表
#+LATEX_HEADER: \lstdefinelanguage{org}{}
3.6 当标题变得太长时
值得考虑将所有文档自定义选项直接放在 LaTeX 文件中,并使用以下命令包含它
#:LATEX_HEADER: \input{mycustom}
特别是当它开始增长时,尽管你失去了“一个文件适用于所有内容”的感觉,但这也很不错。但是,如果你想包含冗长的自定义设置或更多编程语言,这可能会有所回报。你的 mycustom.tex 文件和文档标题中也可以混合搭配一些内容。
3.7 摘要
你可以通过包含 #+BEGIN_abstract/#END_abstract
块,为你的文章添加摘要
#+BEGIN_abstract ...The abstract text… #+END_abstract
摘要的第一段将缩进。使用 \noindent
删除缩进。
3.8 附录
这不完全是标题的一部分,但它控制文档的基本外观,最终也控制目录的外观。如果你需要区分正文和附录,例如,对于之前讨论的参考文献,只需包含
#+LATEX: \appendix
在你希望正文结束的文档中的点处。在此行之后,可以放置任何内容并将其编号为附录。
3.9 暂时放弃的事项
不起作用的事情之一是使用 #+LANGUAGE:
指令选项在 Emacs 中设置 fly/ispell-mode 的字典。它仅在 PDF 标题中生成指令。
#+LANGUAGE: es
仅在 TEX 文件中生成以下输出
\hypersetup{ … pdfcreator={Emacs 28.0.91 (Org mode 9.5.2)}, pdflang={Es} }
4 org-mode 优点
org 和 LaTeX 的适当混合使文档焕发光彩。请记住,由于 org-mode 在某种程度上也是 LaTeX,因此我们可以在 org 文档中使用大量 LaTeX 代码,例如 \ldots
、\LaTeX
、内联数学表达式等。一个值得注意的例子是 \linebreak
命令。有时 LaTeX 对换行符的排版不正确,你需要像在原生文档中一样插入它,以控制行不会溢出你的边距。另一个候选命令是 \clearpage
。如果你需要额外的分页符来使最终结果看起来更好,请在编辑过程结束时使用它。
如果你需要更大的 LaTeX 代码块,可以使用以下命令嵌入它
#+begin_export LaTeX <your LaTeX code here> #+end_export
让我们深入研究导出器,并检查 org-mode 文档结构如何导出到 LaTeX,以及你如何影响它们的导出方式。
4.1 表格
org 表格已正确转换为 LaTeX
表 1
示例表格
org LaTeX
测试 1 测试 2
测试 3 测试 4
此表是从以下代码生成的
#+label: tab1 #+caption: The sample table #+ATTR_LATEX: :environment longtable :align p{2cm}p{3cm} :placement [H] :center t | =org= | \LaTeX | |-------+--------| | test1 | test2 | | test3 | test4 |
如果你没有显式定义 environment:,则导出器使用 tabular 环境。要引用此表,你需要使用 org 方式,即 Table\nbsp{}[[tab1]]
,这将在文档中生成表 1。值得检查不同环境设置生成的 LaTeX 代码。在进一步介绍表格时,我们将探讨如何使用 Python3 创建表格。
4.2 列表
让我们测试 org 中不同列表类型生成的环境。起点是 https://orgmode.org/manual/Plain-lists-in-LaTeX-export.html。
LaTeX 中的基本列表环境不是在文档中生成漂亮列表的最佳选择。你可以通过扩展列表创建的不同包获得更好的控制。enumitem 包非常方便,因为它提供了逐行列表和内联列表。要使用它,请在文档标题中包含以下行
# Compacted lists #+LaTeX_HEADER: \usepackage[inline]{enumitem} #+LaTeX_HEADER: \setlist{nosep}
如果你不进一步自定义列表,这就是带有 - 标记的列表的处理方式
-
第一个元素
-
第二个元素
-
一个子元素
-
这就是带有 1. 的列表,子元素为 1) 的处理方式
-
第一个元素
-
第二个元素
-
一个子元素
-
带有数字顺序的元素始终为 1.、2. 等,数字子元素始终为 (a)、(b) 等。
现在进行一个实验:尝试使用 itemize*
来
-
在同一段落中拥有列表
-
使它们看起来漂亮
-
使整个事情正常工作
要生成这种枚举,列表的序言必须是
#+ATTR_LATEX: :environment itemize* #+ATTR_LATEX: :options [itemjoin={,}, itemjoin*={, and }]
不要再次使用 enumerate* 到 1. 看看我们是否可以拥有标签,2. 看起来漂亮,3. 有意义,以及 4. 使整个事情正常工作。
要获得最后一个列表,你需要以下代码
#+ATTR_LATEX: :environment enumerate* #+ATTR_LATEX: :options [itemjoin={{, }}, itemjoin*={{, and }}]
-
看看我们是否可以拥有标签
-
看起来漂亮
-
有意义
-
使整个事情正常工作。
如你所见,编号的内联列表产生更漂亮的输出。项目符号内联列表需要进一步自定义,因此请尝试使用它们以使其适合你的需求。
4.3 使用 Python3 生成文档内容
你可以在文档中包含 Python 代码,以动态生成列表、表格、图形甚至文档内容。通用 org 块结构为:
#+BEGIN_SRC python :results output :exports both <your Python code here> #+END_SRC #+RESULTS:
这将对 Python 代码列表进行排版,然后在 #+RESULTS:
行中显示脚本生成的输出(到 stdout)。
这是 Python3 中用于简单斐波那契数列生成器的示例。
MAX_FIBO = 13 fibo = [ None ] * MAX_FIBO golden = [ None ] * MAX_FIBO fibo[0],golden[0] = 0,0 fibo[1],golden[1] = 1,1 for n in list(range(2,MAX_FIBO)): fibo[n] = fibo[n-1] + fibo [n-2] golden[n] = fibo[n-1] / fibo[n] print (' '.join([f'{f:5d}' for f in fibo[1:]])) print (' '.join([f'{g:.3f}' for g in golden[1:]])) 1 1 2 3 5 8 13 21 34 55 89 144 1.000 1.000 0.500 0.667 0.600 0.625 0.615 0.619 0.618 0.618 0.618 0.618
在第二个示例中,我们使用 :results value
而不是 :results output
,即
#+BEGIN_SRC python :results value :exports both <Python code> return <something> #+END_SRC #+RESULTS:
用脚本返回的值替换 #+RESULTS:
MAX_FIBO = 13 fibo = [ None ] * MAX_FIBO golden = [ None ] * MAX_FIBO fibo[0],golden[0] = 0,0 fibo[1],golden[1] = 1,1 for n in list(range(2,MAX_FIBO)): fibo[n] = fibo[n-1] + fibo [n-2] golden[n] = fibo[n-1] / fibo[n] return '\n'.join([' '.join([f'{f:<5d}' for f in fibo[1:]]), ' '.join([f'{g:.3f}' for g in golden[1:]])]) 1 1 2 3 5 8 13 21 34 55 89 144 1.000 1.000 0.500 0.667 0.600 0.625 0.615 0.619 0.618 0.618 0.618 0.618
如你所见,你需要在 :results output
和 :results value
之间明智地选择,因为它会影响代码的复杂性。
org-mode 将代码设置在 lstlisting 中,并将结果设置在 verbatim 环境中。因此需要在文档标题中重新定义这两个环境,如第 3.2 节所示。
请记住,你需要在 Emacs 的 org-mode 自定义中激活 Python 执行。如果你信任你的代码,你可以声明 Python 代码是安全的:
(eval-after-load "org" progn ;; enable python for in-buffer evaluation org-babel-do-load-languages 'org-babel-load-languages '((python . t))) ;; all python code be safe setq org-confirm-babel-evaluate nil) setq org-babel-python-command "python3")) )
4.4 混合和组合
让我们尝试使用 Python 生成表格并导出它。我们可以使用我们在第 4.1 节中学到的大部分内容。
下面的代码暗示了 tabulate.tabulate() 的扩展版本,该版本允许你使用导出的表格中的 attr_latex
设置标签、标题和 LaTeX 属性。此版本是 https://github.com/paaguti/python-tabulate 提供的原始代码的分支。
Python 代码应设置在带有 :noweb
标头的块中
#+header: :noweb strip-export #+BEGIN_SRC python :results value raw :exports both <Python code> #+END_SRC #+RESULTS:
以下代码生成了一个漂亮的表格
import math import pandas as pd import tabulate xvals = [math.pi * i / 5 for i in range(10)] df = pd.DataFrame({ 'x': xvals, 'sin(x)' : [math.sin(xvals[i]) for i in range (10)], 'cos(x)' : [math.cos(xvals[i]) for i in range (10)] }) return tabulate.tabulate(df, headers=df.columns, tablefmt='orgtbl', floatfmt=".3f", caption='Table exported from Python with extended tabulate', label='labextend', attr_latex=':environment longtable :align p{2cm}p{3cm}p{3cm} :placement [h] :center t', showindex=False)
表 2:从 Python 导出的带有扩展 tabulate 的表格
x sin(x) cos(x)
0.000 0.000 1.000
0.628 0.588 0.809
1.257 0.951 0.309
1.885 0.951 -0.309
2.513 0.588 -0.809
3.142 0.000 -1.000
3.770 -0.588 -0.809
4.398 -0.951 -0.309
5.027 -0.951 0.309
5.655 -0.588 0.809
4.5 图形、放置等
为了方便图形放置,建议在文档标题中包含 float 包
#+LATEX_HEADER: \usepackage{float}
让我们探索生成图形的方法。我们将使用 Python3 生成一个图形,该图形显示如何使用斐波那契数逼近黄金关系
import matplotlib, os matplotlib.use('Agg') import matplotlib.pyplot as plt figure = './images/python-matplot-fig.png' fig=plt.figure(figsize=(6,4)) MAX_FIBO = 13 index = [ n for n in range(MAX_FIBO) ] fibo = [ None ] * MAX_FIBO golden = [ None ] * MAX_FIBO fibo[0],golden[0] = 0,0 fibo[1],golden[1] = 1,1 for n in list(range(2,MAX_FIBO)): fibo[n] = fibo[n-1] + fibo [n-2] golden[n] = fibo[n-1] / fibo[n] plt.plot(index, golden) fig.tight_layout() plt.savefig(figure) return '\n'.join(['#+ATTR_LATEX: :width .7\\textwidth :placement [H]', '#+CAPTION: Approaching the golden relation with Fibonacci', '#+NAME: plot2', f' [[file:{figure}]]'])

如果你通过将光标放在 #+BEGIN_SRC
行上直接执行代码,你可以看到生成的 org 代码,并且你的 PDF 文件中将获得重复的图形。你需要删除此代码才能使图形仅包含一次。
正如你所观察到的,代码块返回一个多行字符串,其中包含控制图形外观和标题的序言,以及对其中创建的文件的 org 样式引用。你可以在代码中使用此策略。你需要将代码括在如下所示的 SRC 块中
#+header: :noweb strip-export #+BEGIN_SRC python :results value raw :exports both <your Python code> #+END_SRC #+RESULTS:
为了使此代码块正常工作,你需要在导出到 LaTeX 之前手动创建目录 ./images
。或者,你需要在 org 文件的开头包含以下源块,以确保目录存在
#+BEGIN_SRC python :results raw :exports none import os try: os.mkdir('./images') except Exception as e: return f'# Exception creating the image directory: {e}' return '# OK' #+END_SRC #+RESULTS:
执行后,该块将在你的 org 文件中添加注释,并且在生成的 PDF 文件中不会显示任何内容。在此块之后,你还可以包含以下行
#+LATEX_HEADER: \DeclareGraphicsExtensions{.png, .pdf} #+LATEX_HEADER: \graphicspath{{./}{images/}}
以避免在 LaTeX 块中引用图形时必须编写目录和文件名扩展名
\begin{figure}[H] \centering \includegraphics[width=.5\textwidth]{python-matplot-fig} \caption{\label{fig:test1}The plot produced in the Python code} \end{figure}

或直接使用 org
#+ATTR_LATEX: :width .7\textwidth :placement [H] #+CAPTION: The plot inlined #+NAME: plot3 [[file:./images/python-matplot-fig.png]]
这将产生

当然,引用图形会有所不同。我可以将 LaTeX 方式 (\ref{fig:test1}
) 用于图 2,将 org 方式(即 [[plot2]]
)用于图 1 或图 3。
4.6 首字母缩略词
在标题中包含 acronym 包,如下所示
#+LATEX_HEADER: \usepackage[printonlyused,nohyperlinks]{acronym}
然后在末尾使用 LaTeX 块,其中包含首字母缩略词定义(以及可选的节/章标题)
#+begin_export LaTeX \section{Acronyms} \begin{acronym} \acro{pdf}[PDF]{Portable Document Format} \end{acronym} #+end_export
这样,你可以使用 \ac{pdf}
来统一拼写出 PDF 首字母缩略词,并将其放在文档末尾的首字母缩略词列表中。
4.7 如果文档增长……
如果你的文档增长并开始变得难以管理,org-mode 允许你将其拆分为子文档,并使用 #+INCLUDE:
指令将它们包含到你的主文档中。这在 org-mode 手册 [5] 中进行了解释。对于那些具有 LaTeX 经验的人来说,这大致等同于 \input{}
指令。但是,#+INCLUDE:
允许你控制文档的包含方式。
5 结论:以及从这里开始……
你在这里看到的只是开始。使用 org-mode 是一种不错的 LaTeX 入门方式。LaTeX 提供了无数的包。除了使用 Python3 生成表格和图形外,你可能还想了解一下如何使用 TiKZ 包为文档编程图形,并使用以下命令包含它们
#+LATEX: \input{myfig}
LaTeX 还具有用于编写演示文稿的包。org-mode 支持使用 beamer 包 [2] 编写演示文稿。org-mode 中基本演示文稿的外观和感觉等同于大多数 Office 包(如 LibreOffice)的轮廓模式。由于 Beamer 只是另一个 LaTeX 包,因此使用你在此处学到的所有内容都没有限制。
如果你想使用 org 和 beamer 制作演示文稿,你需要扩展 org-mode-save-export 函数,以检测你何时想要导出到 LaTeX 以及何时生成演示文稿。在生成演示文稿时,你必须使用 org-beamer-export-to-latex 函数而不是 org-latex-export-to-latex 函数(请参阅第 2.4 节)。
但这不仅仅是使用 Python 从实验数据生成文档和演示文稿,org-mode 还可以用于其他用途。我已经开始使用 Emacs 动态生成实验室脚本。受到 [1] 的启发,我使用 org-mode 记录了许多关于 Emacs 的实验。我需要在我的 org-babel-load-languages 列表中包含 shell,并进一步探索导出选项,因为某些文本模式界面产生的输出比文档有用或合理的输出更多。但是,在某种意义上,你一举两得。
首字母缩略词
PDF 便携式文档格式
参考文献
[1] Howard Abrahams。Literate DevOps。2014 年 11 月。http://howardism.org/Technical/Emacs/literate-devops.html.
[2] Eric S. Fraga。在 org-mode 中编写 Beamer 演示文稿。2022 年 2 月。https://orgmode.org/worg/exporters/beamer/tutorial.html.
[3] Matthias Geier。使用 Latexmk。https://mg.readthedocs.io/latexmk.html.
[4] Eric H. Nielsen。Emacs org-mode 示例和 Cookbook。2015 年 7 月。http://ehneilsen.net/notebook/orgExamples/org-examples.html.
[5] Org mode 手册:包含文件。https://orgmode.org/manual/Include-Files.html.
[6] PDF Tools。2020 年 5 月。https://github.com/politza/pdf-tools。
[7] PlantUML。使用 PlantUML 绘制 UML。https://plantuml.com/guide.15
[8] Org 模式中的 Python 源代码块。2021 年 1 月。https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-python.html.
[9] Stathis Sideris。ditaa:通过 ASCII 艺术进行图表绘制。2021 年 1 月。https://github. com/stathissideris/ditaa.
[10] Delorie Software。获取 djgpp。2007 年 1 月。http://www.delorie.com/djgpp/getting.html。