マクロツイーター

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

TeX 以外(例えば BibTeX)でナベアツする件について

最近、TeX がそのブログネタ作成用言語としての能力を存分に発揮する事例が増えていて、それは大変喜ばしいことである。しかしそれと同時に非常に残念な事実も存在する。それは、TeX と同時にインストールされる BibTeX が持っているはずのネタ作成能力がほとんど省みられていないことである。少しネットを探した限りでは、FizzBuzz を実装した例すら見つからない。こんな残念極まる事態が他にあるだろうか。

嘆いてみても仕方が無いので、この状況を打破すべく初めの一歩を踏み出すことにした。

……というわけで、ナベアツ。*1

訳が解らないかも知れないが、これは「文献スタイルファイル」(拡張子 .bst)である。LaTeX において、TeX のプログラムが「パッケージファイル」(拡張子 .sty)に書かれるのと同様、BibTeX のプログラムは文献スタイルファイルに書かれる。(だから普通の LaTeX ユーザの目に触れることはない。)よく使われる文献スタイルは alpha や plain である。*2そして、BibTeX のプログラムの実行は、LaTeX 文書を通して行われる。この辺りの手順は BibTeX のユーザであれば既によく知る所であろうが、初心者の便宜のために説明しておく。まずは、上掲のナベアツプログラム(bibnabeazz スタイル)を使用した LaTeX 文書の例を挙げる。

[test-bibnabeazz.tex]
\documentclass[a4paper]{article}
\usepackage{type1cm}  % 例のアホなフォントのため
\begin{document}
\bibliographystyle{bibnabeazz}
\nocite{standard,multi3,contains3}
\bibliography{bibnabeazz1}
\end{document}

読み込むプログラム(スタイルファイル)を指定する命令が \bibliographystyle である。ここでは当然 bibnabeazz が指定されている。そして、ここが BibTeX プログラミングの最も特異な点であるが、プログラムに与える入力値は、直接文書中で指定するのでなく、代わりに「入力値の候補」(「エントリ」と呼ばれる)を列挙した「データベースファイル」(拡張子 .bib)に記述し、その上で「実際に使う入力値の列」を「エントリの名前」(「キー」と呼ばれる)を列挙する。具体的には、\bibliography 命令でデータベース名*3を指定し、使用エントリ(のキー)は、\nocite という命令でコンマ区切りで指定する。((\cite という命令もあるが、ナベアツの場合には使わないのでここでは説明を省略する。))すると、\bibliography 命令の箇所に、プログラムの実行結果が出力される。この辺りの事柄は、多くの BibTeX ユーザにとってお馴染みであろう。

データベースファイル bibnabeazz1.bib の中身を以下に示す。

[bibnabeazz1.bib]
% ナベアツの入力のデータベース

%% プレアンブル
@Preamble{
"\providecommand*{\ahofont}{\usefont{OT1}{cmfr}{m}{it}\Large}" #
"\providecommand*{\redfont}{\color{red}}" #
"\providecommand*{\sanefont}{\normalsize\normalfont\normalcolor}" #
"\providecommand*{\primestyle}{}"
}

%% [範囲] 1から40まで数えて(標準)
@Range{standard,
        start = 1,
        end = 40
}

%% [範囲] 1から100まで数えて
@Range{until100,
        start = 1,
        end = 100
}

%% [条件] 3の倍数の時にアホ(\ahofont)になります
@RuleMultiple{multi3,
        number = 3,
        style = "\ahofont"
}

%% [条件] 3の付く数字の時にアホ(\ahofont)になります
@RuleContains{contains3,
        number = 3,
        style = "\ahofont"
}

%% [条件] 5の倍数の時に赤く(\redfont)なります
@RuleMultiple{multi5,
        number = 5,
        style = "\redfont"
}

%% [条件] 9の倍数の時に正気(\sanefont)に戻ります
@RuleMultiple{multi9,
        number = 9,
        style = "\sanefont"
}

%% [条件] 素数の時に \primestyle になります
@RulePrime{prime,
        style = "\primestyle"
}

書き方は例を見れば明らかと思われるので省略する。慣れたユーザから見れば非常に典型的な形式のデータベースファイルであることが判るだろう。(えっ違う?*4)ここで、(test-bibnabeazz.tex 中の)\nocite で指定されたエントリは standard, multi3, contains3 の 3 つであるから、これは

1から40まで数えて
3の倍数と3が付く数字の時だけアホになります

という「標準の」ナベアツの規定を表していることが判る。

BibTeX プログラムの実行を含む LaTeX 文書のコンパイル組版)は以下のような手順で行う。((正確には、後半の latex の繰り返しは、参照や引用(citation)に関する警告が出なくなるまで行う必要がある。無論この手順で得られるのは DVI 形式なので、これを PDF 形式に変換したければ dvipdfmx 等を最後に実行する。あるいは latex の代わりに pdflatex を実行する。))

latex test-bibnabeazz
bibtex test-bibnabeazz
latex test-bibnabeazz
latex test-bibnabeazz

結果として、次のような出力が得られる。

今度は入力を変えて実行してみよう。

1から100まで数えて
3の倍数と3が付く数字の時だけアホになり
5の倍数だけ赤くなり 9の倍数で正気に戻ります

この規定の場合、\nocite の引数を以下のようにすればよい。

\documentclass[a4paper]{article}
\usepackage{type1cm,color}  % 赤くするため
\begin{document}
\bibliographystyle{bibnabeazz}
\nocite{until100,multi3,contains3,multi5,multi9}
\bibliography{bibnabeazz1}
\end{document}

そして、BibTeX である以上 dirty trick もちゃんと存在する。*5今使っているデータベースの prime の条件(素数である)で適用されるスタイル \primestyle は、@Preamble 命令((この中に書かれたテキストは文書中にそのまま出力される。ただし、\bibliography の箇所であり「LaTeX のプレアンブル」の中ではない。ちなみに、BibTeX に添付されている文献データベースの tugboat.bib 等でも @Preamble 命令は使われている。))に書かれた定義は空になっている。(つまり単純に指定しても効果なし。)これを利用して、

1から100まで数えて
3の倍数と3が付く数字の時だけアホになり
5の倍数だけ赤くなり 素数の時は枠で囲まれます

という規定を実現してみよう。

実は、bibnabeazz の出力の TeX ソースでは、各整数は

{\outnum{1}}

のような形になっている。そして、幾つかの「条件」を満たす場合は

{\ahofont\redfont\sanefont\outnum{45}}

のような形になる。((\nocite の中で multi3、multi5、multi9 の順に指定されているのでそれに対応する順番にスタイル命令が並ぶ。\sanefont は全ての装飾を取り消すので、結果的に「正気に戻る」ことになる。))ここでこれらの命令が全て(引数のない)宣言型命令であることに注意されたい。いま、\primestyle を LaTeX 標準の \fbox 命令を用いて枠囲みをするように定めたいのであるが、\fbox は引数のテキストを適用範囲とし、宣言型命令としては使えない。どうすればよいだろうか。

ここで、\outnum という制御綴が置かれていることはポイントである。といってもこの命令自体は何もしない(\outnum{1}1 に展開される)。しかし、\outnum を区切りに利用することで、\primestyle は自身と(末端の)} にあるトークン列を捉えることができる。すなわち、

\def\primestyle#1\outnum#2{\fbox{#2}}

とマクロ \primestyle を定義すると、例えば、

{\foo\primestyle\bar\outnum{23}}

{\foo\fbox{\bar{23}}}

と同じ動作にすることが可能になる。最終的に、求める規定は次のようにして実現できる。

\documentclass[a4paper]{article}
\usepackage{type1cm,color}  % 赤くするため
\def\primestyle#1\outnum#2{\fbox{#2}}
\begin{document}
\bibliographystyle{bibnabeazz}
\nocite{until100,multi3,contains3,multi5,prime}
\bibliography{bibnabeazz1}
\end{document}
*  *  *

というわけで、

FizzBuzz」や「えるたそ」は賢明な読者諸君に任せることにする。

*1:FizzBuzz でもいいけど、最終的に TeX の出力になるのでナベアツの方がよいだろう。

*2:これらは BibTeX が標準として用意しているもので、何れも(ナベアツではなく)文献リストの出力を行う。

*3:この例では bibnabeazz1 のみが指定されているが、コンマ区切りで複数指定が可能である。

*4:聞くところによると、BibTeX プログラムは、「(一定の形式の)文献リストを出力する」という動作を行うものが何故か圧倒的に多いらしい。従って、データベースのエントリも、ナベアツの条件などよりも、寧ろ文献情報が書かれることが非常に一般的であるようだ。

*5:ソート順を部分的に改変するためにダミーのマクロを使う等の「dirty trick」が BibTeX の公式の説明文書で平然と述べられていたりする。