> 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/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-tw/shen-ru-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

我第一次知道 LuaTeX，是在 2009 年底／2010 年初，當時它仍處於中期測試版發布階段（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 當時仍處於測試版開發階段，而且正在快速發展，我希望能跟上最新更新，因此對我來說最好的選擇就是自行從原始碼建置（編譯）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 一同發布。開發者非常積極，發現的任何錯誤通常都會在回報後不久修正——例如，透過 [dev-luatex 郵件列表](https://mailman.ntg.nl/mailman/listinfo/dev-luatex) 或透過 [線上 LuaTeX 錯誤追蹤系統](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 社群以及之後處理作者（La）TeX 檔案的人而言都至關重要：最明顯的是學術出版商，以及像 Overleaf 和 ShareLaTeX 這樣的雲端服務。

許多 TeX 使用者可能都想利用可變字型；例如，實作新的設計可能性，或為棘手的排版問題找到解決方案。因此，在某種意義上，這裡存在一個兩難：TeX 使用者想要取得一項新技術，但其實作取決於一個非常有限的資源：能夠且合格的開發者人數。修改 TeX 的內部結構很困難，而且一般而言，能避免就應盡量避免，那麼是否有另一種方式來為 TeX 增加（某些類型的）新功能／能力呢？有！而 LuaTeX 已經走上了這條路。

#### 早期實驗：OpenType 可變字型與 LuaTeX

LuaTeX 的設計已經讓可變字型技術能夠快速實驗。事實上，到了 2017 年 4 月，使用 LuaTeX 的 ConTeXt TeX 格式就已經有一個 [測試版](https://mailman.ntg.nl/pipermail/ntg-context/2017/088343.html) 實作了 OpenType 可變字型。這之所以可行，是因為 ConTeXt 的字型支援是以 Lua 程式碼建構的（而且 ConTeXt 有自己以 Lua 撰寫的 fontloader）。

## 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 語言，作為控制與編程其排版行為的方式：大約 320 個低階命令（原始命令）可供 TeX 巨集套件的使用者與開發者使用。這些命令對 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/3aab87102f8dd95cca582d1238d1ea6ceb8c342e)

**圖 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 %重新定義 \\ 的意義，以避免展開問題
以下是 {\ttfamily\string\hsize} 的目前值（透過 \LaTeX）：
\the\hsize\par
\directlua{
% 使用 Lua API 取得 \hsize 的目前值
local hs=tex.hsize
% 使用 Lua API 函式輸出一些
% LaTeX 程式碼以及 \hsize 的值
tex.print("這裡是 {\\ttfamily\\string\\hsize}
由 Lua 程式碼回報的值（以縮放點計）： ")
tex.print(hs.."\\par")
% 使用 Lua API 為 \hsize 設定一個新值
tex.hsize="400pt" % 或使用 tex.hsize=400*65536（以縮放點計）
}%
% 在 \directlua 結束後，請 LaTeX
% 告訴我們 \hsize 的新值
這裡是 {\ttfamily\string\hsize} 的值，由
\LaTeX{} 在 {\tt\string\directlua} 結束後回報：
\the\hsize\par
\end{document}
```

這裡有一張圖，顯示 LuaTeX 排版上述 LaTeX 程式碼的結果：

![執行 LuaTeX 的結果](/files/26815606da29e5a2b5d7bd4f3142dedcb5b0c132)

請注意，TeX 的「小技巧」 `\let\\\relax` 其用意是避免 LuaTeX 對 Lua 程式碼進行「展開」所造成的問題：這個主題我們在下文會簡要提及。

### 使用 Lua 程式碼

在您的 TeX/LaTeX 文件中使用 Lua 程式碼有兩種主要選項：

1. **內嵌**：直接在您的 `.tex` 文件中撰寫 Lua 程式碼（如上面的例子）；
2. **外部**：將 Lua 程式碼儲存在外部 `.lua` 程式檔中，並使用 Lua 的功能將它們載入與執行。

選項（1）最適合較短的 Lua 程式碼片段。選項（2）則用於較大型的 Lua 程式或函式庫。它有一個明顯優勢，就是可避免涉及 TeX 所謂 `\catcode` 值（這可能會「相當令人沮喪」）。造成這些 `\catcode` 問題的原因，是在送入 LuaTeX 內建 Lua 解譯器之前，Lua 程式碼會先進行「展開」。這種展開可能很難理解，因此我們會在後續文章中進一步探討。

當然，也有 LaTeX 套件可以協助您在 .tex 檔案中使用 Lua 程式碼——例如，您可以使用 [luacode 套件](https://ctan.org/pkg/luacode?lang=en).

## 摘要，以及本篇文章第 2 部分的導引

LuaTeX 所採用的軟體元件，加上內嵌的 Lua 腳本語言，提供了一個強大的組合，可用來打造能解決各式各樣複雜排版問題的解決方案——以及設計文件製作工作流程，而這些流程可因與基於 TeX 的排版引擎緊密整合而受益。在 [本文第二部分](/latex/zh-tw/shen-ru-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://overleaf-pro.ayaka.space/latex/zh-tw/shen-ru-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.
