マクロツイーター

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

今さら人に聞けない zref パッケージのキホン(3)

前回の続き)
zref のうまみ

ところで、実際に完成した lastdo.sty のコードについて、ネタ元の某フォーラムにある回答に載せられている実装と比較すると、zref の枠組を利用したにも関わらずコードがあまり簡単になっていないようにも見える。この課題で zref を使うのは“大袈裟”なのであろうか。

実はそうではなくて、zref を利用することには大きなメリットがある。それは「相互参照の収束」の判定を自動で zref が行ってくれることである。

lastdo パッケージを使った文書を実際にコンパイルしてみよう。

[test-lastdo.tex]
\documentclass[a4paper]{article}
\usepackage{lastdo}
\NewLastDoCommand\hoge{Hoge}{LastHoge}
\NewLastDoCommand\fuga{Fuga}{LastFuga}
\begin{document}
\hoge, \fuga, \hoge, \hoge! \fuga!!
\end{document}

補助ファイル(test-lastdo.aux)が無い状態で (pdf)latex で test-lastdo.texコンパイルすると端末の表示は以下のようになる。「Label(s) may have changed. 」の警告が出ていることが判る。

This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/W32TeX) (preloaded format=latex)
 restricted \write18 enabled.
entering extended mode
(./test-lastdo.tex
LaTeX2e <2015/01/01>
……(略)……
No file test-lastdo.aux.
[1] (./test-lastdo.aux)

LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.

 )
Output written on test-lastdo.dvi (1 page, 256 bytes).
Transcript written on test-lastdo.log.
zref の処理の様子

ちなみに、この時の組版結果は以下の様である。設計において、「初回実行では回数をゼロと見なす」としたので、どの lastdo 命令の実行も「最後」ではないと見なされている。

補助ファイル(test-lastdo.aux)の内容を見ておこう。

\relax 
\providecommand\zref@newlabel[2]{}
\zref@newlabel{lastdo:}{\lastdo@hoge{3}\lastdo@fuga{2}}

「ラベル“lastdo:”においてプロパティ lastdo@hoge の値が 3 で lastdo@fuga の値が 2 であった」という事実が \zref@newlabel という内部命令を用いて記録されていることがわかる((2 行目の \providecommand は「途中で zref パッケージの使用を止めた」場合に \zref@newlabel が未定義でエラーになるのを防ぐために書かれている。zref が読み込まれている場合はこの \providecommand は採用されない。))。

そしてこの補助ファイルがある状態で再度コンパイルを行うと、今度は「Label(s) may have changed. 」の警告が出なくなる。

This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/W32TeX) (preloade
 format=latex)
 restricted \write18 enabled.
entering extended mode
(./test-lastdo.tex
LaTeX2e <2015/01/01>
……(略)……
(./test-lastdo.aux) [1] (./test-lastdo.aux) )
Output written on test-lastdo.dvi (1 page, 264 bytes).
Transcript written on test-lastdo.log.

そして、組版結果をみると……。

期待通りのものが得られている。