1

This is a follow up question to https://tex.stackexchange.com/a/307507/36296. The linked answer works perfectly fine, as long as each chapter title fit into a single line. For two line entries, the blue bar is too long (marked by the red circle).

Requirements (already fulfilled for single line chapters):

  • The blue line should reach until the baseline of the last line (the lower edge of non descending characters)

  • In case the image is larger than the entry (the cases without sections), the line should reach until the lower edge of the image.

enter image description here

\documentclass[a4paper]{book}

\usepackage{xcolor}
\usepackage{geometry}
\usepackage{framed}
\usepackage{etoc}\etocglobaldefs
\usepackage{mwe}
\usepackage[linktoc=all, colorlinks=true, linkcolor=black]{hyperref}
\colorlet{tocleftbarcolour}{blue}

\newlength{\tocmargin}
\setlength{\tocmargin}{1cm}

\newlength{\tocleftbarsep}
\setlength{\tocleftbarsep}{2pt}

\newlength{\tocleftbarwidth}
\setlength{\tocleftbarwidth}{2pt}
\newlength{\tocleftbardepth}
\setlength{\tocleftbardepth}{0pt}

\newenvironment{tocleftbar}
    {\def\FrameCommand {%
            \hspace{\dimexpr\tocmargin\relax}%
            \textcolor{tocleftbarcolour}
                  {\vrule width \tocleftbarwidth depth \tocleftbardepth\relax}%
            \hspace{\tocleftbarsep}%
            \hspace{-\dimexpr\tocmargin\relax}%
        }%
        \MakeFramed {\leftskip\tocmargin\rightskip\tocmargin
                     \FrameRestore}%
    }
    {\endMakeFramed}

\newif\ifintocleftbar
\newbox\tempdecobox

\newcommand*{\EmergencyEndLeftBarEnv}{%
    % previous chapter had no section
      \LARGE
      \vskip-\baselineskip
      \vskip-\lineskip % assume height of images > baseline
      \vskip-\parskip
      \vskip-\tocleftbardepth % for fun
      \noindent
      \vphantom{\usebox{\tempdecobox}}%
            % we close a group here hence \etocname, etc.. get lost
            % immediately thereafter; this is preemptively counteracted
            % by the \etocglobaldefs issued after loading etoc
    \end{tocleftbar}%
}

\etocsetstyle{chapter}
   {\nobreak\etocskipfirstprefix}% don't break immediately after Part
   {\pagebreak[2]}% but allow break after section or subsection
   {\ifintocleftbar\EmergencyEndLeftBarEnv\fi
    \begin{tocleftbar}
     \LARGE
     \intocleftbartrue
         \sbox\tempdecobox{\sectocdeco}%
         \edef\heightoflastbox{\the\ht\tempdecobox}%
     \noindent\makebox[0pt][r]
       {\smash
         {\raisebox{\dimexpr-\height+\ht\strutbox\relax}{\usebox{\tempdecobox}}}%
        \hspace{\dimexpr2\tocleftbarsep+\tocleftbarwidth\relax}}%
     \parbox[t]{\dimexpr\hsize-2\tocmargin\relax}
        {\strut\etocname\strut
         \hspace{0.5em}\dotfill\nobreak\hspace{0.5em}\strut\etocpage}%
      \par
      \normalsize
      \leftskip\dimexpr\leftskip+\tocmargin\relax
   }
   {\ifintocleftbar\EmergencyEndLeftBarEnv\fi}

\etocsetstyle {section}
   {\nopagebreak[3]\vspace{1pt}\etocskipfirstprefix}
   {\vspace {1pt plus .2pt minus .2pt}}
   {\noindent\llap{\makebox[\tocmargin][l]{\etocnumber}}%
    \etocname
    \nobreak\hspace{0.5em}{\itshape\etocpage}\par }
   {\end{tocleftbar}}

\newcommand*{\setsectocdeco}[1]% need to make a global def here
% because the \end{tocleftbar} will close a group
  {\addtocontents{toc}{\gdef\string\sectocdeco{\protect#1}}}   



\begin{document}

\tableofcontents

\setsectocdeco{\includegraphics[height=1.5cm]{example-image-c}}
\chapter{This is the first chapter. No sections here.}

\chapter{Another chapter}
\section{foo}
bar
\section{foo}
bar
\section{foo}
bar
\section{foo}
bar

\chapter{And this one is the last chapter but with a very long title}

\end{document}
5
  • there is a side problem with your mwe, the \setsectocdeco expects two arguments and receives one. It gobbles chapter. Actually it was originally [1] in its definition.
    – user4686
    Sep 22, 2016 at 17:46
  • hmm the [1] presumably became [2] it happened to me once here on tex.sx I don't recall the reason.
    – user4686
    Sep 22, 2016 at 17:47
  • @jfbu Thanks for noticing! I think I know how this happened. I deleted an image and inserted a new one and TeX.SE automatically changed all the link numbers. But it is rather unfortunate, that this also happens in code. Sep 22, 2016 at 17:49
  • about your question itself I can not reply until later tonight (European time)
    – user4686
    Sep 22, 2016 at 17:55
  • @jfbu Meanwhile many thanks for considering to look into it! Take all the time you need, no hurry. Sep 22, 2016 at 17:58

1 Answer 1

1

Here we go. A hack to get the number of lines of multi-line chapter heading and take appropriate action.

enter image description here

\documentclass[a4paper]{book}

\usepackage{xcolor}
\usepackage{geometry}
\usepackage{framed}
\usepackage{etoc}\etocglobaldefs
\usepackage{mwe}
\usepackage[linktoc=all, colorlinks=true, linkcolor=black]{hyperref}
\colorlet{tocleftbarcolour}{blue}

\newlength{\tocmargin}
\setlength{\tocmargin}{1cm}

\newlength{\tocleftbarsep}
\setlength{\tocleftbarsep}{2pt}

\newlength{\tocleftbarwidth}
\setlength{\tocleftbarwidth}{2pt}
\newlength{\tocleftbardepth}
\setlength{\tocleftbardepth}{0pt}

\newenvironment{tocleftbar}
    {\def\FrameCommand {%
            \hspace{\dimexpr\tocmargin\relax}%
            \textcolor{tocleftbarcolour}
                  {\vrule width \tocleftbarwidth depth \tocleftbardepth\relax}%
            \hspace{\tocleftbarsep}%
            \hspace{-\dimexpr\tocmargin\relax}%
        }%
        \MakeFramed {\leftskip\tocmargin\rightskip\tocmargin
                     \FrameRestore}%
    }
    {\endMakeFramed}

\newif\ifintocleftbar
\newbox\tempdecobox

\newcommand*{\EmergencyEndLeftBarEnv}{%
    % previous chapter had no section
      \LARGE
\ifdim\dimexpr\NbOfLines\baselineskip<\ht\tempdecobox
      \vskip-\NbOfLines\baselineskip
      \vskip-\lineskip % assume height of images > baseline
      \vskip-\parskip
      \vskip-\tocleftbardepth % for fun
%\noindent\vphantom{\usebox{\tempdecobox}}%
      \vskip\ht\tempdecobox
\fi
            % we close a group here hence \etocname, etc.. get lost
            % immediately thereafter; this is preemptively counteracted
            % by the \etocglobaldefs issued after loading etoc
    \end{tocleftbar}%
}


\etocsetstyle{chapter}
   {\nobreak\etocskipfirstprefix}% don't break immediately after Part
   {\pagebreak[2]}% but allow break after section or subsection
   {\ifintocleftbar\EmergencyEndLeftBarEnv\fi
    \begin{tocleftbar}
     \LARGE
     \intocleftbartrue
         \sbox\tempdecobox{\sectocdeco}%
     \noindent\makebox[0pt][r]
       {\smash{\raisebox{\dimexpr-\height+\ht\strutbox\relax}{\usebox{\tempdecobox}}}%
       \hspace{\dimexpr2\tocleftbarsep+\tocleftbarwidth\relax}}%
       \parbox[t]{\dimexpr\hsize-2\tocmargin\relax}
          {\strut\etocname\strut
           \hspace{0.5em}\dotfill\nobreak\hspace{0.5em}\strut\etocpage
           \par\xdef\NbOfLines{\the\prevgraf}}%
      \par
      \normalsize
      \leftskip\dimexpr\leftskip+\tocmargin\relax
   }
   {\ifintocleftbar\EmergencyEndLeftBarEnv\fi}

\etocsetstyle {section}
   {\nopagebreak[3]\vspace{1pt}\etocskipfirstprefix}
   {\vspace {1pt plus .2pt minus .2pt}}
   {\noindent\llap{\makebox[\tocmargin][l]{\etocnumber}}%
    \etocname
    \nobreak\hspace{0.5em}{\itshape\etocpage}\par }
   {\end{tocleftbar}}

\newcommand*{\setsectocdeco}[1]% need to make a global def here
% because the \end{tocleftbar} will close a group
  {\addtocontents{toc}{\gdef\string\sectocdeco{\protect#1}}}   

\renewcommand{\etocaftertochook}{\thispagestyle{empty}}

\begin{document}

\tableofcontents

\setsectocdeco{\includegraphics[height=1.5cm]{example-image-c}}

\chapter{This is the first chapter. No sections here.}

%\section{A}

A

\chapter{Another chapter}
\section{foo}
bar
\section{foo}
bar
\section{foo}
bar
\section{foo}
bar

\chapter{And this one is almost the last chapter but with a very long title
  And this one is almost the last chapter but with a very long title 
And this one is almost the last chapter but with a very long title }

\chapter{And this one is almost the last chapter but with a very long title}

\chapter{And this one is the last chapter but with a very long title and some sections}

\section{foo}
bar

\end{document}

edit as per comment

enter image description here

\documentclass[a4paper]{book}

\usepackage{xcolor}
\usepackage{geometry}
\usepackage{framed}
\usepackage{etoc}\etocglobaldefs
\usepackage{mwe}
\usepackage[linktoc=all, colorlinks=true, linkcolor=black]{hyperref}
\colorlet{tocleftbarcolour}{blue}

\newlength{\tocmargin}
\setlength{\tocmargin}{1cm}

\newlength{\tocleftbarsep}
\setlength{\tocleftbarsep}{2pt}

\newlength{\tocleftbarwidth}
\setlength{\tocleftbarwidth}{2pt}
\newlength{\tocleftbardepth}
\setlength{\tocleftbardepth}{0pt}

\newenvironment{tocleftbar}
    {\def\FrameCommand {%
            \hspace{\dimexpr\tocmargin\relax}%
            \textcolor{tocleftbarcolour}
                  {\vrule width \tocleftbarwidth depth \tocleftbardepth\relax}%
            \hspace{\tocleftbarsep}%
            \hspace{-\dimexpr\tocmargin\relax}%
        }%
        \MakeFramed {\leftskip\tocmargin\rightskip\tocmargin
                     \FrameRestore}%
    }
    {\endMakeFramed}

\newif\ifintocleftbar
\newbox\tempdecobox

% we more or less assume table of contents typeset while \parskip=0pt

\newcommand*{\EmergencyEndLeftBarEnv}{%
    % previous chapter had no section
      \LARGE
\ifdim\dimexpr\NbOfLines\baselineskip-\dp\strutbox<\ht\tempdecobox
      \vskip-\NbOfLines\baselineskip
      \vskip-\tocleftbardepth % for fun
      \vskip\ht\tempdecobox\prevdepth0pt\relax
    \end{tocleftbar}
\else 
    \vskip-\dp\strutbox\end{tocleftbar}
\fi
            % we close a group here hence \etocname, etc.. get lost
            % immediately thereafter; this is preemptively counteracted
            % by the \etocglobaldefs issued after loading etoc
}


\etocsetstyle{chapter}
   {\nobreak\etocskipfirstprefix}% don't break immediately after Part
   {\pagebreak[2]}% but allow break after section or subsection
   {\ifintocleftbar\EmergencyEndLeftBarEnv\fi
    \begin{tocleftbar}
     \LARGE
     \intocleftbartrue
         \sbox\tempdecobox{\sectocdeco}%
     \noindent\makebox[0pt][r]
       {\smash{\raisebox{\dimexpr-\height+\ht\strutbox\relax}{\usebox{\tempdecobox}}}%
       \hspace{\dimexpr2\tocleftbarsep+\tocleftbarwidth\relax}}%
       \parbox[t]{\dimexpr\hsize-2\tocmargin\relax}
          {\strut\etocname\strut
           \hspace{0.5em}\dotfill\nobreak\hspace{0.5em}\strut\etocpage
           \par\xdef\NbOfLines{\the\prevgraf}}%
      \par\prevdepth\dp\strutbox
      \normalsize
      \leftskip\dimexpr\leftskip+\tocmargin\relax
   }
   {\ifintocleftbar\EmergencyEndLeftBarEnv\fi}

\etocsetstyle {section}
   {\nopagebreak[3]\vspace{1pt}\etocskipfirstprefix}
   {\vspace {1pt plus .2pt minus .2pt}}
   {\noindent\llap{\makebox[\tocmargin][l]{\etocnumber}}%
    \etocname
    \nobreak\hspace{0.5em}{\itshape\etocpage}\par }
   {\xdef\PrevDepth{\the\prevdepth}\vskip-\PrevDepth\relax
    \end{tocleftbar}\prevdepth\PrevDepth\relax}

\newcommand*{\setsectocdeco}[1]% need to make a global def here
% because the \end{tocleftbar} will close a group
  {\addtocontents{toc}{\gdef\string\sectocdeco{\protect#1}}}   

\renewcommand{\etocaftertochook}{\thispagestyle{empty}}

\begin{document}

\tableofcontents

\setsectocdeco{\includegraphics[height=1.5cm]{example-image-c}}

\chapter{This is the first chapter. No sections here.}

%\section{A}

A

\chapter{Another chapter}
\section{foo}
bar
\section{foo}
bar
\section{foo}
bar
\section{foo}
bar

\chapter{And this one is almost the last chapter but with a very long title
  And this one is almost the last chapter but with a very long title 
And this one is almost the last chapter but with a very long title }

\chapter{And this one is almost the last chapter but with a very long title}

\chapter{And this one is the last chapter but with a very long title and some sections}

\section{gggppp}
bar
\section{gggppp}
bar

\end{document}
3
  • the \vskip-\lineskip in \EmergencyEndLeftBarEnv I don't understand it anymore and I think it should be removed. Not doing it as I would need to update image.
    – user4686
    Sep 22, 2016 at 20:46
  • Thank you so much for your answer! There is just a small detail between it and being perfect: Would it be possible to end with the baseline? At the entry with page no. 7 the lines seems to include the descending parts of the letters. Sep 22, 2016 at 21:07
  • That's fantastic! Sep 23, 2016 at 8:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .