70

I'm preparing a document using the book class. In the table of contents, the space between the subsection number and title is too wide. How to reduce it?

Mico
  • 506,678

3 Answers3

99

Without any packages:

In the standard documentclass without the influence of a package like titletoc you have to redefine the command \l@subsection. In the file book.cls you find the following settings:

\newcommand*\l@section{\@dottedtocline{1}{1.5em}{2.3em}}
\newcommand*\l@subsection{\@dottedtocline{2}{3.8em}{3.2em}}
\newcommand*\l@subsubsection{\@dottedtocline{3}{7.0em}{4.1em}}
\newcommand*\l@paragraph{\@dottedtocline{4}{10em}{5em}}
\newcommand*\l@subparagraph{\@dottedtocline{5}{12em}{6em}}

The command \@dottedtocline expects the following parameters:

\renewcommand{\l@<typ>}{\@dottedtocline{<level>}%
                                       {<indentation>}%
                                       {<numwidth>}}

To reduce the indentation of subsection you can do:

\makeatletter
 \renewcommand*\l@subsection{\@dottedtocline{2}{1.8em}{3.2em}}
\makeatother

Example:

\documentclass{book}
\makeatletter
\renewcommand*\l@subsection{\@dottedtocline{2}{1.8em}{3.2 em}}
\makeatother
\begin{document}
\tableofcontents
\chapter{foo}
\section{bar}
\subsection{foobar}
\end{document}

The method is equal for floating environments. The standard class book.cls provides \l@figure and and \l@table with the following settings:

\newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}}
\let\l@table\l@figure

Package titletoc

By using the package titletoc you can set the indentation using \dottedcontents:

\dottedcontents{<section>}[<left>]{<above-code>}
{<label width>}{<leader width>}

Example

\documentclass{book}
\usepackage{titletoc}
\dottedcontents{subsection}[5.5em]{}{3.2em}{1pc}

\begin{document}
\tableofcontents
\chapter{foo}
\section{bar}
\subsection{foobar}
\end{document}

The argument <section> can be somewhat irritating. The argument allows the name without a leading backslash so that figure and table are allowed, too.


Package tocloft

The package tocloft offers more than the following setting. The indentation is set by the length \cftXindent. The X stands for:

  • part for \part titles
  • chap for \chapter titles
  • sec for \section titles
  • subsec for \subsection titles
  • subsubsec for \subsubsection titles
  • para for \paragraph titles
  • fig for figure \caption title
  • tab for table \caption titles

Example:

\documentclass{book}
\usepackage{tocloft}
\setlength{\cftsubsecindent}{2em}

\begin{document}

\tableofcontents
\chapter{foo}
\section{bar}
\subsection{foobar}
\end{document}

KOMA-Script

With a recent version of KOMA-Script one can use \RedeclareSectionCommand to change the entries in the table of contents as well. You can use that for all defined sectioning commands.

\documentclass{scrbook}
\RedeclareSectionCommand[%
tocindent=9em,tocnumwidth=7em,]{subsection}
\begin{document}

\tableofcontents
\chapter{foo}
\section{bar}
\subsection{foobar}
\end{document}

The modification of figure and table is equal to the standard class and defined as follow:

\newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}}
\let\l@table\l@figure

Package tocstyle (link in German)

With recent versions of KOMA-Scrpt, many parts of tocstyle are unneeded. It will be completely incorporated in KOMA-Script in the future.

To manipulate the toc (or other list of ...) in combination with a class of the KOMA bundle you should use the package tocstyle. The package is part of the KOMA bundle but with a separate documentation. The influence of the indentation is given indirectly by entryhook which can be set by \settocfeature

One of the benefits oftocstyle is the automatic calculation of the needed indentation.

Example:

\documentclass{scrbook}

\usepackage{tocstyle}
\usetocstyle{KOMAlike}
\settocfeature[toc][2]{entryhook}{\protect\hspace*{-1.5em}\nobreakspace}
\begin{document}

\tableofcontents
\chapter{foo}
\section{bar}
\subsection{foobar}
\end{document}
Johannes_B
  • 24,235
  • 10
  • 93
  • 248
Marco Daniel
  • 95,681
  • 2
    tocstyle without option tocindentmanual calculates the needed indention itself, so to much indent shouldn't be. And the depth of subsection is AFAIK 2, so the second optional argument of \settocfeature should be 2 not 9. BTW: If the space after the number is to large you may change the feature spaceafternumber. – Schweinebacke Nov 06 '11 at 15:48
  • @Schweinebacke: Welcome on stack exchange. I toke the wrong number ;-). Thanks. The spaceafternumber influence the space between the number and the title. I want to reduce the intention in front of the section number. – Marco Daniel Nov 06 '11 at 15:56
  • If added the information about spaceafternumber only, because I'm not sure if the OP wanted to change the indentation before the number or the indentation of the text, because there's a hanging indent after the number. It shouldn't be a critic to your excellent answer only an addendum. – Schweinebacke Nov 06 '11 at 16:05
  • @Schweinebacke: I doesn't sound like critic ;-). But adding this information to my answer I must change also the other sections. (regards mechanicus -- mrunix :-) ) – Marco Daniel Nov 06 '11 at 16:32
  • OK. BTW: <distance "number <-> text" > sounds like space between number and text, but its the hanging indent of the text aka the width reserved for number and space between number and text. – Schweinebacke Nov 06 '11 at 16:59
  • @Schweinebacke: What do you suggest? I searched a short description of this behavior. – Marco Daniel Nov 06 '11 at 17:50
  • With my about 25 year unused school english it's hard to find a good term. Maybe "width of number". At source2e the LaTeX team simply uses \@dottedtocline{ ⟨level⟩ }{ ⟨indent⟩ }{ ⟨numwidth⟩ }{ ⟨title⟩ }{ ⟨page⟩ }. – Schweinebacke Nov 07 '11 at 07:21
  • @Schweinebacke: I know the problem with "school English". – Marco Daniel Nov 07 '11 at 15:52
  • I need to reduce space BEFORE number and title of subsection in the tableofcontents – Ilya Ginzburg Nov 11 '11 at 10:41
  • @IlyaGinzburg: Do you use any additional packages or which documentclass do you use? indention isn't the same as space above or below. – Marco Daniel Nov 11 '11 at 16:47
  • 3
    Since KOMA-Script version 3.16 you can use \RedeclareSectionCommand[tocindent=1.8em,tocnumwidth=3.2em]{subsection}. – esdd Mar 18 '16 at 23:43
  • This was such a great and inclusive answer. Thank you so much. (Special props for KOMA.) – kando Aug 02 '16 at 17:25
  • The first solution also works in LyX with titlesec – Ufos Oct 12 '16 at 14:03
  • I wanted to change the spacing for chapters too, and that setting (for \l@chapter) can be found in book.cls as well. – AstroFloyd Mar 28 '22 at 14:15
  • The note about KOMA-Script's figure and table is not correct (anymore). \l@figure and \l@table are defined using tocbasic's \DeclareTOCStyleEntry and should be modified using \DeclareTOCStyleEntry. This also works with a standard class (see my answer). – cabohah Feb 07 '24 at 07:45
  • The experimental tocstyle is no longer part of KOMA-Script nor of MiKTeX or TeX Live. However the automatic calculation can be done using tocbasic as shown in my answer. – cabohah Feb 07 '24 at 07:49
6

The macro in charge of setting the numbers and space between the titles is \numberline. It's defined in the LaTeX kernel as:

\def\numberline#1{\hb@xt@\@tempdima{#1\hfil}}

\numberline{<stuff>} sets its argument <stuff> inside a box of width \@tempdima. The length \@tempdima is set by the macros \l@<type> that is responsible for setting any <type> within the ToC (like section, subsection, figure, etc.).

If you wish to have a natural separation between the numbers and titles within the ToC, you need to modify \numberline to not set its contents in a box, but rather just set the number followed by some space, as in:

\renewcommand{\numberline}[1]{#1~}

The above redefinition will set the number followed by a ~ (tie). You can change this to suit your needs (\hspace{<len>}, :~, ...). Note that this will hold for for all elements that use it (including figures in the LoF and tables in the LoT).

enter image description here

\documentclass{article}

\renewcommand{\numberline}[1]{#1~}

\usepackage{lipsum}% Just for this example
\AtBeginDocument{\sloppy}% Just for this example

\begin{document}

\tableofcontents

\section{A section}
\lipsum[1-50]

\setcounter{section}{9}
\section{Another section}
\lipsum[1-50]

\setcounter{section}{99}
\section{Yet another section}
\lipsum[1-50]

\setcounter{section}{999}
\section{Last section}
\lipsum[1-50]

\end{document}

If you're using tocloft, a similar setup applies with some minor alterations, since tocloft allows for the insertion of content before and after the sectional unit numbering:

\usepackage{tocloft}
\makeatletter
\renewcommand{\numberline}[1]{{\@cftbsnum #1\@cftasnum~}\@cftasnumb}
\makeatother
Werner
  • 603,163
0

You can use package tocbasic and reconfigure the ToC entries, to automatically detect the needed space for the numbers and the hierarchical indent:

\documentclass{article}
\usepackage{tocbasic}
\DeclareTOCStyleEntries[dynnumwidth,dynindent]{tocline}{section,subsection,subsubsection,paragraph,subparagraph}% Reconfigure ToC entries for section … subparagraph to use the needed number width and indent

\usepackage{blindtext}

\begin{document}

\tableofcontents

\blinddocument

\setcounter{section}{9} \blinddocument

\setcounter{section}{99} \blinddocument

\setcounter{section}{999} \blinddocument

\end{document}

After two LaTeX runs the problem is still there:

ToC with problem

But after at least three LaTeX runs you get:

After three LaTeX runs everything is fine.

If you work with a KOMA-Script class or a derived class instead of a standard class, you don't need to load tocbasic yourself, because the KOMA-Script classes already use this package. On the other hand, as you see in the example above, you don't need to use a KOMA-Script class to be able to use the features of tocbasic.

cabohah
  • 11,455