LaTeXでマクロの引数をオーバーロード
はじめに
TeX Forumにこんな質問が来ていた.
要は,TeXのマクロを関数っぽいものとみなし,その上で同名のマクロに引数の個数が異なるものをオーバーロードさせたいというものである.TeXのマクロは単なる字句の置き換え規則に過ぎない*1ので,これを実現するにはTeX言語沼に入らないといけない*2.
先の記事の場合,要件は1引数および2引数の場合のみだったが,今後,複数の場合でオーバーロードしたい場合があるかもしれない.単に,そのようなマクロを定義するためのマクロをつくるのが面白そうなので作ってみた.
スタイルファイルの紹介
公開場所
今回,スタイルファイルをoverload.styとして,hak7a3 / overload — Bitbucketに公開しておいた.
使い方
overload.styの使い方は,非常に簡単である.まず,\usepackageでoverload.styを読み込む.
\usepackage{overload}
次に,\newoverloadでオーバーロードするコントロールシーケンスを登録する.
\newoverload{\foo}
ここでは,\fooを「これから複数の引数に対応するマクロ」として登録している.最後に,各引数の個数に対応する動作を\addoverloadで登録する.\addoverloadは\newoverloadで登録したコントロールシーケンス,引数の個数,およびマクロの置き換えテキストを引数として受け取り,オーバーロード用のマクロを作成する.
\addoverload{\foo}{2}{(2):#1 and #2} \addoverload{\foo}{1}{(1):#1 only} \addoverload{\foo}{0}{(0):orz}
この例では,上から順に2引数,1引数,および引数がない場合の動作を登録している*3.
引数をオーバーロードするように定義したマクロは,引数の末尾を示す\endinvokeを末尾に付加して呼び出す必要がある.例を示す.
\foo\endinvoke \foo{bar}{baz}\endinvoke \foo{bar}\endinvoke
上から順に,引数なし,2引数,および1引数呼び出しに対応する,先に述べたように,TeXのマクロは単純なテキストの置き換えしかできないので,そもそも引数の扱いが普通の言語と異なる.それを回避する方法として,今回は末尾を明記する手法を用いた.
これを実行すると,次の結果を得ることができる.
引数の個数に従って,マクロの動作が変化していることがわかる.
overload.styで提供されるマクロ展開部分は完全展開可能にしてあるので,\edefの内部でも利用可能である.実際,overload.styのテストコードでそのような使い方をしている.