Hatena::ブログ(Diary)

アセトアミノフェンの気ままな日常

2016-09-16

存在するはずの LaTeX パッケージのオプションがなぜか未定義?(続き)

もう少し昨日のアレについて補足しておく。

昨日述べたとおり

% NG
\begin{filecontents}{test1.sty}
\DeclareOption{loadxspace}{\relax}
\ProcessOptions
\AtEndOfPackage{\RequirePackage{xspace}}
\end{filecontents}
\documentclass{article}
\usepackage[loadxspace]{test1}
\begin{document}
\end{document}

はエラーになる。しかし

% OK
\begin{filecontents}{test0.sty}
\DeclareOption{loadxspace}{\AtEndOfPackage{\RequirePackage{xspace}}}
\ProcessOptions
\end{filecontents}
\documentclass{article}
\usepackage[loadxspace]{test0}
\begin{document}
\end{document}

は正常に通る。これは特に不思議なことではないし、この OK な書式を各種パッケージがあちこちで使っている例も見つかる。

最初の NG になるケースについてもう少し厳密にいうと

パッケージ内で \ProcessOptions した後に、\AtEndOfPackage{\RequirePackage{hoge}} されることが現状「未考慮」である

ということなのだと思う。そもそも、\DeclareOption 以外の場所で \AtEndOfPackage を発行する必要性がほとんど生じない(自分でパッケージの末尾に書けば済む場合がほとんど)なので、それでもよいということなのだろう。

この現状「未考慮」とおぼしきものを大丈夫にしようとすると

  • コレ (Gist: 20160916-AtEndOfPackage-RequirePackage-test.tex)

みたいな感じになる。

ちなみに

もうひとつアレな挙動がある。

この回答では、\AtEndOfPackage{\RequirePackage{hoge}} とするのが workaround とされている。そうすることで、「親パッケージ読み込みが完全に終了したあとに、子パッケージを読み込む」ということが可能になるのである。というわけで、上の

自分でパッケージの末尾に書けば済む場合がほとんど

は必ずしも成り立たないのである。

で、この TeX.SX のソースと今回僕が発見したアレな挙動の合わせ技で、こんな変なことが起きる。これはヤバい…

\documentclass{article}

\begin{filecontents}{test0.sty}
\DeclareOption{FOO}{\typeout{*** FOO OPTION ***}}
\ProcessOptions\relax
\RequirePackage{test1}
%\AtEndOfPackage{\RequirePackage{test1}} % <= "workaround" proposed in TeX.SX
\end{filecontents}

\begin{filecontents}{test1.sty}
\RequirePackage{test0}
\end{filecontents}

\usepackage[FOO]{test0}

\begin{document}

\end{document}

つまり、二つのパッケージが互いに相手を必要としている場合である。

\ProcessOptions よりあとに、オプション実装を持たない子パッケージを読み込むと、どうやっても(素朴に \RequirePackage しても TeX.SX 的な workaround をしても)エラーが出る

というアレすぎる挙動になる*1\RequirePackage\ProcessOptions よりあとに書いてはダメ、というのはさすがにアレすぎないだろうか…

追記:問題発覚

当初 Gist に置いたコードだと、別の問題が発生してしまった:

\documentclass{article}
\usepackage[dvips]{geometry}
\begin{document}
\end{document}

これを処理したときに

! LaTeX Error: Unknown option `dvips' for package `geometry'.

が出てしまう。keyval を使うパッケージでは内部でこのエラーを出さないようにするハンドリングを独自で持っていて、それと衝突してしまうらしい…

→ というわけで改良版 (2016-09-16 17:42 GMT+09:00)

もうひとつ不自然な挙動があったそうです

上記の件を報告したところ、今度は LaTeX team から最近発覚した(全く別の)問題について教えていただきました → こちら

*1:ちなみに、このケースに対する正しい workaround は「test0.sty のなかで \RequirePackage{test1} を \ProcessOptions より前に持ってくる」である。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

Connection: close