我参与了一个大项目的后期阶段,我们使用以下 \tocless 命令来排除特定子部分出现在目录中:
\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[2]{\bgroup\let\addcontentsline=\nocontentsline#1{#2}\egroup}
但是,我最近发现这会弄乱引用,如随附的 MWE 中所示。有没有办法更改 \tocless 的定义来纠正此行为?
\documentclass[12pt,a4paper]{memoir}
\setcounter{tocdepth}{2}
\usepackage[usehighlevels]{alnumsec}
\alnumsectionlevels{1}{section,subsection,subsubsection,paragraph}
\alnumsecstyle{aaaa}
\surroundarabic[{.}][]{}{}
\otherseparators{1}
\alnumsecstyle{aaaa}
\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[2]{\bgroup\let\addcontentsline=\nocontentsline#1{#2}\egroup}
\begin{document}
\tableofcontents
\section{this the first section}
\subsection{this is a normal subsection}\label{subsec:AA}
\tocless\subsection{this is a subsection not in TOC}\label{subsec:AB}
\section{this the second section}
\tocless\subsection{this is another subsection not in TOC}\label{subsec:BA}
\begin{itemize}
\item referring to 1.1: \ref{subsec:AA}
\item referring to 1.2: \ref{subsec:AB}
\item referring to 2.1: \ref{subsec:BA}
\end{itemize}
\end{document}
答案1
这是一个通过临时更改tocdepth
计数器(写入.toc
文件然后恢复)的解决方案
\documentclass[12pt,a4paper]{memoir}
\setcounter{tocdepth}{2}
\usepackage[usehighlevels]{alnumsec}
\alnumsectionlevels{1}{section,subsection,subsubsection,paragraph}
\alnumsecstyle{aaaa}
\surroundarabic[{.}][]{}{}
\otherseparators{1}
\alnumsecstyle{aaaa}
\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[1]{\addtocontents{toc}{\protect\setcounter{tocdepth}{1}}%
#1
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}%
}
\begin{document}
\tableofcontents
\section{this the first section}
\subsection{this is a normal subsection}\label{subsec:AA}
\tocless{\subsection{this is a subsection not in TOC}}\label{subsec:AB}
\section{this the second section}
\tocless{\subsection{this is another subsection not in TOC}}\label{subsec:BA}
\begin{itemize}
\item referring to 1.1: \ref{subsec:AA}
\item referring to 1.2: \ref{subsec:AB}
\item referring to 2.1: \ref{subsec:BA}
\end{itemize}
\end{document}
更新
稍微改进的tocless
命令有一个可选参数,指示目录深度级别。
\documentclass[12pt,a4paper]{memoir}
\usepackage{etoolbox}
\setcounter{tocdepth}{2}
\usepackage[usehighlevels]{alnumsec}
\alnumsectionlevels{1}{section,subsection,subsubsection,paragraph}
\alnumsecstyle{aaaa}
\surroundarabic[{.}][]{}{}
\otherseparators{1}
\alnumsecstyle{aaaa}
\newcommand{\tocless}[2][]{%
\begingroup
\edef\temptocdepth{\number\value{tocdepth}}%
\edef\newtocdepth{\the\numexpr\value{tocdepth}-1}% Calculating a default new tocdepth
\ifblank{#1}{% Apply default
\addtocontents{toc}{\protect\setcounter{tocdepth}{\newtocdepth}}%
}{% Use the value from #1
\addtocontents{toc}{\protect\setcounter{tocdepth}{#1}}%
}%
#2%
\addtocontents{toc}{\protect\setcounter{tocdepth}{\temptocdepth}}% Restoring
\endgroup
}
\begin{document}
\tableofcontents
\section{this the first section}
\subsection{this is a normal subsection}\label{subsec:AA}
\tocless{\subsection{this is a subsection not in TOC}}\label{subsec:AB}
\section{this the second section}
\tocless[2]{\subsection{this will be in in TOC}}\label{subsec:BA}
\begin{itemize}
\item referring to 1.1: \ref{subsec:AA}
\item referring to 1.2: \ref{subsec:AB}
\item referring to 2.1: \ref{subsec:BA}
\end{itemize}
\end{document}
答案2
问题源于对部分单元进行分组,这否定了引用能力。一种解决方案是将 放在\label
标题内,但这需要更改编码。
下面通过在分段单元后\tocless
恢复的定义来避免在定义中进行分组:\addcontentsline
\documentclass{memoir}
\setcounter{tocdepth}{2}
\usepackage[usehighlevels]{alnumsec}
\alnumsectionlevels{1}{section,subsection,subsubsection,paragraph}
\alnumsecstyle{aaaa}
\surroundarabic[{.}][]{}{}
\otherseparators{1}
\alnumsecstyle{aaaa}
\newcommand{\nocontentsline}[3]{}
\let\oldaddcontentsline\addcontentsline
\newcommand{\tocless}[2]{%
\let\addcontentsline\nocontentsline
#1{#2}
\let\addcontentsline\oldaddcontentsline}
\begin{document}
\tableofcontents
\section{this the first section}
\subsection{this is a normal subsection}\label{subsec:AA}
\tocless\subsection{this is a subsection not in TOC}\label{subsec:AB}
\section{this the second section}
\tocless\subsection{this is another subsection not in TOC}\label{subsec:BA}
\begin{itemize}
\item referring to 1.1: \ref{subsec:AA}
\item referring to 1.2: \ref{subsec:AB}
\item referring to 2.1: \ref{subsec:BA}
\end{itemize}
\end{document}
创建部门单位时,适当的反击是\refstep
-ed,这会导致名为 的宏的更新\@currentlabel
。\@currentlabel
使用 进行更新\def
,它具有局部范围,并且无法在组之外存活。
答案3
您必须注意,\@currentlabel
在组结束后,哪个是正确的。您还应该注意的可选参数\subsection
。
\documentclass[12pt,a4paper]{memoir}
\usepackage{xparse}
\setcounter{tocdepth}{2}
\usepackage[usehighlevels]{alnumsec}
\alnumsectionlevels{1}{section,subsection,subsubsection,paragraph}
\alnumsecstyle{aaaa}
\surroundarabic[{.}][]{}{}
\otherseparators{1}
\alnumsecstyle{aaaa}
\newcommand{\nocontentsline}[3]{}
\makeatletter
\NewDocumentCommand{\tocless}{msoom}{%
\begingroup
\let\addcontentsline\nocontentsline
\IfBooleanTF{#2}
{#1{#5}}% case \subsection*{z}
{\IfNoValueTF{#3}
{#1{#5}}% case \subsection{z}
{\IfNoValueTF{#4}
{#1[#3]{#5}}% case \subsection[x]{z}
{#1[#3][#4]{#5}% case \subsection[x][y]{z}
}%
}%
}%
\edef\x{\endgroup\def\noexpand\@currentlabel{\@currentlabel}}\x
}
\makeatother
\begin{document}
\tableofcontents
\section{this the first section}
\subsection{this is a normal subsection}\label{subsec:AA}
\tocless\subsection{this is a subsection not in TOC}\label{subsec:AB}
\section{this the second section}
\tocless\subsection{this is another subsection not in TOC}\label{subsec:BA}
\begin{itemize}
\item referring to 1.1: \ref{subsec:AA}
\item referring to 1.2: \ref{subsec:AB}
\item referring to 2.1: \ref{subsec:BA}
\end{itemize}
\end{document}
答案4
memoir 类有\settocdepth
-command(其他类可以通过tocvsec2
包获取)来(临时或全局)设置目录深度:
\documentclass[12pt,a4paper]{memoir}
\setcounter{tocdepth}{2}
\usepackage[usehighlevels]{alnumsec}
\alnumsectionlevels{1}{section,subsection,subsubsection,paragraph}
\alnumsecstyle{aaaa}
\surroundarabic[{.}][]{}{}
\otherseparators{1}
\alnumsecstyle{aaaa}
\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[2]{\bgroup\let\addcontentsline=\nocontentsline#1{#2}\egroup}
\begin{document}
\tableofcontents
\section{this the first section}
\subsection{this is a normal subsection}\label{subsec:AA}
\settocdepth{section}
\subsection{this is a subsection not in TOC}\label{subsec:AB}
\section{this the second section}
\subsection{this is another subsection not in TOC}\label{subsec:BA}
\begin{itemize}
\item referring to 1.1: \ref{subsec:AA}
\item referring to 1.2: \ref{subsec:AB}
\item referring to 2.1: \ref{subsec:BA}
\end{itemize}
\settocdepth{subsection}
\subsection{this is again in the toc}
\end{document}