如何在 \addcontentsline 中使用宏?

如何在 \addcontentsline 中使用宏?

首先要提醒一下:我怀疑我是否已经完全掌握\def\edef或,\let并且\expandafter在经过一系列尝试解决以下问题后感到完全不知所措。

我想为章节标题添加自定义标签,即我的文档有不同的部分,标题字符串应该反映这一点。章节标题前面应该有 A1、A2、A3、...K1、K2、K3、...D1、D2、D3、...,具体取决于提供给宏的计数器\unit{counter}{title}

创建计数器没有问题,条件有效,添加带星号的节命令来抑制默认节编号也很简单。当 \addcontentsline 发挥作用时,一切都乱套了,告诉我已\endcsname插入(在我的代码中的一些变体中\def\expandafter我最终得到一个错误,说我定义的节宏未定义——尽管包hyperref似乎导致了那里的一些问题)。不管怎样,下面是一个最小的例子。

\documentclass{article}

\usepackage{ifthen}

\newcounter{parta}
\setcounter{parta}{0}
\newcounter{partb}
\setcounter{partb}{0}

\newcommand\unit[2]{%
  \def\tag{A}
  \def\cnt{#1}
  \ifthenelse{\equal{#1}{morph}}%
    {\def\tag{A}}%
    {%
      \ifthenelse{\equal{#1}{syntax}}%
      {\def\tag{B}}%
      {}%
    }%
  \def\numtag{\refstepcounter{\cnt}\tag\arabic{\cnt}}
  \expandafter\def\expandafter\unittitle{\numtag{} #2}
  \section*{\unittitle}
  \addcontentsline{toc}{section}{\unittitle}}

\begin{document}
\unit{parta}{foo}
\unit{partb}{bar}
\end{document}

我收到的错误是

! Missing \endcsname inserted.
<to be read again> 
                   \csname\endcsname 
l.27 \unit{parta}{foo}

我知道我可以使用软件包titlesec或类似程序来实现类似的功能,但这个过程一开始似乎很简单。我认为这很容易解决,我太愚蠢了。我难道不是在调整在发送到辅助文件之前扩展的字符串吗?谢谢你的帮助!

答案1

你把事情搞得太复杂了。你不需要根据你传递的内容来设置条件,因为你可以用以下方式为这些数字/计数器定义“前缀”:

在此处输入图片描述

\documentclass{article}

\newcommand{\parta}{A}% Prefix for parta
\newcommand{\partb}{B}% Prefix for partb
\newcounter{parta}
\newcounter{partb}

\newcommand\unit[2]{%
  \stepcounter{#1}% Step counter
  \section*{\csname #1\endcsname\arabic{#1} #2}% Section title is "<counter prefix><counter> <title>"
  \addcontentsline{toc}{section}{\csname #1\endcsname\arabic{#1} #2}% Add to ToC
}

\begin{document}

\tableofcontents

\unit{parta}{foo}
\unit{partb}{bar}
\unit{parta}{baz}

\end{document}

上述方法之所以有效,是因为写入 ToC 的内容已完全展开,并且可以,因为传递给的定义非常简单。在您的示例中 - \unittitle- 由 组成\numtag,其中包括一个\refstepcounter- 执行大量后台计算和定义的宏。


事实上,LaTeX 提供了一种相当简单的方法来处理你的需求。计数器的值和它的表示是有区别的。值是 LaTeX 内部的东西,而表示可以是\roman、 或\arabic\alphabetic。因此,你可以通过重新定义 来为这个表示添加一个前缀\the<counter>

\documentclass{article}

\newcounter{parta}
\newcounter{partb}
\renewcommand{\theparta}{A\arabic{parta}}
\renewcommand{\thepartb}{B\arabic{partb}}

\newcommand\unit[2]{%
  \stepcounter{#1}% Step counter
  \section*{\csname the#1\endcsname{} #2}% Section title is "<counter prefix><counter> <title>"
  \addcontentsline{toc}{section}{\csname the#1\endcsname{} #2}% Add to ToC
}

\begin{document}

\tableofcontents

\unit{parta}{foo}
\unit{partb}{bar}
\unit{parta}{baz}

\end{document}

答案2

不确定这是否就是您要找的。

\documentclass{article}

\usepackage{ifthen}
\newcounter{parta}
\newcounter{partb}
\newcounter{partc}

\newcommand\unit[2]{%
  \def\mytag{A}
  \setcounter{#1}{\value{#1}}
  \ifthenelse{\equal{#1}{partc}}%
    {\def\mytag{C}}%
    {%
      \ifthenelse{\equal{#1}{partb}}%
      {\def\mytag{B}}%
      {}%
    }%
  \refstepcounter{#1}%
  \edef\numtag{\mytag\arabic{#1}}
  \expandafter\def\expandafter\unittitle\expandafter{\numtag{} #2}
  \section*{\unittitle}
  \addcontentsline{toc}{section}{\unittitle}%
}

\begin{document}
\tableofcontents
\hrulefill

\unit{parta}{foo}
\unit{parta}{foo-ex}
\unit{partb}{bar}
\unit{partb}{bar none}
\unit{partb}{barbel}
\unit{partc}{foo-bar}
\end{document}

在此处输入图片描述

相关内容