10

How can protrusion in the headings of document divisions be fixed when using pdfLaTeX and titlesec?

In this answer I provide a tentative patch which allows character protrusion to work normally in the titles of sectional divisions (\section, \section*, \paragraph, \subparagraph* etc.)

For example:

\documentclass[a4paper]{book}
\usepackage[utf8]{inputenc}
\usepackage[showframe,pass]{geometry}
\usepackage{cfr-lm}
\usepackage[protrusion=true,factor=3000]{microtype}
\makeatletter
\def\@ssect#1#2#3#4#5{% modified from latex.ltx - for starred sections below chapter level
  \@tempskipa #3\relax
  \ifdim \@tempskipa>\z@
    \begingroup
      #4{%
        \interlinepenalty \@M \noindent #5\@@par}%
    \endgroup
  \else
    \def\@svsechd{#4{%
        \cfr@microfix@sec{#1}#5}}%
  \fi
  \@xsect{#3}}
\def\@sect#1#2#3#4#5#6[#7]#8{% modified from latex.ltx - for unstarred sections below chapter level
  \ifnum #2>\c@secnumdepth
    \let\@svsec\@empty
  \else
    \refstepcounter{#1}%
    \protected@edef\@svsec{\@seccntformat{#1}\relax}%
  \fi
  \@tempskipa #5\relax
  \ifdim \@tempskipa>\z@
    \begingroup
      #6{%
        \@hangfrom{\cfr@microfix@sec{#3}\@svsec}%
          \interlinepenalty \@M #8\@@par}%
    \endgroup
    \csname #1mark\endcsname{#7}%
    \addcontentsline{toc}{#1}{%
      \ifnum #2>\c@secnumdepth \else
        \protect\numberline{\csname the#1\endcsname}%
      \fi
      #7}%
  \else
    \def\@svsechd{%
      #6{\cfr@microfix@sec{#3}%
      \@svsec #8}%
      \csname #1mark\endcsname{#7}%
      \addcontentsline{toc}{#1}{%
        \ifnum #2>\c@secnumdepth \else
          \protect\numberline{\csname the#1\endcsname}%
        \fi
        #7}}%
  \fi
  \@xsect{#5}}
\newcommand*\cfr@microfix@sec[1]{%
  \ifdim#1=0pt
    \noindent
  \else
    \hskip #1\relax
  \fi}
\makeatother

\begin{document}
\let\cleardoublepage\relax
\chapter{`Charlie}
\chapter*{`Charlie}
\section{Charlie nss}
\noindent {\Large\bfseries 1.1}
\section*{`Charlie ss}
\subsection{Charlie nsss}
\subsection*{`Charlie sss}
\subsubsection{`Charlie nsss}
\subsubsection*{`Charlie ssss}

\paragraph{`Charlie np} paragraph

\paragraph*{`Charlie sp} paragraph

\subparagraph{`Charlie nsp} subparagraph

\subparagraph*{`Charlie ssp} subparagraph

\noindent{\Large\bfseries`Charlie\par}
\noindent `Charlie
\end{document}

patched headings in a standard class

This patch seems to work for the standard classes (minimal testing) and the KOMA classes (ultra-minimal testing). No patch is necessary for Memoir, where protrusion works out-of-the-box, or for document divisions above \section, such as \chapter and \chapter*.

Moreover, the patch should - theoretically - work with customised versions of \@section etc.

However, it does not work if titlesec is loaded because the package apparently uses an entirely different mechanism for formatting the headings.

That is, adding

\usepackage{titlesec}

to the preamble breaks the patch:

broken patch

I can't even work out which part of the code is actually responsible for the problem. If I alter the definition of \ttlh@<shape>#1#2#3#4#5#6#7#8, for example, and then redefine a section title with \titleformat{\paragraph}[runin]..., I can't restore the protrusion even if a left quotation mark is inserted at the very start of the definition:

\def\ttlh@runin#1#2#3#4#5#6#7#8{%
  `x\vskip 0pt
  \global\@noskipsectrue
  \gdef\ttl@makeline##1{##1}%
  \ttl@changecentercr
  #1{\ifhmode\ttl@hmode@error\fi
     \global\sbox\ttl@box{%
       \ttl@calc\hspace{#6}%
       \ifttl@label{\strut#2}\ttl@calc\hspace{#3}\fi
       #4{#8}#5\unskip}}%
    \gdef\@svsechd{\unhbox\ttl@box}}

Nor can I figure out whether one of the many \ttl@spacing... is responsible. I can't find the documentation explaining implementation and comments in the package files themselves are not casting much light on the code, at least for me. Then again, I'm not even sure that titlesec.sty is the correct file to be looking in.

I understand that the tanglement is the result of an attempt by the package to pick up on the existing sectioning commands so that it works, at least in theory, with non-standard classes. But knowing the cause of its impenetrability makes it no less impenetrable :(.

  • @Johannes_B Best solution is to banish titlesec in my opinion, but that's probably not what you had in mind. – cfr Apr 30 '17 at 12:33
  • Why not? I am not a big fan of titlesec :-) – Johannes_B Apr 30 '17 at 12:35
  • @Johannes_B My general motto is: whatever you want to do with titlesec is more easily done without. (Where the ambiguity is intended.) Every config I've used it in I've ended up eliminating it from because it is totally impossible to get it to do what I want or to tweak later. Possibly the code is good. I don't know. But the documentation is not. It fails to mention crucial points, leaving you to spend hours attempting to do what the documentation suggests should be possible, but which the code ensures is impossible. I understand other people like it. I have an allergy. – cfr Apr 30 '17 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.