いものやま。

雑多な知識の寄せ集め

TeX言語で遊んでみた。

技書博10で配ったフリーペーパーの内容をブログにも書いておく。

 \TeX = 組版

 \TeXといえば普通は組版を思い浮かべると思う。

けど \TeXが実際にやっているのは一列に並んだトークン(≒命令)を順に処理しているだけだったりする。 組版できるのはそういった命令の中に組版用のものがあり、その命令が処理された結果にすぎない。

なので \TeX組版以外で使うこともできる。

Hello, TeX.

まずはプログラムの基本の「Hello, world.」から。

% hello.tex
% 入出力用のマクロ(≒関数)
\def\ReadStdin#1{{\endlinechar=-1 \global\read0 to#1}}
\def\WriteStdout#1{\immediate\write0{#1}}

\ReadStdin\Name     % 入力を求めて\Nameに代入
\WriteStdout{Hello, \Name.}     % 出力

\end

これを実行すると次のようになる:

$ luatex --halt-on-error hello.tex
...
\Name =TeX
Hello, TeX.
...

\Name =と入力を求められるのでTeXと入力すると、それが使われてHello, TeX.と表示される (そして組版の命令はないので組版はされない)。

計算

整数変数(レジスタ)を用意して四則演算もできる。

% calc.tex;入出力用のマクロは省略

\ReadStdin\Input
\newcount \Value    % 整数変数
\Value = \Input     % 入力を代入

\multiply\Value by 2    % \Value *= 2
\WriteStdout{Value * 2: \number\Value}

\advance\Value by -3    % \Value += -3
\WriteStdout{Value * 2 - 3: \number\Value}

\divide\Value by 4      % \Value /= 4
\WriteStdout{(Value * 2 - 3) / 4: \number\Value}

\end

実行例は以下:

$ luatex --halt-on-error calc.tex
...
\Input =42
Value * 2: 84
Value * 2 - 3: 81
(Value * 2 - 3) / 4: 20
...

ちゃんと計算できてるのが分かると思う。

条件分岐と繰り返し

条件分岐と繰り返しだってできる。 繰り返しはマクロを再帰的に展開するので関数型っぽい。

% fibonacci.tex;入出力用のマクロは省略

\ReadStdin\Input
\chardef\Count = \Input     % 繰り返し回数

\newcount \I 
\newcount \Value

\def\Fibo(#1,#2,#3){% 今の回数, 前の数, 今の数
    \ifnum #1<\Count
        \WriteStdout{#3}
        \I = #1  \advance\I by 1
        \Value = #3  \advance\Value by #2
        \edef\Next{\noexpand\Fibo(\number\I,#3,\number\Value)}
    \else
        \edef\Next{\relax}
    \fi
    \Next}

\Fibo(0,0,1)
\end

これを実行すると1, 1, 2, 3, 5, 8, 13, ...とフィボナッチ数列が出力されるので試してみてほしい。

Goodbye, TeX!

ただ見ての通りかなりクセが強くて扱いづらい。 命令が一列に並んでるのを順に処理してるだけなので感覚としてはアセンブラに近いかも。 書くのも大変だし、それ以上に読むのが大変。 組版したいだけなのにね。

ということで。

 \TeXグッバイしたい!


今日はここまで!