[Tex/LaTex] alignment problems for \part and \chapter in table of contents created with titletoc

horizontal alignmentpage-numberingspacingtable of contentstitletoc

In my table of contents, created using titletoc, there are some alignment problems that I am unable to debug.

Problem 1:
My code allows me to control the label width for chapters and sections, but not for parts: there the label width seems to depend on the letter used as part label (I need to use customized part labels, involving letters that correlate with the part titles), with W producing a much wider label width than I. This results in part titles that are not aligned with the chapter titles.

Problem 2:
The page numbers on the right are not well aligned — this is glaringly clear for part page numbers larger than 100, but actually also true for boldface chapter numbers versus unboldface section numbers. I need to use \large boldface fonts for part, and normalsize boldface fonts for chapters.

Help would be much appreciated! I have spent hours customizing the toc using the titletoc package, hence would prefer a solution using that package rather than switching to something else.

\documentclass[12pt,a4paper,openany]{book} 
\renewcommand{\familydefault}{cmss} 
\usepackage[pagestyles, outermarks]{titlesec}
\usepackage{titletoc}

\titlecontents{part}[0mm]  
  {\vspace{12pt}\large\normalfont\bfseries}  
  {\contentslabel{10mm}}{}            
  {\titlerule*[.75em]\bfseries{\contentspage}}  

\titlecontents{chapter}[9.3mm]     
  {\vspace{4pt}\normalsize\normalfont\bfseries}  
  {\contentslabel{9.3mm}}{}   
  {\titlerule*[.75em]\bfseries{\contentspage}}  

\titlecontents{section}[21.6mm]   
  {\vspace{0pt}\normalsize\normalfont} 
  {\contentslabel[\thecontentslabel]{12.3mm}}{}
  {\titlerule*[.75em]{.}{\contentspage}}   

\begin{document}

\pagenumbering{roman}   
\tableofcontents  
\clearpage

\chapter*{Preface}  
\addcontentsline{toc}{chapter}{Preface}  
\clearpage 

\pagenumbering{arabic}   
\setcounter{chapter}{0}
\renewcommand\thepart{I} 
\renewcommand{\thechapter}{{I\arabic{chapter}}}
\renewcommand{\thesection}{{I\arabic{chapter}.\arabic{section}}} 
\renewcommand{\thesubsection}{}
\clearpage 
\part{Island}               
\chapter{Desert}
\section{Shelter}
\chapter{Paradise}
\section{Beach}
\setcounter{chapter}{0}
\renewcommand\thepart{W} 
\renewcommand{\thechapter}{{W\arabic{chapter}}}
\renewcommand{\thesection}{{W\arabic{chapter}.\arabic{section}}} 

\setcounter{page}{50}  
\clearpage
\part{Water}              
\chapter{Ice} 
\section{Snow}
\chapter{Liquid}
\section{Wave}

\clearpage 
\setcounter{page}{400} 
\renewcommand\thepart{L}  
\renewcommand{\thechapter}{{L\arabic{chapter}}}
\renewcommand{\thesection}{{L\arabic{chapter}.\arabic{section}}} 
\part{Land}             
\chapter{Continent}
\section{Mountain}
\chapter{Rock}  
\section{Stone}

\clearpage
\setcounter{chapter}{0}
\renewcommand\thepart{A} 
\renewcommand{\thechapter}{{A\arabic{chapter}}}
\renewcommand{\thesection}{{A\arabic{chapter}.\arabic{section}}} 
\part{Animals}               
\chapter{Mammals}
\section{Humans}
\chapter{Reptiles}
\section{Lizards}  

\end{document}  

minimal working example

I have actually come upon a solution to problem 2 (page-number-non-alignment) just now at this post
Apparently \bfseries{\contentspage} influences the line filling in an unwanted way. The solution is to use \hfill\bfseries\thecontentspage, as in the revised code below, which produces nicely right-aligned page numbers, see below. I'm still stuck with problem 1, though.

\documentclass[12pt,a4paper,openany]{book} 
\renewcommand{\familydefault}{cmss} 
\usepackage[pagestyles, outermarks]{titlesec}
\usepackage{titletoc}

\titlecontents{part}[0mm]  
  {\vspace{12pt}\large\normalfont\bfseries}  
  {\contentslabel{10mm}}{}            
  {\hfill\bfseries\thecontentspage}  

\titlecontents{chapter}[9.3mm]     
  {\vspace{4pt}\normalsize\normalfont\bfseries}  
  {\contentslabel{9.3mm}}{}   
  {\hfill\bfseries\thecontentspage}

\titlecontents{section}[21.6mm]   
  {\vspace{0pt}\normalsize\normalfont} 
  {\contentslabel[\thecontentslabel]{12.3mm}}{}
  {\titlerule*[.75em]{.}\thecontentspage}   

\begin{document}

\pagenumbering{roman}   
\tableofcontents  
\clearpage

\chapter*{Preface}  
\addcontentsline{toc}{chapter}{Preface}  
\clearpage 

\pagenumbering{arabic}   
\setcounter{chapter}{0}
\renewcommand\thepart{I} 
\renewcommand{\thechapter}{{I\arabic{chapter}}}
\renewcommand{\thesection}{{I\arabic{chapter}.\arabic{section}}} 
\renewcommand{\thesubsection}{}
\clearpage 
\part{Island}               
\chapter{Desert}
\section{Shelter}
\chapter{Paradise}
\section{Beach}
\setcounter{chapter}{0}
\renewcommand\thepart{W} 
\renewcommand{\thechapter}{{W\arabic{chapter}}}
\renewcommand{\thesection}{{W\arabic{chapter}.\arabic{section}}} 

\setcounter{page}{50}  
\clearpage
\part{Water}              
\chapter{Ice} 
\section{Snow}
\chapter{Liquid}
\section{Wave}

\clearpage 
\setcounter{page}{400} 
\renewcommand\thepart{L}  
\renewcommand{\thechapter}{{L\arabic{chapter}}}
\renewcommand{\thesection}{{L\arabic{chapter}.\arabic{section}}} 
\part{Land}             
\chapter{Continent}
\section{Mountain}
\chapter{Rock}  
\section{Stone}

\clearpage
\setcounter{chapter}{0}
\renewcommand\thepart{A} 
\renewcommand{\thechapter}{{A\arabic{chapter}}}
\renewcommand{\thesection}{{A\arabic{chapter}.\arabic{section}}} 
\part{Animals}               
\chapter{Mammals}
\section{Humans}
\chapter{Reptiles}
\section{Lizards}  

\end{document}  

minimal working example

Following up on the patch suggested by esdd to gain control of the label width for part, I post essd's version with two lines added to format the title of parts. These lines somehow interfere with the patch, because the title label is now shifted to the right.

\documentclass[12pt,a4paper,openany]{book} 
\renewcommand{\familydefault}{cmss}
\usepackage[pagestyles, outermarks]{titlesec}
\usepackage{titletoc}

\titleclass{\part}{top}
\titleformat{\part}[display]%     this line messes up the patch
{\normalfont\Huge}{\centering\thepart}{1em}{\centering}                      
\titleformat{\chapter}{\normalfont\LARGE}{\thechapter}{1em}{}
\titleformat{\section}{\normalfont\Large}{\thesection}{1em}{} 

\titlecontents{part}[10mm]
  {\vspace{12pt}\large\normalfont\bfseries}
  {\contentslabel{10mm}}{}
  {\hfill\thecontentspage}

\titlecontents{chapter}[10mm]
  {\vspace{4pt}\normalsize\normalfont\bfseries}
  {\contentslabel{10mm}}{}
  {\hfill\thecontentspage}

\titlecontents{section}[22.3mm]
  {\vspace{0pt}\normalsize\normalfont}
  {\contentslabel[\thecontentslabel]{12.3mm}}{}
  {\titlerule*[.75em]{.}\thecontentspage}

\usepackage{xpatch}
\makeatletter
\xpatchcmd\@part
  {\addcontentsline{toc}{part}{\thepart\hspace{1em}#1}}
  {\addcontentsline{toc}{part}{\protect\numberline{\thepart}#1}}
  {}{\PatchFailed}
\makeatother

\usepackage[linktocpage]{hyperref}% after the patch

updated MWE

Best Answer

Update (with redefinition of \part using \titleformat)

Regarding to the additions in the question: If you redefine \part using \titleformat patching \@part does not help anymore. But then adding the option newparttoc for package titlesec will solve your issue:

\documentclass[12pt,a4paper,openany]{book} 
\renewcommand{\familydefault}{cmss}
\usepackage[pagestyles, outermarks,
  newparttoc% <- added
]{titlesec}
\usepackage{titletoc}
\usepackage[linktocpage]{hyperref}

\titleclass{\part}{top}
\titleformat{\part}[display]
  {\normalfont\Huge}{\centering\thepart}{1em}{\centering}%
  [\setcounter{chapter}{0}]% <- added to reset the chapter counter for each part

\contentsmargin{0pt}%<- added (as suggested by jvd in a comment)

\titlecontents{part}[10mm]% <- changed
  {\vspace{12pt}\large\normalfont\bfseries}
  {\contentslabel{10mm}}{}
  {\hfill\thecontentspage}

\titlecontents{chapter}[10mm]
  {\vspace{4pt}\normalsize\normalfont\bfseries}
  {\contentslabel{10mm}}{}
  {\hfill\thecontentspage}

\titlecontents{section}[22.3mm]
  {\vspace{0pt}\normalsize\normalfont}
  {\contentslabel[\thecontentslabel]{12.3mm}}{}
  {\titlerule*[.75em]{.}\thecontentspage}

\renewcommand\thechapter{\thepart\arabic{chapter}}
\setcounter{secnumdepth}{1}
\begin{document}
\pagenumbering{roman}
\tableofcontents
\chapter*{Preface}
\addcontentsline{toc}{chapter}{Preface}
\cleardoublepage 
\pagenumbering{arabic}
\renewcommand\thepart{I}
\part{Island}
\chapter{Desert}
\section{Shelter}
\chapter{Paradise}
\section{Beach}

\cleardoublepage% only for the example
\setcounter{page}{51}% only for the example
\renewcommand\thepart{W}
\part{Water}
\chapter{Ice}
\section{Snow}
\chapter{Liquid}
\section{Wave}

\cleardoublepage% only for the example
\setcounter{page}{401}% only for the example
\renewcommand\thepart{L}
\part{Land}
\chapter{Continent}
\section{Mountain}
\chapter{Rock}
\section{Stone}

\clearpage
\renewcommand\thepart{A}
\part{Animals}
\chapter{Mammals}
\section{Humans}
\chapter{Reptiles}
\section{Lizards}
\end{document}

Result:

enter image description here


Original answer (without the redefinition of \part using \titleformat)

You could patch \@part to remove the fixed space between the part number and the entry text and to use \numberline instead.

\usepackage{xpatch}
\makeatletter
\xpatchcmd\@part
  {\addcontentsline{toc}{part}{\thepart\hspace{1em}#1}}
  {\addcontentsline{toc}{part}{\protect\numberline{\thepart}#1}}
  {}{\PatchFailed}
\makeatother

enter image description here

Code:

\documentclass[12pt,a4paper,openany]{book} 
\renewcommand{\familydefault}{cmss}
\usepackage[pagestyles, outermarks]{titlesec}
\usepackage{titletoc}

\titlecontents{part}[10mm]
  {\vspace{12pt}\large\normalfont\bfseries}
  {\contentslabel{10mm}}{}
  {\hfill\thecontentspage}

\titlecontents{chapter}[10mm]
  {\vspace{4pt}\normalsize\normalfont\bfseries}
  {\contentslabel{10mm}}{}
  {\hfill\thecontentspage}

\titlecontents{section}[22.3mm]
  {\vspace{0pt}\normalsize\normalfont}
  {\contentslabel[\thecontentslabel]{12.3mm}}{}
  {\titlerule*[.75em]{.}\thecontentspage}


\usepackage{xpatch}
\makeatletter
\xpatchcmd\@part
  {\addcontentsline{toc}{part}{\thepart\hspace{1em}#1}}
  {\addcontentsline{toc}{part}{\protect\numberline{\thepart}#1}}
  {}{\PatchFailed}
\makeatother

\usepackage[linktocpage]{hyperref}% after the patch

\xpretocmd\part{\setcounter{chapter}{0}}{}{\PatchFailed}
\renewcommand\thechapter{\thepart\arabic{chapter}}
\setcounter{secnumdepth}{1}


\begin{document}
\pagenumbering{roman}
\tableofcontents
\chapter*{Preface}
\addcontentsline{toc}{chapter}{Preface}
\cleardoublepage 
\pagenumbering{arabic}
\renewcommand\thepart{I}
\part{Island}
\chapter{Desert}
\section{Shelter}
\chapter{Paradise}
\section{Beach}

\cleardoublepage% only for the example
\setcounter{page}{51}% only for the example
\renewcommand\thepart{W}
\part{Water}
\chapter{Ice}
\section{Snow}
\chapter{Liquid}
\section{Wave}

\cleardoublepage% only for the example
\setcounter{page}{401}% only for the example
\renewcommand\thepart{L}
\part{Land}
\chapter{Continent}
\section{Mountain}
\chapter{Rock}
\section{Stone}

\clearpage
\renewcommand\thepart{A}
\part{Animals}
\chapter{Mammals}
\section{Humans}
\chapter{Reptiles}
\section{Lizards}
\end{document}

With KOMA-Script classes, there there is no need to patch an internal command:

\documentclass[12pt,a4paper,openany]{scrbook} 
\renewcommand{\familydefault}{cmss} 
%\usepackage[pagestyles, outermarks]{titlesec}

\usepackage{titletoc}

\titlecontents{part}[11mm]
  {\vspace{12pt}\large\normalfont\bfseries}
  {\contentslabel{11mm}}{}
  {\hfill\thecontentspage}

\titlecontents{chapter}[11mm]
  {\vspace{4pt}\normalsize\normalfont\bfseries}
  {\contentslabel{11mm}}{}
  {\hfill\thecontentspage}

\titlecontents{section}[23.3mm]
  {\vspace{0pt}\normalsize\normalfont}
  {\contentslabel[\thecontentslabel]{12.3mm}}{}
  {\titlerule*[.75em]{.}\thecontentspage}

\usepackage{xpatch}
\usepackage[linktocpage]{hyperref}
\xpretocmd\part{\setcounter{chapter}{0}}{}{\PatchFailed}
\renewcommand\thechapter{\thepart\arabic{chapter}}
\setcounter{secnumdepth}{1}
\begin{document}

\pagenumbering{roman}
\tableofcontents
\chapter*{Preface}
\addcontentsline{toc}{chapter}{Preface}

\clearpage 
\pagenumbering{arabic}
\renewcommand\thepart{I} 
\renewcommand{\thechapter}{{\thepart\arabic{chapter}}}
\part{Island}
\chapter{Desert}
\section{Shelter}
\chapter{Paradise}
\section{Beach}

\clearpage
\setcounter{page}{50}% only for the example
\renewcommand\thepart{W}
\part{Water}
\chapter{Ice} 
\section{Snow}
\chapter{Liquid}
\section{Wave}

\clearpage
\setcounter{page}{400}% only for the example
\renewcommand\thepart{L}
\part{Land}
\chapter{Continent}
\section{Mountain}
\chapter{Rock}
\section{Stone}

\clearpage
\renewcommand\thepart{A} 
\part{Animals}
\chapter{Mammals}
\section{Humans}
\chapter{Reptiles}
\section{Lizards}
\end{document}

But with KOMA-Script classes, there is also no need to use tocloft to format the toc entries:

\documentclass[12pt,a4paper,openany]{scrbook} 
\renewcommand{\familydefault}{cmss} 
%\usepackage[pagestyles, outermarks]{titlesec}

\setuptoc{toc}{numberline}
\DeclareTOCStyleEntry[
  beforeskip=12pt,
  pagenumberbox=\pnmbox,
  indent=0pt,
  numwidth=10mm,
]{tocline}{part}
\DeclareTOCStyleEntry[
  beforeskip=4pt,
  pagenumberbox=\pnmbox,
  indent=0pt,
  numwidth=10mm,
]{tocline}{chapter}
\DeclareTOCStyleEntry[
  indent=10mm,
  numwidth=12.3mm
]{tocline}{section}
\setkomafont{partentry}{\large\normalfont\bfseries}
\setkomafont{chapterentry}{\normalfont\bfseries}
\newcommand*\pnmbox[1]{\mbox{#1}}

\usepackage{xpatch}
\usepackage[linktocpage]{hyperref}
\xpretocmd\part{\setcounter{chapter}{0}}{}{\PatchFailed}
\renewcommand\thechapter{\thepart\arabic{chapter}}
\setcounter{secnumdepth}{1}
\begin{document}

\pagenumbering{roman}
\tableofcontents
\chapter*{Preface}
\addcontentsline{toc}{chapter}{Preface}

\clearpage 
\pagenumbering{arabic}
\renewcommand\thepart{I} 
\renewcommand{\thechapter}{{\thepart\arabic{chapter}}}
\part{Island}
\chapter{Desert}
\section{Shelter}
\chapter{Paradise}
\section{Beach}

\clearpage
\setcounter{page}{50}% only for the example
\renewcommand\thepart{W}
\part{Water}
\chapter{Ice} 
\section{Snow}
\chapter{Liquid}
\section{Wave}

\clearpage
\setcounter{page}{400}% only for the example
\renewcommand\thepart{L}
\part{Land}
\chapter{Continent}
\section{Mountain}
\chapter{Rock}
\section{Stone}

\clearpage
\renewcommand\thepart{A} 
\part{Animals}
\chapter{Mammals}
\section{Humans}
\chapter{Reptiles}
\section{Lizards}
\end{document}