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

The org-mode LaTeX exporter: LaTeX for non-TEXers

作者: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

此处需要考虑的事项包括

  1. 标题限制: 将标题限制设置为 H:3 会将 org 中的所有 **** 标题(第 4 级及更高级别)转换为枚举,标题和文本作为 LaTeX 中的 \item。我个人使用 org 列表代替。这使得文档更易于编辑。

  2. 目录: toc:t 将在文档开头,标题正下方添加目录。

  3. 要导出的 LaTeX 类: article 或 report 是不错的选择。选择将影响不同的标题级别如何转换为 LaTeX。article 将对所有级别依赖 \section{} 和 friends,而 report 将为 org 中的 1 级标题生成 \chapter{},默认情况下,这将在每个章节之前生成分页符。

  4. 文档类的选项: #+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. 第二个元素

    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 }}]
  1. 看看我们是否可以拥有标签

  2. 看起来漂亮

  3. 有意义

  4. 使整个事情正常工作。

如你所见,编号的内联列表产生更漂亮的输出。项目符号内联列表需要进一步自定义,因此请尝试使用它们以使其适合你的需求。

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}]]'])
Approaching the golden relation with Fibonacci
图 1:使用斐波那契逼近黄金关系 

如果你通过将光标放在 #+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}
Approaching the golden relation with Fibonacci
图 2:在 Python 代码中生成的绘图

或直接使用 org

#+ATTR_LATEX: :width .7\textwidth :placement [H] 

#+CAPTION: The plot inlined 

#+NAME: plot3 

[[file:./images/python-matplot-fig.png]]

这将产生

Approaching the golden relation with Fibonacci
图 3:使用 org 块内联的绘图 

当然,引用图形会有所不同。我可以将 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

Pedro A. Aranda Gutiérrez 博士目前在大学讲授计算机网络相关主题,他在一家大型电信公司的研发部门工作多年,并在那里迷上了 Emacs。在空闲时间,他喜欢阅读和听音乐。

加载 Disqus 评论