这是一个后续问题https://tex.stackexchange.com/a/307507/36296。只要每个章节标题都适合一行,链接答案就可以正常工作。对于两行条目,蓝色条太长(用红色圆圈标记)。
要求(已实现单行章节):
蓝线应延伸到最后一行的基线(非降序字符的下边缘)
如果图像大于条目(没有部分的案例),则线应该延伸到图像的下边缘。
\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}
答案1
开始吧。一个获取多行章节标题行数并采取适当措施的技巧。
\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}
根据评论进行编辑
\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}