TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am involved in the later stages of a big project, in which we use the following \tocless command to exclude specific subsections from appearing in the table of contents:

\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[2]{\bgroup\let\addcontentsline=\nocontentsline#1{#2}\egroup}

However, I recently found out that this messes up the references as can be seen in the enclosed MWE. Is there a way to change the definition of \tocless to correct this behaviour?

\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}

bad refs

share|improve this question
up vote 4 down vote accepted

Here's a solution by temporarily changing the tocdepth counter (writing to .toc file and then restoring)

\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}

enter image description here

Update A slightly improved tocless command that has an optional argument, indicating a tocdepth level.

\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}
share|improve this answer
    
This solution is specific to \tocless\subsection, which one might as well replace by a single macro (say) \toclesssubsection. This will not work as expected if you're using \tocless\section. – Werner Mar 11 at 18:27
    
@Werner: I added another solution with specification of the toc depth counter ago -- and I did not claim that it would work for other levels ;-) – Christian Hupfer Mar 11 at 18:39
    
@ChristianHupfer you answered exactly the question's title ;-) – touhami Mar 11 at 18:42
    
@touhami: Yes -- not more, not less ;-) – Christian Hupfer Mar 11 at 18:46

The problem stems from grouping the sectional unit, which negates the referencing capability. One solution would be to place the \label inside the title, but that would require a coding change.

The following avoids grouping in the definition of \tocless by restoring the definition of \addcontentsline after the sectional unit:

enter image description here

\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}

When a sectional unit is created, the appropriate counter is \refstep-ed, which leads to an update of a macro called \@currentlabel. \@currentlabel is updated using \def, which has a local scope and doesn't survive beyond the group.

share|improve this answer

You have to take care that \@currentlabel is the right one after the group ends. You also should be careful about the optional arguments to \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}

enter image description here

share|improve this answer

The memoir class has the \settocdepth-command (which other class can get with the tocvsec2 package) to (temporarly or globally) set the toc depth:

\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}

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.