
Betrachten Sie dieses Beispiel:
\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}
Wenn \renewcommand\chapter
ich das erste Kommentarzeichen entferne, \def\startnewpart{FALSE}
wird das Dokument einwandfrei kompiliert.
Wenn ich stattdessen das zweite Kommentarfeld entferne, \def\startnewpart{FALSE}
erhalte ich eine Fehlermeldung:
Chapter 1.
! Missing { inserted.
\@makechapterhead ...1\par \nobreak \vskip 40\p@ }
l.21 \tableofcontents
Wo ist der Unterschied?
In diesem Beispiel untersuche ich, wie man eine Steuervariable verwendet, \startnewpart
um die Ausführung von zu steuern \chapter
. \def\startnewpart{FALSE}
soll den Wert von zurücksetzen \startnewpart
.
Antwort1
\secdef
ist definiert als
% latex.ltx, line 6086:
\def\secdef#1#2{\@ifstar{#2}{\@dblarg{#1}}}
In Ihrem Fall erhalten Sie
\@ifstar{\@schapter}{\@dblarg{\@chapter}}
Betrachten wir nun \@ifstar
das folgende Token. Wenn Sie die zweite \def
Zeile auskommentieren, ist das nächste Token kein *
, sondern \def
. Somit findet LaTeX
\@dblarg{\@chapter}\def\startnewpart{FALSE}
Hier ist die Definition von \@dblarg
:
% latex.ltx, line 1105:
\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
So erhalten Sie
\kernel@ifnextchar[{\@chapter}{\@xdblarg{\@chapter}}\def\startnewpart{FALSE}
Das Makro \kernel@ifnextchar
nimmt drei Argumente auf, hier [
, {\@chapter}
und {\@xdblarg{\@chapter}}
und prüft, ob das nächste Token ist [
. Es ist nicht so, weil es ist \def
, also ist der Effekt, dass man erhält
\@xdblarg{\@chapter}\def\startnewpart{FALSE}
OK, schauen wir uns an \@xdblarg
:
% latex.ltx, line 1106:
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}
Hier #1
ist {\@chapter}
(aber die Klammern werden per Regel entfernt), also erhalten Sie
\@chapter[{\def}]{\def}\startnewpart{FALSE}
das ist sicherlich nichts, was Sie in Ihrem Code haben möchten.
Es ist nicht wirklich an gebunden \def
. Befehle wie
\secdef\A\B
\@ifstar{A}{B}
\@ifnextchar<char>{A}{B}
sollenstetskommen in einem Definitionscode ans Ende, weil sie sehen möchten, was als nächstes kommt.