从目录中排除子部分但允许正确引用

从目录中排除子部分但允许正确引用

我参与了一个大项目的后期阶段,我们使用以下 \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}

在此处输入图片描述

相关内容