マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

それでも TeX でプログラミングしたい人のための何か (11)

あるいは 〜私の TeX プログラム変換環境〜

【しぶとく宣伝】

TeXLaTeX Advent Calendar

あなたにしか知らない LaTeX がある

きっと TeX 芸もある。

(詳細は ATND のページで)

私の TeX コーディングスタイル

ここまで、コーディングの様式についての一般的な注意を述べた。参考として、私が採用しているスタイルを紹介しておく。無論、この「私の TeX スタイル」が客観的に他のものより優れていると主張するものでは全くない。

  • 無視される空白類文字を活用してプログラムの可読性を確保する。
  • しかし、マクロ定義*1の中で「実行されない空白トークン」は利用しない。つまり余計な「空白トークン」は入れない。(マクロ定義の外では空白トークンや空行を許容する。)
  • 行末の改行文字が不要な空白トークンになる場合は「%」を付ける。しかし、行末にあるのが制御語の場合は(空白トークンにならないので)「%」は付けない。
  • (直接の)数字列で書かれた数値は必ず空白トークンで終結させる。ただし文の途中でかつ直後に数字でない文字トークンが続く場合は空白を入れないこともある。*2数字列がマクロや引数パラメタによるものの場合は紛らわしい*3ので \relax終結させる。
  • 前項の場合で、当該の数字列が行末にある場合は、改行文字を空白トークンとして利用する。(つまり「%」を付けない。)
  • 単位付数字列で書かれた寸法値は原則として \relax終結させる。*4
  • マクロの中では \par は明示的に書き、空行で表すことはしない。また、紛らわしい場合は空白トークンの代わりに \space を使う場合がある。

いくつか例を挙げてみる。

\xx@t=\xx@foo \advance\xx@t 2
\ifnum\xx@t>\xx@limit
  \xx@warn{foo is too big}%
  \xx@t=\xx@limit
\fi

ここで「=」「>」の前後に空白を置くことはしない。数値「2」は改行文字で終結させている。((それから、私は決して「by」を書かない。))

\def\xx@out@label#1{%
  \par
  \setbox0\hbox{\xx@pfx #1}%
  \ifdim\wd0=0pt\relax
    \textbf{??}\space
  \else (\unhbox0)
  \fi
}

\setbox〜 の行の末尾の「%」は無くても出力に影響しない((直前に \par で段落を抜けているため。))が、不要な空白トークンは入れたくない。\textbf{??} の後に意図的に空白を入れることを示すために \space を入れた。(無くても出力は同じだけど単に「%」を入れ忘れているのと区別が付かない。)

\@namedef の \edef 版

以前の説明で、配列の変数(「名前参照」に変換した)への代入を行うのには \@namedef を用いると述べた。\@namedef{xxx}...\def\xxx... と等価なのであった。しかし、代入する文字列の中で他の変数がある場合は(それを文字列に展開する必要があるので*5\def でなく \edef が必要になる。残念ながら、名前参照の \edef の命令は用意されていないので自分で作っておくことにする。((この実装コードは今は理解しなくてもよい。LaTeX\@namedef の実装の中の \def\edef に置き換えたものである。))

(「xx」は名前空間の文字列)
\def\xx@nameedef#1{%
  \expandafter\edef\csname#1\endcsname
}

例えば、Lua の「ary[j] = count」((count は整数変数とする。))というコードを TeX に書き換えると、

\xx@nameedef{xx@ary/\the\xx@j}{\the\xx@count}

という風になる。(文字列として扱うので \xx@count\the を付けて文字列に展開する必要がある。)

*1:あるいは一般的にマクロやプリミティブの引数となるトークン列。

*2:直後が制御綴の場合は空白を入れる。

*3:マクロや引数パラメタが内部値である場合は空白で終結してはならず、それと区別がつきにくい。

*4:寸法値の終結の規則は非常にややこしい。

*5:普通の言語と同様の扱いを前提とすれば。