
次の例を考えてみましょう。
\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}
\renewcommand\chapter
最初のコメントを外す と、\def\startnewpart{FALSE}
ドキュメントは正常にコンパイルされます。
代わりに 2 番目のコメントを外すと、\def\startnewpart{FALSE}
エラーが発生します。
Chapter 1.
! Missing { inserted.
\@makechapterhead ...1\par \nobreak \vskip 40\p@ }
l.21 \tableofcontents
違いはどこにあるのでしょうか?
\startnewpart
この例では、制御変数を使用して の実行を制御する方法を説明します\chapter
。\def\startnewpart{FALSE}
は の値をリセットすることを目的としています\startnewpart
。
答え1
\secdef
と定義されている
% latex.ltx, line 6086:
\def\secdef#1#2{\@ifstar{#2}{\@dblarg{#1}}}
あなたの場合は
\@ifstar{\@schapter}{\@dblarg{\@chapter}}
次に\@ifstar
次のトークンを見てみましょう。2\def
行目のコメントを外すと、次のトークンは ではなく になります*
。\def
したがって、LaTeXは
\@dblarg{\@chapter}\def\startnewpart{FALSE}
の定義は次のとおりです\@dblarg
:
% latex.ltx, line 1105:
\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
つまり、
\kernel@ifnextchar[{\@chapter}{\@xdblarg{\@chapter}}\def\startnewpart{FALSE}
このマクロは\kernel@ifnextchar
、3つの引数、ここではとを受け取り[
、次のトークンが であるかどうかをチェックします。 ではないのは であるためです。その結果、次のようになります。{\@chapter}
{\@xdblarg{\@chapter}}
[
\def
\@xdblarg{\@chapter}\def\startnewpart{FALSE}
さて、次を見てみましょう\@xdblarg
:
% latex.ltx, line 1106:
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}
これは#1
({\@chapter}
ただし、括弧は規則により削除されます)、次のようになります。
\@chapter[{\def}]{\def}\startnewpart{FALSE}
これは、コードに含めたくないものであることは間違いありません。
実際には に結びついていません\def
。
\secdef\A\B
\@ifstar{A}{B}
\@ifnextchar<char>{A}{B}
すべきいつも定義コードの最後に来るのは、次に何が来るかを確認したいからです。