4

I'm trying to create a table of contents with the tocloftpackage that; has two-columns, is inside a colored and framed box and has dotted lines all the way up to the page numbers. The default behaviour has the dotted line stop to early before the page number, leaving too much white space for what I want.

I have experimented a little with setting @pnumwidth, but that is a fixed value and page numbers can be single or multiple digit numbers. In the example below I've set @pnumwidth to 6pt which works fine for single digit page numbers, but doesn't work for two-digit page numbers as that for section 6, "Antarctica", and the following sections below.

A bonus question is; how can I make the "and" in the section title "Antigua and Barbados" lie closer to Antigua?

\documentclass[twoside]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{multicol} % For having two-columns in TOC and in text
\usepackage{tocloft} % For styling the table of contents
\usepackage{xcolor} % We want to use \fcolorbox
\usepackage{blindtext} % To generate dummy text

%\setcounter{tocdepth}{1} %Control depth of table of contents

% This removes the default TOC heading by redefining the cftmaketoctitle command in the tocloft package
\makeatletter
\renewcommand{\@cftmaketoctitle}{}
\renewcommand{\@pnumwidth}{6pt}
\makeatother

\renewcommand{\cftsecleader}{\cftdotfill{\cftsecdotsep}}
\renewcommand\cftsecdotsep{\cftdot}
\renewcommand\cftsubsecdotsep{\cftdot}

\begin{document}

\setlength\fboxsep{20pt} % Set spacing for the TOC box
\setlength\fboxrule{2pt} % Set border with for the TOC box
\fcolorbox{red}{yellow}{\parbox{\dimexpr \linewidth-2\fboxsep-2\fboxrule}{%
  \centering{\textsc{\Large{Table Of Contents}}}
  \setlength\columnsep{25pt}
  \begin{multicols}{2}
    \tableofcontents
  \end{multicols}
}}

\section{Africa}
\subsection{Angola}
\subsection{Algeria}
\subsection{Benin}
\section{Asia}
\subsection{Afganistan}
\subsection{Armenia}
\subsection{Azerbaijan}
\section{Europe}
\subsection{Albania}
\subsection{Andorra} 
\subsection{Armenia}
\section{North America}
\subsection{Anguilla}
\subsection{Antigua and Barbuda}
\subsection{Aruba}
\section{South America}
\subsection{Argentia}
\subsection{Bolivia}
\subsection{Brazil}
\blindtext[75]
\section{Antarctica}
\subsection{South pole}
\section{Australia}
\subsection{Australia}
\subsection{Tasmania}
\end{document}

enter image description here

Comments to answers below: Thanks everyone who took the time to reply! My problems are solved, thanks to you.

I preferred Werner's solution to the main dotted line problem, where the commands \cftsecfillnum and \cftsubsecfillnum were renewed.

And I preferred Marijn's solution to my bonus problem, with the section title "Antigua and Barbuda", by typesetting the titles in the TOC to ragged right.

I preferred these answers, since both are general solutions and both only modify the preamble, and not the body of the document.

2
  • Mr. Cohen, consider looking at etoc package, it might provide you with tools you require. Also, it is very powerfull all the way and pretty easily configurable (sadly, mostly beyond my newbie skills). Also, consider looking at KOMA-script scrart and tocbasic, I think there are macros provided to fix the legth between numbers and dots. Commented Jan 1, 2020 at 17:14
  • To address the bonus question: You could change \subsection{Antigua and Barbuda} to \subsection[\mbox{Antigua and} Barbuda]{Antigua and Barbuda}.
    – Mico
    Commented Jan 1, 2020 at 20:50

3 Answers 3

4

You can update the section and subsection number filler (\cftsecfillnum and \cftsubsecfillnum) and remove the setting inside a box.

\renewcommand{\cftsecfillnum}[1]{%
  {\cftsecleader}\nobreak
  {\cftsecpagefont #1}\cftsecafterpnum\par
}
\renewcommand{\cftsubsecfillnum}[1]{%
  {\cftsubsecleader}\nobreak
  {\cftsubsecpagefont #1}\cftsubsecafterpnum\par
}

enter image description here

0
2

The bonus question can be answered from the tocloft manual, page 5. The important term here is ragged right, which is LaTeX/typesetting terminology for 'align left'.

To have the (sectional) titles in the ToC, etc., typeset ragged right with no hyphenation

\renewcommand{\@tocrmarg}{2.55em plus1fil}

where the value 2.55em can be changed for whatever margin space you want.

Actually there is also a user level command \cftsetrmarg to redefine this macro, which is a bit easier to use because it does not require \makeatletter or \renewcommand.

The main question is a bit more involved. The approach shown in the MWE below redefines a macro in which \@pnumwidth is used, such that the required width is computed first, stored in \@pnumwidth and then used to construct the box for the number, which in turn influences the width of the dotted line. The macro is set globally such that it also applies to other places where the macro is used after the calculation.

The solution is a bit quick and dirty, in the sense that 1. it hardcodes values for <10, <100 and <1000, so documents with 1000 pages or more are not handled properly, and 2. the calculations are done in the command for a section title (because this was the top-level entry in the MWE from the OP), which means that it does not work properly for chapters etc., and also if the page number border is between a section and a subsection (e.g., section starts on page 9 with a subsection on page 10) then it will not work. This can be addressed if needed by redefining also \cftsubsecfillnum and similar commands, search the tocloft source for \@pnumwidth to find all the sectioning commands.

MWE:

\documentclass[twoside]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{multicol} % For having two-columns in TOC and in text
\usepackage{tocloft} % For styling the table of contents
\usepackage{xcolor} % We want to use \fcolorbox
\usepackage{blindtext} % To generate dummy text

%\setcounter{tocdepth}{1} %Control depth of table of contents

% This removes the default TOC heading by redefining the cftmaketoctitle command in the tocloft package
\makeatletter
\renewcommand{\@cftmaketoctitle}{}
% Calculate the desired width of the page number box to influence the length of the dotted line
\renewcommand{\cftsecfillnum}[1]{%
  \ifnum#1<10%
  \gdef\@pnumwidth{6pt}%
  \else%
  \ifnum#1<100%
  \gdef\@pnumwidth{12pt}%
  \else%
  \gdef\@pnumwidth{18pt}%
  \fi\fi%
  {\cftsecleader}\nobreak
  \makebox[\@pnumwidth][\cftpnumalign]{\cftsecpagefont #1}\cftsecafterpnum\par
}
\makeatother
\cftsetrmarg{2.55em plus1fil} % set left alignment for multiline titles

\renewcommand{\cftsecleader}{\cftdotfill{\cftsecdotsep}}
\renewcommand\cftsecdotsep{\cftdot}
\renewcommand\cftsubsecdotsep{\cftdot}

\begin{document}

\setlength\fboxsep{20pt} % Set spacing for the TOC box
\setlength\fboxrule{2pt} % Set border with for the TOC box
\fcolorbox{red}{yellow}{\parbox{\dimexpr \linewidth-2\fboxsep-2\fboxrule}{%
  \centering{\textsc{\Large{Table Of Contents}}}
  \setlength\columnsep{25pt}
  \begin{multicols}{2}
    \tableofcontents
  \end{multicols}
}}

\section{Africa}
\subsection{Angola}
\subsection{Algeria}
\subsection{Benin}
\section{Asia}
\subsection{Afganistan}
\subsection{Armenia}
\subsection{Azerbaijan}
\section{Europe}
\subsection{Albania}
\subsection{Andorra} 
\subsection{Armenia}
\section{North America}
\subsection{Anguilla}
\subsection{Antigua and Barbuda}
\subsection{Aruba}
\section{South America}
\subsection{Argentia}
\subsection{Bolivia}
\subsection{Brazil}
\blindtext[75]
\section{Antarctica}
\subsection{South pole}
\section{Australia}
\subsection{Australia}
\subsection{Tasmania}
\end{document}

Result:

enter image description here

1
  • \centering and \Large do not take arguments. I'd therefore replace \centering{\textsc{\Large{Table Of Contents}}} with {\centering\textsc{\Large Table of Contents}\par}.
    – Mico
    Commented Jan 1, 2020 at 20:04
0

You can modify \@pnumwidth in the middle of the TOC using \addtocontents on the appropriate page.

\documentclass[twoside]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{multicol} % For having two-columns in TOC and in text
\usepackage{tocloft} % For styling the table of contents
\usepackage{xcolor} % We want to use \fcolorbox
\usepackage{blindtext} % To generate dummy text

%\setcounter{tocdepth}{1} %Control depth of table of contents

% This removes the default TOC heading by redefining the cftmaketoctitle command in the tocloft package
\makeatletter
\renewcommand{\@cftmaketoctitle}{}
\renewcommand{\@pnumwidth}{5pt}
\makeatother

\renewcommand{\cftsecleader}{\cftdotfill{\cftsecdotsep}}
\renewcommand\cftsecdotsep{\cftdot}
\renewcommand\cftsubsecdotsep{\cftdot}

\begin{document}
\setlength\fboxsep{20pt} % Set spacing for the TOC box
\setlength\fboxrule{2pt} % Set border with for the TOC box
\fcolorbox{red}{yellow}{\parbox{\dimexpr \linewidth-2\fboxsep-2\fboxrule}{%
  \centering{\textsc{\Large{Table Of Contents}}}
  \setlength\columnsep{25pt}
  \begin{multicols}{2}
    \tableofcontents
  \end{multicols}
}}

\section{Africa}
\subsection{Angola}
\subsection{Algeria}
\subsection{Benin}
\section{Asia}
\subsection{Afganistan}
\subsection{Armenia}
\subsection{Azerbaijan}
\section{Europe}
\subsection{Albania}
\subsection{Andorra} 
\subsection{Armenia}
\section{North America}
\subsection{Anguilla}
\subsection[Antigua~and~Barbuda]{Antigua and Barbuda}
\subsection{Aruba}
\section{South America}
\subsection{Argentia}
\subsection{Bolivia}
\subsection{Brazil}
\blindtext[75]
\makeatletter
\addtocontents{toc}{\string\renewcommand{\string\@pnumwidth}{11pt}}
\makeatother
\section{Antarctica}
\subsection{South pole}
\section{Australia}
\subsection{Australia}
\subsection{Tasmania}
\end{document}

demo


You can also use

\subsection[\hbox{Antigua and Barbuda}]{Antigua and Barbuda}

to fit it into one line.

1
  • 1
    \subsection[Antigua\,and\,Barbuda]{Antigua and Barbuda} would appear to be preferable to \subsection[\hbox{Antigua and Barbuda}]{Antigua and Barbuda}.
    – Mico
    Commented Jan 1, 2020 at 20:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .