LaTeX パッケージのオプションには空白を含めないほうがよい話
この記事は、サブブログの 2016-09-17 投稿記事を移転してきたものです。
LaTeX team からいただいた情報によると、「パッケージ読込時に “,
” 区切り周囲にスペースを入れると Option clash する例」が最近発覚したらしい。以下の例示ソースで再現可能*1。
\documentclass{article} \usepackage[a, b, c]{foo} \usepackage[a ]{foo} \stop
! LaTeX Error: Option clash for package foo.
同じパッケージが 2 回以上使われそうになった場合、本来ならば「2回目のオプションたちが1回目のオプションたちの部分集合であればスルー、もし増えていたら Option clash エラー」となるべきである。ところが、上記ソースでは空白がおかしな作用をして、部分集合になっているのに clash している。これも次回リリース(2017-01-01)で直すつもりらしい。
\def\@if@pti@ns#1#2{% \let\reserved@a\@firstoftwo \edef\reserved@b{\zap@space#2 \@empty}% <- new \@for\reserved@b:=\reserved@b\do{% <- changed \ifx\reserved@b\@empty \else \expandafter\in@\expandafter{\expandafter,\reserved@b,}{,#1,}% \ifin@ \else \let\reserved@a\@secondoftwo \fi \fi }% \reserved@a}
ついついやってしまいがちな「空白」。特にオプションを多数指定する場合、コード上は改行して書くことも多いだろう:
\usepackage[dvipdfmx,% bookmarks=true,% bookmarksnumbered=true,% colorlinks=true,% setpagesize=false,% pdftitle={LaTeX研修課程},% pdfauthor={ななしのごんべぇ},% pdfsubject={hyperref入門・演習},% pdfkeywords={TeX; dvipdfmx; hyperref; color;}]{hyperref}
最後の %
を書く習慣は付けておくと無難、ということであろう。
LaTeX パッケージ作者もオプションには空白を含めないほうがよい話
こんなタレコミも。
「LaTeXパッケージのオプションで空白するとアレ」で思い出した話:
— ZR-TeXnobabbler🤔 (@zr_tex8r) September 18, 2016
実は \ExecuteOptions の引数の中の余計な空白は無視されない。#TeX #LaTeX pic.twitter.com/bf3Np41Rwr
\begin{filecontents}{test3.sty} \DeclareOption{foo}{\typeout{*** FOO OPTION ***}} \DeclareOption{bar}{\typeout{*** BAR OPTION ***}} \DeclareOption{baz}{\typeout{*** BAZ OPTION ***}} \DeclareOption{qux}{\typeout{*** QUX OPTION ***}} \ExecuteOptions{foo, bar} \ProcessOptions\relax \end{filecontents} \documentclass{article} \usepackage[baz, qux]{test3} \begin{document} a \end{document}
パッケージが既定で foo と bar を実行し(パッケージ内で作者が \ExecuteOptions
で指定)、さらにユーザが baz と qux を指定する(\usepackage
のオプション)ので、全部で四つのメッセージが出そうである。ところが
*** FOO OPTION *** *** BAZ OPTION *** *** QUX OPTION ***
確かに、本来は出るはずの BAR が表示されなかった!「\usepackage
はコンマの周りに空白があってもよいのに、\ExecuteOptions
はダメ」というトラップがあったようだ。この件を報告したところ、LaTeX team の方も「20年経って今頃なんでこんなに…?」と戸惑っていた…。
追記:対処されたようです (2016-10-04)
LaTeX2e public svn をみると、2016/10/02 付けで「\ExecuteOptions
に空白があるとオプションを無視する話」と「\@if@pti@ns
で空白があると Option clash する話」について対処された (r1227) 。いちばん難しい「\ProcessOptions
の干渉」はまだで、バグ懸念で慎重になっているようだ(2018-12-01 現在も未対応の模様)。
*1:これは一般化した記述であるが、たとえば foo → graphicx、a → dvipdfmx、b → dvips、c → dvipsone 等と置き換えてみるとよいだろう。