ドキュメントクラスのオプション引数で条件文を使用するとエラーが発生する

ドキュメントクラスのオプション引数で条件文を使用するとエラーが発生する

\documentclassとステートメントのオプション パラメータ間の奇妙な相互作用に遭遇しました。何らかの理由で、ステートメントがある場合、内容がなくても\ifコードはコンパイルされます。\else

\newif\ifdraftversion \draftversionfalse
\newif\iffullversion  \fullversionfalse

\documentclass[
  \iffullversion  twoside,  \fi %works if the \fi here are
  \ifdraftversion draft,    \fi % \else\fi instead
  11pt
]{article}

\begin{document}
This is a MWE, although it generates an extra warning that would
disappear if I added substantially more content to the document
\end{document}

この回避策は特に面倒ではありませんが、実際に関係するバグを特定したり、何を誤解しているのかを解明したりすることはできませんでした。私の直感が無効な構文を使用するように導く何らかの理由があるのでしょうか。もしそうなら、それはどこ/何/なぜでしょうか。

答え1

コマンドは\documentclass記録処理を行い、次に

\@fileswithoptions\@clsextension

この時点では、オプションと引数はまだ検討されていません。マクロは\@fileswithoptions引数を吸収し、次に[続くかどうかを確認します。この決定の後、マクロは以下を実行します。

\@fileswith@ptions\@clsextension[<options>]{article}

さらにオプションの引数を探すと、最終的に次のようになります。

\@fileswith@pti@ns\@clsextension[<options>]{article}[]

末尾のオプション引数を指定していないためです。このマクロは

\xdef\@classoptionslist{\zap@space<options> \@empty}

では、あなたのオプションでそれを実行したらどうなるかを考えてみましょう。トークン化の後、

\zap@space \iffullversion twoside, \fi\ifdraftversion draft, \fi 11pt \@empty

の定義\zap@space

% latex.ltx, line 7764:
\def\zap@space#1 #2{%
  #1%
  \ifx#2\@empty\else\expandafter\zap@space\fi
  #2}

最初の呼び出しでは、#1は空なので、

\zap@space\iffullversion twoside, \fi\ifdraftversion draft, \fi 11pt \@empty

これは\iffulversion twoside,入力ストリームに残され、その後

\ifx\fi\ifdraftversion draft, \fi 11pt \@empty

何が間違っているかわかりますか? 条件文はそれら\fiを比較して\ifdraftversion削除します。

を使用する場合\else\fi、比較はこれら 2 つ間で行われます。\relax\fiまたは を使用できます\whateverevenundefined\fi

この時点で、不均衡は\fi明らかです。アプリケーションでは後でエラーが発見されますが、クラス オプション内の条件文を避ける必要があることを説明するにはこれで十分でしょう。

ちなみに、これは機能します:

\newif\ifdraftversion \draftversionfalse
\newif\iffullversion  \fullversionfalse
\def\safetybelt{\empty}

\documentclass[%
  \safetybelt\iffullversion  twoside,\fi
  \safetybelt\ifdraftversion draft,\fi
  11pt
]{article}

答え2

「回避策」は\else\fi思われる機能します。オプションはカンマで分割されるため、、、および のオプションが\iffullversion twosideあり\fi\ifdraftversion draftます\fi 11pt

次のコード思われる期待通りに動作する(実験によってのみ検証済み):

\documentclass[
  \iffullversion  twoside\fi, %works if the \fi here are
  \ifdraftversion draft\fi, % \else\fi instead
  11pt
]{article}

関連情報