1

The following memoir documentclass source produces two tables of contents -- a short one and a detailed one. (The difference is that only the latter includes subsections.)

Question: How do I get the name of each of those (the values of \shortcontentsname and \longcontentsname, respectively), to appear in the headers of its pages after its first? E.g., I want to see

iv                                                   Detailed Contents

and

Detailed Contents                                                   v

for the left-hand page iv and the right-hand page v, respectively.

As the source shows, I tried

\createplainmark{shorttableofcontents}{both}{\shortcontentsname}
\createplainmark{longtableofcontents}{both}{\longcontentsname}  

within \makepsmarks{main}, but that produces headers with just the page numbers. I also tried, instead

\createplainmark{shortttoc}{both}{\shortcontentsname}
\createplainmark{longtoc}{both}{\longcontentsname} 

and

\createplainmark{toc::shorttoc}{both}{\shortcontentsname}
\createplainmark{toc::longtoc}{both}{\longcontentsname}   

but with the same results.

\documentclass{memoir}

%% PAGE STYLEs
\nouppercaseheads
\makepagestyle{main} 
\makeheadrule{main}{\textwidth}{\normalrulethickness}
\makeevenhead{main}{\bfseries\sffamily\thepage}{}{\bfseries\sffamily\leftmark}
\makeoddhead{main}{\bfseries\sffamily\rightmark}{}{\bfseries\sffamily\thepage} 
\addtopsmarks{main}{}{%
  % insert "Chapter\space" & "Section\space" if desired as 4th argument:
  \createmark{chapter}{left}{shownumber}{}{\enspace} 
  \createmark{section}{right}{shownumber}{}{\enspace}
}
% daleif (https://tex.stackexchange.com/a/512636/13492):
\makepsmarks{main}{%
  \createmark{chapter}{both}{shownumber}{}{\enspace} % use both not left
  \createmark{section}{right}{shownumber}{}{\enspace}
  \createplainmark{toc}{both}{\contentsname}
  \createplainmark{lof}{both}{\listfigurename}
  \createplainmark{lot}{both}{\listtablename}
  \createplainmark{bib}{both}{\bibname}
  \createplainmark{index}{both}{\indexname}
  \createplainmark{glossary}{both}{\glossaryname}
  % ---> My attempted additions: <---
  \createplainmark{shorttableofcontents}{both}{\shortcontentsname}
  \createplainmark{longtableofcontents}{both}{\longcontentsname}  
}

\chapterstyle{default}
\pagestyle{main}

%% SECTIONING STYLES
\setsecnumdepth{subsection}

% CROSS-REFERENCING
\usepackage[pdftex]{hyperref}
\hypersetup{colorlinks,linkcolor=red}
\usepackage[nameinlink,noabbrev]{cleveref}
\usepackage{crossreftools}

%% SHORT & LONG TOCs
%% Code by Christian Hupfer 
% Just in case we're not loading hyperref
\makeatletter
%
\@ifpackageloaded{hyperref}{%
}{
  \providecommand{\@currentHref}{}
  \providecommand{\hyperlink}[2]{#2}
  \providecommand{\getrefnumber}[1]{}
  \providecommand{\phantomsection}{}
}
\AtBeginDocument{%
  \newcommand{\shortcontentsstuff}{%
  \contentsline{chapter}{\hyperlink{\getrefnumber{toc::shorttoc::anchor}}{\shortcontentsname}}{\pageref{toc::shorttoc}}{\getrefnumber{toc::shorttoc::anchor}}
}
\newcommand{\longcontentsstuff}{%
  \contentsline{chapter}{\hyperlink{\getrefnumber{toc::longtoc::anchor}}{\longcontentsname}}{\pageref{toc::longtoc}}{\getrefnumber{toc::longtoc::anchor}}
}
}
\newif\if@shorttoc
%
\renewcommand{\tableofcontents}{%
  \if@twocolumn
  \@restonecoltrue\onecolumn
  \else
  \@restonecolfalse
  \fi
  \chapter*{\contentsname
   \@mkboth{%
     \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}
 % Addition
 \if@shorttoc
 \protected@edef\@currentlabel{shorttoc}% Rather unimportant
 \edef\@currentlabelname{\shortcontentsname}% For \nameref
 \label{toc::shorttoc}% 
 % Now let us fix the hyperanchor for the short toc
 \edef\@currentlabelname{}%
 \protected@edef\@currentlabel{\@currentHref}\label{toc::shorttoc::anchor}
 \else
 \protected@edef\@currentlabel{longtoc}% Rather unimportant
 \edef\@currentlabelname{\longcontentsname}
 \label{toc::longtoc}%
 % Now let us fix the hyperanchor for the long toc
 \edef\@currentlabelname{}%
 \protected@edef\@currentlabel{\@currentHref}\label{toc::longtoc::anchor} 
 \fi
 % End of additions
 \@starttoc{toc}%
 \if@restonecol\twocolumn\fi
}
%
\newcommand{\longcontentsname}{Detailed Contents}
\newcommand{\shortcontentsname}{Short Contents}
%
\newcommand{\shorttableofcontents}[1][1]{%
  \begingroup
  \@shorttoctrue
  \setcounter{tocdepth}{#1}
  \let\shortcontentsstuff\relax
  \phantomsection
  \write\@auxout{\string\@writefile{toc}{\protect\longcontentsstuff}}
  \let\contentsname\shortcontentsname% Disabling the \shortcontentsstuff in toc
  \tableofcontents
  \endgroup
  \@shorttocfalse% Disable the short toc
}
\newcommand{\longtableofcontents}[1][3]{%
  \begingroup
  \setcounter{tocdepth}{#1}
  \phantomsection
  \let\longcontentsstuff\relax% Disabling the \longcontentsstuff in toc
  \write\@auxout{\string\@writefile{toc}{\protect\shortcontentsstuff}}
  \let\contentsname\longcontentsname
  \tableofcontents
  \endgroup
}
%
\makeatother

%% FOR THIS DEMO:
\usepackage{lipsum}

\begin{document}

\frontmatter
\shorttableofcontents\cleardoublepage
\longtableofcontents

\mainmatter
\chapter{One}
\lipsum[1]

\section{A section}
\subsection{First}
\lipsum[1-7]
% Many (sub-)sections to force multi-page TOC
\subsection{Second}
\subsection{Third}\subsection{Four}\subsection{Five}\subsection{Six}
\subsection{Seven}\subsection{Eight}\subsection{Nine}
\subsection{Ten}\subsection{Eleven}\subsection{Twelve}
\subsection{Thirteen}\subsection{Fourteen}\subsection{Fifteen}
\subsection{Sixteen}\subsection{Seventeen}\subsection{Eighteen}
\subsection{Nineteen}\subsection{Twenty}\subsection{Twenty-one}
\subsection{Twenty-two}\subsection{Twenty-three}\subsection{Twenty-four}
\subsection{Twenty-five}\subsection{Twenty-six}\subsection{Twenty-seven}
\section{B section}\section{C section}\section{D section}
\section{E section}\section{F section}\section{G section}\section{H section}
\section{I section}\section{J section}\section{K section}\section{L section}
\section{M section}\section{N section}\section{O section}\section{P section}
\section{Q section}\section{R section}\section{S section}\section{T section}
\section{U section}\section{V section}\section{W section}\section{X section}
\section{Y section}\section{Z section}\section{AA section}\section{BB section}
\section{CC section}\section{DD section}\section{EE section}\section{FF section}
\section{GG section}\section{HH section}\section{II section}\section{JJ section}
\section{KK section}\section{LL section}\section{MM section}\section{NN section}
\section{OO section}\section{PP section}\section{QQ section}\section{RR section}
\section{SS section}\section{TT section}\section{UU section}\section{VV section}
\section{WW section}\section{XX section}\section{YY section}\section{ZZ section}

\end{document}

Here's what I get now for pages in the detailed table of contents:

Detailed contents even-page header misssing longcontentsname

Detailed contents odd-page header misssing longcontentsname

References:

  • This question is a follow-up to https://tex.stackexchange.com/a/512636/13492 (which is working as desired for other frontmatter and mainmatter.
  • The code for the two tables of contents comes in part from https://tex.stackexchange.com/a/346433/13492. Thsy method, unfortunately, does not preserve the pagestyle for pages after chapter page in the Short Contents and the Long Contents. It does, however, produce the wanted entries of each of the two TOCs in, and only in, the other; and it makes the links on each of those entries point to the top of the corresponding TOC page.

Partial solution:

Using the etoc package allows a short and a long table of contents that do preserve the page style and chapter style -- without, however, seeming to allow each of the two TOCs to have an entry only for the other TOC.

See: memoir: Exclude entry of other TOC from each of two TOCs,

  • Again you are creating marks that are never executed. Toc marks does not use \createmark as the name of the toc is not something that changes and thus one can get aways with a simpler interface. Guess what the ` \createplainmark{toc}{both}{\contentsname}` lines does? – daleif Oct 18 at 14:49
  • What exactly is that insane piece of toc code suppose to do? What is your goal here? It is not particularly clear. Removing almost everything from that answer and using \newcommand{\shorttableofcontents}[1][1]{% \begingroup \setcounter{tocdepth}{#1} \let\contentsname\shortcontentsname \tableofcontents* \endgroup } and your definition for the name seems to work fine. That redefinition of \tableofcontents removes everything that memoir does so of course everything you try via memoir interfaces fail – daleif Oct 18 at 14:57
  • Among other things, that "insane" piece of toc code is to make an entry for the Detailed Contents to appear in the Short Contents (and, as I recall, vice versa). See the 2nd reference at the end of my post. – murray Oct 18 at 15:11
  • They they be in both or crossed aka short in long, and long in short? – daleif Oct 18 at 15:21
  • @daleif: Yes, an entry for each in the other. But no entry for Short Contents in the shorttableofcontents, and similarly for longtableofcontents. – murray Oct 18 at 15:25
4

Here is a better solution. This works with and without biblatex and hyperref. Special thanks to Ulrike Fischer for the trick in https://tex.stackexchange.com/a/513634/3929 which forms the basis for this solution.

Also added a slight change for memoir such that the anchor for the toc header now is above the header and not below. This will be included in the next memoir release.

I did not include your arguments for the long and short toc, I trust you can make those adjustments yourself.

\documentclass[a4paper]{memoir}

% this changes where the hyperref anchor for the TOC header is, will
% be in the next memoir release
\makeatletter
\renewcommand{\newlistof}[3]{%
  \@namedef{ext@#2}{#2}
  \@ifundefined{c@#2depth}{\newcounter{#2depth}}{}
  \setcounter{#2depth}{1}
  \@namedef{#2mark}{\markboth{#3}{#3}}
   \@namedef{#1}{\@ifstar{\@nameuse{mem@#1}{01}}{\@nameuse{mem@#1}{00}}}
  \@namedef{cft#2beforelisthook}{}%
  \@namedef{cft#2afterlisthook}{}%
  \@namedef{mem@#1}##1{%
    \ensureonecol
    \par
    \begingroup
      \phantomsection
      \if##1
        \ifmem@em@starred@listof\else
          \addcontentsline{toc}{chapter}{#3}
        \fi
      \fi
      \@nameuse{@#2maketitle}
      \parskip\cftparskip
      \@nameuse{cft#2beforelisthook}%
      \@starttoc{#2}%
      \@nameuse{cft#2afterlisthook}%
    \endgroup
    \restorefromonecol}
  \@namedef{@#2maketitle}{%
    \@nameuse{#2headstart}
   {\parindent\z@
    \parskip\z@
%%%%  \parskip\cftparskip
    \interlinepenalty\@M
    \@nameuse{print#2nonum}%
    \@nameuse{print#2title}{#3}%
    \@nameuse{#2mark}%
    \thispagestyle{chapter}%
    \@nameuse{after#2title}
   }
    \@afterheading}
  \@namedef{#2headstart}{\chapterheadstart}
  \@namedef{after#2title}{\afterchaptertitle}
  \@namedef{print#2nonum}{\printchapternonum}
  \@namedef{print#2title}##1{\printchaptertitle{##1}}
} % end \newlistof
\newlistof{tableofcontents}{toc}{\contentsname}

\makeatother

% just to show this woth with biblatex and hyperref
\usepackage{biblatex}
\usepackage[colorlinks]{hyperref}


\newif\ifSHORT
\newif\ifLONG

% credit for Ulrike Fischer for this idea, we need to have the
% conditionals defined **inside** the toc
\DeclareRobustCommand\activateif{%
\let\showShort\ifSHORT
\let\showLong\ifLONG
\let\stopShort\fi
\let\stopLong\fi
}

\usepackage{xpatch}


% next use patching to add a wrapper around the \addcontentsline
% that \tableofcontents generates. Since this is inside a group we
% don't having one patch messing up the other
\makeatletter
\newcommand\shortTOC{
  \begingroup
  \setcounter{tocdepth}{0}
  \def\contentsname{Short toc}
  \xpatchcmd{\mem@tableofcontents}%
  {\addcontentsline{toc}{chapter}{\contentsname}}{%
    \addtocontents{toc}{\protect\showShort}%
    \addcontentsline{toc}{chapter}{\contentsname}
    \addtocontents{toc}{\protect\stopShort}%
  }{\typeout{ok}}{\typeout{failed}}
  \LONGtrue
  \tableofcontents
  \endgroup
}

\newcommand\longTOC{
  \begingroup
  \setcounter{tocdepth}{3}
  \def\contentsname{Long toc}
  \xpatchcmd{\mem@tableofcontents}%
  {\addcontentsline{toc}{chapter}{\contentsname}}{%
    \addtocontents{toc}{\protect\showLong}%
    \addcontentsline{toc}{chapter}{\contentsname}
    \addtocontents{toc}{\protect\stopLong}%
  }{\typeout{ok}}{\typeout{failed}}
  \SHORTtrue
  \tableofcontents
  \endgroup
}

% automatically add the activation to the toc
\AtBeginDocument{
  \addtocontents{toc}{\activateif}
}

\makeatother

\usepackage{kantlipsum}
\begin{document}

\frontmatter

\shortTOC

\clearpage

\longTOC

\mainmatter

\newcommand\Sample{
\chapter{Chap}
\kant[1]
\section{Test}
\kant[1]
\subsection{Test}
\kant[1]
}

\Sample\Sample\Sample\Sample\Sample\Sample\Sample
\Sample\Sample\Sample\Sample\Sample\Sample\Sample
\Sample\Sample\Sample\Sample\Sample\Sample\Sample
\Sample\Sample\Sample\Sample\Sample\Sample\Sample


\end{document}

Old fragile solution removed

  • Yes, this does work. It's essential, though, for the links to go to the tops of the two TOCs pages, that the code come after hyperref is loaded. (It's shown that way in the source, but I want to make that explicit here. – murray Oct 22 at 17:08
  • This method causes an error if I also load biblatex! See: tex.stackexchange.com/questions/513429/…. – murray Oct 23 at 22:15
  • @murray see updated version – daleif Oct 25 at 14:21
  • I think this completely solves the problem. I'm about to try it with my actual book-length document to make sure there's nothing I'm overlooking. – murray Oct 26 at 14:24
  • a snag - I have a sectioning command \subsec which is an unnumbered version of \subsection, and unfortunately it is appearing in the long (detailed) toc, too. I'll post a new question on this. – murray Oct 27 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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