Verwenden von \def in \newcommand

Verwenden von \def in \newcommand

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\chapterich 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, \startnewpartum die Ausführung von zu steuern \chapter. \def\startnewpart{FALSE}soll den Wert von zurücksetzen \startnewpart.

Antwort1

\secdefist 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 \@ifstardas folgende Token. Wenn Sie die zweite \defZeile 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@ifnextcharnimmt 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 #1ist {\@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.

verwandte Informationen