addcontentsline 中的宏参数扩展问题

addcontentsline 中的宏参数扩展问题

我正在尝试使用 将 添加section*到目录中addcontentsline。它是我正在处理的一组较大命令的一部分的宏。我想要的是基于节级计数器添加目录条目。但是使用宏获取当前节级的字符串会导致addcontentsline我无法弄清楚的错误。这是我的问题的一个最小(不)工作示例(顺便说一下,我正在使用 overleaf。)

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{xifthen}        % If else commands

\makeatletter
\newcounter{counter@section@level}

\newcommand{\currentSectionString}{
    \ifthenelse{\equal{\value{counter@section@level}}{0}}{section}{}
}

\makeatother

\begin{document}

\tableofcontents

\currentSectionString                    % to check the macro itself, works as expected

\section*{Foo}
\addcontentsline{toc}{section}{Foo}                  % works as expected

\section*{Bar}
\addcontentsline{toc}{\currentSectionString}{Bar}    % does not work

\section{FooBar}                                     % overlapping in toc

\end{document}

答案1

\ifthenelse不可扩展。您需要该参数才能扩展为,section

\addcontentsline{toc}{\currentSectionString}{Bar}

就好像

\addcontentsline{toc}{\def\tmp{section}\tmp}{Bar}

由于同样的原因,它也无法工作。

您可以使用可扩展的测试,例如 \ifcase

\addcontentsline{toc}{\ifcase\mycounter section\or subsection\else error\fi}{Bar}

答案2

我的印象是您想自动将带星号的部分添加到目录中。

\documentclass{article}
\usepackage[utf8]{inputenc}

\NewCommandCopy{\latexsection}{\section}
\NewCommandCopy{\latexsubsection}{\subsection}

\RenewDocumentCommand{\section}{sO{#3}m}{%
  \IfBooleanTF{#1}{% starred section
    \latexsection*{#3}%
    \checkfortoc{#3}{\addcontentsline{toc}{section}{#3}}%
  }{% nonstarred section
    \latexsection[#2]{#3}%
  }%
}
\RenewDocumentCommand{\subsection}{sO{#3}m}{%
  \IfBooleanTF{#1}{% starred subsection
    \latexsubsection*{#3}%
    \addcontentsline{toc}{subsection}{#3}%
  }{% nonstarred section
    \latexsubsection[#2]{#3}%
  }%
}
% do the same for the other sectional levels you need

\ExplSyntaxOn
\NewDocumentCommand{\checkfortoc}{mm}
 {
  \str_if_eq:eeF { #1 } { \contentsname } { #2 }
 }
\ExplSyntaxOff


\begin{document}

\tableofcontents

\section*{Foo}

\section*{Bar}

\section{FooBar}

\end{document}

需要对 进行额外检查\section,因为\tableofcontents确实如此\section*{\contentsname},但目录不应该进入目录。

答案3

例如,\addcontentsline{toc}{section}{Foo}在输入 .toc 文件期间,宏\contentsline会触发其他操作
\csname l@section\endcsname\l@section

因此,的第二个参数\addcontentsline必须由可在 之间使用的标记组成\csname..\endcsname,即其扩展不会产生非字符标记的标记。
\ifthenelse-stuff 会产生非字符标记,因此既不能在 之间使用,\csname..\endcsname也不能与在 之间插入的宏参数一起使用\csname..\endcsname。对于在某个阶段扩展会产生\ifthenelse-stuff 的宏,情况也是如此。

如果您坚持使用\ifthenelse-stuff,则需要更改处理的顺序,以便\ifthenelse在处理之前完成 -stuff \addcontentsline- 那这个怎么样?:

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{xifthen}        % If else commands

\makeatletter
\newcounter{counter@section@level}%
% The optional argument of \DoWithCurrentSectionString denotes tokens that
% process "{section}" as argument.
\newcommand{\DoWithCurrentSectionString}[1][\@firstofone]{%
    \ifthenelse{\equal{\value{counter@section@level}}{0}}{#1{section}}{%
%      \ifthenelse{\equal{\value{counter@section@level}}{1}}{#1{subsection}}{%
%         ...
%      }%
    }%
}%
\makeatother

\begin{document}

\tableofcontents

\noindent\hrulefill

\DoWithCurrentSectionString               % to check the macro itself, works as expected

\kern\ht\strutbox\hrule\hfill

\section*{Foo}
\addcontentsline{toc}{section}{Foo}                  % works as expected

\section*{Bar}
\DoWithCurrentSectionString[{\addcontentsline{toc}}]{Bar}    % does work

\section{FooBar}                                     % overlapping in toc

\end{document}

在此处输入图片描述

.aux 文件:

\relax 
\@writefile{toc}{\contentsline {section}{Foo}{1}{}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{Bar}{1}{}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {1}FooBar}{1}{}\protected@file@percent }
\gdef \@abspage@last{1}

.toc 文件:

\contentsline {section}{Foo}{1}{}%
\contentsline {section}{Bar}{1}{}%
\contentsline {section}{\numberline {1}FooBar}{1}{}%


为了好玩,这里提供了一种可扩展的方法,它使用分隔参数而不是\if...-constructs:

\documentclass{article}
\usepackage[utf8]{inputenc}

\makeatletter
\newcounter{counter@section@level}
\newcommand{\currentSectionString}{%
   \expandafter\currentSectionStringSelect\expandafter{\number\value{counter@section@level}}%
}%
\newcommand\currentSectionStringSelect[1]{%
  \currentSectionStringFork
  #1!1!2!3!4!{section}%
  0!#1!2!3!4!{subsection}%
  0!1!#1!3!4!{subsubsection}%
  0!1!2!#1!4!{paragraph}%
  0!1!2!3!#1!{subparagraph}%
  0!1!2!3!4!{subparagraph}%
  !!!!%
}%
\@ifdefinable\currentSectionStringFork{%
  \long\def\currentSectionStringFork#10!1!2!3!4!#2#3!!!!{#2}%
}%
\makeatother

\begin{document}

\tableofcontents

\noindent\hrulefill

\currentSectionString               % to check the macro itself, works as expected

\kern\ht\strutbox\hrule\hfill

\section*{Foo}
\addcontentsline{toc}{section}{Foo}                  % works as expected

\section*{Bar}
\addcontentsline{toc}{\currentSectionString}{Bar}    % does work

\section{FooBar}                                     % overlapping in toc

\end{document}

在此处输入图片描述

.aux 文件:

\relax 
\@writefile{toc}{\contentsline {section}{Foo}{1}{}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{Bar}{1}{}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {1}FooBar}{1}{}\protected@file@percent }
\gdef \@abspage@last{1}

.toc 文件:

\contentsline {section}{Foo}{1}{}%
\contentsline {section}{Bar}{1}{}%
\contentsline {section}{\numberline {1}FooBar}{1}{}%

相关内容