2

How do I align headings whithout interfering with my TOC? This what I have:

1 Chapter
1.1 Section
1.1.1. Subsection

This is what I need

1      Chapter
1.1    Section
1.1.1. Subsection

I am using the titlesec package, but so far I have not been able to find a solution. Another problem, basically preventing me from "cheating", is that I am using the tocloft package. Thus, I need to find a way to align my headings without interfering with the TOC.

MME:

\documentclass{scrreprt}

\usepackage{atveryend}
\usepackage{titlesec}


\titleformat{\chapter}{\normalfont\fontsize{12.5}{0}\bfseries}{\thechapter}{1em}{}
\titleformat{\section}{\normalfont\fontsize{10}{0}\bfseries}{\thesection}{1em}{}
\titleformat{\subsection}{\normalfont\fontsize{10}{0}\bfseries}{\thesubsection}{1em}{}
\titleformat{\subsubsection}{\normalfont\fontsize{10}{0}\bfseries}{\thesubsubsection}{1em}{}
\titleformat{\paragraph}{\normalfont\fontsize{10}{0}\bfseries}{\theparagraph}{1em}{}

\titlespacing*{\chapter}{0pt}{0pt}{14pt}
\titlespacing*{\section}{0pt}{14pt}{7pt}
\titlespacing*{\subsection}{0pt}{14pt}{0pt}
\titlespacing*{\subsubsection}{0pt}{7pt}{0pt}
\titlespacing*{\paragraph}{0pt}{14pt}{0pt}
\titlespacing*{\bhead}{0pt}{14pt}{0pt}

\makeatletter
\newlength{\secnumwidth}
\setlength{\secnumwidth}{0pt}
\providecommand*{\usesecnumwidth}{0pt}

\newcommand*{\secnumwidthbox}[1]{%
  \begingroup
    \sbox0{#1}%
    \ifdim\wd0>\secnumwidth
      \global\secnumwidth=\wd0\relax
    \fi
  \endgroup
  \leavevmode
  \hbox to 
    \ifdim\usesecnumwidth>\secnumwidth
      \usesecnumwidth
    \else
      \secnumwidth
    \fi
  {#1\hfil}%
}

\let\org@chapterformat\chapterformat
\renewcommand*{\chapterformat}{%
  \secnumwidthbox{\org@chapterformat}%
}

\renewcommand*{\othersectionlevelsformat}[3]{%
  \secnumwidthbox{#3\autodot\hfill\enskip}%
}

\AfterLastShipout{%
  \if@filesw
    \immediate\write\@mainaux{%
      \string\gdef\string\usesecnumwidth{\the\secnumwidth}%
    }%
  \fi
  \ifdim\usesecnumwidth=\secnumwidth
  \else
    \@latex@warning@no@line{Rerun LaTeX, because \noexpand\usesecnumwidth
      has changed}
  \fi
}
\makeatother

\begin{document}
\chapter{Chapter}
\section{Section}
\subsection{Subsection}
\end{document}
5
  • 1
    Please help us to help you and add a minimal working example (MWE) that illustrates your problem. It will be much easier for us to reproduce your situation and find out what the issue is when we see compilable code, starting with \documentclass{...} and ending with \end{document}.
    – user31729
    Jun 12, 2014 at 12:35
  • 1
    Where do you want to align the headings? In the TOC or at the place where the section headers appear (and the chapter etc. headers...)?
    – user31729
    Jun 12, 2014 at 12:41
  • I need to align the headings where the section and chapter headers appear. Basically "inline" alignment. All headings within the TOC are aligned. Now I need to do the same thing where all headings appear. Jun 12, 2014 at 13:04
  • @DanielKeys: So really "inline", i.e. as a bead on a string just in a line of "text"? If it would be like this, pardon me, it would look awful in my point of view.
    – user31729
    Jun 12, 2014 at 15:40
  • Can you add the \titleformat code you're using?
    – egreg
    Jun 13, 2014 at 16:23

2 Answers 2

3

The following example uses class scrreprt as example (the question has not specified the class). The methods can be adopted to other classes (more or less easily).

Macros \chapterformat for the number in \chapter and \othersectionlevelsformat for the number in \section and friedns are redefined. First the number including dot and separation space is measured, then the number is set in a box with a width that can hold the longest entry. The width of the widest number is written into the .aux file at the end of the document. Therefore two LaTeX runs are necessary.

Example file:

\documentclass{scrreprt}

\usepackage{atveryend}

\makeatletter
\newlength{\secnumwidth}
\setlength{\secnumwidth}{0pt}
\providecommand*{\usesecnumwidth}{0pt}

\newcommand*{\secnumwidthbox}[1]{%
  \begingroup
    \sbox0{#1}%
    \ifdim\wd0>\secnumwidth
      \global\secnumwidth=\wd0\relax
    \fi
  \endgroup
  \leavevmode
  \hbox to 
    \ifdim\usesecnumwidth>\secnumwidth
      \usesecnumwidth
    \else
      \secnumwidth
    \fi
  {#1\hfil}%
}

\let\org@chapterformat\chapterformat
\renewcommand*{\chapterformat}{%
  \secnumwidthbox{\org@chapterformat}%
}

\renewcommand*{\othersectionlevelsformat}[3]{%
  \secnumwidthbox{#3\autodot\hfill\enskip}%
}

\AfterLastShipout{%
  \if@filesw
    \immediate\write\@mainaux{%
      \string\gdef\string\usesecnumwidth{\the\secnumwidth}%
    }%
  \fi
  \ifdim\usesecnumwidth=\secnumwidth
  \else
    \@latex@warning@no@line{Rerun LaTeX, because \noexpand\usesecnumwidth
      has changed}
  \fi
}
\makeatother

\begin{document}
\chapter{Chapter}
\section{Section}
\subsection{Subsection}
\end{document}

Result

Package titlesec

Package titlesec redefines internals of KOMA-Script. A place for hooking into titlesec to add \secnumwidthbox would be \ttlh@hang:

\documentclass{scrreprt}

\usepackage{atveryend}
\usepackage{etoolbox}
\usepackage{titlesec}


\titleformat{\chapter}{\normalfont\fontsize{12.5}{0}\bfseries}{\thechapter}{1em}{}
\titleformat{\section}{\normalfont\fontsize{10}{0}\bfseries}{\thesection}{1em}{}
\titleformat{\subsection}{\normalfont\fontsize{10}{0}\bfseries}{\thesubsection}{1em}{}
\titleformat{\subsubsection}{\normalfont\fontsize{10}{0}\bfseries}{\thesubsubsection}{1em}{}
\titleformat{\paragraph}{\normalfont\fontsize{10}{0}\bfseries}{\theparagraph}{1em}{}

\titlespacing*{\chapter}{0pt}{0pt}{14pt}
\titlespacing*{\section}{0pt}{14pt}{7pt}
\titlespacing*{\subsection}{0pt}{14pt}{0pt}
\titlespacing*{\subsubsection}{0pt}{7pt}{0pt}
\titlespacing*{\paragraph}{0pt}{14pt}{0pt}
\titlespacing*{\bhead}{0pt}{14pt}{0pt}

\makeatletter
\newlength{\secnumwidth}
\setlength{\secnumwidth}{0pt}
\providecommand*{\usesecnumwidth}{0pt}

\newcommand*{\secnumwidthbox}[1]{%
  \begingroup
    \sbox0{#1}%
    \ifdim\wd0>\secnumwidth
      \global\secnumwidth=\wd0\relax
    \fi
  \endgroup
  \leavevmode
  \hbox to 
    \ifdim\usesecnumwidth>\secnumwidth
      \usesecnumwidth
    \else
      \secnumwidth
    \fi
  {#1\hfil}%
}

\let\org@chapterformat\chapterformat
\renewcommand*{\chapterformat}{%
  \secnumwidthbox{\org@chapterformat}%
}

\renewcommand*{\othersectionlevelsformat}[3]{%
  \secnumwidthbox{#3\autodot\hfill\enskip}%
}

% Patch for titlesec
\patchcmd\ttlh@hang{%
  \sbox\z@{#2\strut\ttl@calc\hspace{#3}}%
}{%
  \sbox\z@{\secnumwidthbox{#2\strut\ttl@calc\hspace{#3}}}%
}{}{\errmessage{Cannot patch \string\ttlh@hang}}

\AfterLastShipout{%
  \if@filesw
    \immediate\write\@mainaux{%
      \string\gdef\string\usesecnumwidth{\the\secnumwidth}%
    }%
  \fi
  \ifdim\usesecnumwidth=\secnumwidth
  \else
    \@latex@warning@no@line{Rerun LaTeX, because \noexpand\usesecnumwidth
      has changed}
  \fi
}
\makeatother

\begin{document}
\chapter{Chapter}
\section{Section}
\subsection{Subsection}
\end{document}

Result titlesec

1
  • Your example works just fine, but I can´t use it with my titleformat etc. I can´t figure out why. I posted a MME in my previous posting. I guess there is a conflict between my spacing and its measuring. By the way: I am using a custom document class. I changed the the renewcommand into a newcommand and it did not work either. Jun 18, 2014 at 9:46
1

The simplest way is to wrap the heading counters in a fixed-width box. For example, a 40pt width box:

\makeatletter
\def\@seccntformat#1{\makebox[40pt][l]{\csname the#1\endcsname}}
\makeatother

sample preview

wraper box

You must log in to answer this question.

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