
다음 예를 고려하십시오.
\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}
문서가 제대로 컴파일됩니다.
대신 두 번째 주석을 제거하면 \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
다음 토큰을 살펴보겠습니다. 두 번째 줄의 주석 처리를 제거하면 \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}
~해야 한다언제나다음에 무엇이 올지 보고 싶어하기 때문에 정의 코드에서 마지막에 옵니다.