
Considere este ejemplo:
\documentclass{report}
\def\startnewpart{FALSE}
\makeatletter
\renewcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
% \def\startnewpart{FALSE}
\thispagestyle{plain}%
\global\@topnum\z@
\@afterindentfalse
\secdef\@chapter\@schapter
% \def\startnewpart{FALSE}
}
\makeatother
\begin{document}
\tableofcontents
\chapter{Methods}
Some text
\end{document}
Si \renewcommand\chapter
descomento el primero, \def\startnewpart{FALSE}
el documento se compila bien.
Si en cambio descomento el segundo \def\startnewpart{FALSE}
me sale un error:
Chapter 1.
! Missing { inserted.
\@makechapterhead ...1\par \nobreak \vskip 40\p@ }
l.21 \tableofcontents
¿Dónde está la diferencia?
En este ejemplo, estoy explorando cómo usar una variable de control \startnewpart
para controlar la ejecución de \chapter
. \def\startnewpart{FALSE}
está destinado a restablecer el valor de \startnewpart
.
Respuesta1
\secdef
Se define como
% latex.ltx, line 6086:
\def\secdef#1#2{\@ifstar{#2}{\@dblarg{#1}}}
En tu caso obtienes
\@ifstar{\@schapter}{\@dblarg{\@chapter}}
Ahora \@ifstar
mira el siguiente token. Si descomentas la segunda \def
línea, el siguiente token no es *
, sino \def
. Así LaTeX encuentra
\@dblarg{\@chapter}\def\startnewpart{FALSE}
Aquí está la definición de \@dblarg
:
% latex.ltx, line 1105:
\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
Así obtienes
\kernel@ifnextchar[{\@chapter}{\@xdblarg{\@chapter}}\def\startnewpart{FALSE}
La macro \kernel@ifnextchar
absorbe tres argumentos, aquí [
, {\@chapter}
y {\@xdblarg{\@chapter}}
y comprueba si el siguiente token es [
. No lo es, porque lo es \def
, entonces el efecto es obtener
\@xdblarg{\@chapter}\def\startnewpart{FALSE}
Bien, veamos \@xdblarg
:
% latex.ltx, line 1106:
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}
Aquí #1
está {\@chapter}
(pero las llaves se eliminarán por regla), por lo que terminarás con
\@chapter[{\def}]{\def}\startnewpart{FALSE}
lo cual seguramente no es algo que le gustaría tener en su código.
Realmente no está ligado a \def
. Comandos como
\secdef\A\B
\@ifstar{A}{B}
\@ifnextchar<char>{A}{B}
deberíasiemprevienen al final en un código de definición, porque quieren ver lo que viene después.