3

Along the lines of similar questions on this site, e.g.:

Changing the section title

I wanted to define a custom, section-like structure of my own -- \unit -- which would be similar to a section. However, I actually wanted it to have the font size and spacing above and below it of subsection in the default article class (because it is at subsection level in my document). I also wanted a \subunit to go underneath it.

Now I know I could have modified \section and \subsection with titlesec or whatever, but I wasn't very interested in that, because I wanted to keep \section and \subsection and have another, independent set of structures, \unit and \subunit.

So what I did was to simply take the standard definition of \subsection in article.cls:

\newcommand\subsection{\@startsection{subsection}{2}{\z@}%
                                     {-3.25ex\@plus -1ex \@minus -.2ex}%
                                     {1.5ex \@plus .2ex}%
                                     {\normalfont\large\bfseries}}

And use it to define unit. Ditto for \subsubsection and \subunit:

\makeatletter
\newcounter{unit}
\newcounter{subunit}[unit]

\renewcommand{\theunit}{\arabic{unit}}
\renewcommand{\thesubunit}{\theunit.\arabic{subunit}}

\newcommand\unit{\@startsection{unit}{1}{\z@}%
  {-3.25ex \@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\normalfont\large\bfseries}}

\newcommand\subunit{\@startsection{subunit}{2}{\z@}%
  {-3.25ex \@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\normalfont\normalsize\bfseries}}

\let\unitmark\@gobble
\let\subunitmark\@gobble
\makeatother

I was feeling quite pleased with myself, but then I decided to modify my definition of unit (only) to put the word Unit before the number and a colon afterwards, i.e.:

Unit 1: Normal Working

This is definitely something I'd like to be able to do elsewhere and I'm not the only one, I think. It'd be nice to easily be able to produce section headings along the lines of Exercise 1, Question 1 and even Chapter 1 if you don't want the full blown chapter style of the report class.

So what I resorted to doing was delving into the internals of \@startsection and re-implementing them, hard coding the parameters I'd decided on and getting rid of all the unnecessary \if \fis, since I wasn't defining an ultra-generic structure, but a specific instantiation.

That led me to this:

\newcommand\unit[1]{%
  \par
  \@tempskipa -3.25ex \@plus -1ex \@minus -.2ex\relax
  \@tempskipa -\@tempskipa \@afterindentfalse
  \addpenalty\@secpenalty\addvspace\@tempskipa
  \refstepcounter{unit}%
  \begingroup
    \normalfont\large\bfseries{%
      \@hangfrom{\hskip \z@\relax Unit~\theunit:\space}%
        \interlinepenalty \@M #1\@@par}%
  \endgroup
  \@xsect{1.5ex \@plus .2ex}}

Which is the result of taking the definitions of \@startsection and \@sect from latex.ltx

\def\@startsection#1#2#3#4#5#6{%
  \if@noskipsec \leavevmode \fi
  \par
  \@tempskipa #4\relax
  \@afterindenttrue
  \ifdim \@tempskipa <\z@
    \@tempskipa -\@tempskipa \@afterindentfalse
  \fi
  \if@nobreak
    \everypar{}%
  \else
    \addpenalty\@secpenalty\addvspace\@tempskipa
  \fi
  \@ifstar
    {\@ssect{#3}{#4}{#5}{#6}}%
    {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}}
\def\@sect#1#2#3#4#5#6[#7]#8{%
  \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{\hskip #3\relax\@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{\hskip #3\relax
      \@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}}

And, as I say, putting in values and getting rid of unnecessary \if statements and alternatives I won't be using.

The Problem

The problem is, the new version of \unit produces excess vertical space above the heading, as you can see if you compare the output of the two.

Code for output on left

\documentclass[12pt]{article}
\pagestyle{plain}
\usepackage[margin=1.8cm]{geometry}
\geometry{a4paper}
\usepackage[parfill]{parskip}
\usepackage{amsmath}

\makeatletter
\newcounter{unit}
\newcounter{subunit}[unit]

\renewcommand{\theunit}{\arabic{unit}}
\renewcommand{\thesubunit}{\theunit.\arabic{subunit}}

\newcommand\unit{\@startsection{unit}{1}{\z@}%
  {-3.25ex \@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\normalfont\large\bfseries}}
% \newcommand\unit[1]{%
%   \par
%   \@tempskipa -3.25ex \@plus -1ex \@minus -.2ex\relax
%   \@tempskipa -\@tempskipa \@afterindentfalse
%   \addpenalty\@secpenalty\addvspace\@tempskipa
%   \refstepcounter{unit}%
%   \begingroup
%     \normalfont\large\bfseries{%
%       \@hangfrom{\hskip \z@\relax Unit~\theunit:\space}%
%         \interlinepenalty \@M #1\@@par}%
%   \endgroup
%   \@xsect{1.5ex \@plus .2ex}}
\newcommand\subunit{\@startsection{subunit}{2}{\z@}%
  {-3.25ex \@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\normalfont\normalsize\bfseries}}

\let\unitmark\@gobble
\let\subunitmark\@gobble
\makeatother

\title{Log Book}
\date{}

\begin{document}

\maketitle

\section*{Activity Log}

\unit{Normal Working}

\subunit{Shift handover}

A good shift handover includes discussion of the past, present and future: what
has happened, what is happening now, what might happen in future.

\end{document}

Code for output on right

\documentclass[12pt]{article}
\pagestyle{plain}
\usepackage[margin=1.8cm]{geometry}
\geometry{a4paper}
\usepackage[parfill]{parskip}
\usepackage{amsmath}

\makeatletter
\newcounter{unit}
\newcounter{subunit}[unit]

\renewcommand{\theunit}{\arabic{unit}}
\renewcommand{\thesubunit}{\theunit.\arabic{subunit}}

% \newcommand\unit{\@startsection{unit}{1}{\z@}%
%   {-3.25ex \@plus -1ex \@minus -.2ex}%
%   {1.5ex \@plus .2ex}%
%   {\normalfont\large\bfseries}}
\newcommand\unit[1]{%
  \par
  \@tempskipa -3.25ex \@plus -1ex \@minus -.2ex\relax
  \@tempskipa -\@tempskipa \@afterindentfalse
  \addpenalty\@secpenalty\addvspace\@tempskipa
  \refstepcounter{unit}%
  \begingroup
    \normalfont\large\bfseries{%
      \@hangfrom{\hskip \z@\relax Unit~\theunit:\space}%
        \interlinepenalty \@M #1\@@par}%
  \endgroup
  \@xsect{1.5ex \@plus .2ex}}
\newcommand\subunit{\@startsection{subunit}{2}{\z@}%
  {-3.25ex \@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\normalfont\normalsize\bfseries}}

\let\unitmark\@gobble
\let\subunitmark\@gobble
\makeatother

\title{Log Book}
\date{}

\begin{document}

\maketitle

\section*{Activity Log}

\unit{Normal Working}

\subunit{Shift handover}

A good shift handover includes discussion of the past, present and future: what
has happened, what is happening now, what might happen in future.

\end{document}

enter image description here

4

In your cleanup of \@startsection, this conditional:

  \if@nobreak
    \everypar{}%
  \else
    \addpenalty\@secpenalty\addvspace\@tempskipa
  \fi

evaluates to true, thus \everypar{}. In your code you used the false branch, thus the difference.

But I invite you to reconsider your approach. Stripping down \@startsection and its subordinates will, for starters, make hyperref not work with your newly-defined sections (hyperref patches \@startsection).

Instead, you can redefine \theunit and \thesubunit to print the section headings with the format you want:

\renewcommand{\theunit}{Unit~\arabic{unit}:\space}
\renewcommand{\thesubunit}{Subunit~\arabic{unit}.\arabic{subunit}:\space}

Also, if you want the \quad space after \thesection but not after \theunit, you can redefine \@seccntformat to check for that with a little help from expl3 (could be done without expl3, but why? ;-)

\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \StrCaseF \str_case:nnF
\ExplSyntaxOff
\renewcommand{\@seccntformat}[1]{%
  \csname the#1\endcsname
  \StrCaseF{#1}{{unit}{}{subunit}{}}{\quad}% To remove \quad from \unit and \subunit
}

With that, the output looks like what you want:

enter image description here

Full code:

\documentclass[12pt]{article}
\pagestyle{plain}
\usepackage[margin=1.8cm]{geometry}
\geometry{a4paper}
\usepackage[parfill]{parskip}
\usepackage{amsmath}

\makeatletter
\newcounter{unit}
\newcounter{subunit}[unit]

\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \StrCaseF \str_case:nnF
\ExplSyntaxOff

\renewcommand{\theunit}{Unit~\arabic{unit}:\space}
\renewcommand{\thesubunit}{Subunit~\arabic{unit}.\arabic{subunit}:\space}
\renewcommand{\@seccntformat}[1]{%
  \csname the#1\endcsname
  \StrCaseF{#1}{{unit}{}{subunit}{}}{\quad}% To remove \quad from \unit and \subunit
}

\newcommand\unit{\@startsection{unit}{1}{\z@}%
  {-3.25ex \@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\normalfont\large\bfseries}}
\newcommand\subunit{\@startsection{subunit}{2}{\z@}%
  {-3.25ex \@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\normalfont\normalsize\bfseries}}

\let\unitmark\@gobble
\let\subunitmark\@gobble
\makeatother

\title{Log Book}
\date{}
\pagenumbering{gobble}
\begin{document}

\maketitle

\section*{Activity Log}

\unit{Normal Working}

\subunit{Shift handover}

A good shift handover includes discussion of the past, present and future: what
has happened, what is happening now, what might happen in future.

\end{document}
|improve this answer|||||
  • Fantastic! I thought I had tried the \everypar{} branch, but the thing is I tried that and it didn't work, then I tried something else and that didn't work, but obviously I needed to try both of them together! I didn't know I was breaking hyperref and I'm happy to hear about better solutions, but are there any side effects to your alternative? If not, then I'm really quite tempted by it. – Au101 Feb 9 at 4:05
  • I have a lot of time for the basic classes and the basic sectioning commands provided by them, but I've long been a proponent of LaTeX's define a complex structure at the start and then use that and you can redefine it at will if you change a design choice. And as I say the basics are good enough in most cases, but I've long thought it'd be good to have a way to easily 'roll your own'. Customising, for example, section is quite easy with titlesec, but defining totally separate structures seems quite tricky. And the question 1, section 1, exercise 1, etc. style is something i've long wanted – Au101 Feb 9 at 4:07
  • @Au101 You will not break hyperref (since you are not changing \@startsection itself), but hyperref's hyprelinking features will not work for \(sub)unit, because it doesn't know it has to patch (neither how to patch) \(sub)unit. As far as I can see, there is no issue with the solution I proposed: \the(sub)unit and \@seccntformat are customisation points, so it's okay to redefine them. That's how I'd do it. – Phelype Oleinik Feb 9 at 4:09
  • Thank you very much – Au101 Feb 9 at 4:14
  • @Au101 About LaTeX's design: its current appearance is essentially a backwards compatibility to Lamport's LaTeX, which dates back to the 90s or earlier. We can't change anything there without breaking the documents of hundreds (if not thousands) of users. The LaTeX3 project's aim is to provide an actual typesetting system based on document elements and how the document designer would put them, with no strings attached to LaTeX's original layout (see this answer). We just lack the manpower to do all that :-) – Phelype Oleinik Feb 9 at 4:14

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.