Encontrei uma interação estranha entre os parâmetros opcionais \documentclass
e \if
as instruções. Por alguma razão, o código é compilado se houver uma \else
instrução, mesmo que não tenha conteúdo:
\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}
Embora essa solução alternativa não seja particularmente onerosa, não consegui isolar o bug real envolvido ou descobrir o que entendi mal. Existe alguma razão pela qual minha intuição está me levando a usar sintaxe inválida e, em caso afirmativo, onde/o quê/por quê?
Responder1
O \documentclass
comando faz alguma contabilidade e depois chama
\@fileswithoptions\@clsextension
Neste ponto, as opções e o argumento ainda não foram analisados. A macro \@fileswithoptions
absorve seu argumento e então verifica se [
segue. Após esta decisão, ele executa
\@fileswith@ptions\@clsextension[<options>]{article}
que procura mais um argumento opcional; no final chegamos a
\@fileswith@pti@ns\@clsextension[<options>]{article}[]
porque você não especifica o argumento opcional final. Esta macro faz
\xdef\@classoptionslist{\zap@space<options> \@empty}
então devemos perguntar o que acontece se fizermos isso com suas opções. Após a tokenização, obtemos
\zap@space \iffullversion twoside, \fi\ifdraftversion draft, \fi 11pt \@empty
A definição de \zap@space
é
% latex.ltx, line 7764:
\def\zap@space#1 #2{%
#1%
\ifx#2\@empty\else\expandafter\zap@space\fi
#2}
Para a primeira chamada, #1
está vazio, então obtemos
\zap@space\iffullversion twoside, \fi\ifdraftversion draft, \fi 11pt \@empty
Isso sai \iffulversion twoside,
no fluxo de entrada e depois faz
\ifx\fi\ifdraftversion draft, \fi 11pt \@empty
Você consegue ver o que está errado? A condicional \fi
os compara \ifdraftversion
e os remove.
Se você usar \else\fi
, a comparação será entre esses dois; você poderia usar \relax\fi
ou \whateverevenundefined\fi
.
Neste ponto o desequilíbrio \fi
é claro. Na sua aplicação, o erro é descoberto posteriormente, mas isso deve ser suficiente para explicar que as condicionais nas opções de classe devem ser evitadas.
A propósito, isso funciona:
\newif\ifdraftversion \draftversionfalse
\newif\iffullversion \fullversionfalse
\def\safetybelt{\empty}
\documentclass[%
\safetybelt\iffullversion twoside,\fi
\safetybelt\ifdraftversion draft,\fi
11pt
]{article}
Responder2
A "solução alternativa" usando \else\fi
apenasparecetrabalhar. Suas opções são divididas entre vírgulas, então você tem as opções \iffullversion twoside
,, \fi\ifdraftversion draft
e \fi 11pt
.
O seguinte códigoparecefuncionar conforme esperado (verificado apenas por experimento):
\documentclass[
\iffullversion twoside\fi, %works if the \fi here are
\ifdraftversion draft\fi, % \else\fi instead
11pt
]{article}