![如何在 \addcontentsline 中使用宏?](https://linux22.com/image/430034/%E5%A6%82%E4%BD%95%E5%9C%A8%20%5Caddcontentsline%20%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%AE%8F%EF%BC%9F.png)
首先要提醒一下:我怀疑我是否已经完全掌握\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
或\alph
abetic。因此,你可以通过重新定义 来为这个表示添加一个前缀\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}