> 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/ja/xiang-xi-ji-shi/09-an-introduction-to-luatex-part-2-understanding-directlua.md).

# LuaTeX入門（第2部）：\directluaを理解する

## この記事の目的

この記事の第1部では、 [LuaTeX入門（第1部）：LuaTeXとは何か、そして何がこれほど異なるのか？](/latex/ja/xiang-xi-ji-shi/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md)では、非常に汎用性の高いTeXエンジンとしてのLuaTeXを簡単に概観しました。LuaTeXは、文書エンジニアリングおよび制作のソリューションを構築するための幅広いツールを提供する、洗練されたプログラム可能な組版システムです。

この最終回では、LuaTeXツールボックスの最も重要な構成要素である `\directlua` コマンドを詳しく見ていきます。このコマンドは、Luaスクリプト言語を通じてLuaTeXの組版をプログラムで制御するための「ゲートウェイ」を提供します。

しかし、LuaTeXを完全に活用するには、 `\directlua` には、いくつかのTeXトピックに関する背景知識が必要です。すなわち、TeXのトークン、トークンリスト、展開機構です。この記事の目的は、これらの基本的なTeX概念を探究し説明することです。具体的には、 `\directlua` の背後にあるTeX関連の処理を組み合わせて、その動作への理解を深め、LuaTeXを使った独自の組版ソリューションを構築するための基礎を提供します。

この記事には、次の重要な側面を実演し説明するための多数の短い例が含まれています。 `\directlua`の挙動について、短いコード断片を優先し、意図的に過度に複雑なコードを避けています。必要に応じて、例では基本的な（raw/plain）TeXを使用します。大半の人はLaTeX（マクロ）を使用し好みますが、基本的なTeXコマンドには単純さという利点があります。

## LuaTeXにおけるLuaの紹介

[Lua](https://www.lua.org/about.html) は、その [ソースコード](https://www.lua.org/download.html) が非常に移植性が高く、ソフトウェアアプリケーションへ容易に組み込めるスクリプト言語です。これにより、開発者はプログラムにスクリプト機能を組み込めます。Luaは [多くのアプリケーション](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) に組み込まれており、ソフトウェアゲーム業界で人気のある選択肢です。おそらく最も有名な例は [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeXは、その名が示すように、Luaスクリプト言語を組み込んだTeXエンジンです。ユーザーはLuaプログラム（スクリプト）を文書に含めることで、LuaTeXの組版動作を制御できます。LuaTeXを直接制御することに加え、ユーザーはLuaを非常に有能なプログラミング言語として純粋に活用し、TeX言語では実現が極めて困難な作業を行えます。TeX言語は、どのように見ても学習し習得するのが難しい言語です。Luaの追加と統合により、LuaTeXは2つのプログラミング言語を直接サポートする、非常に汎用的かつ強力なTeXエンジンになります。

### 文書でLuaとTeXを使用する：\directluaの登場

LuaとTeXは、2つの *非常に異なる* プログラミング言語です。Luaは多くの人がプログラミング言語として考えるものにかなり近い一方、カテゴリコード、トークン、マクロ、展開機構を備えたTeXは、プログラムを書く言語に対する大半の人の経験や期待から大きく離れています。しかし歴史が示すように、TeX言語は、多少難解な動作方式ではあっても、設計された目的、すなわち組版の制御に優れているため、長く使われ続けています。

単一のTeX文書内でLua言語とTeX言語を混在させるという課題に対処するため、LuaTeXの開発者は次という新しいコマンドを導入しました。 `\directlua` これは、Luaを独立したプログラミング言語として使用する場合にも、LuaTeXの組版動作を制御する場合にも、Luaを使用するための手段です。

この `\directlua` コマンドにより、ユーザーはTeX文書内にLuaコードを埋め込むことができます。そのコードは後でLuaTeX内蔵のLua言語インタプリタに渡されます。しかし、 `\directlua` では、次のことも可能です。 *組み合わせる* Luaと（La）TeXのコードを、同じ `\directlua` コマンド内で組み合わせられます。ただし、LuaとTeXベースのプログラミング言語には根本的な違いがあるため、追加の複雑さが生じます。（La）TeXとLuaコードを組み合わせて使用する際の重要な課題は、両言語が平和に共存し、「互いの邪魔」をしないようにすることです。

`\directlua` は、文書内の短いLuaコード断片での使用に最も適していますが、必要であればより大規模なLuaプログラムでも使用できます。一般に、より本格的なLuaプログラムやLuaコードライブラリは外部ファイルに保存され、Luaの `dofile()` 関数を `\directlua` コマンド内で使用して読み込むことができます。TeX処理の観点では、外部Luaコードファイルを使用する大きな利点は、TeXのカテゴリコード機構から生じる複雑さを回避できることです。このトピックはこの記事で詳しく取り上げます。

### \directluaのより正式な説明

この [LuaTeXリファレンスマニュアル](http://www.pragma-ade.com/general/manuals/luatex.pdf) は、 `\directlua` を次のように説明しています（若干修正）：

> LuaコードをTeX入力と統合するには、いくつかの新しいプリミティブが必要です。プリミティブ `\directlua` は、Luaコードを直ちに実行するために使用されます。基本構文は `\directlua{⟨code⟩}`と呼ばれます。 `⟨code⟩` は完全に展開され、その後Luaインタプリタに渡されます。読み取りと展開が `⟨code⟩`に適用された後、結果のトークンリストは、次を使用して表示された場合と同じように文字列へ変換されます。 `\the\toks`.

もちろん、これは技術的には正確ですが、トークンや展開といった低レベルのTeX処理についてある程度の知識がなければ、理解しやすいものではないかもしれません。

## \directluaを理解する：どのトピックを扱うか？

この記事では、いくつかの重要な背景トピックを詳しく見て、 `\directlua` の動作と、TeXおよびLuaを自分の `⟨code⟩`.

次のトピックを、理解の基礎を提供するのに十分な詳しさで探究します。 `\directlua` と、その内部で使用するコードの「前処理」：

* カテゴリコードとTeXトークン：テキストからトークンへ、トークンからテキストへの変換。
* TeXの展開処理（および展開の防止）。
* 文字および文字列のためのLuaエスケープシーケンス／機構。
* Lua形式のコメントの使用。
* LuaTeXのLua APIへの短い導入。

TeXエンジンがどのようにトークンを作成・使用するかを理解し、TeXの展開機構を認識すれば、LuaTeXの驚くべき汎用性を引き出すために必要な基礎を得られます。 `\directlua` コマンド。

## 基礎：テキストからトークンへ、トークンからテキストへ

Overleafでは、TeXトークンと関連概念を深く掘り下げた記事をいくつか公開しているため、ここではそのすべてを繰り返しません。代わりに、 `\directlua`.

に対する理解を深めることに関連する分野／トピックを概説します。以下は、興味を持たれるかもしれない既刊記事の一覧です。

* [TeXトークンとは何か？](/latex/ja/xiang-xi-ji-shi/53-what-is-a-tex-token.md)
* [TeX トークンリストとは何か？](/latex/ja/xiang-xi-ji-shi/54-what-is-a-tex-token-list.md)
* [\expandafterはどのように動作するか：TeXトークン入門](/latex/ja/xiang-xi-ji-shi/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [全6回シリーズ：TeXマクロは実際にはどのように動作するのか？](/latex/ja/sononotopikku/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### 文字トークンを理解する

TeXエンジンがテキストファイルから読み取れるあらゆる文字は、2つの数値で表現されます。

* その *文字コード* （ASCII値、または現在ではUnicodeコードポイント）。
* その文字の、TeX固有の2番目の値である *カテゴリコード*.

カテゴリコードについてさらに知りたい読者には、Overleafが公開した次の入門記事がおすすめです： [では、どこから始めるべきか？ カテゴリコードからです](/latex/ja/sononotopikku/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

たとえば、TeXエンジンが文字 `ある` を読み込む場合、次の2つの情報を取得できます。 `ある`の文字コード（65）と、そのカテゴリコード（通常は11）です。TeXがその文字 `ある`を入力すると、そのカテゴリコードは変更されません。しかし、ユーザーマクロによってカテゴリコードを変更し、 *後続の* 文字 `ある` であって、 *まだ読み取られていない* ものに影響を与えることがあります。したがって、TeXは、 *この* 文字 `ある`, *今読み込まれた*のカテゴリコードが11であることを記録する必要があります。そのため、TeXは整数の組（65,11）を使って、 *文字トークン*と呼ばれる別の整数値を計算します。そのトークン値を計算してTeXの内部処理へ渡すことにより、その特定の `ある` とそのカテゴリコードは *結び付けられます*。事実上、その文字トークンは *カプセル化している* のです。すなわち、TeXエンジンの内部で後続の組版処理に使用するために、TeXがその文字について知る必要のあるデータを保持します。

#### 文字トークンはどのように計算されるか？

まず、TeXエンジンは、いわゆる *アクティブ文字*を作成するためにカテゴリコード13を使用することを覚えておく必要があります。カテゴリコード13の文字はすべてミニマクロのように動作します。したがって、後述するように、アクティブ文字のトークンは、10、11、12など他のカテゴリコードを持つ通常の文字とは異なる方法で計算されます。

〜については *非アクティブ* 文字：

* 古い8ビットエンジン（KnuthのTeX、e-TeX、pdfTeX）は、 *非アクティブ* 文字の文字トークンを次のように計算します。

$$\text{(non-active) character token} = (256 \times \text{category code}) + (\text{ASCII character code})$$

* Unicode文字値を扱う必要があるLuaTeXでは、 *非アクティブ* 文字の計算は類似していますが、はるかに大きな整数値を生成します。

$$\text{(non-active) character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

カテゴリコード11の文字Aについて先ほどの例に戻ると、LuaTeXは次の文字トークン値を計算します。 $$2^{21} \times 11 + 65 = 23068737$$。いったん計算されると、その文字トークン値は *結び付けます* その特定の文字Aをカテゴリコード値11に結び付けます。ユーザーマクロは後続の文字Aのカテゴリコードを変更できますが、このAのカテゴリコードは、LuaTeXの内部処理を通過する際に使用するトークンへ変換された時点で固定されています。LuaTeXは、読み込まれた時点で決定されたその文字の意図された意味を保持、すなわちカプセル化しています。

TeXエンジンは全部で [16種類のカテゴリコード](/latex/ja/sononotopikku/43-table-of-tex-category-codes.md) や *を使用します。* これらのカテゴリコードのいずれも、 `\catcode` コマンドを介して、 *を使用します。* TeXエンジンが読み取れる任意の文字に割り当てることができます。カテゴリコードの変更は、TeXエンジンが入力中の特定の文字を処理する方法を変えるために使用され、TeXユーザーは特別な組版結果や動作を生み出すマクロを書くことができます。

**アクティブ文字**

前述のとおり、TeXエンジンは文字に「特別な意味」を付与するためにカテゴリコード13を使用し、その文字をいわゆる *アクティブ文字* にします。これはミニマクロのように動作します。先頭の `\` は不要であり、単独の文字だけで、そのカテゴリコードにより、マクロのような動作を引き起こすのに十分です。

アクティブ文字はミニマクロとして機能するため、 *文字トークン* には変換されず、 *コマンドトークン*と呼ばれる第2の（整数）トークン型へ変換されます。これらは次のように計算されます。

* 古い8ビットエンジン（KnuthのTeX、e-TeX、pdfTeX）では、アクティブ文字のトークンは次により計算されます。

1. 中間値を計算します。これは $$\text{curcs}$$ (**cur**rent **c**ontrol **s**equence）と呼ばれます。ここで $$\text{curcs} = \text{character code} + 1$$3. 次の条件でトークン値を計算します。 $$\text{active character token} = \text{curcs} + \text{4095}$$

* LuaTeXでは、アクティブにできる可能性のあるすべてのUnicode文字を扱う必要があるため、計算は少し複雑です。

1. 中間整数値を計算します。 $$\text{curcs}$$ これは、いわゆる *ハッシュ関数* を、UTF-8で表現されたアクティブ文字のUnicodeコードポイント値に適用して得ます。 $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. 整数トークン値を計算します。 $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**例**

* 8ビットエンジン：アクティブ文字 `~` （文字コード126）のトークン計算は、 $$\text{curcs} = 126 + 1 = 127$$となり、トークン値は $$4095 + 127 = 4222$$.
* LuaTeX：アクティブ文字 `~` のトークン計算は、 $$\text{curcs}=3186$$ となり、トークン値は $$3186 + 2^{29} - 1 = 536874097$$です。LuaTeXトークンははるかに大きな整数値を使用します！

### コマンドトークンを理解する

処理に加えて、 *個々の* 文字だけでなく、TeXエンジンはもちろん、 *連続した文字列* も処理できます。これらは *コマンド* と呼ばれます（より正確には、 *制御綴*）。慣例として、 `\` 文字はコマンド開始を示すために使用されますが、それは単なる慣例です。実際には、カテゴリコード0（エスケープ文字）の任意の文字を代わりに使用できます。

TeXエンジンは、次の名称で知られる2種類のコマンドを認識します。 *制御語* や *制御記号*:

* **制御語**：カテゴリコード11を持つ1文字以上から構成されるコマンド。
* **制御記号**：その文字のカテゴリコードが *は* 11ではない単一文字のコマンド。例： `\$`, `\#` または `\\`.

**注**：TeXプリミティブ `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` や `\toksdef` も制御綴の定義に使用されますが、通常のマクロ定義とは異なり、結果として得られる制御綴（制御語または制御記号）は *展開可能ではありません*。これらについては後でより詳しく探究します。

#### コマンドトークンはどのように計算されるか？

アクティブ文字と同様に、TeXエンジンはコマンドを表すために第2種類の整数トークン値を使用します。 *コマンドトークン*。アクティブ文字もミニマクロのように振る舞うため、コマンドトークンを生成することを思い出してください。

8ビットエンジンがコマンドトークン整数を作成する際に使用する計算は、この [Overleafの記事](/latex/ja/xiang-xi-ji-shi/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values)で確認できます。ここでは、LuaTeXのコマンドトークン計算における主要な手順を要約します。LuaTeXは8ビット値よりかなり大きくなり得るUnicode文字コード値を処理しなければならないため、計算はわずかに異なりますが、古い8ビットエンジンと同じ一般原則に従います。

入力コマンドを検出した後、LuaTeXを含むTeXエンジンは先頭の `\` 文字を無視します。これはコマンドトークン値の計算には使用されず、TeXエンジンにコマンドを処理する必要があることを知らせる「スイッチ」として機能するだけです。コマンドトークン値は、コマンド名に含まれる（1つ以上の）文字列を使用して計算されます。LuaTeXは制御記号と制御語のコマンドトークンを同じアルゴリズムで計算します。

1. 中間整数値を計算します。 $$\text{curcs}$$ これは、いわゆる [ハッシュ関数](https://en.wikipedia.org/wiki/Hash_function) コマンド名に含まれる文字のUnicode UTF-8文字列に対して： $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. 次の条件でコマンドトークン値を計算します。 $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**例**

* の `\\` コマンド（制御記号）について、LuaTeXは次を計算します。 $$\text{curcs}=94$$。結果として、 `\\` のトークン値は次のようになります。 $$94 + 2^{29} - 1 = 536871005$$.
* の `\vskip` プリミティブコマンド（制御語）について、LuaTeXは次を計算します。 $$\text{curcs}=3560$$。結果として、 `\vskip` のトークン値は次のようになります。 $$3560 + 2^{29} -1 = 536874471$$.
* ユーザー定義マクロ `\mynewmacro` （制御語）について、LuaTeXは次を計算します。 $$\text{curcs} = 2971$$。結果として、 `\mynewmacro` のトークン値は次のようになります。 $$2971 + 2^{29} -1 = 536873882$$.

作成されたトークンは、いわゆる *トークンリスト* を通じて後で使用するために保存することも、TeXエンジン内部でさらに処理するために直ちに渡すこともできます。整数値を使ってトークンを表現する方法は、あらゆる種類のコンピューティングプラットフォーム／オペレーティングシステムで機能するだけでなく、TeXがデータを保存・処理する非常に効率的な方法でもあります。

### TeXエンジンがトークンの種類（コマンドか文字か）を識別する方法

特定の整数トークン値が与えられると、 $$T$$について、TeXエンジンは、 $$T$$ がコマンドを表すか文字を表すかを、 $$T$$ が特定の $$\text{threshold value}$$を超えるかどうかを検査することで容易に判定できます。その $$\text{threshold value}$$ はTeXエンジンによって異なります。 $$T \geq \text{threshold value}$$ すると $$T$$ がコマンドトークンであり、そうでなければ $$T$$ は文字トークンです。この $$\text{threshold value}$$ は $$4095$$ は8ビットエンジン用であり、 $$2^{29}-1$$ はLuaTeX用の（536,870,911）です。Knuthは、彼のTeXエンジンと、そのコード／アーキテクチャに基づく後続のすべてのエンジンが、トークン値を素早く容易に検査できるように、トークン計算式で使用する方法を設計しました。

## トークンは分解できる（そしてテキストへ戻せる）

トークン（整数）は、TeXエンジンが入力項目（文字またはコマンド）について記録する必要のあるすべてを「カプセル化」する仕組みです。しかし、TeXエンジンがトークン化処理を逆にする必要がある場合があります。つまり、そのトークン値を生成するために元々読み込まれたもの、すなわち個々の文字またはコマンド名を形成する1文字以上の文字列を調べる場合です。

* **文字トークンの場合**：任意の文字トークンは、その構成要素である文字コードと、その文字に割り当てられた対応するカテゴリコードに分割できます。 *元々読み込まれた時点で*。すべてのTeXエンジンと同様に、LuaTeXは元のカテゴリコード割り当てを変更しませんが、以降の内部処理活動でそれを利用します。
* **コマンドトークンの場合：** これらは少し詳細になりますが、アクティブ文字のトークンを含むLuaTeXのコマンドトークン計算を見ると、次のパターンに従っていることが分かります。 $$\text{command token} = \text{curcs} + 2^{29} -1$$

ここで $$\text{curcs}$$ は、生成されるコマンドトークンの種類、すなわちアクティブ文字、制御記号、制御語に応じて計算されます。この $$\text{curcs}$$ 変数は、 *極めて* TeXエンジンの内部操作における重要な構成要素です。任意のコマンドトークン（整数）値が与えられれば、LuaTeXは、 $$\text{curcs}$$ の値を、そのコマンドトークンから次を用いて非常に容易に抽出できます。 $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### なぜ $$\text{curcs}$$ はそれほど重要なのか？

内部TeX変数 $$\text{curcs}$$ (**cur**rent **c**ontrol **s**equence）は、TeXエンジンの内部における「舞台裏」の操作で極めて重要な構成要素です。コード内で直接使用またはアクセスすることはできず、また使用もしませんが、 $$\text{curcs}$$ は極めて重要な役割を果たします。なぜならTeXエンジンは、 $$\text{curcs}$$ の現在値を、エンジンが現在認識しているすべてのコマンドに関するデータを保存する内部テーブルへのインデックスとして使用するからです。これらのテーブルには、コマンドの現在の意味、すなわち何をするのか、または何を表すのかに関する情報が保存されます。さらに、その $$\text{curcs}$$ 値を計算するために元々使用された文字列も記録されます。 $$\text{curcs}$$ の値をコマンドトークンから抽出することで、TeXエンジンは任意の（コマンド）トークンに対応する名前、すなわち人間が読めるテキストを判定できます。これにより、 `\directlua`の動作において重要な側面であるトークンからテキストへの変換を実行できます。

### 整数トークンを文字または文字列（コマンド名）へ戻す

TeXエンジンが入力文字または文字列を整数トークン値へ変換することを見てきましたが、TeXエンジンが次のことを行う必要がある場面もあります。 *逆にする* その処理を、つまりそれらの整数トークン値を作成するために元々使用された人間が読めるテキストを出力することです。例：

* エラーまたは警告メッセージを画面または `.log` ファイルに書き込むこと。
* 次を介してTeX/LaTeXコードをテキストファイルへ出力すること。 `\write` コマンド;
* 内でトークン列をテキストへ変換する場合 `\directlua` （すぐに見ていきます！）

#### 文字トークンをテキストへ変換する

前述のとおり、非アクティブ文字のトークンは、入力文字のカテゴリコードと文字コード（Unicode値）を使用して計算されます。LuaTeXは次の式を使用します。

$$\text{character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

整数 $$\text{character token}$$ 値を分割して、その構成要素である文字コード（$$\text{Unicode value}$$）と $$\text{category code}$$.

#### を取得することは、単純なプログラミング作業です。

コマンドトークンをテキストへ変換する `\`）を除いたマクロ名は、TeXエンジン内部におけるマクロ定義処理の一部として保存されます。

TeXエンジンが、整数コマンドトークンが元々計算された人間が読めるテキストにアクセスまたはそれを出力する必要がある場合、最初にそのトークンの $$\text{curcs}$$ 値を決定します。LuaTeXでは、 $$\text{curcs} = \text{token} - (2^{29} -1$$）です。 $$\text{curcs}$$ コマンドトークンから抽出した *文字列プール* と呼ばれる内部データ構造にアクセスして、その特定の $$\text{curcs}$$ 値、ひいては対応するコマンドトークンを計算するために元々使用された人間が読める文字列を判定できます。

これから見るように、これらのトークン処理活動、すなわち文字列を整数トークン値へ変換することと、整数トークン値を文字列へ戻すこと（「デトークン化」）は、 *基本的な機構* の内部で使用されます。 `\directlua`.

## トークンリスト

TeXエンジンが入力を読み取り、文字およびコマンドトークンを生成して処理しているとき、エンジンに対して、トークンを以降の処理へ渡すのを（一時的に）停止し、代わりに後で使うために保存するよう指示する特定のコマンドに遭遇することがあります。最も一般的な例は、マクロ定義コマンドのいずれかを使ってマクロを定義することです。 `\def`, `\edef`, `\gdef` または `\xdef`。LaTeXコマンドの例として、 `\newcommand` は、最終的に実際のマクロ定義処理を行う低レベルプリミティブを中心に構築された追加機能を提供するマクロです。マクロは、保存された特定のトークンリスト、すなわちトークンリストに与えられた名前と見なすことができます。

TeXエンジンは、 *広範に* トークンリストを使用します。特に、 [一時的な内部専用リスト](/latex/ja/xiang-xi-ji-shi/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) を内部処理目的で使用します。すべてのTeXエンジンは、ユーザーまたはTeXエンジン自体が必要とするときのために保存されるトークンリストを作成するユーザーレベルのコマンドも提供します。トークンリスト作成コマンド（組み込みプリミティブ）の数はTeXエンジンによって異なりますが、すべてのエンジンが共通してサポートする最小限の中核セットがあります。たとえば、 `\toks` プリミティブです。

実際には、トークンリストは単なる保存された整数値の列です。

* 入力を読み取って、文字またはコマンドを表す個々のトークンを生成（計算）する。
* その後、各トークンを保存し、入力からトークンが生成された順序を保持する。

TeXエンジンは、 [連結リスト](https://en.wikipedia.org/wiki/Linked_list) （単方向連結型）と呼ばれるデータ構造を使ってトークンリストを保存します。トークンリストについて詳しく知りたい読者は、Overleafの記事 [TeX トークンリストとは何か？](/latex/ja/xiang-xi-ji-shi/54-what-is-a-tex-token-list.md) を読むことをおすすめします。この記事では、トークンリストの背後にある概念／考え方を類推によって構築しています。TeXのトークンリスト、およびそれらがマクロ処理でどのように使用されるかの詳細な探究は、Overleafの記事シリーズ [TeX マクロは実際にどのように動作するのか？](/latex/ja/sononotopikku/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### 図示したトークンリスト

次の図は、以下の入力から生成された対応するトークン値を持つ、LuaTeX生成のトークンリストを示しています。

`Hi, \TeX! \hskip 5bp`

たとえば、次を定義した場合、 `\mymacro` as `\def\mymacro{Hi, \TeX! \hskip 5bp}` の定義は、 `\mymacro` のようなトークンリストを使用してメモリに保存されます。

![](/files/d159c50556fd17d799a116106381d73111da81f5)

トークンリストは、 *ノード*と呼ばれる連結項目の列です。これは、リスト内の各項目を保持するために割り当てられたLuaTeXメモリの小さなパッケージに与えられた名前です（鎖の個々の輪のようなものです）。各ノードには整数トークン値と、 *次の* 連鎖内のノードのメモリアドレスが含まれ、 [連結リスト](https://en.wikipedia.org/wiki/Linked_list)と呼ばれるデータ構造を形成します。最後のノードは、次のノードには存在しないため、次のノードに特別な「null値」を使用してリストの終わりを示します。

**注：**

* 便宜上、個々のノードのアドレスを含めていますが、実際にはそのデータはトークンリストのノード内に保存されません。 *次ノード* のアドレスだけが、TeXエンジンのトークンリストを構築するために必要です。
* 図中の「各トークンの意味」と題された第2列は、各ノードに含まれるトークンの情報を収めた一連の灰色のボックスを示しています。これらは純粋に情報提供のためのものであり、 *は* はトークンリストに実際に保存されるデータの一部を構成しません。

上図のトークンリストに含まれるトークン値の表を以下に示します。

|          |              |                                                                 |           |
| -------- | ------------ | --------------------------------------------------------------- | --------- |
| **入力項目** | **入力の種類**    | <p><strong>カテゴリコード</strong><br><br><strong>（文字の場合）</strong></p> | **トークン値** |
| H        | 文字           | 11                                                              | 23068744  |
| i        | 文字           | 11                                                              | 23068777  |
| ,        | 文字           | 12                                                              | 25165868  |
|          | 文字           | 10                                                              | 20971552  |
| \TeX     | コマンド（マクロ）    |                                                                 | 536871539 |
| !        | 文字           | 12                                                              | 25165857  |
|          | 文字           | 10                                                              | 20971552  |
| \hskip   | コマンド（プリミティブ） |                                                                 | 536874247 |
| 5        | 文字           | 12                                                              | 25165877  |
| b        | 文字           | 11                                                              | 23068770  |
| p        | 文字           | 11                                                              | 23068784  |

**注：** 元の入力テキストには、その後にaがあります `\hskip` コマンドですが、トークン一覧にはその文字を表すトークンがありません。その文字は LuaTeX の入力スキャン（読み取り）プロセスによって吸収されました。というのも、その文字は LuaTeX が構成する文字を探す検索を終わらせるために使われたからです。 `\hskip` コマンド。

## \directlua の実際の動作

ここまででトークン、トークンリスト、そしてトークンをテキストへ変換することを見てきたので、次の課題は TeX エンジンにおけるトークン……の概念を理解することです *の展開*.

述べたように、 `\directlua{⟨code⟩}` に処理させることができます `⟨code⟩` Lua と TeX/LaTeX のコードの両方を含んでいますが、LuaTeX に内蔵された Lua 言語インタプリタは TeX や LaTeX を理解しません。では、どうしてこれが動くのでしょうか？ どのようにして……が `⟨code⟩` Lua インタプリタを理解できないコマンドで完全に混乱させることなく、TeX/LaTeX の命令を含めることができるのでしょうか？ たとえば、次の `\directlua` コマンドは TeX マクロだけを使っていますが、動作します:

```
\def\aa{tex}
\def\bb{.}
\def\cc{print}
\def\dd{("Hello")}
\directlua{
   \aa\bb\cc\dd
}
```

この `\directlua` コマンドにより LuaTeX は組版します `Hello` しかし、Lua 言語は TeX マクロを理解しないのに、なぜ、どのようにしてこれが動くのでしょうか？

答えは、先ほど私たちが借用した説明の中に含まれています。 [LuaTeXリファレンスマニュアル](http://www.pragma-ade.com/general/manuals/luatex.pdf) ただし、次のように考えることができます。 `\directlua{⟨code⟩}` LuaTeX が最初にその……を「前処理」することによって動作します。 `⟨code⟩` Lua インタプリタに何かが渡される前に。この「前処理」の性質、すなわち本当の意味と、あなたの……に対するその影響は `⟨code⟩`—これが、の力と柔軟性を活用したい読者を助けるために、次に取り上げるテーマです `\directlua`.

### \directlua を LuaTeX が処理する方法: 第一印象

……に関する理解を深めるために `\directlua`の「前処理」活動については、起こることの概要を示す次の簡略図から始めることができます。 `⟨code⟩` が与えられる `\directlua{⟨code⟩}` は、まず上で述べた処理と計算を使ってトークンに変換されます。そのトークン列はトークンリストに格納されます。そのトークンリストが構築されると、リスト内の各トークンはそのテキスト表現に戻されます。各トークン—文字トークンでもコマンドトークンでも—が生成するテキストは結合（連結）され、実行のために Lua インタプリタへ渡される単一のコード文字列が作られます。

![](/files/0e2bc1c1d8a1f0231a598151eca361244a187ef4)

しかし待ってください。テキストからトークンへ行き、そのトークンをすぐにまたテキストへ戻すことに何の意味があるのでしょうか？ この図に含めていない追加の、そして重要な処理があることを知っても驚かないでしょう: *トークン展開*。あなたの……のテキストから生成されるすべてのトークンは `⟨code⟩` ある種の「検査」にかけられ、LuaTeX はそのトークンが次のサブセットに属するコマンドを表しているかどうかを調べます。 *展開可能コマンド*。もしそうなら、LuaTeX はそのコマンドを……によって除外します。 *取り除き* それをあなたの……から `⟨code⟩` や *置き換え* TeX エンジンが……と呼ぶ *トークン展開*.

### \directlua を LuaTeX が処理する方法: 第二の見方（展開について）

TeX の展開メカニズムは、Knuth の元の TeX ソースコードと設計に由来する（またはそれに基づく）ため、TeX 系組版エンジンすべての中核的な要素です。しかし、展開という概念は、簡潔でありながら理解しやすい言葉で説明するのが難しいです。実際には、展開は単一の処理を表す「包括的」な用語ですが、その結果としてさまざまな出力を生みます。こうした多様な結果は、展開を適用できるコマンドの種類がやや雑多であることに起因するので、各展開可能コマンドにはある種の「展開動作」があると考えることができます。

最初の *近似として* 展開を理解するためには、トークン（コマンド）の展開とは次を意味すると言えます。 *取り除き* TeX の現在の入力からそのコマンド（トークン）を *置き換える* それを、その特定の展開可能コマンドを実行して得られるトークン列で置き換えること—つまり元のトークンを、その展開の結果／帰結で置き換えること *動作*。ただし、トークンを TeX に読ませる新しいトークンを生成する、というこの展開の初期の「定義」は、すべての展開可能コマンドに完全に当てはまるわけではありませんが、出発点としては十分です。

分かりやすい例を挙げると、TeX のプリミティブ `\jobname` は展開可能コマンドであり、その *の展開* は、メインの TeX 入力ファイル名を表す文字トークン列です。TeX がある `\jobname` コマンド（トークン）を展開すると判断した場合、それは *取り除かれ* TeX の現在の入力ソースから *置き換えられ* それが生成する文字トークン列によって置き換えられます。その後 TeX はそれを読み取り／処理します。

の中では `\directlua`、展開可能トークンが処理（取り除き）され、新しいトークンで置き換えられると、LuaTeX は直ちにその新しく置いたトークンを読み進めます—しかし、その新しいトークンの中には展開可能なものもあります。 `\directlua` いわゆる *完全展開*、LuaTeX はそれらの新しいトークンを読み、さらにもう一度展開処理を行って、新たな（展開可能な）トークンを展開（除去）します—この展開処理は、展開可能トークンが残らなくなるまで続きます。ただし、この「展開し続ける」規則には重要な例外が 2 つあり、どちらも以下で説明します:

* 構文 `\the\toks`;
* 選択した 1 つ以上のトークンに対する展開の意図的な防止（抑制）。

述べたように、展開を理解するための私たちの作業用定義（一次近似）は、展開可能コマンドのサブセットが示す展開動作の全範囲をカバーしていません。たとえば、いくつかの展開可能コマンドは、 `\jobname` のようにトークンを生成しませんが、次のことを行う場合があります:

* 入力からトークンを「ふるい分ける」: TeX エンジンの条件分岐コマンド（`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`、…）は展開可能です。その展開動作は一種の「トークンのフィルタリング」であり、条件分岐は……で使うことができます `\directlua`.
* 入力中のトークンを「入れ替える」: その [`\expandafter` コマンド](/latex/ja/xiang-xi-ji-shi/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) は展開可能で、2 つのトークンが展開される順序を変えます。
* 展開を防ぐ: 展開可能コマンド `\noexpand` や `\unexpanded` は入力中のコマンドトークンの展開を抑制します。
* 入力内の文字列をコマンドトークンに変換する: `\csname … \endcsname.`
* 内部量を文字トークン列に変換する: `\number` や `\the` は、内部量の値を表す文字トークン列を生成する展開可能コマンドです。
* コマンドトークンを文字トークンに変換する: `\string` や `\detokenize` は、引数をカテゴリコード 12 の文字トークン列に変換する展開可能コマンドです。注意してください、 `\detokenize` は……とは異なります。 `\string`: `\detokenize` は複数のトークンを処理でき、から作成されたコマンドトークンを処理したあとに、カテゴリコード 10 のスペース文字を挿入します。 *制御語*。実質的には、 `\detokenize` はコマンド名の後ろに末尾のスペース文字を追加します—この記事の後半で例をいくつか見ます。

#### 展開の「定義」を洗練する

ここで私たちの定義を一般化して、コマンド（トークン）の展開とは次を含むと言えます。 *除去* TeX の現在の入力ソースからそのコマンド（トークン）を *置き換え* による *トークン操作* そのコマンドが行う操作の結果で置き換えることです。要するに、展開処理は、TeX の現在の入力にあるトークンに対して展開可能コマンドが何らかの「操作」を行い、その後 TeX が読み取るトークンの数や振る舞いに影響を与えます—その「操作」の正確な性質は、どのコマンドが展開されているかによって決まります。すべてのマクロとアクティブ文字は展開可能ですが、TeX エンジンの組み込みコマンド（プリミティブ）のうち展開可能と分類されるのはごく少数です—展開可能コマンドの一覧は、使用している TeX エンジンによって異なります。

新しい TeX エンジンはすべて、その祖先（それが派生した旧世代の TeX エンジン）に組み込まれていたプリミティブコマンドを継承し、その継承されたプリミティブの一部は展開可能です。もちろん、新しい TeX エンジンは、古いエンジンに含まれる一部のプリミティブコマンドを実装しないか、新しいエンジンの要件に合わせてその動作を変更することがあります。さらに、新しい TeX エンジンは通常、自身の拡張機能を支えるために追加のプリミティブを実装します—その一部も展開可能である場合があります。その結果、使用している TeX エンジンに応じて、利用できる展開可能コマンドの数は変わります—LuaTeX にはかなり多くのものがあります。

展開の説明／理解におけるもう一つの難しさ、そしておそらく本当の課題は、TeX エンジンが実際にいつ展開処理を行うのか、あるいは行わないのかを正確に知ることです。これは大きく複雑な話題で、展開は TeX エンジン内部の仕組み全体に深く組み込まれています。ここでは、\directlua における展開の使用以外に詳しく説明する余裕はありません。 *いつ* TeX エンジンが実際に展開処理を行うのか、あるいは行わないのか。 `\directlua`.

### \directlua を LuaTeX が処理する方法: 最終確認

次の図は、LuaTeX エンジン内部で行われる `\directlua` 前処理活動を要約しています。この図では、実際に処理を行う 2 つの低レベル（内部）LuaTeX 関数も示します: `scan_toks()` や `tokenlist_to_cstring()`。これらの関数は C 言語で書かれており、実行可能な LuaTeX ソフトウェアの奥深くに存在します。これらは LuaTeX の内部機構の一部であり、 *直接* あなたの TeX/LaTeX コードからアクセスできるものではありません。

![](/files/4745f09e73b054a42ea5e4e3c2295905754f0b90)

次の `\directlua ⟨code⟩`の前処理活動の説明は、上の図を要約したものです。

1. あなたの ⟨code⟩ にある文字列は、 `scan_toks()`によって処理されます。その目的は、⟨code⟩ を文字ごとに読み取り、文字トークンとコマンドトークンを生成することです。トークンを作成するため、読み込まれる時点で ⟨code⟩ の各文字に割り当てられているカテゴリコードは非常に重要です。
2. の処理中、 `scan_toks()`のトークン処理（生成）では、任意の展開可能コマンド（トークン）は展開されます。 *ただし* 次のようなコマンドによって防止されます。 `\protected` （マクロ定義）、 `\noexpand`, `\unexpanded` などです。アクティブ文字（カテゴリコード 13）も（防止されない限り）展開されます。
3. によって作成されたトークンの流れは `scan_toks()` 1 つの長いトークンリストとして構築されます—そのリストに含まれるトークンには、あなたの……内にある展開可能コマンド（マクロなど）に展開を適用して生成されたものも含まれます。 `⟨code⟩`。また、 `scan_toks()` *終了しません* 展開不可能なコマンドを表すトークンの実行を引き起こしたり起動したりはしません。そのような展開不可能トークンは単にそのまま通過し、構築中のトークンリストに組み込まれます。
4. トークンリストが完成し、すべての展開処理が終わると、そのトークンリストは次の別の関数で処理されます。 `tokenlist_to_cstring()` この関数は最終的なトークンリスト内の各トークンを、そのテキスト表現へ戻します。これにより、Lua インタプリタへ渡す Lua コードとなるテキスト文字列が生成されます。正常に実行するには、その文字列に構文的に正しい Lua コードが含まれていなければなりません。
5. そのコードの Lua による処理は 2 段階で行われます:
6. LuaTeX に内蔵された Lua インタプリタは、前の段階で生成された Lua コードを解析し、「コンパイル」します。この解析／コンパイルに失敗すると、Lua インタプリタは（構文エラーなどの）エラーを生成します。これらのエラーは、あなたが次を使うことを選ばない限り、LuaTeX の実行を失敗させる可能性があります。 `--interaction=nonstopmode` をコマンドラインで。
7. 解析／コンパイルが成功すると、Lua インタプリタは手順 (5a) でコンパイルされたコードを実行します。

要するに、 `scan_toks()` 関数は LuaTeX の前処理活動の中核です。その主な仕事は、あなたの……のテキストに含まれるすべての展開可能な TeX/LaTeX コマンドを展開することです。 `⟨code⟩` そして、処理したものすべてからトークンリストを構築することです。繰り返しになりますが、強調しておくと、 `scan_toks()` *は展開不可能なコマンドを実行しません* （トークン）: 単に *保存するだけです* それらのトークンを、自身が構築しているトークンリストに。完了すると、そのトークンリストはその後変換されます *テキスト表現へ戻され* 、 `tokenlist_to_cstring()`—トークンリストは TeX 専用の概念であり、Lua インタプリタにはまったく異質です。そのため、これをテキストに変換して Lua コードにし、Lua インタプリタへ渡す必要があります。

## プログラミング言語の「インターフェース」としての展開

次のように考えることができます。 `\directlua`の展開処理を、「TeX World」から「Lua World」へデータ／情報を渡すための仕組み、あるいはインターフェースとして使うことです。つまり、TeX 言語が Lua 言語へデータを伝える方法を提供するということです。たとえば、次のような TeX コード `\number\count75` を使うと、カウントレジスタ 75 に格納された「TeX World」の値を「Lua World」の整数変数 x に渡すことができます:

```
\count75=1564 % "TeX World" に存在するデータ
\directlua{
   local x=\number\count75 \space % TeX データを「Lua World」へ転送
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" and y = "..y)
}
```

これにより次の Lua コードが生成されます

```
 local x=1564 tex.print("x= "..x) local y = (2*x-65)/5 tex.print(" and y = "..y)
```

**注**：私たちは `<space>\space` の後に `\number\count75` スペース文字が次の間に保持されるように追加しました `1564` や `tex.print`—ここでは厳密には必要ありません。省略しても Lua はコードを正しく解析できるからです。直後に続くスペース文字は `\count75` TeX エンジンが数値を探すときの処理中に吸収されます—ここでは、次に渡される値です `\count`。 `75` の後のスペース文字は、LuaTeX の桁列の検索を終了させるために使われます `75` 、入力から吸収されます。 `\space` マクロは、テキストを区切るために必要なスペース文字を提供するように展開されます `1564` や `tex.print`.

上のコードを使うと、LuaTeX は次を組版します

`x= 1564 and y = 612.6`

ここで「データ受け渡し」メカニズムは次によって実現されています。 `\number`：この場合、TeX に次を指示する展開可能コマンドです。 `\count` レジスタに保存します `75` そしてその値（`1546`）から、各桁ごとに 1 つの文字トークンを生成し、結果として次の桁のトークン列になります `1`, `5`, `6` や `4`。これら 4 つの文字トークンは、によって構築中のメイントークンリストに組み込まれます `\directlua` そして、その後トークンリストがテキストへ変換されるときに、そのテキスト表現へ戻されます。確かに、から始まって `\count75` LuaTeX 内に格納されたレジスタ値から Lua コード用の数字へ至るのは、かなり回りくどい経路ですが、最終的にはうまくいきます。

**ヒント:** LuaTeX の展開処理の結果を確認したいなら、次のようなコードを書けます:

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" and y = "..y)]]
   print(foo)
}
```

この例では、長いブラケット方式を使って文字列変数 `foo` を作成しています。その目的は、次の間にあるものすべての展開から生成された Lua コード文字列を保持することです。 `[[` や `]]`。その文字列は Lua 関数呼び出し `print(foo)`.

Overleaf では、次の内容を書き出すことで同様の結果を確認できます `foo` を `.log` ファイルへ、LuaTeX の Lua 関数 `texio.write()`:

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" and y = "..y)]]
   texio.write(foo)
}
```

## \directlua トークンリスト内のトークン: 展開不可能トークンと未展開トークン

すでに述べたように、 `\directlua{⟨code⟩}` は *完全展開* あなたの……に対して `⟨code⟩`：展開不可能トークンだけが残るまで、すべての展開可能コマンドを取り除き、展開します。によって作成されたトークン列は `\directlua`の処理（……内で）によって `scan_toks()` 関数）で連ねられてトークンリストを形成し、その個々のトークンは Lua に渡すためにテキストへ戻されます。

しかし、この話の最後の部分はまだ扱っていません。というのも、次の内部で構築されるトークンリストまで到達できるコマンドトークンの 2 つの「クラス」を考える必要があるからです。 `\directlua`：これらを次のように呼びます *短縮コマンドトークン* や *未展開* トークン:

* **短縮コマンドトークン**：この種類のコマンドトークンは、TeX プリミティブのいずれかを使って定義された制御綴りから生じます `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` や `\toksdef`。これらのプリミティブコマンドは、数値を表す制御綴りを定義するために使われます—その結果として得られる制御綴りは *実際の* 展開不可能です。
* **未展開トークン**：このトークン型は、通常なら展開されるはずのコマンドから生じますが `\directlua` 次のいずれかが起きています。
* 明示的に指示された *実際の* それらを展開するように。たとえば、次のコマンドによる展開の抑制 `\noexpand` または `\unexpanded`—これがどのように行われるかは後ほど説明します。
* 次のシーケンスを処理して挿入されたトークン `\the\toks` （これについては後述します）。

### \directlua トークンリストにおけるトークンの 2 つの「グループ」

これまでの議論を踏まえると、最初の段階で構築されるトークンリストに含まれるトークンは `\directlua`の前処理（……内）で `scan_toks()` 関数）では 2 つのグループに分かれると言えます:

1. *本質的に展開不可能な* トークン

* 非アクティブなものを表す任意のトークン *文字*;
* 展開不可能なものを表す任意のトークン *プリミティブ* *コマンド*;
* 次を表す任意のトークン *短縮コマンド* （これらは展開不可能です。以下参照）。

3. *未展開* トークン:

* 展開可能コマンドを表す任意のトークンで、その展開が *抑制された* （または回避された） `\directlua`の前処理中に。

#### 短縮コマンドトークン: 展開不可能コマンドの作成

述べたように、TeX エンジンは、構築するために使えるプリミティブ（組み込みコマンド）の集合を提供します *展開不可能な* 制御綴り（ここでは次で示します `⟨command⟩`）。これらのプリミティブは次の形を取ります:

* `\chardef ⟨command⟩ = ⟨numeric value⟩`
* `\mathchardef ⟨command⟩ = ⟨numeric value⟩`
* `\countdef ⟨command⟩ = ⟨numeric value⟩`
* `\dimendef ⟨command⟩ = ⟨numeric value⟩`
* `\skipdef ⟨command⟩ = ⟨numeric value⟩`
* `\muskipdef ⟨command⟩ = ⟨numeric value⟩`
* `\toksdef ⟨command⟩ = ⟨numeric value⟩`

ここで `⟨numeric value⟩` は、それぞれのコマンドに適した整数値です。

ここでは、次の使い方を簡単に見直して `\chardef` これらのプリミティブの重要な特徴、すなわち `⟨command⟩` を実演します。これは展開不可能な ``\chardef\mydollar=`\$`` を使って制御綴りを作成し `\mydollar` それを使って次を組版できます `$`:

`I paid \mydollar30.`

これにより次が組版されます `I paid $30.` 制御綴り `\mydollar` によって作成された `\chardef` は展開不可能です。次の例で分かります。

```
\chardef\mydollar=`\$
\directlua{
   local x =[[I paid \mydollar30.]]
   texio.write(x)
}
```

これは次のテキストを `.log` ファイル

`I paid \mydollar 30.`

これは示しています `\mydollar` は *実際の* が……中に展開され `\directlua`の前処理中に。後に現れるスペースは `\mydollar` コマンドトークンがテキストとしての表現に変換されるときに追加されます。

次を使うと `\chardef` を使って制御綴りを作成すると、その制御綴り（コマンド）の TeX 内部での分類の結果、それは *展開不可能な* となります。これは、マクロ定義コマンドのいずれか（\def、\edef、\gdef、または \xdef）で定義された制御綴りとは大きく異なる振る舞いです。上で述べたように、トークンリストを構築する過程で `\directlua` は、受け取る各コマンドトークンを調べて展開可能かどうかを確認します。コマンドトークンが展開不可能なら、それはそのままトークンリストへ通され、そのテキスト表現は後で、トークンリスト内のトークンをテキスト形式へ戻した結果として生成される Lua コード文字列の中に再び現れます。

**plain TeX と LaTeX に関する簡単な注意**

歴史的には、Knuth の元の plain TeX では、一般的に使われる制御記号 `\%`, `\&`, `\#` や `\$` が `\chardef`—標準的なマクロ定義コマンドのいずれかを使ってではなく `\def`, `\edef`, `\gdef` または `\xdef`。たとえば:

```
   \chardef\#=`\#
   \chardef\$=`\$
   \chardef\%=`\%
   \chardef\&=`\&
```

この奇妙な `` `\ `` という構文は、数値の文字コード値を得るための TeX の方法です。昔の plain TeX 環境では、これらの制御記号は（ `\chardef`のために）展開不可能ですが、LaTeX（またはパッケージ）はそれらを *マクロ* として再定義して、拡張機能を提供する場合があります—その場合は展開可能になるので、この点に注意が必要です。

**これは \directlua にどのような影響を与えるのでしょうか？**

次のコードを plain TeX と LaTeX で実行した結果を比較してみましょう。簡単のため、結果は次の場所に書き出します `.log` ファイルへ、LuaTeX の Lua API 関数 `texio.write()`.

```
\directlua{
   local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]]
   texio.write(x)
}
```

このコードを **plain TeX** で実行すると、次の出力が `.log` ファイルに生成され、展開の結果が示されます:

```
\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.
```

明らかに、plain TeX では制御記号のどれも`\$`, `\#`, `\%` または `\&` 展開されていません—なぜならそれらはすべて次を使って作られているからです `\chardef`.

そのコードを次で実行すると **LaTeX** 文書:

```
\documentclass{article}
\begin{document}
   \directlua{local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]] texio.write(x)}
\end{document}
```

で実行すると、次の出力が `.log` ファイル

```
\protect \TU\textdollar 150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.
```

明らかに、LaTeX で実行すると plain TeX とは異なる結果になります。なぜなら LaTeX ではコマンド `\$` が展開されており、それがマクロであることを示しているからです。

**注：** plain TeX と LaTeX のどちらでも `\directlua` は制御記号を完全には処理していません `\%`, `\&`, `\#` や `\$` 対応する文字を生成するために。によって行われる展開処理中に `\directlua` これらの制御記号を表すトークン—あるいは LaTeX ではその展開結果—は、そのまま構築中のメイントークンリストへ通されます。

**注：** 制御記号は、カテゴリコード11ではない単一の文字から形成されます。たとえば `\#`。制御記号を表すトークンがその文字列表現に戻されるとき、TeXエンジンはそのテキストの後に空白文字を挿入しません。この制御記号に対する特別な扱いは、TeXエンジンの動作に組み込まれた規則です。

### 未展開トークン：展開の抑制

`\directlua`の前処理は、TeXエンジンが展開を行っている一例ですが、あなたはそれを *防ぎたい* 本来なら展開される1つ以上のトークンに展開が適用されるのを防ぎたいことがあります。別の例として、LuaTeX（およびすべてのTeXエンジン）は、 `\directlua`を処理するときに、 `\write` コマンド：

`\write file-number {⟨material⟩}`

\write は、TeXエンジンに出力するよう指示します `⟨material⟩`—しばしばTeX/LaTeXコマンドを含む—テキストファイル（`file-number`）; その中の展開可能なコマンドは `⟨material⟩` 、妨げられない限り、 `⟨material⟩` がそのファイルに実際に書き出される前に展開されます。

予想どおり、TeXエンジンには展開を抑制したり制御したりするコマンドがあります：

* `\noexpand⟨token⟩`：単一の `⟨token⟩`;
* `\unexpanded{⟨material⟩}`： `⟨material⟩`の中にあるすべての展開可能なコマンド（トークン）の展開を防ぎます。実質的には、 `\noexpand`;
* `\protected`：マクロ定義に付ける接頭辞で、特定の状況（たとえば `\directlua`, `\write` または `\edef`).

名前は別のことを示唆していますが、 `\noexpand` や `\unexpanded` すでに *展開可能コマンド* そして、TeXエンジンの展開処理を「トークン操作」として見るよい例を示します：ここでの操作は、後続する1つ以上のトークン（コマンド）の展開を防ぐことです。なぜなら `\noexpand` や `\unexpanded` どちらも展開可能なコマンドなので、 `\directlua`の前処理中に、あなたの `⟨code⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` 単一の `⟨token⟩`. `\noexpand` の内部で `\directlua` は展開され（入力から取り除かれ）、その「展開動作」の結果に置き換えられます。 `\noexpand` を展開すると、特別な（隠れた） `⟨marker token⟩` が生成され、それが元の `⟨token⟩` の前に置かれます。展開を抑制したいものです：その `⟨marker token⟩` は「次のトークンを展開しない」と示すフラグとして働きます。なぜなら `\directlua` は完全展開を行っているため、展開可能なコマンドの「展開動作」の結果として生じたトークンを再処理します。したがって、 `\noexpand ⟨token⟩` の展開が完了すると、LuaTeXは結果を読み直し、2トークン列 `⟨marker token⟩⟨token⟩` を見つけます。これにより元の `⟨token⟩` は、未展開のまま、 `\directlua`.

**例**

次のように書くと

```
\directlua{
   local x= "\TeX"
}
```

その `\TeX` マクロはその構成トークンに展開され、plain TeXでは、次のテキストがLuaに渡されます（注：Luaはこのコードを処理できません。これは単に処理の流れを示す例です）：

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

もし *抑制すると* の展開を `\TeX` を使って `\noexpand`

`\directlua{local x= "\noexpand\TeX"}`

次のLuaコードが生成されます（繰り返しますが、Luaはこのコードを実行できません。これは単に `\noexpand`):

`local x= "\TeX "`

そのため `\noexpand`, `\directlua` は展開されません `\TeX` ただ、 `\TeX` コマンドを、そのままの形で、第1段階の `\directlua`の前処理中に。

**注：** の後に現れる空白文字は `\TeX` LuaTeXがその後行う `\TeX` 整数トークン値をその文字列表現に戻す変換（ `tokenlist_to_cstring()` 関数内）によって挿入されます。

#### \unexpanded{⟨material⟩}

`\unexpanded` は、 `⟨material⟩`。すでに述べたように、TeXエンジンが展開を行うと、どの展開可能なコマンドも *取り除かれ* 入力から *置き換えられ* され、その「展開動作」の結果に置き換えられます。では、それは `\unexpanded`にとって実際には何を意味するのでしょうか？通常、 *完全展開*、あるコマンドの展開処理が完了すると、TeXエンジンはそのコマンドの「展開動作」から生じたトークンを読み／処理し続けます。つまり、生成されたトークンをさらに展開する必要があります。しかし、 `\unexpanded` *はそれを回避します* それ以上の展開を行いません。以下がその方法です。

TeXエンジンの内部では、 `\unexpanded` コマンドはまず、 `⟨material⟩` の中の文字やコマンドを、 *未展開* 個のトークンからなる一時的なトークンリストへ変換します。すべてのトークンが作成され、その一時リストに格納された後、 `\unexpanded` コマンドは `\directlua` から *スキップさせます* それらを読み戻して処理することを—\directlua が完全展開を行っているにもかかわらず—。その代わり、それらの *未展開* トークンはそのまま通過し、 `\directlua` によって構築されているメインのトークンリストに取り込まれます（ `scan_toks()` 関数内）。このようにして、 `⟨material⟩` の中のすべてはトークンに変換され、そのトークン群では展開処理が省略されます。 `\unexpanded{⟨material⟩}` の動作は、 `\the\toks`と似ています。これは後で説明します。

**例**

`\unexpanded` は、 `\noexpand` と同様の結果を生みますが、複数のトークンの展開を防げます。例を示します：

```
\directlua{
   local x = "\unexpanded{\foo\bar\foobar}. But Lua can't process this code!"
}
```

これにより、Lua用のコードとして次のテキストが生成されます：

`local x = "\foo \bar \foobar . But Lua can't process this code!"`

**注**：各コマンド名の後に空白文字があります。これもまた、LuaTeXが未展開トークン `\foo`, `\bar` や `\foobar` を、その後の `tokenlist_to_cstring()` 関数内でテキストに戻す変換の結果です。

#### \protected マクロ定義

この `\protected` コマンドは、TeXが展開済みトークンリストを構築しているときに、そのマクロが展開されるのを防ぐためにマクロ定義へ付ける接頭辞です。たとえば、 `\directlua`の前処理中に。

**例**

次のマクロを、 `\protected` 接頭辞を使う場合と使わない場合で定義するとします：

```
\def\macroA{"This unprotected macro contains a string"}
\protected\def\macroB{"This protected macro also contains a string"}
```

Luaの文字列連結演算子（`..`）を使って次のように書くと

```
\directlua{
   local x=\macroA..\macroB
}
```

`\directlua`の前処理では、Luaに渡すために次のコードが生成されます：

`local x="This unprotected macro contains a string"..\macroB`

`\macroA` は `\protected` で定義されていないため展開され、連結される文字列の最初の部分を生成しますが、 `\macroB` は `\protected` で定義されているため、展開されていません。

前処理中、LuaTeXの `scan_toks()` 関数は `\macroA`のトークンを作成し、それが通常の展開可能コマンドだと認識して展開しました。その展開により、 `"This unprotected macro contains a string"`の各文字ごとに1つずつ文字トークンが生成されます。各文字トークンは順に渡され、構築中のトークンリストに追加されます。

もう一度 `scan_toks()` は、 `\macroB` そのコマンドが `\protected` として定義されていることに気づき、展開しません。 `\macroB` を表すトークンは、手を加えられず（展開されず）に構築中のトークンリストへ通過します。そのトークンリストが構築された後、前処理の次の段階では、 `tokenlist_to_cstring()` 関数内で、トークンリスト内のすべてのトークンをその文字列表現に戻します。未展開の `\macroB` を表すトークンが検出され、そのテキスト表現に変換されます。その結果、 `\macroB` というテキストがLua向けのコードに現れます。なお、Luaは実際には `"This unprotected macro contains a string"..\macroB` を連結して最終的な文字列を作れません。なぜなら `\macroB` はLuaの文法では意味を持たないため、次のエラーになります： `unexpected symbol near '\'`.

**豆知識**:  `\protected` コマンドは $$\varepsilon\text{-}\mathrm{\TeX}$$によって導入されました。これはKnuthの元のTeXソフトウェアに対する最初の主要拡張であり、コードの系譜に $$\varepsilon\text{-}\mathrm{\TeX}$$.

### 未展開トークン：\directlua で \the\toks を使う

プログラミングにおいては、対処し活用すべきこうした「特例」がなければ同じではありません。 `\the` と組み合わせて `\toks` での `\directlua` コマンドはそのような特例の一つです。

#### \toks の簡単な背景

TeXのプリミティブ `\toks` TeXエンジンに、いくつかのトークンを後で使うために保存するよう指示します。つまり、それらのトークンはさらに処理されることなく脇に置かれ、 *トークンレジスタ*で指定したメモリ位置に保存されます。たとえば、TeXエンジンにトークンを作成し、トークンレジスタ位置 `100` が

`\toks100={Hi, \TeX! \hskip 5bp}`

ここでTeXはトークンレジスタ `100` を使って、メモリ内の既知の場所にアクセスします。そこはトークンのリストを保持するための記憶領域です。

の間のすべてを表すトークンが作成され、 `{` や `}` が作成されます。 *ただし展開はされず*、それらはトークンリストとして連ねられます。これは、この記事の前半で見たトークンリストと似ています。それらのトークンを再利用するには `\the\toks100` と書きます。ここで `\the` （展開可能なコマンド）が、保存されたトークンを取得し、あなたが `\the\toks100`。別の見方をすると、 `\the\toks` はTeXにその場所へいくつかのトークンを挿入させます。

この `\toks` コマンド *は展開しません* 作成して保存するよう求められたトークンのどれも。単に、 `{` や `}` の間の文字やコマンドをトークンに変換して保存するだけです。

#### \directlua に戻る

展開の議論で述べたように、 `\directlua{⟨code⟩}` は *完全展開* のトークン値は次のようになります。 `⟨code⟩`：すべての展開可能なコマンドを取り除き、その展開動作の結果で置き換えること—さらに *さらに展開し* 展開可能なコマンドの最初の展開から生じたトークンを

`\the` は展開可能なコマンドなので `\directlua` はそれを展開します。しかし、 `\the` がと組み合わせて使われると `\toks` の内部で `\directlua`、たとえば `\the\toks⟨token register⟩`、挿入されたトークンは *それ以上展開されません*。 `\the\toks⟨token register⟩` の展開は、 *未展開* に保存された `⟨token register⟩`のトークン列を、 `\directlua`この動作は通常の完全展開の過程を迂回します。実質的に、それらのトークンはそのまま通過し、 *未展開*となって `\directlua`—この未展開トークンの通過処理は `\unexpanded`と、先に述べたものと動作が似ています。

**例**

次のマクロを定義するとします： `\mymacro` as `\def\mymacro{\TeX}`。これには `\TeX` コマンド（これはマクロです）に対するトークンが1つだけ含まれています。つまり、 `\mymacro` 別のマクロ `\TeX`を含む展開可能なコマンドがあり、そのマクロもまた展開可能です。

次のコードでは、Luaが文字列変数を作成しようとします： `x`:

```
\def\mymacro{\TeX}
\directlua{
   local x="\mymacro"
}
```

の中では`directlua`、 `\mymacro` のトークンが展開されますが、その結果、別の展開可能なトークン `\TeX`が生じ、それがさらに展開されます。plain TeXでは、それらの展開の結果、次のテキストがLuaに渡されます：

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

このコードは、 `\TeX` マクロの展開版を表すテキストを含む文字列を定義しようとします。この例を実行するとLuaはその文字列を構築しようとしますが、失敗してエラーが発生します：

`invalid escape sequence near ' "T\k'.`

この記事の後半で「invalid escape sequence」の意味を見ていきます。

では、 `\mymacro` を使う場合と、 `\TeX` によって生成されたトークンリストの中に `\toks` コマンド：

```
\toks100={\TeX}
\directlua{
   local x="\the\toks100"
}
```

LuaTeXの `\directlua` 処理は、Lua向けに次の文字列を生成します：

`local x = "\TeX "`

の後の空白文字は `\TeX` LuaTeXのコマンドトークンから文字列への変換処理によって生成されます。

**ただし注意してください：**:  `\TeX` マクロは *実際の* その構成トークンへ展開されています。 `\the\toks100` により、レジスタ100に保存されたトークンが挿入されましたが、それだけです。それらは *実際の* それ以上展開されず、 `\directlua` によって構築されているメインのトークンリストに組み込まれます（関数 `scan_toks()`内）。 `\toks` によって作成されたトークンリストにトークンを入れるのも、トークンの展開を防ぐ別の方法です。

この例を実行しても、同様にエラーになります：

`invalid escape sequence near ' "\T'.`

Luaのエスケープシーケンスについては、この記事の後半で説明します。

## 展開で使われるその他のコマンド／技法

この節では、展開が適用される状況で役立つ追加のTeXコマンド／手法を見ていきます（たとえば `\directlua`).

### \string ⟨token⟩

`\string` は、⟨token⟩をカテゴリコード12の文字トークン列に変換する展開可能なコマンドです。

たとえば、 `\string\TeX` は4つの文字トークン列を生成します `\`, `T`, `e` や `X` ここで各文字にはカテゴリコード12が割り当てられます（先頭の `\` 文字も含めて）。

次のように書くと

```
\directlua{
   local x="I will use \string\newcommand"
   print(x)
}
```

その `\string` コマンドは展開され、カテゴリコード12の文字トークン列になります。 `\string` が展開されると、その結果の文字トークン（ `\newcommand`の各文字を表すもの）は、 `\directlua`によって構築されているメインのトークンリストに組み込まれます。 `\directlua` がメインのトークンリストの構築を終えると、その構成トークンは文字列表現に戻され、Luaインタープリタに渡すための次のコードが生成されます：

`local x="I will use \newcommand" print(x)`

このコードがLuaに渡されると、 `print(x)` は文字列 `x` を画面（コンソール）に出力します。しかし、ここでは少し意地悪をして、あえて `\n`で始まるコマンドの例を使いました。ローカルのTeX環境でこの例を実行できれば、Luaが画面に次のテキストを出力するのがわかるでしょう：

```
   I will use
   ewcommand
```

このコードをOverleafで実行するには、LuaTeXに直接 `.log` ファイルへ、LuaTeX の Lua API 関数 `texio.write(*string*)`:

```
\directlua{
   local x="I will use \string\newcommand"
   texio.write(x)
}
```

結果として生成された `.log` ファイルを確認すると、そこにも

```
   I will use
   ewcommand
```

この予期しない出力は、Luaが `\n` の先頭にある `**\n**ewcommand` を改行文字（文字コード10）を表すエスケープシーケンスとして解釈するためです。つまり、 `ewcommand`で始まる新しい行のテキストを開始したいのだとLuaが想定するのです。Luaのエスケープシーケンスについては、この記事の後半で説明します。

### \detokenize{⟨material⟩}

`\detokenize` は、その効果として、 `\string` の複数トークン版であり、同様に `⟨material⟩` 内のすべてをカテゴリコード12の文字トークン列に変換する展開可能なコマンドです—*ただし* 空白文字（ASCII/Unicode値32）はカテゴリコード10になります。 `\detokenize` また、 *制御語* ファイルを探し（たとえば `\foo`）であるコマンド名の後には末尾の空白文字が挿入されますが、 *制御記号* ファイルを探し（たとえば `\#`, `\%` などの後には空白文字は挿入されません）。

### 例

たとえマクロ `\foohoo`, `\foo`, `\bar` や `\foobar` が定義されていなくても、次のように書くと：

```
\directlua{
   local x = "\string\foohoo\detokenize{\foo\bar\foobar}"
}
```

Luaインタープリタに渡すコードとして、次のテキストが生成されます

`local x = "\foohoo\foo \bar \foobar "`

を使わずに `\string` や `\detokenize` 次のように書くと：

`\directlua{local x = "\foohoo\foo\bar\foobar"}`

`\directlua` 処理します `\foohoo`を処理し、それがコマンドだと認識して展開しようとします。しかし `\foohoo` が定義されていないため、エラーになります：

```
   ! Undefined control sequence.
   l.1 \directlua{local x = "\foohoo
                      \foo\bar\foobar"}
         ?
```

なぜなら `\string` や `\detokenize` それらの引数を一連の文字トークンに変換します。 `\directlua`の展開処理は、展開可能なコマンドトークンを検出する機会を確かに得ます `\foohoo`, `\foo`, `\bar`または `\foobar`：それらは展開を引き起こすずっと前に、文字トークン列へ変換されるからです。

前述のとおり、コマンドの展開とは、それを入力から取り除き、その「展開動作」の結果に置き換えることです。展開の結果（通常はトークン）は、その後TeXエンジンによって読み取られます。ここでの「展開動作」は、 `\string` や `\detokenize` の「展開動作」は、入力から文字トークンとコマンドトークンを取り込み、それらを文字トークン列に変換することです。最初は一時的なトークンリストに保存され、 `\directlua` が後で読み取ります。それらの文字トークンは、 `\directlua`.

次の図は、どのように `\string` が `\foohoo` コマンドを文字トークン列に変換し、その結果として一時的なトークンリストが作られ、それがその後 `\directlua` それらの文字トークンを構築中のメインのトークンリストに組み込みます。

![](/files/21dd5b988b01f26ebe6e2cc1df5fe96136d01bfe)

もし `\string` または `\detokenize` は引数中の文字に出会います。たとえば `\string a` または `\detokenize{abc}` それらの文字（ここではカテゴリコード11）は文字トークンを生成しますが、カテゴリコード12になります。

注：

上の例に戻ると：

`\directlua{local x = "\string\foohoo\detokenize{\foo\bar\foobar}"}`

これにより、Luaインタープリタに渡すコードとして次のテキストが生成されます

`local x = "\foohoo\foo \bar \foobar "`

次のことがわかります：

* `\detokenize` は各マクロ名の後に空白文字を挿入しましたが `\string` はそうしませんでした。
* `\string` は単一のトークンに作用します。
* 文字列 `"\foohoo\foo \bar \foobar "` を定義するために使った `x` では、Luaのエスケープ文字機構（後述）に再び出会います：

  * `\bar` は `\b` で始まります。これはLuaのエスケープシーケンスで、 [バックスペース文字](https://en.wikipedia.org/wiki/Backspace) （文字コード8）を表すために使われます。
  * コマンド `\foohoo`, `\foo` や `\foobar` はすべて `\f`、Luaのエスケープシーケンスで、 [フォームフィード文字](https://en.wikipedia.org/wiki/Page_break#Form_feed) (文字コード12)。

  文字シーケンスが `\b` や `\f` 二重引用符で作成された文字列の中で使われるため、 `"..."` それを防ぐ手順を取らない限り、望ましくない結果を生みます。Lua のいわゆる *ロングブラケット* 文字列方式と、Lua のエスケープシーケンスについて、今やあわせて議論できます。

## 「Lua のエスケープシーケンス」とは何でしょうか？

プログラミング言語は、言語の構文の一部として特定の文字を「特別な用途」のために予約しています。実際には、それらの文字は何らかの特別な意味を持つように定義されています。しかし、たとえば標準的な振る舞いが構文エラーを引き起こしてしまうような、より長い文字列の一部としてその文字を埋め込みたい場合には、その文字の特別な意味を一時的に「オフ」にする必要があることがあります。要するに、その文字は *〜なしの* 本来の解釈を発動させずに処理され—気づかれないまま通り抜ける必要があります。これを行うために、プログラマは *エスケープ* 「特別な文字」がいわゆる *エスケープシーケンス*.

標準的な例（Lua でもサポートされています）は、文字列内に二重引用符を入れる場合で、内側の二重引用符をエスケープシーケンス `\\"`:

`"When asked about LuaTeX they replied: \"It is an awesome TeX engine!\" I agreed."`

Lua 言語は、エスケープシーケンスを扱うためのいくつかの仕組みを提供しています:

* 標準的なシーケンスには `\n` (改行), `\r` (復帰), `\\` (バックスラッシュ), `\\"` (二重引用符), `\t` (水平タブ), `\v` (垂直タブ) と `\'` (単一引用符) が含まれます;
* `\xXX`、ここで `XX` は、ちょうど2桁の16進数字からなるシーケンスです;
* `\ddd`、ここで `ddd` は、最大3桁の10進数字からなるシーケンスです;
* この記事を書いていた時点（2019年8月）では、LuaTeX の最新バージョンはまだ Overleaf では利用できませんでしたが、Lua 5.3 を使用しており、UTF-8 エスケープシーケンスのサポートが導入されていました: `\u{XXX}`。これは UTF-8 でエンコードされた Unicode 文字に対するエスケープ機構で、 `XXX` は、その文字のコードポイントを表す1つ以上の16進数字からなるシーケンスです。囲み括弧 `{ }` が必須であることに注意してください。

### エスケープシーケンスの制御

伝統的に、文字列は `"this is a string"`のように二重引用符で定義されます。そのような文字列の中ではエスケープシーケンスを使えます: `"this is a string.\nI'll now start on a new line."`。ただし Lua には、文字列を定義するためのもう一つの、 *非常に* 便利な仕組みがあります。いわゆる *ロングブラケット* 方式で、テキストを `[[` や `]]`:

`[[I am a long brackets string]]`

ロングブラケット方式で作成された文字列の中では、Lua の文字エスケープ機構は *オフにされます*。つまり、エスケープシーケンスは通常の文字として扱われます。たとえば、文字列

`[[I am a long brackets\n string]]`

その `\n` では、エスケープシーケンスは単一の復帰文字（ASCII コード 13）としてではなく、2つの通常の文字として扱われます: `\` その後に `n`.

### なぜロングブラケット文字列はそんなに便利なのでしょうか？

後ほど見ていくように、LuaTeX は、 `\directlua` と一緒に使える、LuaTeX の組版動作を制御するための、特殊で組み込みの Lua 関数群を提供しています。その多くの関数の中には `tex.print(*string*)` があり、Lua コードの材料を `*string*` LuaTeX に返して組版させることができます。非常に簡単な例は次のとおりです:

`\directlua{tex.print("Hello, World!")}`

これにより LuaTeX は `Hello, World!`

この `*string*` で使われている `tex.print(*string*)` には、LuaTeX に処理させる TeX および LaTeX コマンドを表すテキストを含めることもできます。ただし、TeX/LaTeX コマンドは `\` 文字で始まるため、二重引用符で作成された文字列では問題になります。Lua は文字列を解析して最初の `\` 文字を検出し、それをエスケープシーケンスの始まりとして解釈しようとするからです。Lua がそのエスケープシーケンスを処理しようとすると、通常は失敗します。なぜなら、多くの TeX/LaTeX コマンド名の先頭の `\` と組み合わさっても、Lua が知っている有効なエスケープシーケンスにならないからです。たとえば、 `"I like \LaTeX"` Lua には `\L` が見え、「無効なエスケープシーケンス」というエラーで失敗します。これが、上で述べたエラーの原因です。

#### ロングブラケット文字列が役に立ちます！

文字列を作成（定義）するためのロングブラケット方式は非常に便利です。TeX/LaTeX コマンドが `\` 文字で始まっていても、ロングブラケット文字列方式は Lua のエスケープシーケンス機構を無効化（オフ）するからです。ここで、マクロが展開されるのを防ぐ必要があることを忘れないでください。たとえば `\protected` または `\noexpand`.

仮に次のような `\newtest` マクロを定義したとしましょう。

`**\protected**\def\newtest#1{引数: #1}`

そして、LuaTeX の Lua API 関数 `\directlua` とともに `tex.print()`:

```
\directlua{
   tex.print("\newtest{Hello}")
}
```

を使うと、 `\protected`のため、マクロ `\newtest` は展開されず、その結果、次のテキストが Lua に渡されます:

`tex.print("\newtest {Hello}")`

の後ろに追加された空白文字と開き波括弧（ `\newtest` ) の前に`{`の副作用です。 `\directlua`がコマンドトークンをテキスト表現に戻す変換の

このコードは Lua に渡され、その後 LuaTeX の関数 `tex.print()` を実行しますが、問題があり、その現れ方は使用しているフォントによって異なります。Overleaf の LaTeX では、次のような出力が見えるでしょう:

![](/files/b4a376e8f956120029a8d87c7c531bd204d8d67e)

さらにログファイルには警告が出ます:

```
   文字がありません:
   フォント [lmroman10-regular]:+tlig;! に (U+000A) はありません
```

Plain TeX では、次のような出力が見えるかもしれません:

![](/files/47bd9bf3a6d7e7c02cf4058d53ddb599b820efdb)

どちらの場合も、 `\newtest` マクロは呼び出されず、出力は意図したものではありません。エラーの原因は Lua のエスケープ文字機構です。テキスト `\newtest {Hello}` では、マクロ名は `\n` で始まり、Lua はそれを改行文字のエスケープシーケンスとして認識するため、 `\n` を ASCII 文字 10、つまり16進数では 0A に置き換えます。LaTeX のエラーメッセージでは、 `U+000A` は Unicode 値を 4 桁の16進数で表す方法です。

なぜなら `\n` が改行文字に変換されると、LuaTeX はマクロ呼び出しとしてではなく、ASCII 文字コード 10 で始まるテキストを組版するよう要求されていると考えます:

`⟨ASCII 10⟩ewtest {Hello}`

使用するフォントによって、LuaTeX は `⟨ASCII 10⟩` 文字を組版できる場合もできない場合もありますが、残りのテキストはそのまま出力され、 `{` や `}` はグループとして扱われ、印字されません。

Plain TeX では結果が異なります。既定のフォントが Computer Modern Roman で、文字コード10が見えると奇妙なエンコーディングのために大文字のオメガが組版されるからです。

これらの問題を防ぐには、Lua のエスケープ機構が適用されないようにロングブラケット文字列を使う必要があります。正しい結果は

`\directlua{tex.print([[\newtest{Hello}]])}`

で得られ、次のスクリーンショットに示す結果になります:

![](/files/7c28400176003e2887d5c650065f52edc33ac429)

### 展開と、展開されないコマンドの非実行

展開について述べたとき、TeX エンジンが *取り除き* 現在の入力から展開可能なコマンド（トークン）を *置き換え* る過程だと説明しました。\directlua は *展開のみ* の処理（トークンリストを生成するため）を行っているので、それ以上 LuaTeX の処理を進めることはできません。展開可能なコマンドが読み込まれて完全に展開されると、その展開結果—しばしば展開不能なコマンド（トークン）を含みます—が構築中のトークンリストに組み込まれ、Lua に渡すためにテキストに戻せるようになります。 *終了しません* ここで重要なのは次の原則です:

の活動の間、 *展開のみ* トークンリストを生成することを目的とした処理では、LuaTeX を含む TeX エンジンは、 *実行しません* どんな展開不能な基本命令、組み込み命令、TeX コマンドも。

の場合、 `\directlua{⟨code⟩}`が完全に展開された版が `⟨code⟩` 展開不能な TeX/LaTeX コマンドを生成する、またはそれを含んでいるなら、それらは *Lua に渡されます* （テキストとして表現されます）。

#### 例

展開のみの処理（たとえば `\directlua`の中）では展開不能な基本命令が実行されないことを示す例です。次のマクロ `\setcountreg` 次のように:

`\def\setcountreg#1#2{\count#1=#2\relax}`

**注**を定義します:  `\relax` をパラメータ `#2` の後に置くのは、パラメータ `#2`.

の数値（引数）を探す際に LuaTeX が入力を読み進めすぎるのを防ぐためです。 `\directlua`の外で

```
   \setcountreg{100}{50}
   count レジスタ 100 の値は \the\count100 です。
```

と実行すると

`count レジスタ 100 の値は 50 です。`

この文脈では、どの TeX エンジンでもマクロを処理します `\setcountreg`—マクロを展開し、引数を決定して、さらに読み進め、マクロの置換テキスト（定義）に含まれる *および動作* （実行）コマンドを処理し続けます。ここでの結果は、 `50` をレジスタ `\count100`.

しかし、TeX エンジンが *展開のみ* の処理を行っているとき、つまり `\directlua`のときは、 *実行しません* マクロ定義に含まれる展開不能コマンドは。

次のように書くと

```
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{50}]]
}
```

とすると、Lua 用のコードとして次のテキストが生成されます:

`local x = [[\count 100=50\relax ]]`

上で生成された Lua コードを見ると、 `\directlua` その `\setcountreg` の中で`#1` や `#2`が展開され、その引数が対応するパラメータ（ `\count` は *は実行されず* の処理中に `\directlua`）に代入されていることがわかりますが、それ以上は進みません: 展開不能な基本 TeX コマンド

ただし、結果として得られた文字列を `x` *LuaTeX に戻せば* を通じて `tex.print(x)` のように

```
\count100=50 % count100 を初期値 50 に設定
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{250}]]
   tex.print(x)
}
count レジスタ 100 に格納されている値は \the\count100 です。
```

が終わると `\directlua` 出力は次のようになります

`count レジスタ 100 に格納されている値は 250 です。`

count レジスタ `100` が実際に値 `250`.

上の例から生成された Lua コードは

`local x = [[\count 100=250\relax ]] tex.print(x)`

このコードは `x` をロングブラケット方式で作成した文字列として定義します。これは誤ったエスケープシーケンスによるエラーを避けるために使われます。もし二重引用符を使って `"..."` x を定義すると、文字の組み合わせ `\c` の先頭にある `\count` がエラーを引き起こします: `' "\c' の近くで無効なエスケープシーケンス`.

LuaTeX の Lua API 呼び出し `tex.print(x)` により LuaTeX は TeX コード列 `\count 100=250\relax` や `\count100` に値 `250` が割り当てられます。組版された出力からわかるとおりです:

`count レジスタ 100 に格納されている値は 250 です。`

#### 注意: マクロと LuaTeX の Lua API

上の例では、 `\directlua`の事前処理（展開）中に LuaTeX はコード `\count 100=250`を実行しなかったことを見ました。これは `展開不可能な` 基本命令 `\count`です。このコードを実行するには、 *LuaTeX に戻す* を通じて `tex.print()`.

`\directlua` は、トークンリストを構築するために展開のみの処理を行う LuaTeX の一例にすぎません。同様の展開処理とトークンリスト生成を行う他のコマンドもあり、たとえば `\write` や `\edef`です。これらのコマンドも、展開処理中に展開不能な基本命令を実行しません。展開のみの処理でトークンリストを構築するとき、TeX エンジンは展開不能な基本命令を実行しない、というのが一般原則です。

**LuaTeX の Lua API を使うようにマクロを書き換える**

私たちは `\setcountreg` マクロを、 `tex.setcount()`と呼ばれる LuaTeX の Lua API 関数を使って書き換えることができます。これにより、count レジスタ `100`:

```
   \def\setcount#1#2{\directlua{tex.setcount(#1,#2)}}
   \count100=50
   count レジスタ 100 には \the\count100\par が入っています
   \setcount{100}{250}
   count レジスタ 100 には現在 \the\count100\par が入っています
```

このコードは次のように組版します:

```
count レジスタ 100 には 50 が入っています
count レジスタ 100 には現在 250 が入っています
```

ここでは `tex.setcount()`を使っており、LuaTeX の多くの Lua API 関数のひとつです。 *直接アクセス* LuaTeX の内部データ格納領域にアクセスして、値 `250` を count レジスタ `100`に相当するメモリ位置に置いています。つまり、実質的には *回避し* LuaTeX の標準的な TeX エンジンの入力処理方法—入力の読み取り、トークンの生成、TeX 基本命令の実行—を。とはいえ注意すべき点があります。LuaTeX の Lua API 関数を使うと、展開のみの処理 *が副作用をもたらすことがあります*。純粋な TeX/LaTeX コマンドではそれ以外では不可能な、TeX エンジン内部の値の変更です。

**例: 予期しない副作用**

ここでは、 *予期しない* 副作用を示す例を紹介します。 `\directlua`のマクロを使うと起こり得ます。次のコードを書いたとします:

```
\def\dochange{\directlua{tex.setcount(999,12345)}}
\edef\careful{\dochange}
\the\count999
```

このコードを実行すると、次のように組版されます `12345`!

どうしてそんなことが？ 私たちは *明示的に* その値を count レジスタ `999`に入れるためのコードやマクロを呼び出していません。あるいは、呼び出したのでしょうか？

私たちは `\dochange` に置き換え `\directlua` コマンドを定義しました。これは `tex.setcount()` を使って値 `12345` を count レジスタ `999`に格納します: TeX コードでは `\count999=12345`に相当します。次に標準の TeX 基本命令 `\edef` を使ってマクロ `\careful`を定義しました—予期しない副作用を引き起こすのは `\edef` の使用です。

`\edef` は引数を完全に展開します: ここでは、展開可能なマクロ `\dochange` を検出し、それを展開します。 `\dochange` マクロは展開可能なコマンド `\directlua` を使っており、その中には Lua API 呼び出しが含まれています。したがって `\dochange` の展開は `\directlua` の展開を引き起こし、それが `tex.setcount()` の呼び出しにつながり、count レジスタ `999`.

もし `\dochange` を TeX コマンドを使うように再定義すると:

```
   前: count レジスタ 999 には \the\count999\par が入っています
   \def\dochange{\count999=12345\relax}
   \edef\careful{\dochange}
   後: count レジスタ 999 には \the\count999\par が入っています
```

このコードを実行すると、次のように組版されます

```
前: count レジスタ 999 には 0 が入っています。
後: count レジスタ 999 には 0 が入っています。
```

明らかに、 `\count999`には何の影響もありませんでした。 `\edef` を定義するとき、 `\careful` それは展開されますが、 `\dochange` その展開が生成するのは展開不能な TeX 基本命令だけです。それらは *は実行されず* されるのではなく、単に *格納* され、 `\careful`.

定義を構成するトークンリストの中に保存されます。おまけに、同じ原則がこれがなぜ組版出力を生むのかも説明します:

```
\def\dochange{\directlua{tex.print("Hello")}}
\edef\careful{\dochange}
```

## LuaTeX の Lua API の簡単な紹介

これまで見てきたように、 `\directlua` は、通常の Lua コードや Lua と TeX/LaTeX コードの混合を書くことを可能にするだけでなく、LuaTeX の組版ソフトウェア内部の動作と通信したり直接制御したりするために使える（呼び出せる）、LuaTeX 固有の追加 Lua 関数群へのアクセスも提供します。この記事ではいくつかの Lua 関数を使いましたが、 `tex.print()`, `texio.write()`, `tex.setcount()` そしてそれらは *多数の* さらに多くとともに、 [LuaTeXリファレンスマニュアル](http://www.pragma-ade.com/general/manuals/luatex.pdf) で文書化されています。そこでは関連する関数群が *ライブラリ*.

これらの Lua 関数は LuaTeX の Lua API（**ある**アプリケーション **P**ログラミング **I**インターフェース）と考えることができ、Lua をドライバとして LuaTeX の組版動作を制御することで、高度な組版および文書工学ソリューションを構築するためのツールを提供します。

前述のとおり、LuaTeX は API をライブラリと呼ばれる関数の集合に整理しています。これは、目的や動作で関連づけられた関数群です。各関数集合は、LuaTeX の内部プロセス、データ構造、データ格納、および組版アルゴリズムの特定の側面にアクセスするために設計されています。内部的には、LuaTeX は複数のコンポーネント—主に C で書かれたソフトウェアライブラリ／ツール群—から構成されており、それらは TeX エンジン自体だけでなく、Lua、MetaPost、Kpathsea、FontForge、libpng、zlib などの他のサブシステムも含みます。これらのライブラリは統合されて LuaTeX 実行ソフトウェアの機能と特長を構築しており、ユーザーは Lua API を通じて、これら複数のソフトウェアコンポーネントの統合と連携から生まれる LuaTeX の機能にアクセスできます。

## いくつかの例と落とし穴

この節では、この記事で提供した話題、概念、説明を使った、さらなる例をいくつか示します。

### チルダ文字 (\~) の使用

Lua 言語は `~` 文字（チルダと呼ばれる）を、その構文の一部として使用します。これには「等しくない」テストを行うための構文も含まれます。たとえば、変数が `x` に等しくない `4` 次のように書けます：

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

この単純な Lua コードを〜経由で実行しようとすると `\directlua`:

```
\directlua{
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
}
```

エラーが発生します：

`[\directlua]:1: '\' の近くで 'then' が期待されています。`

おかしいですね。コード自体は正しいのです： `'then'` を使っていて、コード中に `\` という文字はありません。では何が悪かったのでしょうか？ これを理解するには、TeX/LaTeX にとって `~` は通常、カテゴリコード 13 の「特殊文字」として定義されることを思い出す必要があります。いわゆるアクティブ文字で、ミニマクロのように振る舞い、したがって展開の対象になります。 `\directlua` が `~` 文字を検出すると、それは *によって展開されます* 入力から *置き換え* その展開結果に置き換えられます。プレーン TeX を使うと、LuaTeX が生成して Lua インタプリタへ渡す結果のテキスト（コード）には、実際には `~` 文字は含まれておらず、次のようになります：

`local x=3 if x \penalty \@M \ = 4 then print("x is not equal to 4") end`

この `~` という文字は *取り除かれ* や *展開されて* その構成コマンドへ変換されています。上の Lua コードは、プレーン TeX におけるアクティブ文字 `~`の定義から生じたものです。これで、Lua がエラー `'then' が '\' の近くで期待されています`を返す理由がわかります。つまり、このコードの解析を始めますが、 `\penalty` という、Lua にとっては意味を持たない単語に遭遇し、構文エラーを起こすのです。

これを修正するには、 `~` 文字が、LuaTeX がコードを処理している時点で安全なカテゴリコードを持っている必要があります。たとえば、コードをグループで囲むことで `\directlua` のカテゴリコードを一時的に 11（文字）へ変更できます： `~` を

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

このコードは期待どおりに動作し、 `x is not equal to 4` がコンソールに出力されます。ほかの方法もあります：展開可能なコマンド `\noexpand` または `\string`.

#### \string⟨token⟩ の使用

次を適用できます `\string` 単一文字の `⟨token⟩` `~` に対して `\string` が `~` カテゴリコード 13（アクティブ文字）を持つ

```
\directlua{
   local x=3
   文字に適用して、カテゴリコード 12 を持つ文字トークンを生成できます。もし
   print("x is not equal to 4")
   end
}
```

すると、必要な Lua コードが生成されます：

`local x=3 if x ~= 4 then tex.print("x is not equal to 4") end`

#### \noexpand⟨token⟩ の使用

次を使えます `\noexpand~` アクティブ文字の展開を抑制するために `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
```

展開されていない `~` トークンは、 `\directlua` で構築中のトークンリストを通過し、テキストに戻されたときに動作する Lua コードを生成します。

### # 文字の使用

Lua 言語では `#` 文字を使ってテーブルの長さを求めることができます。ところが、次のコードを試すと

```
\directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
```

LuaTeX が

`テーブルの長さは 2 です`

と組版するだろうと期待するかもしれませんが、

`\directlua]:1: 数値の長さを取得しようとしました`

このエラーが起こるのは、 `#` 文字が通常カテゴリコード 6（マクロ引数）を持つためです。TeX/LaTeX における `#` 文字には 2 つの用途があります：マクロ引数（`#1`, `#2`… `#9`）を示すことと、整列テンプレート（ `\halign` や `\valign`).

もう一度 `\directlua` 用）の置換テキストを示すことです。LuaTeX がトークンを生成してトークンリストを構築するとき、カテゴリコード 6 を持つ `#` 文字を見て、それを表す適切な文字トークンを作成します。最終的なトークンリストをテキスト形式に戻す段階では、# の文字トークン（カテゴリコード 6）は特別な処理を受け、 *2 つの連続する文字*: `##`として出力され、その結果、次のコードが Lua に渡されます：

`local tbl = {} tbl[1] = "Hello" tbl[2] = "World" print(##tbl)`

Lua コードに変換される際、元の `#` が二重化され、それがエラーを引き起こします：

`\directlua]:1: 数値の長さを取得しようとしました`

この問題は、TeX の構文が二重ハッシュ記号 `##` を使って単一の `#` トークンを表したり生成したりするために起こります。この構文は、引数を取る別のマクロを定義するマクロや、 `\halign` または `\valign` テーブル構築コマンド用のテンプレートを作るマクロで使われます。少し紛らわしいので、例を見てみましょう。

#### 例

あるマクロ `\mymacro` を定義するとします。これは単一の引数 `#1`を取りますが、さらに第 2 のマクロ `\foo` も定義します。こちらも単一の引数を取ります。引数 `#1` を `\mymacro` で使うことと `\foo` が自分自身の引数を使うことを区別するために、 `#1` TeX の構文では `##1` の中で `\mymacro` と書いて、 `\foo`:

`\def\mymacro#1{\def\foo##1{#1 Hello##1}}`

もし `\mymacro{Hey!}` と書くと、マクロ `\foo` は次のように定義されます：

`\def\foo#1{Hey! Hello#1}`

次の点に注意してください。 `\mymacro`の引数 `#1` (`Hey!`）が `\foo` の定義に組み込まれ、シーケンス `##1` が `#1` の定義の中で `\foo`へ変換されます。したがって、 `\foo` 次のように:

`\foo{, World!}`

が組版されると期待するでしょう `Hey! Hello, World!`

次のようにすれば `\directlua`の `#` 文字の扱いを解決できます：LuaTeX がコードを処理する前に、そのカテゴリコードを一時的に変更するのです。たとえば：

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
\endgroup
```

これにより次の Lua コードが生成されます

```
local tbl = {} tbl[1] = "Hello" tbl[2] = "World" tex.print("Table length is "..#tbl)
```

これにより、期待していた結果が組版されます：

`テーブルの長さは 2 です`

### % 文字の使用

TeX/LaTeX では、 `%` 文字は通常、コード内に単一行コメントを入れるために使われます。つまり、TeX エンジンに対して、その地点から `%` が書かれている行の末尾までのすべてを無視するよう指示するのです。ただし Lua 言語では、 `%` 文字は `string.format(...)`, `string.gmatch(...)`、そして `string.gsub(...)` のような非常に便利な文字列処理関数の中で使われ、その中で `%` 文字はそれらの関数の構文の一部として重要な役割を果たします。

TeX/LaTeX で使うと、 `%` はカテゴリコード 14 が割り当てられているためコメント文字として機能します。通常の文字として振る舞わせ、TeX/LaTeX の通常の動作を止めるには、そのカテゴリコードを 12 などの安全な値に変更する必要があります。以下の `\directlua` 例では、記事の前半で説明したいくつかの手法に加え、まだ触れていないものを 1 つ使います： ``\catcode`\^^M=12``、これによりコード内で Lua コメントを使えるようになります。これについては後で説明します。

#### 例

以下の例は [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial)から借用し、 `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---これについては後でさらに見ていきます！
\catcode`\%=12
\directlua{
   local str -- 結果を格納するローカル変数を宣言

   tex.print("Using string.format():".."\\par")

   str=string.format("%s %q", "Hello", "Lua user!") -- 文字列と引用付き文字列
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- 文字
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- 指数
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- 浮動小数点
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- 浮動小数点または指数
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- 8 進数、16 進数、16 進数
   tex.print(str.."\\par")

   tex.print("\\vskip3mm".."Using string.gmatch():".."\\par")

   for word in string.gmatch("Hello TeX user", "%a+") do
      tex.print(word.."\\par")
   end

   tex.print("\\vskip3mm".."Using string.gsub():".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- "an" の出現を捕捉して置換
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

次のスクリーンショットは、上のコードの組版結果を示しています：

![\directlua で Lua の文字列関数を使う](/files/0ec74a62ce6790cc07424d5ea85627885c025242)

## なぜ Lua コードは 1 行で表示されるのでしょうか？

お気づきかもしれませんが、この記事の例で示されている（生成された）Lua コード断片はすべて 1 行のテキストとして表示されています。つまり、元の `\directlua` コード断片にあった改行は反映されていません。なぜでしょうか？ それは、Lua コード内の改行が *取り除かれている* からで、Lua コードが 1 本の長いテキスト行になってしまうためです。その動作は、TeX エンジンが行末文字をどのように扱うかに由来します。プログラミングの文献ではこれらは `\directlua`で示される `\r` （キャリッジリターン）と `\n` （改行）です。なぜこうした細かな点を気にする必要があるのかは、Lua のコメント機構を使ってコードの一部をコメントアウトする話をすると明らかになります。

ソフトウェアがテキストファイルを書き出すとき、各行は「改行」文字で終わります。実際の改行文字は、そのファイルを書き出すのに使われるアプリケーションや OS に依存します。Wikipedia には [興味深い記事](https://en.wikipedia.org/wiki/Newline) があり、現在使われている改行文字の歴史・進化を解説しています。

任意のテキストファイルでは、各行の終端は、キャリッジリターン（ASCII/Unicode 文字 13）および/またはラインフィード（ASCII/Unicode 文字 10）のさまざまな組み合わせで終わる可能性があり、これらは `\r` や `\n` で表されます。TeX エンジンはプラットフォーム非依存に設計されているため、テキストファイルで使われる行末の本質的にプラットフォーム依存な性質を回避する方法が必要です。もちろん TeX エンジンには、行末文字を扱うための組み込みの（ただし設定可能な）方法があります。

### TeX エンジンが行末をどう扱うか

LuaTeX が `\directlua{⟨code⟩}` を処理しているとき、 `⟨code⟩` に含まれるテキストを読み取り、 `⟨code⟩`に含まれる行末を処理するための標準的な TeX エンジンの方法を適用します。デフォルトでは、これらの標準的な TeX の方法により、すべての行末文字（キャリッジリターンとラインフィード）は削除され、空白文字に置き換えられます。「デフォルトでは」と言うのは、TeX エンジンの行末文字の扱いは、ユーザー設定可能なパラメータ `\endlinechar`によって変更できるからです。ここでは簡潔に 2 段階で概説しますが、詳細は Overleaf 記事 [\endlinechar の入門：TeX がテキストファイルから行を読む仕組み](/latex/ja/xiang-xi-ji-shi/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### ステップ 1: TeX が独自の行末文字を挿入する

入力ファイルから 1 行のテキストを読み取った後、TeX エンジンはその行末にある `\r` または `\n` 文字をすぐに削除します。次に TeX エンジンは *挿入します* （戻し追加）して、その行末に独自の行末文字を付け加えます。その文字は、ユーザー設定可能な TeX パラメータ `\endlinechar` の値によって決まります。この仕組みにより、TeX エンジンは元の入力テキストファイルに何が含まれていたかに関係なく、行末文字をプラットフォームに依存しない方法で処理できます。

通常、TeX エンジンは設定

`\endlinechar=13`

を使います。これはキャリッジリターン文字（`\r`）です。ただし、ユーザーは後で説明するように、 `\endlinechar`の値として別の文字コードを割り当てることもできます。

したがって、あなたの `⟨code⟩` に含まれ、 `\directlua{⟨code⟩}` によって処理される行末文字はすべて削除され、TeX エンジン自身が決めた 1 文字に置き換えられます。TeX エンジンは、新しいテキスト行をファイルから読み取った直後にこの行末処理を行い、その行の文字を *より前に* （トークン生成のために）処理する前に実行します。しかし話はここで終わりません：TeX エンジンが *は* これらの行末文字をどうするか（挿入したものです）が、Lua コードが 1 行になる理由を説明しています。

#### ステップ 2: TeX が行末文字を空白に変換する

TeX エンジンは、自分自身の行末文字を挿入することに加えて、 `\endlinechar`の値で定義された文字を使って、 *とみなされるべき文字に対してもカテゴリコード 5 を使います。* 結果として、TeX エンジンは通常次のように動作します：

1. で定義された行末文字 `\endlinechar`;
2. その同じ文字 *通常* にカテゴリコード 5 が割り当てられている。

Lua コードが 1 行になってしまうという困りごとを説明するのは、TeX がその行末文字に対して何をするかです。TeX エンジンが入力行を処理すると、最終的にはその行の最後の文字、つまり `\endlinechar`で定義された文字を検出します。通常、その文字はカテゴリコード 5 を持っており、TeX はそれを *します* 空白文字に置き換えます。つまり、行末で TeX は実質的に自分の行末文字を取り除き、空白に置き換えているのです。補足すると、TeX エンジンはカテゴリコード 5 の文字を使って空行を検出し、新しい段落を開始することもありますが、ここでは扱いません。

もちろん TeX ですから、 `\endlinechar` を別の文字に再設定したり、 `\endlinechar` に割り当てられた文字に任意のカテゴリコード値を与えたりして、さまざまな特別なマクロプログラミングの工夫ができます。

Lua コードが 1 行のテキストになってしまうのを防ぎたい場合は、 `\endlinechar` に割り当てられた値を（一時的に）変更するか、標準の行末終端文字 `\r`.

### TeX の奇妙な ^^ 記法

以下の節では、TeX の独特な `^^` 記法に出会います。これは「拡張文字機構」として知られています。Knuth が、行末終端、タブなどの「制御文字」を入力しやすくするために設計したものです。たとえば：

* `^^J` は文字コード 10（`\n`、ラインフィード）を表します；
* `^^M` は文字コード 13（`\r`、キャリッジリターン）を表します。

のような文字列シーケンスは、TeX が対応する文字トークンを生成するために入力文字を読み取っている TeX の入力スキャン処理の早い段階で、対応する文字コードへ変換されます。 `^^M` のようなものは

### \endlinechar に割り当てられた文字を変更する

なお、まだ `~` 文字の展開を防ぐ必要があることを忘れずに、次のように書けます：

```
\begingroup
\endlinechar=10 % 行末文字を \n に変更
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}% ここに \n を表示したくない
\endgroup% あるいはここに \n
```

上の `\endlinechar` の設定は、LuaTeX が読み込む各行の末尾に文字コード 10（`\n`、ラインフィード）を付加させます。これは、 `\n` （ラインフィード）は通常カテゴリコード 12 を持ち、それは次のように書くことで確認できるからです ``\the\catcode`\^^J``。なぜなら `\n` はカテゴリコード 5 を持たないので、LuaTeX はそれを空白文字に変換せず、LuaTeX が読み込む各行の末尾にそのまま残ります。その結果、コード 10 の文字が各行の末尾に残り、 `\directlua` で構築されるトークンリストに入り、さらにその後トークンリストがテキストに変換されると Lua コードに再び現れます。上記の変更により、Lua コードは次の文字列シーケンスとして Lua インタプリタへ送られます：

**\n**local x=3\*\*\n**if x \~= 4 then**\n**print("x is not equal to 4")**\n**end**\n\*\*

ここで **\n** 記法は文字コード 10 を表すつもりであり *実際の* 未知のマクロではありません `\n`。これで Lua インタプリタは、コード中の改行を、まさに元の `\directlua` コマンド：

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

ちなみに、Lua コード文字列の最初の文字が `\n` であることに注意してください（ `ローカル` キーワードの前）。これは `\n` から生じます

`\directlua{`

は、開き `{` の直後に改行があるためで、これも保持されます。これを防ぐには次のように書けます

`\directlua{%`

### \r のカテゴリコードを変更する

Lua コード内の改行を維持するために、 `\r` のカテゴリコードを 5 以外に変更して、 `\r` がもはや行末文字として認識（処理）されないようにすることもできます。この手法でも LuaTeX は `\endlinechar=13` を使い続け、各行の末尾に `\r` を追加し続けます。しかし `\r` はもうカテゴリコード 5 を持たないため、LuaTeX は `\r` 文字を行末として認識せず、空白に変換することもなく、そのまま通して Lua コード内に現れます。

なお、まだ `~` 文字の展開を防ぐ必要があることを忘れずに、次のように書けます：

```
\begingroup
\catcode`\^^M=12 % \r のカテゴリコードを 12 に変更
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

この場合、Lua コードは Lua インタプリタへ次のように送られます：

**\r**local x=3\*\*\r**if x \~= 4 then**\r**print("x is not equal to 4")**\r**end**\r\*\*

ここで `\r` 記法は、未知のマクロではなく文字コード 13 を表すつもりです `\r`。先ほどの `\endlinechar` の例と同様に、Lua インタプリタはコード中の改行を、まさに元の `\directlua` コマンド：

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

ちなみに、Lua コード文字列の最初の文字が `\r` であることにも改めて注意してください（local キーワードの前）：これも

`\directlua{`

#### \r はなぜカテゴリコード 12 で、11 ではないのか？

答えは、入力ファイルから読み込んだ TeX/LaTeX コマンドの末尾に `\r` （カテゴリコード 11 の）文字が誤って追加されてしまうことで起こるエラーのリスクを避けるためです。例を見てみましょう：

```
\begingroup
\catcode`\^^M=11 % \r のカテゴリコードを 11 に変更
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

次のエラーが発生します：

```
   ! Undefined control sequence.
   l.9 \endgroup
```

それはどうして真実になりうるのでしょうか。なぜなら `\endgroup` は標準の TeX プリミティブコマンドだからです。エラーの原因はかなり微妙です：LuaTeX が最後の行のテキスト、つまり `\endgroup`を読み取ったとき、同時にその行の末尾に `\endlinechar` 文字 `\r` も追加したからです。すると LuaTeX の内部メモリでは、LuaTeX は文字列

`\endgroup\r`

を見ています。ここで `\r` はコード 13 の文字を示しており、未知の TeX マクロの名前ではありません。 `\r`.

LuaTeX がこの行をテキストファイルから読み込んだ時点では、元の `\begingroup` はまだ有効です：つまり、対応する `\endgroup` コマンドを実行してまだ閉じていないグループの中にいるのです。そのコマンドを実行すると `\r` は以前のカテゴリコード値 5 に戻ります。

LuaTeX が行テキスト `\endgroup\r` の処理（トークン生成）を始めると、最初の文字 `\` をエスケープ文字として認識し、コマンド名を探し始めます。コマンド名を特定するために LuaTeX はカテゴリコード 11 の文字列を探しますが、 `\r` もカテゴリコード 11 を持つため、LuaTeX は `\r` 文字（依然としてカテゴリコード 11）が *コマンドの一部を形成していると考えます* という名前の `\endgroup\r` が存在しないので、LuaTeX は `未定義の制御綴` エラーを報告します。だからこそ 11 ではなく 12 を使ったのです。

LuaTeX のエラーメッセージはコンソールに書き出されたため、 `\r` 文字を簡単には見たり気づいたりできず、何がエラーの原因だったのかが明白ではありませんでした。

### なぜ行末を気にするのでしょうか？

それは、コード内で Lua のコメント方法を使えるようにするためです！ LuaTeX の標準機構である `%` 文字を追加してコード内の単一行をコメントアウトする方法は使えますが、Lua 言語には独自の、とても便利な *複数行* のコメント機構があり、それを活用したい場合があるのです。

まず、行折り返しの問題に対処せずに単一行の Lua コメントを使おうとすると何が起こるか見てみましょう。TeX がコードの単一行をコメントアウトするのに `%` 文字を使うのに対し、Lua では二重ハイフンを使います： `--`.

これを実行しようとすると何が起こるでしょうか：

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- これはこの複雑なテストの結果を出力します
   print("x is not equal to 4")
   end
}
```

エラーが発生します：

`[\directlua]:1: 'end' が <eof> の近くで期待されています`

このエラーは、Lua インタプリタへ渡された Lua コードに改行がないために起こります。インタプリタは 1 本の連続した文字列しか見ず、その中の途中からコメントが始まっているのです：

```

local x=3 if x ~= 4 then -- これはこの複雑なテストの結果を出力します print("x is not equal to 4") end
```

次以降のすべて `**local x=3 if x ~= 4 then**` はコメントアウトされたものとして扱われるため、インタプリタは不完全な Lua コード片を見せられることになり、その結果エラー

`'end' が <eof> の近くで期待されています`.

ここで `<eof>` はファイルの終わりを意味します。

おそらくお気づきのとおり、これを修正するには、改行が最終的な Lua コードにそのまま送られるようにする必要があります。たとえば、 `\r` を 12 に設定して：

```
\begingroup
\catcode`\^^M=12 % \r のカテゴリコードを 12 に変更
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- この複雑なテストの結果を出力します
   print("x is not equal to 4")
   end
}
\endgroup
```

ここで、Lua インタプリタは文字列を見ていますが、その中には `\r` 次のように記述された改行 `\directlua` フラグメント：

**\r**local x=3\*\*\r**if x \~= 4 then**\r\*\*-- この複雑なテストの結果を出力します\*\*\r**tex.print("x is not equal to 4")**\r**end**\r\*\*

これは実質的には、次のように書くのと同じです

```
   local x=3
   if x \noexpand~= 4 then
   -- この複雑なテストの結果を出力します
   print("x is not equal to 4")
   end
```

つまり Lua はこのコードを正しく処理し、コメントアウトした行を無視できるということです。

**ブロックコメント**

Lua 言語には、次のように呼ばれる構文もあります [「ブロックコメント」](https://www.lua.org/pil/1.3.html) （または *長いコメント*)：これらは次で始まります `--[[` そして対応する `]]`。この便利な構文を使えば、複数行コメントを書いたり、一時的に削除したいコードの一部をコメントアウトしたりできます：

```
\begingroup
\catcode`\^^M=12 % \r のカテゴリコードを 12 に変更
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ この複雑なテストの結果を出力します
   それは本当に
   そんなに驚くべき結論だからです]]
   print("x is not equal to 4")
   end
}
\endgroup
```

## まとめとして

まず、この充実した記事を最後まで読んでくださったなら、おめでとうございます！ 私たちは、LuaTeX を通じて最大限に活用するために必要な背景となる、TeX 関連の概念や話題について、かなり包括的なガイドを作成しようとしました。 `\directlua` コマンド。私たちの願いは、Overleaf のユーザーコミュニティ、さらにはその先にも役立ち価値のある、ためになる記事を作成できたことです。いつものように、ご意見をいただければ大変うれしく思いますので、どうぞ遠慮なく [お問い合わせください](https://www.overleaf.com/contact) この記事へのコメントや、今後取り上げてほしいトピックの提案をお寄せください。

楽しい $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ Graham Douglas と Overleaf チームより。

### そして最後に... luacode パッケージを使うだけです

TeX と Lua は根本的に異なる方法で動作しますが、\、%、\~、#、^、& など、各言語の文脈では「特別な意味」を持つ文字がいくつか共通しています。もちろん、Lua と TeX はそれらの特別な意味を *非常に* それぞれ異なる目的のためです。問題のある文字についての考察からは、なぜ問題が起こり得るのか、そしてどう解決できるのかがわかります。しかし、多くの小さな Lua コード片を手作業で修正するのはかなり面倒なので、ほとんどのユーザーはそうした難しさを取り除いてくれる LaTeX パッケージを使うことを好みます。そのようなパッケージの一つが [`luacode`](https://ctan.org/pkg/luacode?lang=en) であり、次を扱う作業を簡単にするための一連の機能を提供します `\directlua`、しかし少なくとも今では問題点についてよりよく理解できたかもしれません `luacode` を代わりに解決してくれます。


---

# 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/ja/xiang-xi-ji-shi/09-an-introduction-to-luatex-part-2-understanding-directlua.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.
