> 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/36-pandora-s-hbox-using-luatex-to-lift-the-lid-of-tex-boxes.md).

# 潘多拉的 \hbox：使用 LuaTeX 掀开 TeX 盒子的盖子

## 引言

盒子和胶水是两个关键概念，它们为 TeX 的排版模型和能力奠定了基础。基于上一篇文章中的入门材料， [盒子与胶水：使用 LuaTeX 的简明而直观的介绍](/latex/zh-cn/shen-du-wen-zhang/11-boxes-and-glue-a-brief-but-visual-introduction-using-luatex.md)，这篇配有大量插图的文章将更详细地探讨盒子和胶水。我们还提供一个新的基于 LuaTeX 的 [Overleaf 项目](https://www.overleaf.com/latex/examples/exploring-the-structure-of-tex-boxes-with-luatex/pwdrypmtdbgs) ，让你能够探索 TeX 盒子的深层内部结构——从而帮助你真正理解它们的行为。Overleaf 项目的创建在很大程度上得益于 Patrick Gundlach 的工作，因此我们要 [向他致谢](#credits-thanks-patrick).

## 为什么选择 LuaTeX？

首先，有必要再次说明 LuaTeX 与 LuaLaTeX 之间的区别：

* LuaTeX 是一个基于 TeX 的可执行排版引擎的名称；
* LuaLaTeX 指的是将 LaTeX 宏包与 LuaTeX 引擎结合使用。

这种区别极其重要，因为在本文中，我们利用的是 LuaTeX 引擎本身的内建能力，而不仅仅是借助 LaTeX 宏包所提供命令的特性/功能。

不确定 TeX 引擎与 LaTeX 宏包之间区别的读者，或许可以阅读我们之前发表的一篇文章， [《名称里有什么：TeX 多种风味指南》](/latex/zh-cn/shen-du-wen-zhang/55-what-s-in-a-name-a-guide-to-the-many-flavours-of-tex.md)，其中对这些差异作了较为详细的说明。那篇文章还讨论了把“TeX”作为一种编程语言，以及基于 TeX 的排版引擎（例如 pdfTeX、XeTeX 和 LuaTeX）不仅在特性和功能上各不相同，而且所支持的 TeX 语言“风味”也有所差异。这就引出了我们对 LuaTeX 的选择。除了支持基于 TeX 的编程语言之外，LuaTeX 还内嵌了 Lua 脚本语言——为你提供一种简单却非常强大的传统编程语言。借助 Lua 以及 LuaTeX 内建的功能，你可以以前所未有的方式探索和控制 LuaTeX 的排版活动，而其他任何 TeX 引擎都做不到这一点——这其中包括探查 TeX 盒子内部结构的能力；因此，LuaTeX 是本文及其配套 Overleaf 项目的理想（也是唯一）选择。

### pdfTeX/XeTeX 与 LuaTeX：图示

下面的 *示意图* 旨在突出 pdfTeX/XeTeX 与 LuaTeX 设计之间的重要比较。当然，pdfTeX 和 XeTeX 都允许用户编写能够影响排版行为的 TeX 代码；然而，这些 TeX 引擎内部所包含的更深层结构，以及排版过程中构造的底层数据，大多都无法通过用户命令和宏访问。就这一点而言，与 LuaTeX 相比，它们是 *相对* 封闭的系统。

#### pdfTeX/XeTeX

![{{{alt}}}](/files/1f5d97cf732ed3952fb3dab11bc676e36d6e4f93)

#### LuaTeX

LuaTeX 引入了一个名为 `\directlua{...}` 的新原语命令，通过它你不仅可以编写完全访问 Lua 语言的代码，还可以使用 C 和 C++ 等语言编写插件来扩展 LuaTeX 的能力。在 Windows 上，这类插件称为 *动态链接库* （.DLL）；在 Linux 上则称为 *共享对象库* （.so）。然而，LuaTeX 的真正威力来自一大套内建 Lua 函数，它们提供了访问 LuaTeX 内部结构的途径——从而能够对基于 TeX 的排版进行极其复杂的控制和编程。这类函数集合称为 API（应用程序编程接口），正是通过 LuaTeX 的 API，你可以使用 Lua 程序与其基于 TeX 的排版引擎和数据结构进行通信。

![{{{alt}}}](/files/2be0df2045335d899dba26eb13f1af044f14be1a)

借助 LuaTeX 的 `\directlua{...}` 命令，例如，你可以访问隐藏在其他 TeX 引擎中的底层内部 TeX 数据结构。此外，你还可以使用 Lua 脚本执行各种编程计算、字符串处理等操作，并把结果传回 TeX：可能性几乎无穷无尽。然而，本文并不打算对 LuaTeX 作详尽的阐述或教程——尽管举一些能够展现这一惊人强大 TeX 引擎非凡多功能性的例子是很诱人的。

## 盒子与胶水：简要回顾

正如在文章中介绍的那样 [盒子与胶水：使用 LuaTeX 的简明而直观的介绍](https://www.overleaf.com/blog/511-boxes-and-glue-a-brief-but-visual-introduction-using-luatex) ，盒子和胶水是支撑 TeX 排版能力的两个关键概念。下图作为对 TeX 的水平盒和垂直盒行为的极简备忘。注意：水平盒当然可以包含使用从右到左书写语言排版的文本，例如阿拉伯语或希伯来语，这意味着盒子增长的方向可能与下图中为水平盒所示的方向相反。

![{{{alt}}}](/files/46295aa5880ab381c862783d8b7648ac68ea29dc)

### 用于构造盒子的 TeX 原语

如今，大多数人使用 LaTeX 宏包来准备 TeX 文档；该宏包旨在提供一些命令，使用户免受 TeX 很大一部分底层语言——所谓的 *原语*——即内置于 TeX 引擎中的核心命令（有关 TeX 原语的讨论，请参见文章 [《名称里有什么：TeX 多种风味指南》](/latex/zh-cn/shen-du-wen-zhang/55-what-s-in-a-name-a-guide-to-the-many-flavours-of-tex.md) ）。LaTeX 宏集合提供了多种用于创建和存储（保存）盒子的宏，但如果你剥去所有宏代码，就会发现实际上只有 4 个底层原语盒子构造命令：

用于创建水平列表：

* \hbox{...}

用于创建并堆叠垂直列表：

* \vbox{...}
* \vtop{...}
* \vcenter{...}

我们不会解释如何使用所有这些盒子命令，因为网上或 TeX/LaTeX 书中已有大量示例和教程——但我们会看看盒子在 TeX 数据结构内部是如何表示和存储的。

### 胶水：灵活的间距

胶水本质上是一种间距形式，TeX 用它来在水平方向或垂直方向上对项目进行间隔/定位。作为 TeX 用户，我们可以指示 TeX 插入一些固定大小的胶水，也可以使用具有灵活性的胶水——根据需要，它既可以伸展也可以收缩，灵活度可大可小。TeX 用于创建水平间距胶水的命令之一叫做 `\hskip` ，其形式为

`**\hskip** <自然宽度> **plus** <可伸展量> **minus** <可收缩量>`

`**plus**` 和 `**minus**` 是 TeX 关键字，但并非每个胶水都必须使用它们。如果 `**plus**` 或 `**minus**` 未出现，则相应的 `<可伸展量>` 或 `<可收缩量>` 被假定为 0。例如， `\hskip 3pt` 插入了一个固定宽度的胶水，没有伸展或收缩成分。

现在，把 `<可伸展量>` 和 `<可收缩量>` 看作是我们给 TeX 的 *建议* ，因为确切的伸展或收缩量将由 TeX 计算。

为了帮助理解这些概念，下面这幅图把胶水表示成一根弹簧。 `<自然宽度>` 是弹簧在没有张力（伸展）或压缩（收缩）时的长度。 `<可伸展量>` 和 `<可收缩量>` 则是相对于弹簧自然长度来显示的。

![{{{alt}}}](/files/b07c88aa788da3f88bbbddbac4b0781a03b69638)

#### 一个 \hbox 示例

假设我们想创建一个 `\hbox{...}` ，其中只包含字母 A、B、C 和 D，并且我们需要这个盒子的宽度为 100pt（100 个 TeX 点）。此外，可以安全地假定这四个字符的总宽度远小于 100pt，这说明 TeX 需要某种方式来填满盒子中剩余的空间：我们将使用一些胶水来做到这一点。不过，由于我们不知道填满盒子所需的精确胶水量，最好添加一些灵活胶水，让 TeX 负责计算这些胶水需要占据的空间量。在下面的代码片段中，请注意使用“%”来抑制由行尾字符产生的词间空格。

```
\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt B%
\hskip 0pt plus 2fil C%
\hskip 0pt plus 2fill D%
\hskip 0pt plus 3fill}
```

生成的盒子看起来像这样（为清晰起见已放大）：

![{{{alt}}}](/files/4b40306fa5b0f588df2ee2fcba69e8e5244273ee)

这个 `\hbox` 上覆盖着虚线框（红色），用来表示字符的宽度（按 TeX 的视角）。就排版而言，字符被视为小盒子，而填满这个 `\hbox`所需的胶水量则通过考虑每个字符的宽度来确定（计算出来）。

结果表明，TeX 并没有拉伸或收缩 A 和 B 之间的胶水（设为 4pt），而 B 和 C 之间没有胶水（设为 0pt）。不过，C 和 D 之间的胶水以及 D 与盒子末尾之间的胶水都被大幅拉伸了，因为这些胶水具有最灵活的可伸展成分——实际上，它们吸收了填满盒子所需的全部伸展量。

## 回到 LuaTeX

到目前为止，我们已经探讨了盒子和胶水，并看到 LuaTeX 允许访问 pdfTeX 和 XeTeX 中不可见的内部 TeX 结构。现在该举一个例子来更明确地说明这一点了，但首先，我们需要简要了解 TeX 是如何在内存中存储盒子的——我们先从一个类比开始。

### TeX 如何在内存中存储盒子：一个类比

假设出于某种原因，你需要创建一个描述实体盒子的 data model。你会选择哪些数据来提供这种描述呢？一种做法是把信息分成两部分：关于实体盒子本身的数据，以及提供盒子内容列表的数据。因此，我们这个简单模型可能看起来像这样：

1. 关于实体盒子的数据（“元数据”）：

* width
* 高度
* 深度
* 重量
* 颜色
* 类型（木制、塑料、纸板）

3. 关于盒子内容的数据：某种形式的列表，用来描述它所包含的物品——大概不会按特定顺序排列。

而 TeX 存储盒子的方式与此有一个非常贴切的类比。

### TeX 如何在内存中存储盒子：hlist 和 vlist

在内部，TeX 创建一种称为 *hlist* （水平列表）和 *vlist* （垂直列表）的“容器”，分别对应 hbox 和 vbox。这些 hlist/vlist 对象提供了一组关于盒子的“元数据”，同时还提供对盒子实际所包含对象列表的访问——该列表称为 *节点列表*。与实体盒子不同，后者可以以任意顺序放置物品，而对于 TeX 来说，盒子内容的顺序极其重要——它们是要被排版的项目。如果你有任何编程或计算机科学背景，那么你不会对得知 TeX 盒子中的对象是通过所谓的 [双向链表](https://en.wikipedia.org/wiki/Doubly_linked_list)存储，并保留其创建顺序感到惊讶。我们不再进一步讨论链表，因为网上有大量教程、示例和说明。

节点和节点列表的概念是 TeX 工作原理中的一个基本方面，但为了本文的目的，我们只作一个简要概述。节点本质上是一种“迷你容器”，而且（截至 LuaTeX 1.04）大约有 50 种不同类型的节点：反映了 LuaTeX 用于排版的内部数据类型和组件。例如，有表示字形（来自“字符”）、胶水、水平/垂直规则线、惩罚值、“whatsits”、kern 等等的节点。所有排版内容最终都会成为庞大节点列表的一部分，而 LuaTeX 让你可以直接访问这些内部数据结构。LuaTeX 还允许你添加、编辑、修改或创建节点列表，因此例如你可以直接在 Lua 代码中创建盒子，而无需编写任何 TeX 代码。不过，关于这一点的讨论留待他日。

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

下面的示例创建一个 `\hbox` 并将其保存到 0 号盒寄存器中。然后我们用传统 TeX 代码报告该盒子的宽度，并通过 `\directlua{}`的第二种方法获得相同的信息。这里，我们运行一段小小的 Lua 脚本，访问 TeX 的内部盒存储区域以获取该盒子的宽度——当然，这两个值是相同的：2412092sp（sp = 缩放点：65536sp = 1 个 TeX 点）。最终，在这个极其简单的示例中，TeX 代码和 Lua 代码都检视同一组内部数据结构来获取盒子的宽度，但正是通过这种直接访问方式，LuaTeX 打开了通往其他引擎无法提供的大量信息和控制的大门。

![{{{alt}}}](/files/5a1c04f8c8f899f5b31a11f14f951cddcdc8e6ed)

```latex
\documentclass{article}
\begin{document}
\setbox0=\hbox{A\hskip 5pt B\hskip 10pt C}
\fontsize{18}{22}\selectfont
\noindent 使用 \TeX{} 代码，盒 0 的宽度为 \number\wd0\relax \space sp\par
\noindent 我们还可以使用 Lua，并调用 Lua\TeX 的某个函数来获得相同的
信息。\vskip10mm
\noindent 从 Lua 代码中，盒 0 的宽度为
\directlua{
local boxwidth = tex.box[0].width
tex.print(boxwidth.." sp")
}，当然，这与通过 \TeX{} 代码得到的值完全相同。
\end{document}
```

## 将所有内容整合起来：一个 Overleaf 项目

我们已经指出，在内部，TeX 将盒子表示为称为 hlist/vlist 的“容器”，它们存储关于盒子的“元数据”，并提供对构造该盒子的组件列表的访问。使用 LuaTeX，你可以访问盒子的“元数据”以及 TeX 盒子中包含的项目列表：字形、胶水、惩罚值、其他盒子等等。借助 Lua 脚本，可以检查存放在 TeX 内存中的一个盒子，并绘制其所包含内容的详细表示。TeX 盒子及其内容的合适表示是通过 *节点图* 来实现的，而我们已经准备了一个 [Overleaf 项目](https://www.overleaf.com/latex/examples/exploring-the-structure-of-tex-boxes-with-luatex/pwdrypmtdbgs) ，它利用了 Patrick Gundlach 编写的一段出色 Lua 脚本来做到这一点（参见致谢）。我们不会描述检查盒子并生成节点图所需的详细过程——只想指出，任何处理 TeX 盒子的程序/脚本都必须是 *递归* ，因为盒子可以嵌套：也就是说，你可以在 vbox 中嵌 hbox，在 hbox 中再嵌 vbox……将所有盒子类型组合到非常深的嵌套层级中。

![{{{alt}}}](/files/ec1b29ba11b8fc8aa75adfd8337734c906c0b492)

### 该项目提供了什么？

它只实现了 1 个名为 `\dobox{box command}`的命令，例如：

```latex
\dobox{\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt
B\hskip 0pt plus 2fil
C\hskip 0pt plus 2fill
D\hskip 0pt plus 3fill}}
```

该 `\dobox{...}` 命令执行若干任务：

1. 在你的文档中，它排版出盒子的原样 TeX 代码；
2. 它生成 TeX 盒子的 SVG 图形——你可以将其嵌入网页中（正如我们在这篇博文中所做的那样）；
3. 它生成节点列表的 SVG 图形——你也可以将其嵌入网页中（正如我们在这篇博文中所做的那样）；
4. 它输出一个节点列表的 PDF 图形，然后将其导入项目生成的主 PDF 文档中。

由于 LuaTeX 需要存储大量数据来表示复杂的 TeX 盒子——例如当前正在构建的页面，或排版数学公式——节点图很快就会变得非常庞大。对于较大的节点列表，导入的 PDF 图形可能会被文档页面边界裁剪掉——如果你想查看较大的节点图，可以下载该项目的 ZIP 文件并提取你感兴趣的 PDF 图形。下载项目的 ZIP 文件时，请务必在下拉选项列表中选择“Input and Output Files”：

![{{{alt}}}](/files/d1a50a8d19016f5b0b89aa1d8846f02c0d4126b3)

### 来自 Overleaf 项目的图形：简要说明

在展示一些示例之前，值得先对 Overleaf 项目生成的图形做几点说明——我们将使用文中前面提到的同一个 `\hbox` 示例。它在项目的 `\dobox{...}` 命令：

```latex
\dobox{\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt
B\hskip 0pt plus 2fil
C\hskip 0pt plus 2fill
D\hskip 0pt plus 3fill}}
```

下面是 `\hbox` 由 TeX 生成的——为清晰起见，盒子已放大，但边框包含在 Overleaf 项目生成的图形中。

![{{{alt}}}](/files/618009dcee28321a9557714c72691a8b2b62060c)

下面是一个 *带注释的* 表示上述盒子的节点列表 SVG 图——注释用于突出盒子的“元数据”以及它所包含的对象列表：这些注释在 Overleaf 项目生成的图形中并不存在。

[![{{{alt}}}](/files/eba9dc6dc44c13498bc2b3cabbca9fb91c1ac1a0)](https://www.filepicker.io/api/file/ZSwIylUR66eFYPMo0suX)

如果你查看“元数据”部分，可能会注意到一些不熟悉的参数：

* `glue_set`
* `glue_sign`
* `glue_order`

这些参数是 TeX 用来计算此盒子内部胶水需要伸展或收缩多少的设置，并且只是你可以通过 LuaTeX 轻松获取、但无法通过其他 TeX 引擎获取的数据的一个例子。请注意，盒子组件中包含的胶水节点 *保留* 了我们在创建盒子时输入的原始胶水值。这一点至关重要，因为 TeX 提供了以下命令 `\unhbox`, `\unvbox`, `\unhcopy`, `\unvcopy` ，它们会把盒子的内容“解盒”，并将其重新释放回输入流，以再次参与排版操作。只有当 TeX 最终将盒子输出（ship out）到 PDF 或 DVI 文件时，才会将 `glue_set`, `glue_sign` 和 `glue_order` 应用到盒子中包含的任何胶水上——以计算在盒子内定位各组件所需的实际伸展或收缩量，然后生成相应的 PDF 数据或 DVI 操作码。

“元数据”中列出的另一个参数是 `shift`：这是应用 TeX 命令后产生的盒子位移值：

* `\raise`, `\lower` （应用于一个 `\hbox`);
* `\moveleft`, `\moveright` （应用于一个 `\vbox`).

在我们的示例中， `shift` 为 0pt，因为我们并没有使 `\hbox` 偏离其自然位置。

该 [Overleaf 项目](https://www.overleaf.com/latex/examples/exploring-the-structure-of-tex-boxes-with-luatex/pwdrypmtdbgs) 还会输出 PDF 格式的节点图：这里有一个链接，可下载上面的一个 [PDF 文件版本](https://www.filepicker.io/api/file/bezigXESC2FSasvjoh8A) 的节点图。

### Overleaf 项目是如何创建这些图形的？

Overleaf 项目利用了在 Overleaf 服务器上运行已安装软件工具和实用程序的能力——请参见 [这篇博文](/latex/zh-cn/shen-du-wen-zhang/52-using-luatex-to-run-tools-and-utilities-installed-on-overleaf-s-servers.md) 了解更多细节和示例项目。为了生成表示 TeX 盒子的 SVG 图形，盒子的 TeX 代码会被写入一个小文件，然后用 pdfTeX 排版以生成 DVI 文件——注意 pdfTeX 程序是通过几行 Lua 脚本由 LuaTeX 调用执行的。该 DVI 文件随后会使用 `dvisvgm` 实用程序即时转换为 SVG——该实用程序随安装在 Overleaf 服务器上的 TeX Live 发行版一同提供。 `dvisvgm` 以命令行选项 `-n` 执行，以确保任何排版文本都转换为线条/曲线，从而 SVG 文件的正确渲染不依赖于已安装的 TeX 字体。

为了创建节点图，我们使用一个名为 `hiviznodelist.lua` 的 Lua 脚本，它基于 Patrick Gundlach 的工作。该脚本会写出一个所谓的 `.gv` （Graphviz）文件，它是一个文本文件，包含用 `dot` 语言描述的节点图。这个 `.gv` 文件由一个名为 `dot` 的实用程序处理，该程序输出 PDF 和 SVG 两种文件格式的节点图。

### 项目示例

下面是一些使用 Overleaf 项目生成的 SVG 图形的额外示例。包含大量文本（例如，在 \vbox 中）或复杂数学公式的盒子会生成巨大的节点图——如果你探索 Overleaf 项目，建议不要使用过于复杂的盒子来展示你感兴趣的功能。

#### \vbox to 25pt{A}

这个示例演示了将文本直接放入一个 `\vbox`：请注意，即使是这样一个简单的盒子，节点结构也相当复杂。之所以如此复杂，是因为直接放入一个 `\vbox` 中的文本会促使 TeX 进行断行。你可以看到，这个 `\vbox` 盒子的宽度为 345pt：这就是创建该盒子时 `\hsize` 的取值。另请注意，字符“A”包含在一个 `hlist` 中，该节点也有 345 点宽，并且请观察与 `\parfillskip` 和 `\rightskip` 胶水位于盒子内容末尾。这一惩罚值和两个胶水项都是 TeX 的断行活动插入的。如果你查看包含字母“A”的段落行（ `glue_set` ）的`hlist`值，你会发现它极其大（322.500000）：这是为什么呢？因为该段落行宽为 345pt，但只包含一个 `\parindent` 和字母“A”：剩余空间必须由 `\parfillskip` 胶水填充，而该胶水必须伸展相当大的距离才能填满该行剩余空间。

![{{{alt}}}](/files/dadb4939c4ba1115ce81154fd1dc6fd49ca12fb6)

[![{{{alt}}}](/files/f4f3a52d5ee2f41d9640303efcb5913106df1a16)](https://www.filepicker.io/api/file/pVtHsNGSQ4m09vBZuOpQ)

[下载 PDF 文件](https://www.filepicker.io/api/file/nBS0uDs2QjqKCKljAm7r)

#### \vbox to 25pt{\hbox{A}}

将这个示例与前一个示例进行比较非常有启发性。这里不仅节点图小得多，而且该盒子的宽度 `\vbox` 只有 7.50002pt：与字符“A”相同的宽度。原因是“A”被包裹在一个 `\hbox` 中，从而阻止了 `\vbox` 触发 TeX 执行断行——这是用 `\vbox`.

![{{{alt}}}](/files/c88d802720e615c30376b5e9f4935a19fd842719)

[![{{{alt}}}](/files/84bb1494a143d73f395e00f5dd1a80e3513db25b)](https://www.filepicker.io/api/file/LHepknjnRGOVEdghW4qH)

[下载 PDF 文件](https://www.filepicker.io/api/file/Yk3uCCQR5ao8Yd3TJCdE)

#### 简单数学：\hbox{$$\displaystyle \int f(x) dx$$}，复杂盒子！

这个示例表明，即使是非常简单的排版数学也会创建详细的盒子结构：排版数学会在 TeX 中生成 *极其* 复杂的数据结构！

![{{{alt}}}](/files/fd785b085b8b7a24de5bd263adc74c16680b3e94)

[![{{{alt}}}](/files/4f4f7dc4b4094f43f109f0f0781c75a882ab828f)](https://www.filepicker.io/api/file/oVFNNvCqT0eZP0qS2odk)

[下载 PDF 文件](https://www.filepicker.io/api/file/D5TepsdaSdeYZvkuSEJt)

## 致谢：感谢 Patrick！

我们要感谢 [Patrick Gundlach](https://twitter.com/patrickgundlach) ，他已授权 Overleaf 使用并分发其 Lua 脚本的修改版本， `viznodelist.lua`，该脚本处理 TeX 盒子并输出一个（以 `dot` 语言编写的）文件，该文件可进一步处理以绘制节点图。Overleaf 项目中包含一个名为 `hiviznodelist.lua`——这是 Patrick 原始代码改名并修改后的版本，可在 [Github](http://gist.github.com/556247)上获取。Patrick 创建了一个基于 LuaTeX 的开源排版系统，名为 [speedata Publisher](https://speedata.github.io/publisher/index.html) ，你可以免费下载并使用——同时也提供商业支持选项。


---

# 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/36-pandora-s-hbox-using-luatex-to-lift-the-lid-of-tex-boxes.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.
