> For the complete documentation index, see [llms.txt](https://ayakaleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ayakaleaf-pro.ayaka.space/latex/zh-cn/shen-du-wen-zhang/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md).

# LuaTeX 入门（第 1 部分）：它是什么——以及它为何如此不同？

LuaTeX 是一个 *工具包*——它包含复杂的软件工具和组件，你可以用它们构建（排版）各种各样的文档。本文的副标题还提出了关于 LuaTeX 的两个问题：它是什么——又是什么让它如此与众不同？对“它是什么？”的回答似乎显而易见：“它是一个 TeX 排版引擎！”确实如此，但更广义地看——本文作者也赞同这种看法——LuaTeX 是一个极其多才多艺的、基于 TeX 的 *文档构建与工程系统*.

### LuaTeX 解析：从哪里开始？

本文第一篇关于 LuaTeX 的文章旨在提供一个理解这款 TeX 引擎所提供内容及其设计为何/如何使用户能够为复杂的排版和设计问题构建/设计/创建广泛解决方案的背景——也许还能在一定程度上提供“面向未来”的保障，因为用户越来越需要能够适应不断变化技术生态的基于 TeX 的软件。在本文作者看来，在建立对 LuaTeX 的能力和潜力的理解时，列出并描述其特性/功能并不一定是最佳起点。对于不熟悉其他 TeX 引擎的读者来说，这种方法帮助不大，而且基于特性的比较对他们而言可能并不特别有意义。

冒着耗尽读者耐心的风险（“直接说重点！”），我将采取一种更“整体”的方法，希望提供有用的背景，但代价是需要额外阅读一些内容——并深入几个编程主题以帮助理解。在 [第 2 部分](/latex/zh-cn/shen-du-wen-zhang/09-an-introduction-to-luatex-part-2-understanding-directlua.md) 我们探讨使用 `\directlua` 但现在，我们先尝试为理解 LuaTeX 奠定基本基础。

本文强烈反映了作者在逐步理解并欣赏 LuaTeX 过程中的个人“旅程”：先了解一些 LuaTeX 开发背后的理念，并将其视为一个软件工具容器，你就能更好地体会这款令人惊叹的软件所开启的广阔解决方案领域。

## LuaTeX：不只是为学术界或数学！

LuaTeX 内置的丰富特性和功能，不仅能通过传统 LaTeX 提供异常高质量的排版，还为开发定制的、非基于 LaTeX 的复杂文档制作与工程问题解决方案提供了巨大空间。LuaTeX 内嵌了强大的 Lua 脚本语言，这意味着例如你可以使用 Lua 将“插件”（外部软件库）加载到 LuaTeX 中；这进一步实现了高度自动化、与现有软件系统或工作流程的集成，并可利用专用软件进行数据、文本或图形处理。

从历史上看，TeX 一直与学术写作/出版相关，尤其是在数学领域，但 LuaTeX 尤其在许多其他领域中也具有重要的应用潜力——包括商业 PDF 文档制作。一个这样的例子是 [speedata publisher](https://speedata.github.io/publisher/) 它在基于 XML 的工作流程中纯粹将 LuaTeX 用作 PDF 生成引擎——它完全不使用 LaTeX。事实上，speedata publisher 几乎不包含任何 TeX 代码——我问了 [Patrick Gundlach](https://twitter.com/patrickgundlach)，speedata publisher 的开发者，他确认总共只使用了大约三行 TeX 代码。其强大的排版能力是用 Lua 代码设计和实现的，使用的是 LuaTeX 的 Lua API（本文后面会讨论这个主题）。

## 一个简短的个人故事：我最初是如何发现 LuaTeX 的

我最初是在 2009 年末/2010 年初了解到 LuaTeX 的，当时它还处于 beta 中期发布阶段（0.50 版）。那时我正在寻找基于 TeX 的软件，用于排版我学习阿拉伯语时写下的手写笔记。Google 搜索显示了一组来自 TUG 2009 会议的视频（[现在在 YouTube 上](https://www.youtube.com/playlist?list=PL2D4DD50DC9C0BA0E)），其中包括非常高质量的阿拉伯语排版演示（通过 Hans Hagen 的 [ConTeXt 宏包](http://wiki.contextgarden.net/Main_Page)）。这些视频还包括一场题为 [LuaTeX 项目：距离 1.0 版本还有一半](https://youtu.be/AKv4po9PGW0).

用于生成那种精美的阿拉伯语排版的 TeX 引擎叫作“LuaTeX”。当时我在科学（物理）出版领域工作，虽然对 TeX/LaTeX 非常熟悉，却从未听说过 LuaTeX：我被它吸引，想进一步了解这款新的 TeX 引擎。由于 LuaTeX 仍处于 beta 开发阶段，并且在快速演进，我希望能及时掌握最新更新，因此对我来说，最好的办法是自己动手从源代码构建（编译）LuaTeX 可执行程序。除了 LuaTeX 可执行程序之外，你还需要一个“TeX 安装”来提供运行 LuaTeX 的环境（例如 texmf.cnf、宏包、字体等）。与其下载并安装庞大的 [TeX Live](https://www.tug.org/texlive/) 发行版，我选择创建一个绝对最小化的自定义 TeX 安装来探索 LuaTeX（这是一个“有趣”的练习，我 [已在我的个人博客上记录](http://www.readytext.co.uk/?cat=30)）。LuaTeX 的每个新版本都会附带其参考手册（例如，对于[1.0.4 版本](https://www.tug.org/svn/texlive/tags/texlive-2017.1/Master/texmf-dist/doc/luatex/base/luatex.pdf?revision=44591\&view=co)），其中记录了该软件的最新特性和功能。然而，它是一本 *参考* 手册，因此对希望开始使用这款不可思议的 TeX 引擎的初学者来说，解释内容（出于必要）相当简略——它默认读者对底层 TeX 概念有一定熟悉度。由于我是在 LuaTeX 开发相对较早的阶段发现它的，当时很难找到好的入门资料，因此我花了一些时间探索、试验（以及一些挫折……），各个部分才开始逐渐拼合起来。不用说，当我被这款令人惊叹的软件迷住后，我的阿拉伯语学习也突然中断了，最终转而编写 LuaTeX [用于阿拉伯语排版的插件](http://www.readytext.co.uk/?p=3143) 来代替！

我自己的“LuaTeX 之旅”当然非常非线性，但在这个过程中，我获得了一个从零开始了解（Lua）TeX（以及 TeX 安装）的机会：我的博客收录了一系列杂七杂八的 [文章](http://www.readytext.co.uk/?cat=3) ，这些内容基于我在那段时间里探索和研究的各种主题。希望本文能够恰当地利用那段时间和经验，帮助其他人开始对 LuaTeX 的能力产生兴趣并进行探索。LuaTeX 仍在持续开发中，撰写本文时已达到 1.0.4 版本，并随 TeX Live 2017 发布。开发者非常活跃，发现的任何 bug 通常都会在报告后不久得到修复——例如，通过 [dev-luatex 邮件列表](https://mailman.ntg.nl/mailman/listinfo/dev-luatex) 或通过 [在线 LuaTeX bug 跟踪器](http://tracker.luatex.org/my_view_page.php)。早在 1.0 版本发布之前，LuaTeX 就已经具备生产可用性——当然，你需要接受其功能会持续演进，而且有时变更可能会破坏你现有的 TeX 代码。如今，LuaTeX 当然也受到 Overleaf 和 ShareLaTeX 平台的支持（以 LuaLaTeX 的形式）。

## 变化中的世界中的 TeX：新技术与工作流程

显然，TeX 引擎并不是运行在一个技术静止的世界中，偶尔会出现一些创新，它们会成为非常明显的候选对象，适合纳入 TeX 引擎——其中一项这样的创新就是 OpenType 可变字体，我们将在下文简要讨论。尽管毫无疑问基于 TeX 的排版软件极其多才多艺，但 TeX 引擎如今是在一个快速变化且高度多样化的软件生态系统中运行——新的工作流程更加凸显了集成能力以及实现各种文档/排版解决方案的灵活性，而 TeX 可能只是其中一个组成部分。

TeX 不仅必须对现有用户保持相关性，还必须通过支持内容创建解决方案来吸引新用户，使其对新一代人仍然有用——这些人未必想把 TeX 作为独立工具来使用，而可能希望通过 Overleaf 这样的在线协作平台，将其作为整体工作流程的一部分。

即便粗略浏览一下 [tex.stackexchange](https://tex.stackexchange.com/) 就会看到使用基于 TeX 的软件所制作和实现的文档与解决方案种类极其丰富——人们不断发现更多想要生成的用例和内容类型，常常展现出惊人的创造力。此外，能够处理基于 TeX 的标记/内容并生成非 PDF（且非 DVI）输出的工作流程需求从未如此迫切——例如 MathML/XML 和 HTML。比如，将 TeX “转换”为 [JATS XML](https://jats.nlm.nih.gov/) 格式（长期用于学术期刊出版），以及近年来电子书出版中 epub 的兴起。

### 可变字体技术——时代在变

2016 年 9 月 14 日，Microsoft、 [Google](https://opensource.googleblog.com/2016/09/introducing-opentype-font-variations.html), [Adobe](https://blog.typekit.com/2016/09/14/variable-fonts-a-new-kind-of-font-for-flexible-design/) 和 Apple 宣布了一项新的字体技术： [OpenType 可变字体](https://medium.com/@tiro/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369)。我们不会详细探讨这项技术，但只需说，诸如 [Thomas Phinney](https://twitter.com/ThomasPhinney) 和 [John Hudson](https://twitter.com/TiroTypeworks) 曾指出（[在 Twitter 上](https://twitter.com/ThomasPhinney/status/917087509342851072)）可变字体技术被采用的速度远快于许多早期字体创新——这很可能是由网页设计师的需求推动的，因为他们需要能够适应移动设备上各种不同屏幕尺寸/分辨率的响应式设计。

显然，OpenType 可变字体是字体技术中一个有趣而令人兴奋的发展，TeX 用户无疑会从中受益——事实上，这个问题不可避免地已经 [在 tex.stackexchange 上被提及](https://tex.stackexchange.com/questions/355104/tex-luatex-xetex-fontspec-support-for-opentype-variable-fonts) ，LuaTeX 的支持则在 LuaTeX [邮件列表中讨论](https://www.tug.org/pipermail/luatex/2016-September/006204.html).

顺便一提，值得注意的是，基于“参数化”字体创建的字体技术并不是一个全新的想法：Knuth 的 METAFONT 和 Adobe 的 Multiple Master 技术在某种程度上可以看作早期先驱，尽管实现细节相当不同。

### 可变字体：我们什么时候需要它们——现在！

任何新的、有用的技术标准/规范都需要时间才能在其目标开发者和实现者生态系统中“落地”——包括消除规范本身措辞中的歧义或不同解释所需的时间。开发者必须阅读并理解文档，并将其转化为真正可运行的软件——在这里，这还包括创建字体以及使用这些字体的技术：兼容的浏览器和排版引擎。TeX 开发者显然需要获得高质量的可变字体，它们可以作为实现（编程）可变字体技术支持时可靠的“基准”。

在 TeX 中实现任何新技术，例如可变字体，都会引发 *潜在的* 修改 TeX 引擎内部结构的需要——当然，是否需要这样做取决于该技术的性质，以及关键的，TeX 行为的哪个方面正在被改变。并不总是有必要修改 TeX 引擎本身，也许只需要修改支撑/辅助软件，包括这些程序中使用的任何“组件”（第三方代码库）。从内部来看，TeX 引擎是 *极其* 复杂得令人头痛——要发展出足以进行可靠修改的对 TeX 源代码的理解，需要相当多且高度专业化的专长（而这种专长的供给非常有限）。同样重要的是，任何修改都不能对 TeX 引擎的长期稳定性/兼容性产生不利影响——这对 TeX 社区以及后续处理作者（La）TeX 文件的人至关重要：尤其是学术出版商，以及 Overleaf 和 ShareLaTeX 这样的云服务。

许多 TeX 用户很可能会对利用可变字体感兴趣；例如，开拓新的设计可能性或解决棘手的排版问题。因此，在某种意义上，这里存在一个两难：TeX 用户想要接触一种新技术，但其实现又取决于一种非常有限的资源：有资格且有能力实现它的开发者数量。修改 TeX 的内部结构很困难，而且一般来说，最好在可能的情况下避免这样做，那么有没有另一种方法来为 TeX 添加（某些类别的）新特性/功能呢？有！而 LuaTeX 选择了这条路径。

#### 早期实验：OpenType 可变字体与 LuaTeX

LuaTeX 的设计使得对可变字体技术的快速试验成为可能。早在 2017 年 4 月，使用 LuaTeX 的 ConTeXt TeX 格式就已经有了一个 [beta 版本](https://mailman.ntg.nl/pipermail/ntg-context/2017/088343.html) ，其中实现了 OpenType 可变字体。这之所以可行，是因为 ConTeXt 的字体支持是用 Lua 代码构建的（而且 ConTeXt 还有自己的 Lua 字体加载器）。

## LuaTeX：背景与历史

从 TeX 的角度看，LuaTeX 尽管已活跃开发超过 10 年，仍可算作“新来的”。LuaTeX 网站 [记载](http://www.luatex.org/roadmap.html) LuaTeX 于 2005 年起步，而我认为其积极且持续的开发始于 2006 年。由于其内在复杂性，以及构建者们的勤勉，LuaTeX 确实花了 10 年时间才达到 1.0 版本，而该版本是 [由其开发者宣布的](https://mailman.ntg.nl/pipermail/dev-luatex/2016-September/005882.html) （Hans Hagen、Hartmut Henkel、Taco Hoekwater、Luigi Scarso）于 2016 年 9 月 27 日宣布的。

在该发布公告中有一项重要的原则性声明：

> “我们的主要目标是提供一种 TeX 变体，它允许用户扩展，而无需调整其内部工作机制。”

这句话完美概括了 LuaTeX 开发背后的理念，并指出了一条路径，使基于 TeX 的软件能够应对我们已经提到的挑战：采用新技术并对新一代用户保持相关性。

现在该来回答本文副标题中的第二个问题了：“是什么让它如此与众不同”。通过探讨“……允许用户扩展，而无需调整内部工作机制”这句话的含义，我们可以更好地理解 LuaTeX 所“带来的核心价值”。

## LuaTeX：打开 TeX 的“黑匣子”

Knuth 的原始 TeX 程序是今天所有现代 TeX 引擎的共同祖先，而 LuaTeX 实际上是最新的演化步骤：它源自 pdfTeX 程序，但加入了一些强大的软件组件，带来了大量额外功能。当 Knuth 编写 TeX 软件的原始版本时，他也提供了 TeX 语言，用来控制和编程其排版行为：用户和 TeX 宏包开发者可以使用大约 320 个底层命令（原语）。这些命令在不同程度上提供了对 TeX 排版行为某些方面的控制或影响，但 TeX 的大部分内部功能、算法、决策过程、数据和数据结构都对用户隐藏。可以说，Knuth 的 TeX 程序并非完全是一个“黑匣子”，但它肯定是很深的灰色——诚然，源代码是公开的，但对绝大多数人来说，那同样是一个不可理解的黑匣子。

我们把 TeX 内部的过程称为某种“黑匣子”；然而，LuaTeX 打开了其基于 TeX 的内部机制，为用户/开发者提供了对许多曾经隐藏在 TeX 引擎深处的过程更大的访问和控制。LuaTeX 还新增了许多原语命令，用于控制新特性。

### LuaTeX：源自 pdfTeX，但不使用 pdfTeX 的代码

为了准确起见，重要的是要指出，尽管我们将 LuaTeX 描述为源自 pdfTeX，但 LuaTeX 并未直接使用 pdfTeX 的原始程序代码。LuaTeX 的一位开发者（Taco Hoekwater）承担了真正 *艰巨到近乎神话般的* 任务：用简洁、现代的 C 代码（CWEB）重写 LuaTeX 的核心 TeX 引擎。

#### 历史说明

部分原因在于 Knuth 原始 TeX 源代码的年代久远——现代后继者都源自于它——对其进行修改以适配或创建新的基于 TeX 的排版引擎是一个复杂而曲折的过程。该过程的一部分需要将 Pascal 代码转换为 C 代码——这并非没有 [一定程度的复杂性](http://www.readytext.co.uk/?p=2529)。由此生成的机器代码 C 代码异常冗长，而且非常难以阅读或理解。显然，将 LuaTeX 的代码完全重写，可以绕开整个 Pascal 到 C 的转换过程。

## LuaTeX 的构建模块

在引言中，我们提到 LuaTeX 是一个“工具包”，并将其描述为“文档构建与工程系统”。我们已经看到，在 LuaTeX 1.0 的公告中，其开发者声明：

> “我们的主要目标是提供一种 TeX 变体，它允许用户扩展，而无需调整其内部工作机制。”

现在是时候把这些线索和想法串联起来，专注于这一切究竟 *实际上意味着什么* 在实践中。

### LuaTeX 拼图

如果你从“引擎盖下”查看，你会看到 LuaTeX 软件——也就是实际可执行程序——是由一组软件组件构成的，这些组件组合在一起提供 LuaTeX 的整体功能。当然，这并不新鲜，大多数软件都是这样构成的。然而，LuaTeX 与其他 TeX 引擎的不同之处在于，这些组件被组合的方式使用户能够更深入地访问 TeX 内部功能的许多方面：TeX 的排版算法、决策过程、数据和数据结构。这种对 TeX 内部机制的开放，使用户无需修改实际的 TeX 引擎本身就能构建新的排版解决方案。

### LuaTeX 中的 Lua：打开“黑匣子”的钥匙

Lua 是一种非常强大、却又易于学习的脚本语言，它 [起源于巴西](https://www.lua.org/about.html)——它创建于 1993 年，至今仍在积极开发中。Lua 的一个优势在于，它可作为一种编程语言，用来将不同的软件组件“粘合”在一起，使你能够通过一种简单而多用途的脚本语言使用它们。Lua 在打开 LuaTeX TeX 引擎内部运作方面起着核心作用，但为了更好地理解这一点的实现方式，值得稍作绕行，简要讨论两个编程概念：

* 应用程序编程接口（API）；
* 编程语言绑定。

如果你对这些概念已经很熟悉，可以随意跳过这一节。这两个主题都不会详细展开——我们不是要追求严格的技术严谨性，而只是提供足够的背景，让你了解这些概念：它们的含义以及与 LuaTeX 的相关性。

### 应用程序编程接口（API）

想象你是一名程序员，写了一些用户（其他程序员）可能会觉得有用的代码，但你的代码很复杂，而且你不想让使用你代码的人去操心那些底层细节。注意，这些程序员/开发者使用的是与你编写代码时相同的编程语言。此外，假设你计划重写代码的某些部分——例如，让它更快、占用更少内存等等。你代码的现有用户不应该为此担心：你计划做的任何更改都不应破坏他们的程序。那么，解决方案是什么？

答案在于一种叫做 API 的东西：即一个 *应用程序编程接口*。你不必要求用户（其他程序员）去访问你代码的底层细节——那些细节可能会变化——而是提供一组特定的 *函数* ，供其他程序员使用。这些函数构成一个 *接口* ，通过它其他开发者可以构建 *应用程序* ，而无需对你的程序内部运作有深入了解。在某种程度上，你可以把它看作包围着你代码的一个额外层，它将用户与那些杂乱的底层细节“隔离”开来。

只要你不更改这些函数（即接口），你就可以自由修改和更新软件的底层细节，而不会影响（破坏）那些依赖你的代码来构建其应用程序的人所做的工作：因此有了“应用程序编程接口”这一术语。

#### API：一个 LaTeX 宏包类比

当你使用 LaTeX 宏包提供的命令时，你可以把该宏包的命令看作一种 API。作为用户，你不一定关心这些命令背后的 TeX 和 LaTeX 技巧（即宏包代码中所做的事情）：你只想使用它们提供的功能。

### 编程语言绑定

我们已经看到，编写/发布一套有用代码的程序员（称为一个 *库*）可以提供所谓的应用程序编程接口（一个函数集合），通过它，使用 *相同* 编程语言的其他程序员可以使用该库（代码集合）。当双方（库开发者和其用户）使用 *相同* 编程语言时，这没问题，但如果使用 *不同* 编程语言的程序员也想使用该库呢？例如，你可能用 Lua 语言编写脚本，但又想使用一个用 C/C++ 等编程语言编写的库。不知怎么地，这两种不同的编程语言（Lua 和 C/C++）需要能够彼此“通信”。解决这个问题的一种方案就是所谓的 [语言绑定](https://en.wikipedia.org/wiki/Language_binding).

语言绑定的技术细节超出了本文的范围，因此我们只给出一般原理的简要总结。本质上，通过给原始库添加一层合适的附加“层”代码，它就可以与另一种编程语言（如 Lua）“通信”：这层代码被称为一个 *绑定*。它使两种语言能够通过一个 API 互操作，第二种语言（如 Lua）的程序员可以借此访问该库提供的功能/服务。

![展示语言绑定概念的示意图。](/files/a1aa8ed73ea9bcb3c1163c8f54d047a97297012e)

**图 1**图 1：展示语言绑定概念的示意图：使得用 Lua 编写的程序能够使用用另一种编程语言编写的外部库。正是通过 Lua 绑定，LuaTeX 的内部组件——以及因此而来的 LuaTeX 很大一部分内部排版功能——才得以供用户开发复杂排版问题的解决方案。

## LuaTeX：两种编程选项——TeX 和 Lua

本质上，LuaTeX 是一种支持两种编程语言的 TeX 引擎：传统的基于 TeX 的语言和 Lua 脚本语言。当然，你可以在同一个 TeX 文档中同时使用这两种语言，或者如果你愿意，也可以继续只走 TeX 路线进行排版：例如，通过 LaTeX（LuaLaTeX）宏包。TeX（或 LaTeX）并不是一门容易使用或学习的编程语言，真正掌握 TeX 众多古怪之处的人也相对很少——TeX 中的“赋值”和“展开”概念，与大多数人对编程语言的期望和经验都相当格格不入。 [记号](https://www.overleaf.com/blog/522-what-is-a-tex-token) 和展开的概念，与大多数人对编程语言的期望和经验都相当格格不入。

加入 Lua 之后，就可以通过一种更易于接近且更常规的编程语言来使用基于 TeX 的排版——正如本文开头所指出的，使用 Lua API 你可以进行 [几乎无需 TeX 代码的复杂排版](http://wiki.luatex.org/index.php/TeX_without_TeX).

### LuaTeX 新增了许多原语

每个 TeX 引擎都提供数百个所谓的原语命令：这是各个排版引擎所支持的基于 TeX 的语言的基本构件。Donald Knuth 发布的原始 TeX 版本提供了大约 320 个命令，而较新的 TeX 引擎（pdfTeX、XeTeX 和 LuaTeX）各自都新增了许多原语，以便为用户提供对各引擎额外特性和功能的访问。LuaTeX 这些大量新原语记录在其 [参考手册](https://www.tug.org/svn/texlive/tags/texlive-2017.1/Master/texmf-dist/doc/luatex/base/luatex.pdf?revision=44591\&view=co).

LuaTeX 引入的众多新原语中，有一个叫作 `\directlua{...}` ，它是使用 Lua 代码的入口：可访问 LuaTeX 引擎内部，用于构建复杂的排版工具和解决方案。

### \directlua{...}：Lua 编程的入口

如前所述，Lua 脚本语言可以看作提供了一个“层”，通过它可以访问 LuaTeX 基于 TeX 的排版引擎以及 LuaTeX 所由众多组件构成的功能。Lua 语言也是使 LuaTeX 具备可扩展性的机制——借助 Lua 加载专业外部软件/代码库的能力。

LuaTeX 提供的 Lua 接口（基于 Lua 的函数集合）统称为其 *Lua API*：它是 LuaTeX 内部引擎/组件与用户文档之间的“通信链路”。

### \directlua{...} 的一个简单示例

下面的 *极其简单的* 这个示例甚至连冰山一角都还没触及。然而，它足以展示通过“TeX 方式”和“Lua 方式”访问 TeX 参数之间相互作用的基本思想。

注意：

* `\hsize` 是一个 TeX 原语（命令），用于设置一个内部参数的值，该参数决定排版行的宽度——例如，你通常会在一个 `\vbox{...}`. `\hsize` 只是其中一个 *许多* 你可以通过 Lua 代码访问和/或修改的 TeX 参数。
* 访问 TeX 参数只是 *极其微小的* LuaTeX 的 Lua API 的一个方面：还有更多内容！

```latex

\documentclass{article}
\begin{document}
\let\\\relax %redefine meaning of \\ to avoid expansion problems
这里是 {\ttfamily\string\hsize} 的当前值（通过 \LaTeX）：
\the\hsize\par
\directlua{
%Get the current value of \hsize using the Lua API
local hs=tex.hsize
% Use a Lua API function to print some
% LaTeX code and the value of \hsize
tex.print("Here is the value of {\\ttfamily\\string\\hsize}
reported from Lua code (in scaled points): ")
tex.print(hs.."\\par")
% Set a new value for \hsize using the Lua aPI
tex.hsize="400pt" % or use tex.hsize=400*65536 (in scaled points)
}%
% After \directlua has finished, ask LaTeX
% to tell us the new value of \hsize
这里是 {\ttfamily\string\hsize} 的值，由
\LaTeX{} 在 {\tt\string\directlua} 结束后报告：
\the\hsize\par
\end{document}
```

这里有一张图片，展示了 LuaTeX 对上面的 LaTeX 代码进行排版后的结果：

![运行 LuaTeX 的结果](/files/35781119e94bb10606c18c58427b3ffa81920717)

请注意，TeX 的“技巧性处理” `\let\\\relax` 是为了避免 LuaTeX 对 Lua 代码进行“展开”所引起的问题：这一主题我们将在下文简要说明。

### 使用 Lua 代码

在你的 TeX/LaTeX 文档中使用 Lua 代码主要有两种方式：

1. **内联**：直接在你的 `.tex` 文档中编写 Lua 代码（如上面的示例）；
2. **外部**：将 Lua 代码存储在外部 `.lua` 代码文件中，并使用 Lua 的功能来加载和运行它们。

选项（1）最适合较短的 Lua 代码片段。选项（2）用于更大的程序或 Lua 代码库。它有一个明显的优势，即你可以避免涉及 TeX 所谓 `\catcode` 值的棘手问题（这可能“相当令人沮丧”）。这些 `\catcode` 问题的原因，是在将 Lua 代码送入 LuaTeX 内置 Lua 解释器之前对其进行“展开”。这种展开可能很难理解，因此我们将在后续文章中进一步探讨。

当然，也有 LaTeX 宏包可以帮助你在 .tex 文件中使用 Lua 代码——例如，你可以使用 [luacode 宏包](https://ctan.org/pkg/luacode?lang=en).

## 总结并介绍本文第 2 部分

构成 LuaTeX 的软件组件，以及内嵌的 Lua 脚本语言，共同提供了一个强大的组合，用于构建能够解决各种复杂排版问题的方案——并设计文档生产工作流，这些工作流可从与基于 TeX 的排版引擎的紧密集成中受益。在 [本文的第二部分](/latex/zh-cn/shen-du-wen-zhang/09-an-introduction-to-luatex-part-2-understanding-directlua.md) 我们将深入探讨 LuaTeX 提供的最强大的命令： `\directlua`.

在那之前，祝你 LuaTeX 愉快！

## 致谢

作者极其感谢 [Luigi Scarso](https://twitter.com/luigi_scarso)，他是 LuaTeX 的开发者之一，抽出时间阅读了本文草稿，并提出了许多非常有帮助的评论和建议。任何仍然存在的事实错误或遗漏，当然都由作者负责。此外，我还要感谢 [Patrick Gundlach](https://twitter.com/patrickgundlach)，……的开发者 [speedata publisher](https://speedata.github.io/publisher/)，感谢他抽出时间回答我的问题。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ayakaleaf-pro.ayaka.space/latex/zh-cn/shen-du-wen-zhang/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
