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}
  • 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 '16 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 '16 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. – user36296 Sep 22 '16 at 17:49
  • about your question itself I can not reply until later tonight (European time) – user4686 Sep 22 '16 at 17:55
  • @jfbu Meanwhile many thanks for considering to look into it! Take all the time you need, no hurry. – user36296 Sep 22 '16 at 17:58
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}
  • 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 '16 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. – user36296 Sep 22 '16 at 21:07
  • That's fantastic! – user36296 Sep 23 '16 at 8:25

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.