这里我定义了一个自定义分段命令,\Unit
,它打印一个编号的主题标题并将其添加到目录中。如果我使用\newcommand
创建编号标签的命令,一切都会正常工作。但如果我用版本 替换它xparse
,\NewDocumentCommand
目录标签中就会缺少数字。
在下面的 MWE 中,您可以通过将 的定义替换为\newcommand
的定义来重现错误。\UnitLabel
\NewDocumentCommand
\documentclass{article}
\usepackage{lipsum}
\usepackage{xparse}
\newcounter{Unit}
% Numbering disappears in TOC if xparse version is used
% \NewDocumentCommand{\UnitLabel}{}{%
\newcommand{\UnitLabel}{%
\makebox[4.5em][l]{Unit \Roman{Unit}}%
}
\NewDocumentCommand{\Unit}{ m }{%
\stepcounter{Unit}
\def\ThisUnit{\UnitLabel{}#1}
\section*{\ThisUnit}
\addcontentsline{toc}{section}{\ThisUnit}%
}
\begin{document}
\tableofcontents
\Unit{Exordium}
\lipsum[1]
\Unit{Disputatio}
\lipsum[2]
\Unit{Peroratio}
\lipsum[3]
\end{document}
答案1
使用\DeclareExpandableDocumentCommand
——这不允许在参数列表末尾出现可选参数,但这不是问题!
该\NewDocumentCommand
版本不可扩展,例如\show\UnitLabel
:
\UnitLabel=\protected macro:
->\makebox [4.5em][l]{Unit \Roman {Unit}}.
l.25 \show\UnitLabel
即\UnitLabel
受到保护。
手册xparse
明确指出,命令\NewDocumentCommand
、\RenewDocumentCommand
和在设计上会生成强大的命令\ProvideDocumentCommand
:\DeclareDocumentCommand
定义了参数说明符的概念后,现在就可以描述使用 xparse 创建函数和环境的方法。接口构建命令是创建 LATEX3 中文档级函数的首选方法。以这种方式生成的所有函数都具有天然的稳健性(使用 e-TEX \protected 机制)。
\documentclass{article}
\usepackage{lipsum}
\usepackage{xparse}
\newcounter{Unit}
% Numbering disappears in TOC if xparse version is used
\DeclareExpandableDocumentCommand{\UnitLabel}{}{%
\makebox[4.5em][l]{Unit \Roman{Unit}}%
}
\NewDocumentCommand{\Unit}{ m }{%
\stepcounter{Unit}
\def\ThisUnit{\UnitLabel{}#1}
\section*{\ThisUnit}
\addcontentsline{toc}{section}{\ThisUnit}%
}
\begin{document}
\tableofcontents
\Unit{Exordium}
\lipsum[1]
\Unit{Disputatio}
\lipsum[2]
\Unit{Peroratio}
\lipsum[3]
\end{document}
答案2
\UnitLabel
用参数定义:
\documentclass{article}
\usepackage{lipsum}
\usepackage{xparse}
\newcounter{Unit}
\NewDocumentCommand{\UnitLabel}{m}{%
\makebox[4.5em][l]{Unit #1}%
}
\NewDocumentCommand{\Unit}{ m }{%
\refstepcounter{Unit}%
\section*{\UnitLabel{\Roman{Unit}}#1}
\addcontentsline{toc}{section}{\UnitLabel{\Roman{Unit}}#1}%
}
\begin{document}
\tableofcontents
\Unit{Exordium}
\lipsum[1]
\Unit{Disputatio}
\lipsum[2]
\Unit{Peroratio}
\lipsum[3]
\end{document}
这样,参数将被扩展,.toc
文件将看起来像
\contentsline {section}{\UnitLabel {I}Exordium}{1}
\contentsline {section}{\UnitLabel {II}Disputatio}{1}
\contentsline {section}{\UnitLabel {III}Peroratio}{1}
这种方法有一个优势,因为您可以\UnitLabel
在排版目录时重新定义。