0

How does one customize the layout of the table of contents? I don't mean customize the style of the nodes of the TOC (chapter name, page number, etc) as here. Rather, I want to add text boxes with arbitrary text (not taken from the contents of the book) to the side of it. Something like this arrangement (the colours are merely for illustration of the structure I'm after):Ideal TOC

Here's sample code:

\documentclass{book}
\usepackage{lipsum,titletoc}
\begin{document}

% TOC CONTENT
%% Right column:
\tableofcontents

%%  Left column
%%% Box 1:
\textbf{Authors:}
\begin{itemize}
    \item[] Barry
    \item[] Betty
    \item[] Berty
\end{itemize}
%%% Box 2:
This is a rather good cookbook, I'm sure you'll agree.

% ACTUAL CONTENT
\chapter{Vegetables}
\lipsum
\chapter{Fruit}
\lipsum
\chapter{Seaweed}
\lipsum

\end{document}
  • 1
    Welcome to TeX.SX! You can probably do this with tcbraster (from tcolorbox), but please show what you've tried so far. – TeXnician Jan 6 '18 at 18:39
  • 1
    See also paracol and flowfram. – John Kormylo Jan 6 '18 at 19:44
  • @TeXnician: tcbraster is a good idea, however, as soon as there's a long ToC, it won't break any longer within the raster. – user31729 Jan 6 '18 at 19:55
  • @ChristianHupfer As this question is really unclear and there's only a picture of one page, it doesn't matter. If the OP would like to have a specific behavior, we need more information. – TeXnician Jan 6 '18 at 20:10
  • @TeXnician: My comment implied that... ;-) – user31729 Jan 6 '18 at 20:10
1

Here is a possible way with tcolorbox, using TikZ nodes in underlays.

The outer box wraps around the \tableofcontents, being shifted to the right side, then two 'side' panels are drawn, each is a separate node. The dimensions of the side panels can be controlled with sidepanel xshift and bottom sidepanel yshift etc.

One underlay is for the unbroken box, the other one appears only for the first box if the box is broken.

If there's no page break for the ToC, tcbraster is easier, of course.

\documentclass{book}
\usepackage{lipsum}%,titletoc}

\usepackage[margin=2cm]{geometry}

\usepackage[most]{tcolorbox}
\usetikzlibrary{calc}

\makeatletter
\tcbset{%
  sidepanel xshift/.store in=\tocbox@sidepanel@xshift,
  sidepanel xshift=5cm,
  sidepanel width/.store in=\tocbox@sidepanel@width,
  sidepanel width=4cm,
  bottomsidepanel yshift/.store in=\tocbox@bottomsidepanel@yshift,
  bottomsidepanel yshift=1cm,
  tocback/.colorlet=tcbcol@tocback,
  tocback=gray!40!white,
  topsidepanel/.style={enhanced,sharp corners, frame hidden, colback=tcbcol@tocback},
  bottomsidepanel/.style={topsidepanel},
}




\DeclareTotalTColorBox{\tableofcontentsbox}{+O{}+m+m}{
  enhanced,
  breakable,
  colupper=white,
  left skip=\tocbox@sidepanel@xshift,
  sharp corners,
  colback=tcbcol@tocback,
  frame hidden,
  remember,
  underlay={%
    \coordinate (topsidepanel) at ($(frame.north west)+(-\tocbox@sidepanel@xshift,0pt)$);
    \node[below right,inner sep=0pt] (topsidepanelnode) at (topsidepanel) {
      \begin{tcolorbox}[topsidepanel,width=\tocbox@sidepanel@width,colupper=white,
        overlay={\node[inner sep=0pt, outer sep=0pt] (topsidepanelbottom) at (frame.south west) {};},#1]
        #2%
      \end{tcolorbox}};
    \node[below right,inner sep=0pt] (bottomsidepanelnode) at ($(topsidepanelbottom) + (0pt,-\tocbox@bottomsidepanel@yshift)$) {
      \begin{tcolorbox}[bottomsidepanel,width=\tocbox@sidepanel@width,colupper=white,#1]
        #3% 
        \end{tcolorbox}};
      },
    underlay first={%
\coordinate (topsidepanel) at ($(frame.north west)+(-\tocbox@sidepanel@xshift,0pt)$);
\node[below right,inner sep=0pt] (topsidepanelnode) at (topsidepanel) {
  \begin{tcolorbox}[topsidepanel,width=\tocbox@sidepanel@width,colupper=white,
    overlay={\node[inner sep=0pt, outer sep=0pt] (topsidepanelbottom) at (frame.south west) {};},#1]
    #2%
  \end{tcolorbox}};
\node[below right,inner sep=0pt] (bottomsidepanelnode) at ($(topsidepanelbottom) + (0pt,-\tocbox@bottomsidepanel@yshift)$) {
  \begin{tcolorbox}[bottomsidepanel,width=\tocbox@sidepanel@width,colupper=white,#1]
    #3% 
    \end{tcolorbox}};
  },
  #1}{%
  \tableofcontents
}
\makeatother

\begin{document}

% TOC CONTENT
%% Right column:
\tableofcontentsbox[fontupper=\large,bottomsidepanel yshift=0.5cm]{\textbf{Authors:}
\begin{itemize}
    \item[] Barry
    \item[] Betty
    \item[] Berty
\end{itemize}
}{
  This is a rather good cookbook, I'm sure you'll agree.%
}


% ACTUAL CONTENT
\chapter{Vegetables}
\lipsum
\chapter{Fruit}
\lipsum
\chapter{Seaweed}
\lipsum

\end{document}

enter image description here

  • Incredible, thanks for this! For portability I wonder why it compiles in LaTeX and LuaLaTeX but not XeLaTeX, where you get the error Package listingsutf8 Warning: Package loading is aborted because of missing \pdf@unescapehex.? I ask because I've been working on a XeLaTeX project but I don't think it'll be a problem to switch to LuaLaTeX to get this working. – kokoro Jan 9 '18 at 12:04
  • @kokoro: Replace \usepackage[most]{tcolorbox} with \usepackage[skins,xparse,breakable]{tcolorbox} – user31729 Jan 9 '18 at 17:44
  • In the end I took a different approach, as I found that your approach lead to the boxes jumping when they became too full up, and I found it difficult to grok all of your latex wizadry! So I went with the approach below. – kokoro Nov 26 '18 at 19:41
0

In the end I deduced that the most stable way of customising the TOC was to place the other boxes as a background to the content of the TOC, so that it wouldn't be effected when it changed size.

First I created a new geometry for the TOC list, in order to push the toc to the right.

\newcommand{\tocgeometry}{
  \newgeometry{
    onecolumn,
    includefoot,
    top=3.2cm,
    width=17.5cm,
    height=27.2cm
  }
}

Then I created a background template using \AddToShipoutPictureFG, taking three options: content (#3), horizontal distance from bottom-left of page (#1) and vertical distance from bottom-left of page (#2). Starred version specifies to place on this page only, not on every page.

\newcommand{\placethis}[3]{
  \AddToShipoutPictureFG*{\put(#1,#2){#3}}}

I copied the \tableofcontents function from article.cls, so that I could customize it in my preamble.

\makeatletter
\renewcommand\tableofcontents{
   % Parbox allows for multi-line text. 
   \placethis{125}{450}{\parbox{15cm}{
        Authors:
        \begin{itemize}
          \item Barry
          \item Betty
          \item Berty
        \end{itemize}}}
    %
    \placethis{75}{257}{\parbox{15cm}{
        This is a rather good cookbook, I'm sure you'll agree.
        }
    \@starttoc{toc}
    }
\makeatother

This also allowed me to place images in place of the \parbox, simply with \includegraphics.

This allowed me to include the TOC in the body of my book like so:

\tocgeometry
\tableofcontents*
\addtocontents{toc}{\protect\thispagestyle{empty}}
\thispagestyle{empty}
\restoregeometry

That's all it took to customize my TOC :)

  • 1
    Your approach will bite you in the very end one day, but it's your decision. – user31729 Nov 26 '18 at 20:40

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.