使用 xparse 命令而不是 LaTeX2e 命令时目录中的计数器失败

使用 xparse 命令而不是 LaTeX2e 命令时目录中的计数器失败

这里我定义了一个自定义分段命令,\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}

这是所需的输出,使用\newcommand在此处输入图片描述

答案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在排版目录时重​​新定义。

相关内容