> For the complete documentation index, see [llms.txt](https://overleaf-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://overleaf-pro.ayaka.space/latex/zh-tw/shen-ru-wen-zhang/36-pandora-s-hbox-using-luatex-to-lift-the-lid-of-tex-boxes.md).

# 潘朵拉的 \hbox：使用 LuaTeX 掀開 TeX 方盒的蓋子

## 簡介

盒子與膠水是兩個關鍵概念，為 TeX 的排版模型與能力奠定基礎。承接前一篇文章中的入門內容， [盒子與膠水：使用 LuaTeX 的簡短但具視覺化的介紹](/latex/zh-tw/shen-ru-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-tw/shen-ru-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 的內建功能，你可以以其他 TeX 引擎無法提供的方式，探索並控制 LuaTeX 的排版活動——這也包括探查 TeX 盒子內部結構的能力；因此 LuaTeX 是這篇文章及其附帶 Overleaf 專案的理想（也是唯一）選擇。

### pdfTeX/XeTeX 與 LuaTeX：圖解比較

下列 *示意圖* 旨在凸顯 pdfTeX/XeTeX 與 LuaTeX 設計之間的一項重要比較。當然，pdfTeX 與 XeTeX 都允許使用者撰寫 TeX 程式碼來影響排版行為；然而，這些 TeX 引擎內部所包含的更深層結構，以及排版過程中所建立的低階資料，大多無法讓使用者命令與巨集直接存取。從這個意義上說，它們相較於 LuaTeX 是 *相對地* 封閉的系統。

#### pdfTeX/XeTeX

![{{{alt}}}](/files/41a13c152c20cbdc29b8b6a8af6c0115520a7a38)

#### LuaTeX

LuaTeX 引入了一個名為 `\directlua{...}` 的新原始命令，透過它你不僅可以撰寫完整存取 Lua 語言的程式碼，還可以使用 C、C++ 之類的語言撰寫外掛來擴充 LuaTeX 的能力。在 Windows 上，這類外掛稱為 *動態連結程式庫* （.DLL）；在 Linux 上則稱為 *共享物件程式庫* （.so）。然而，LuaTeX 真正的力量來自一大組內建的 Lua 函式，它們能存取 LuaTeX 的內部機制——使基於 TeX 的排版能被極為精密地控制與程式化。這類函式組稱為 API（應用程式介面），而你正是透過 LuaTeX 的 API，使用 Lua 程式與其基於 TeX 的排版引擎及資料結構進行通訊。

![{{{alt}}}](/files/830c4e73bf8b1f6a682aa43352f5f600ad4dcc4a)

使用 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/13269f474973cade9a1df7b75ba46727f67e0338)

### 用於盒子構造的 TeX 原始命令

如今，大多數人使用 LaTeX 巨集套件來準備 TeX 文件，其設計目的是提供命令，讓使用者不必直接接觸 TeX 的大量低階語言——也就是所謂的 *原始命令*——TeX 引擎內建的核心命令（參見文章 [名稱裡有什麼：TeX 各種口味指南](/latex/zh-tw/shen-ru-wen-zhang/55-what-s-in-a-name-a-guide-to-the-many-flavours-of-tex.md) ，其中有關於 TeX 原始命令的討論）。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/ccc9116227bbb7655b46b98b9efa45db75007cad)

#### \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/5568c6af93e4524f93c0bec4b8531a2e0efa0e74)

這個 `\hbox` 上面覆蓋了虛線框（紅色）以顯示字元的寬度（以 TeX 的角度來看）。就排版而言，字元被視為小盒子，而填滿這個 `\hbox`所需的膠水量會透過考量每個字元的寬度來決定（計算）。

結果發現，TeX 並沒有伸展或縮減 A 與 B 之間的膠水（設定為 4pt），而 B 與 C 之間沒有膠水（設定為 0pt）。然而，C 與 D 之間的膠水，以及 D 與盒子末端之間的膠水，都大幅伸展了，因為那些膠水具有最彈性的伸展成分——實際上，這些膠水吸收了填滿盒子所需的全部伸展量。

## 回到 LuateX

到目前為止，我們已經探索了盒子與膠水，並看到 LuaTeX 允許存取隱藏在 pdfTeX 與 XeTeX 中、看不見的內部 TeX 結構。現在是時候用一個例子讓這點更明確了，但首先，我們需要先簡單熟悉 TeX 在記憶體中儲存盒子的方式——先從一個類比開始。

### TeX 如何在記憶體中儲存盒子：一個類比

假設出於某種原因，你需要建立一個描述實體盒子的資料模型。你會選擇哪些資料來提供這樣的描述？一種作法是把資訊分成兩部分：一部分是關於實體盒子本身的資料，另一部分是提供盒內內容清單的資料。因此，我們這個簡單的模型可能會像這樣：

1. 關於實體盒子的資料（「中繼資料」）：

* width
* 高度
* 深度
* 重量
* 顏色
* 類型（木製、塑膠、紙板）

3. 關於盒內容的資料：某種形式的清單，用來描述它所包含的物品——可能不特別依任何順序排列。

而這和 TeX 儲存盒子的方式有非常密切的類比。

### TeX 如何在記憶體中儲存盒子：hlists 與 vlists

在內部，TeX 會建立稱為 *hlists* （水平清單）與 *vlists* （垂直清單）的「容器」，分別代表 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＝scaled point：65536sp = 1 TeX point）。歸根究柢，在這個非常簡單的例子中，TeX 程式碼與 Lua 程式碼都在檢視相同的內部資料結構來取得盒子的寬度，但正是這條直接存取的路徑，讓 LuaTeX 開啟了其他引擎無法提供的大量資訊與控制能力。

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

```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 會將盒子表示為稱為 hlists/vlists 的「容器」，它們會儲存關於盒子的「中繼資料」，並提供對構成盒子的元件清單的存取。使用 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/64b205f1a876269446a1d19eb4b063b90c2ff78a)

### 這個專案提供了什麼？

它只實作了一個名為 `\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}}
```

該 `\dobox{...}` 命令會執行多項工作：

1. 在文件中排版出你的盒子的原樣 TeX 程式碼；
2. 產生 TeX 盒子的 SVG 圖形——你可以將其嵌入網頁（就像我們在這篇部落格文章中所做的）；
3. 產生節點清單的 SVG 圖形——你也可以將其嵌入網頁（就像我們在這篇部落格文章中所做的）；
4. 輸出節點清單的 PDF 圖形，然後將其匯入此專案產生的主 PDF 文件。

由於 LuaTeX 為了表示複雜的 TeX 盒子——例如目前正在構建的頁面或排版中的數學式——需要儲存龐大數量的資料，因此節點圖很快就可能變得非常大。對於較大的節點清單，匯入的 PDF 圖形可能會被文件頁面邊界裁切——如果你想檢視大型節點圖，可以下載專案的 ZIP 檔並解壓縮你感興趣的 PDF 圖形。當你下載專案的 ZIP 檔時，請務必在下拉選單中選擇「Input and Output Files」：

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

### 來自 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/3d8e09624dbe67c2bc691fcc28ad24cac939710c)

這裡是一個 *附註的* 代表上方盒子的節點清單 SVG 圖；註解是為了強調盒子的「中繼資料」與其所含物件清單而加入的：這些註解並不會出現在 Overleaf 專案產生的圖形中。

[![{{{alt}}}](/files/56eee64ec80317eca52695defd4dd27606c8fcfe)](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-tw/shen-ru-wen-zhang/52-using-luatex-to-run-tools-and-utilities-installed-on-overleaf-s-servers.md) 以取得更多細節與範例專案。為了產生代表 TeX 盒子的 SVG 圖形，會將該盒子的 TeX 程式碼寫入一個小檔案，然後用 pdfTeX 進行排版以產生 DVI 檔——請注意，pdfTeX 程式是由 LuaTeX 透過幾行 Lua 程式碼來執行的。接著，該 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` 中，而這個 hlist 也同樣寬 345 點，並且可以看到在盒子內容末端有一個很大的懲罰值（10000）以及 `\parfillskip` 和 `\rightskip` 膠水。那個懲罰值與這兩個膠水項目是由 TeX 的斷行活動所插入的。如果你查看包含字母「A」的段落行（ `glue_set` 值，你會看到它非常大（322.500000）：這是為什麼呢？因為該段落行寬 345pt，卻只包含一個`hlist`的文字行 `\parindent` 與字母「A」：剩餘空間必須由 `\parfillskip` 膠水填滿，而這些膠水必須大幅伸展才能補滿該行剩餘的空間。

![{{{alt}}}](/files/139611ebf50bc2a2c46c144ff66415b9bb18d18b)

[![{{{alt}}}](/files/6e52453dd86625eab8395fcc874b2fc82a80ebb1)](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/4b35c8ac462de64663dfd2e2cd71ab7a28840a38)

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

[下載 PDF 檔](https://www.filepicker.io/api/file/Yk3uCCQR5ao8Yd3TJCdE)

#### 簡單數學：\hbox{$$\displaystyle \int f(x) dx$$}，複雜盒子！

這個範例顯示，即使是非常簡單的排版數學式，也會建立出詳細的盒子結構：數學排版會在 TeX 中產生 *極其* 複雜的資料結構！

![{{{alt}}}](/files/64e5fca85926c721bfed5f20092a8a51f42c52db)

[![{{{alt}}}](/files/4a248319675b180dc4f0542f3ba9c4f3ad64548b)](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`的 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://overleaf-pro.ayaka.space/latex/zh-tw/shen-ru-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.
