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


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


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
{}{\PatchFailed}
\makeatother



• From quick look at the code, it appears that package titletoc is intrinsically incapable of distinguishing a numbered part entry from an unnumbered part entry: it will always treat it as unnumbered and \contentslabel never does anything. At least in the book class. To avoid that you would need to hack into \part macro to modify what it adds to .toc file. – user4686 Oct 5 '17 at 12:42

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,
]{titlesec}
\usepackage{titletoc}

\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}
\cleardoublepage
\pagenumbering{arabic}
\renewcommand\thepart{I}
\part{Island}
\chapter{Desert}
\section{Shelter}
\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:

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
{}{\PatchFailed}
\makeatother


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
{}{\PatchFailed}
\makeatother

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

\begin{document}
\pagenumbering{roman}
\tableofcontents
\chapter*{Preface}
\cleardoublepage
\pagenumbering{arabic}
\renewcommand\thepart{I}
\part{Island}
\chapter{Desert}
\section{Shelter}
\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}
\xpretocmd\part{\setcounter{chapter}{0}}{}{\PatchFailed}
\renewcommand\thechapter{\thepart\arabic{chapter}}
\setcounter{secnumdepth}{1}
\begin{document}

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

\clearpage
\pagenumbering{arabic}
\renewcommand\thepart{I}
\renewcommand{\thechapter}{{\thepart\arabic{chapter}}}
\part{Island}
\chapter{Desert}
\section{Shelter}
\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}
\xpretocmd\part{\setcounter{chapter}{0}}{}{\PatchFailed}
\renewcommand\thechapter{\thepart\arabic{chapter}}
\setcounter{secnumdepth}{1}
\begin{document}

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

\clearpage
\pagenumbering{arabic}
\renewcommand\thepart{I}
\renewcommand{\thechapter}{{\thepart\arabic{chapter}}}
\part{Island}
\chapter{Desert}
\section{Shelter}
\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}

• @esdd Thanks, your patch works great for the MWE. But in my actual code I also use \usepackage[linktocpage]{hyperref} to get hyperlinks to page numbers in the toc. If I add that single line to your MWE, I get an error: Undefined control squence \PatchFailed. It would be great if you could make your patch compatible with hyperlink package. Thanks! – jvd Oct 5 '17 at 14:33
• @jvd Load hyperref after the patch. See my updated answer. – esdd Oct 5 '17 at 19:39
• Thanks again, that works. But now I have a further problem. To keep my MWE 'minimal', I had left out two lines for formatting the titles generated by \part, namely \titleclass{\part}{top} \titleformat{\part}[display]{\normalfont\Huge}{\centering}{1em}{\centering}. When I add these, they kill the control over the label width that your patch so nicely provides; as a result the part label is shifted to the right to align with the chapter titles. I updated my question to show this issue. Would be fantastic if you could show me how to get over this final bump! – jvd Oct 6 '17 at 7:38
• Then there is no patch needed. Simple use option newparttoc for titlesec. See my updated answer. – esdd Oct 6 '17 at 8:32
• Fantastic, now its perfect, I marked your solution as accepted, thanks a ton! Final remark: to get a toc whose width perfectly matches the pagewidth, I had to add \contentsmargin{0mm} to your code (without it, the toc was narrower than the pagewidth by about 10mm). Maybe you could add that line to your code, for the benefit of future readers? – jvd Oct 6 '17 at 13:22