He encontrado una interacción extraña entre los parámetros opcionales \documentclass
y \if
las declaraciones. Por alguna razón, el código se compila si hay una \else
declaración, incluso si no tiene contenido:
\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}
Si bien esta solución no es particularmente onerosa, no he podido aislar el error real involucrado ni resolver lo que he entendido mal. ¿Hay alguna razón por la que mi intuición me lleva a utilizar una sintaxis no válida y, de ser así, dónde/qué/por qué?
Respuesta1
El \documentclass
comando hace algo de contabilidad y luego llama
\@fileswithoptions\@clsextension
A estas alturas aún no se han analizado las opciones y el argumento. La macro \@fileswithoptions
absorbe su argumento y luego mira si [
sigue. Después de esta decisión, ejecuta
\@fileswith@ptions\@clsextension[<options>]{article}
que busca un argumento opcional adicional; al final llegamos a
\@fileswith@pti@ns\@clsextension[<options>]{article}[]
porque no especifica el argumento opcional final. Esta macro hace
\xdef\@classoptionslist{\zap@space<options> \@empty}
entonces deberíamos preguntarnos qué pasa si lo hacemos con sus opciones. Después de la tokenización, obtenemos
\zap@space \iffullversion twoside, \fi\ifdraftversion draft, \fi 11pt \@empty
La definición de \zap@space
es
% latex.ltx, line 7764:
\def\zap@space#1 #2{%
#1%
\ifx#2\@empty\else\expandafter\zap@space\fi
#2}
Para la primera llamada, #1
está vacío, por lo que obtenemos
\zap@space\iffullversion twoside, \fi\ifdraftversion draft, \fi 11pt \@empty
Esto sale \iffulversion twoside,
en el flujo de entrada y luego lo hace.
\ifx\fi\ifdraftversion draft, \fi 11pt \@empty
¿Puedes ver lo que sale mal? El condicional \fi
los compara \ifdraftversion
y los elimina.
Si usa \else\fi
, entonces la comparación es entre estos dos; podrías usar \relax\fi
o \whateverevenundefined\fi
.
En este punto el desequilibrio \fi
es claro. En su aplicación, el error se descubre más tarde, pero esto debería ser suficiente para explicar que se deben evitar los condicionales en las opciones de clase.
Esto funciona, por cierto:
\newif\ifdraftversion \draftversionfalse
\newif\iffullversion \fullversionfalse
\def\safetybelt{\empty}
\documentclass[%
\safetybelt\iffullversion twoside,\fi
\safetybelt\ifdraftversion draft,\fi
11pt
]{article}
Respuesta2
La "solución alternativa" usando \else\fi
sóloparecetrabajar. Sus opciones están divididas entre comas, por lo que tiene las opciones \iffullversion twoside
, \fi\ifdraftversion draft
y \fi 11pt
.
El siguiente códigoparecepara funcionar como se esperaba (solo verificado mediante experimento):
\documentclass[
\iffullversion twoside\fi, %works if the \fi here are
\ifdraftversion draft\fi, % \else\fi instead
11pt
]{article}