8

How do I right-align the section/subsection/.. number in the ToC? The distance between the number and the heading should be fixed.

Instead of

|  1     Section
|        1.1      Subsection

I'd like to have something like

|      1 Section
|             1.1 Subsection

(|= left margin)

There must be a package for that...

(And I'd like to play with the indentation as well)

2
  • you might want to think about this a bit more. while i agree with the concept in general, when section numbers are formatted as "chapter.section" and section goes to two digits, to me it looks a bit nicer with the compound number aligned on the decimal point. (of course, there's really no hope for a three-part subsection number with segments numbered 10 or greater.) Aug 17, 2012 at 12:54
  • @barbarabeeton I have thought about it for quite some time and for my case the best solution is to have the numbers right aligned and only a little bit of indentation to the next sublevel :) I have very, very, very long section numbers. The default is just not feasible.
    – topskip
    Aug 17, 2012 at 13:10

1 Answer 1

12

\numberline could be redefined:

\documentclass{article}

\makeatletter
\renewcommand*{\numberline}[1]{%
  \hb@xt@\@tempdima{\hfil#1 }%
}
\makeatother

\begin{document}
\tableofcontents

\section{First}
\subsection{Sub}
\addtocounter{subsection}{9}
\subsection{Foo}
\addtocounter{section}{9}
\section{Next}
\subsection{bar}
\end{document}

Table of contents with right aligned numbers

Specific settings

Since \numberline is used for all levels. When \numberline is executed, the information about the level is no longer available. Therefore, it is much more cumbersome to configure the alignment of \numberline specific to a level.

The following code hooks into \contentsline for catching the level name in macro \nl@current@levelname. Then \numberline reads the level name and calls its implementation for the specified alignment, see the comments in the example.

\documentclass{article}
% \usepackage[bookmarksnumbered, bookmarksopen]{hyperref}

\makeatletter
% Patch, that hooks into \contentsline to store the
% level name in \nl@current@levelname.
%   If package 'hyperref' is loaded, then this
% needs to be called *after* package `hyperref`.
\AtBeginDocument{%
  \let\nl@org@contentsline\contentsline
  \def\contentsline#1{%
    \def\nl@current@levelname{#1}%
    \nl@org@contentsline{#1}%
  }%
}

% \numberline evaluates \nl@current@levelname to find
% the horizontal alignment
\protected\def\numberline#1{%
  \begingroup
    \edef\nl@align{%
      nl@align@%
      \@ifundefined{nl@current@levelname}{}{\nl@current@levelname}%
    }%
    \edef\nl@align{%
      \@ifundefined{\nl@align}\nl@align@{\csname\nl@align\endcsname}%
    }%
    \@ifundefined{nl@numberline@\nl@align}{%
      \errmessage{Unknown alignment '\nl@align' for \noexpand\numberline}%
      \nl@numberline@l{#1}%
    }{%
      \csname nl@numberline@\nl@align\endcsname{#1}%
    }%
  \endgroup
}

% Implementations of `\numberline` for the different horizontal alignments
\newcommand*{\nl@numberline@l}[1]{% left-aligned
  \hb@xt@\@tempdima{#1 \hfil}%
}
\newcommand*{\nl@numberline@c}[1]{% centered
  \hb@xt@\@tempdima{\hfil#1 \hfil}%
}
\newcommand*{\nl@numberline@r}[1]{% right-aligned
  \hb@xt@\@tempdima{\hfil#1 }%
}

% Configuration
% -------------
% Horizonal alignment in \numberline:
%   l: left-aligned
%   c: centered
%   r: right-aligned
% \nl@align@: Default setting
% \nl@align@<levelname>: Setting for specific level

\def\nl@align@{l}% default
\def\nl@align@section{r}

\makeatother

\begin{document}
\tableofcontents

\section{First}
\subsection{Sub}
\addtocounter{subsection}{9}
\subsection{Foo}
\addtocounter{section}{9}
\section{Next}
\subsection{bar}
\end{document}

Result

4
  • See also tocloft package, page 11. It offers facilities to play with the indentation.
    – Guido
    Aug 17, 2012 at 12:54
  • Thanks Heiko for the perfect solution. I should read latex.ltx more often.
    – topskip
    Aug 17, 2012 at 13:12
  • @HeikoOberdiek Can you use this solution to left-align only one specified level, and not the other levels?
    – Karlo
    Jan 23, 2017 at 17:42
  • 1
    @Karlo See updated answer. Jan 23, 2017 at 19:08

You must log in to answer this question.

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