我正在尝试使用 将 添加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}{}%