我正在查看文件book.cls
\section
我注意到,\subsection
和\paragraph
命令的定义中没有强制参数
\newcommand\section{\@startsection {section}{1}{\z@}%
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
{\normalfont\Large\bfseries}}
\newcommand\subsection{\@startsection{subsection}{2}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{1.5ex \@plus .2ex}%
{\normalfont\large\bfseries}}
%etc.
即命令都采用以下形式\newcommand\foosection{\@startsection{foo}{foo}{foo}...}
。然后我查看了\@startsection
定义,发现有一个\@sect
命令需要 8 个参数,但我不太明白哪一个代表要为该部分打印的标题,也不知道如何在不声明的情况下使用强制参数定义命令。
您是否知道该部分的标题是如何进入其定义的,以及强制参数是否以某种方式在命令定义本身中隐式定义?
答案1
让我们以 为例(除了和\section
,它们的行为都差不多)。定义如下:\chapter
\part
\newcommand\section{\@startsection {section}{1}{\z@}%
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
{\normalfont\Large\bfseries}}
因此,当您这样做时,\section
您实际上是\@startsection
在使用一组参数,这些参数将用于了解::#1
命令的名称、要使用的计数器等;#2
:部分标题的级别;#3
:标题的缩进(如果是\paragraph
-type 标题);:#4
标题前的空格,#5
:标题后的空格,以及#6
:样式。在几个条件下,#4
或#5
为负数会产生插入标题,例如\paragraph
,但我不会在这里讨论。
如果你看一下定义,\@startsection
你会发现它需要以下 6 个参数:
\def\@startsection#1#2#3#4#5#6{%
此时,所有完成的\section
命令都是:TeX 尚未查看除此以外的任何内容。现在,在定义的末尾,\@startsecion
您会看到:
\@ifstar
{\@ssect{#3}{#4}{#5}{#6}}%
{\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}
这里,检查以下\@ifstar
内容。*
\section
如果有*
然后将的四个参数\@startsection
传递给\@ssect
:\@ssect{#3}{#4}{#5}{#6}
。但\@ssect
有 5 个参数:
\def\@ssect#1#2#3#4#5{%
因此第五个参数是章节标题。这里不需要可选参数。尝试\section*[optional]{mandatory}
看看。
如果没有*
然后\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}
被使用。
\@dblarg
检查后面是否有[
...]
分隔的参数 ( <optional>
),然后检查是否有<mandatory>
参数。如果有一个[
,则\@dblarg{<code>}[<optional>]{<mandatory>}
扩展为<code>[<optional>]{<mandatory>}
,否则扩展为<code>[<mandatory>]{<mandatory>}
。简而言之,如果没有给出可选参数,它会复制强制参数;因此得名\@dblarg
。
完成后\@dblarg
,您将获得:
\@sect{#1}{#2}{#3}{#4}{#5}{#6}[<optional-or-copy-of-mandatory>]{<mandatory>}
其中,(可能的)可选参数取自输入流,紧接着\section
,而强制参数紧接着。
最后,\@sect
展开,它接受 6 个参数、一个[
...]
分隔的参数和另一个参数:
\def\@sect#1#2#3#4#5#6[#7]#8{%
完成的参数解析\section
。
简而言之,\section
命令本身不接受任何参数。但是,它会扩展为一系列命令,这些命令将解析输入流并处理可能的可选参数并使用它们。今天早些时候有人就可选参数提出了一个密切相关的问题。您可能会发现它很有用:基于位置的可选参数