3

This works:

Based on the answer https://tex.stackexchange.com/a/14964/36296, I put together a MWE which might look ugly, but works fine. At any place during the document I can change the picture to be inserted for next section with my command \setsectocdeco.

\documentclass{book}

\usepackage{graphicx}
\usepackage{etoc}
\usepackage{mwe}

\etocsetstyle{chapter}
{}
{}
{%
    \sectocdeco%
    \etocname%
    \par%
}
{}

\DeclareRobustCommand{\sectocdeco}{}

\newcommand*{\setsectocdeco}[1]{%
    \addtocontents{toc}{\protect\renewcommand{\sectocdeco}{\protect #1}}%
}   

\setsectocdeco{\includegraphics[height=1cm]{example-image-a}}

\begin{document}

    \tableofcontents

    \chapter{Chapter 1}

    \setsectocdeco{\includegraphics[height=1cm]{example-image-b}}
    \chapter{Chapter 2}

\end{document}

enter image description here


This does not:

However if I put these commands into my real ToC (which is based on https://tex.stackexchange.com/a/163707/36296), the image will not be updated:

\documentclass{book}

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

\newlength{\tocmargin}

\newenvironment{tocleftbar}
    {\def\FrameCommand {%
            \hspace{\dimexpr\tocmargin+40pt\relax}%
            {\color{toccolour}\vrule width 2pt depth 6pt}\hspace{6pt}%
            \hspace{-\tocmargin}%
        }%
        \MakeFramed {\leftskip\tocmargin\rightskip\tocmargin\FrameRestore}%
    }
    {\endMakeFramed}

\newif\ifintocleftbar

\etocsetstyle{chapter}
   {\nobreak\etocskipfirstprefix}% don't break immediately after Part
   {\pagebreak[2]}% but allow break after section or subsection
   {\global\let\ETOCthepage\etocthepage%
    \global\let\ETOCthename\etocthename%
    \global\let\ETOCthenumber\etocthenumber%
    \global\let\ETOCthelink\etocthelink%
                \ifintocleftbar\end{tocleftbar}\fi%
                \kern\baselineskip%
                \begin{tocleftbar}
                    \intocleftbartrue
                    \makebox[0pt][r]{%
                        \null\hfill%
                        \ETOCthelink{%
                            \raisebox{-1.5cm}{%
                                \sectocdeco%
                                \hspace*{18pt}%
                            }}}%
                            \parbox[t]{\dimexpr\hsize-2\tocmargin\relax}{%
                                \LARGE\par%
                                \ETOCthelink{\ETOCthename\hspace{0.5em}\dotfill\hspace{0.5em} \nobreak{\etocpage}}%
                                \rule[-\baselineskip]{0pt}{0pt}%
                            }%
                            \par\normalsize\leftskip\dimexpr\leftskip+3em\relax
                        }
                        {\ifintocleftbar\end{tocleftbar}\fi
    }

\DeclareRobustCommand{\sectocdeco}{}

\newcommand*{\setsectocdeco}[1]{%
    \addtocontents{toc}{\protect\renewcommand{\sectocdeco}{\protect#1}}%
}   

\setsectocdeco{\includegraphics[height=1cm]{example-image-a}}

\begin{document}

    \tableofcontents

    \chapter{Chapter 1}

    \setsectocdeco{\includegraphics[height=1cm]{example-image-b}}
    \chapter{Chapter 2}

\end{document}

enter image description here


So long story short: why is the image in the second example not changed?


Use case:

The solutions do not need to be based on the above code. I am looking for something to convert

\documentclass{book}

\usepackage{graphicx}
\usepackage{titlesec}

\titleformat{\chapter}[display]%
{}%
{\secdeco}%
{1em}%
{}%
[]  

\titleformat{name=\chapter,numberless}[display]
{}%
{\secdeco}%
{1em}%
{}%
[]

\newcommand{\secdeco}{\includegraphics[height=1cm]{example-image-a}}

\begin{document}

    \tableofcontents

    \addtocounter{page}{6}

    \chapter{Name of First Chapter}
    \section{Another test section}
    \section{Another test section}
    \subsection{A test subsection}
    \section{Another test section}
    \subsection{A test subsection}
    \subsection{A test subsection with a long title spanning more than one line in the table of contents}

    \renewcommand{\secdeco}{\includegraphics[height=1cm, width=0.5cm]{example-image-b}}
    \chapter{Name of Second Chapter}
    \section{A test section with a long title spanning more than one line in the table of contents}
    \subsection{A test subsection}
    \subsection{Another test subsection}
    \section{A test section}
    \section{Another test section}
    \subsection{A test subsection}
    \section{Another test section}
    \subsection{A test subsection}

    \renewcommand{\secdeco}{\includegraphics[height=1cm]{example-image-a}}
    \chapter{Chapter without Sections}

    \chapter*{Unnumbered Chapter}
    \addcontentsline{toc}{chapter}{Unnumbered Chapter}

\end{document}

into a ToC which should look like this:

enter image description here

The main goals are:

  • For each chapter there should be a rule which is as long as the ToC of this chapter.
  • In case the the height of the image is larger than the space of the ToC of an chapter, the rule should be as long as the image (only happens for chapters without sections)
  • All the images have the same height, but may be of different width. It would be nice if the would be right aligned.
  • the solution should be compatible with \usepackage{titlesec}

(I apologize, this now sounds pretty much like "do it for me", but I thought this would give more opportunities for possible solutions instead of trying to fix the code above)

5
+100

Here you go.

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

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

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

\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
         \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=2cm]{example-image-a}}
\chapter{This is the first chapter. No sections here.}

\setsectocdeco{\includegraphics[height=1cm]{example-image-b}}
\chapter{Another chapter}
\section{foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
  foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
  foo foo 
}
bar
\section{foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
  foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
  foo foo 
}
bar
\section{foo}
bar
\section{foo}
bar
\section{foo}
bar

\setsectocdeco{\includegraphics[height=2cm, width=1cm]{example-image-c}}
\chapter{The third chapter}
\section{foo}
bar
\section{foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
  foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
  foo foo 
}
bar
\section{foo}
bar

\setsectocdeco{\includegraphics[height=1.5cm]{example-image-16x10}}
\chapter{And this one is the last chapter}

\end{document}

enter image description here

  • things like \dimexpr\leftskip+\tocmargin\relax is because \tocmargin was a macro at some point but I used a dimension in the end, thus could have used \advance. Similarly some \relax are explained by similar considerations that the things were macros at some point. – user4686 May 2 '16 at 18:52
  • Thank you so much for solving this problem! Your solution works incredible well! One minor question: At the moment the rule extends the text a few millimetre at the bottom. Is there a way to end it at the baseline of the last line of text? – user36296 May 2 '16 at 19:55
  • you can replace \setlength{\tocleftbardepth}{6pt} by \setlength{\tocleftbardepth}{0pt}. The left bar will extend to the depth of characters on the last line. For example a p will make it extends a bit more than the baseline. You can also add a \strut after \etocname in the section style and do \setlength{\tocleftbardepth}{-\dp\strutbox} which should use the normal size, as employed by the section style. Then it will extend to the baseline exactly in all cases. – user4686 May 2 '16 at 21:01
  • In case you are interested, I asked a follow up question: tex.stackexchange.com/questions/330861/… – user36296 Sep 22 '16 at 17:37
2

This is not a solution, but a step in that direction...too lengthy to put in a comment. Two things had to change to recover the correct images.

1) In the \etocsetstyle macro, both instances of \end{tocleftbar} had to be changed to \endtocleftbar and the one instance of \begin{tocleftbar} had to be changed to \tocleftbar.

2) I had to turn off the MakeFramed environment with the redefinitions

\def\MakeFramed#1{#1}
\def\endMakeFramed{}

These changes cause the proper figure decorations to be recovered. The conclusion at this point is that \MakeFramed ... \endMakeFramed environment is where the current problem is. I don't at this time have enough experience with that package to as yet suggest a remedy.

\documentclass{book}

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

\newlength{\tocmargin}

\newenvironment{tocleftbar}
    {\def\FrameCommand {%
            \hspace{\dimexpr\tocmargin+40pt\relax}%
            {\color{toccolour}\vrule width 2pt depth 6pt}\hspace{6pt}%
            \hspace{-\tocmargin}%
        }%
        \MakeFramed {\leftskip\tocmargin\rightskip\tocmargin\FrameRestore}%
    }
    {\endMakeFramed}
\def\MakeFramed#1{#1}
\def\endMakeFramed{}

\newif\ifintocleftbar

\etocsetstyle{chapter}
   {\nobreak\etocskipfirstprefix}% don't break immediately after Part
   {\pagebreak[2]}% but allow break after section or subsection
   {\global\let\ETOCthepage\etocthepage%
    \global\let\ETOCthename\etocthename%
    \global\let\ETOCthenumber\etocthenumber%
    \global\let\ETOCthelink\etocthelink%
                \ifintocleftbar\endtocleftbar\fi%
                \kern\baselineskip%
                \tocleftbar
                    \intocleftbartrue
                    \makebox[0pt][r]{%
                        \null\hfill%
                        \ETOCthelink{%
                            \raisebox{-1.5cm}{%
                                \sectocdeco%
                                \hspace*{18pt}%
                            }}}%
                            \parbox[t]{\dimexpr\hsize-2\tocmargin\relax}{%
                                \LARGE\par%
                                \ETOCthelink{\ETOCthename\hspace{0.5em}\dotfill\hspace{0.5em} \nobreak{\etocpage}}%
                                \rule[-\baselineskip]{0pt}{0pt}%
                            }%
                            \par\normalsize\leftskip\dimexpr\leftskip+3em\relax
                        }
                        {\ifintocleftbar\endtocleftbar\fi
    }

\DeclareRobustCommand{\sectocdeco}{}

\newcommand*{\setsectocdeco}[1]{%
    \addtocontents{toc}{\protect\renewcommand{\sectocdeco}{\protect#1}}%
}   

\setsectocdeco{\includegraphics[height=1cm]{example-image-a}}

\begin{document}

    \tableofcontents

    \chapter{Chapter 1}

    \setsectocdeco{\includegraphics[height=1cm]{example-image-b}}
    \chapter{Chapter 2}

    \setsectocdeco{\includegraphics[height=1cm]{example-image-c}}
    \chapter{Chapter 3}

\end{document}

enter image description here

  • Thanks for taking your time to look into this problem! As I choose this style mainly because of the rule, I will wait to see if other answers will appear. – user36296 Apr 29 '16 at 9:44
  • @samcarter I might be able to get a rule without the environment, if you can tell me a bit about how the rule is supposed to be. I'm guessing that the rule should grow longer if the chapter heading is multiline? From what I could tell, the rules of adjacent chapters did not connect...is that right? – Steven B. Segletes Apr 29 '16 at 10:38
  • 1
    That would be very helpful! The rules should be similar to the ones in tex.stackexchange.com/a/163707/36296, the two main points are that they should be as long as the all the (sub-)sections from the chapter. But if the height of the image is greater than the space required by the sections, the rule should be of the same height as the image (all images have the same height). Do you think this is worth a new question? I can produce a sketch of what the result should actually look like and add it either to this question or to a new one. – user36296 Apr 29 '16 at 11:31
  • I updated this question with a sketch of what I am actually trying to achieve. – user36296 Apr 29 '16 at 12:49

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.