About
Shop
LaTeX
Software
Books
Gallery
News
Contact
Blog
Settings
Account


6.5.1 Hierarchical Paragraph Numbering

Suppose you want a document that looks something like the following:

Information About Us

  1. This website is run by the Secret Lab of Experimental Stuff (“We”, “Our”). We operate from the University of Somewhere.

Our Products

  1. All Products shown on our site are subject to availability.
  2. You may only purchase our products if you are at least 18 years old.

Refunds

  1. You are entitled to a refund unless:
    1. you have eaten the mind-controlling cookies;
    2. you have thrown the exploding chocolates;
    3. you have used the ray gun as:
      1. a table chock;
      2. a weapon unless:
        1. you have a ray gun permit;
        2. you are an extraterrestrial.

If your browser doesn't implement the CSS setting, each section heading is numbered and each nested level is in the form 1.1. (first level), 1.1.1. (second level), 1.1.1.1 (third level) and 1.1.1.1.1. (fourth level).

End of Image.


The simplest way of achieving this is to use the enumerate environment (described in Volume 1) and redefine the way the counters are displayed. By default, LaTeX allows up to four nested enumerate environments. Each level has a separate counter: enumi, enumii, enumiii and enumiv. Recall from Volume 1 that the displayed value of a counter is governed by the command:

\the⟨counter

(For example, \theenumi.) The default formats for each level use: \arabic, \alph, \roman and \Alph. The format used if the items are cross-referenced using the \label/\ref mechanism prefixes \the⟨counter with:

\p@⟨counter

For example, \p@enumiv\theenumiv. The prefix is ignored if \p@⟨counter doesn't exist (so just \the⟨counter is used).

The above \the⟨counter and \p@⟨counter are general counter-related commands. In addition, for the enumerate environment, there are also commands that determine the item label formats:

\label⟨counter

(For example, \labelenumi for the first level.)

Example:

Suppose you want to have a lower case letter for the third level enumerate items:

\renewcommand*{\theenumiii}{\alph{enumiii}}

and you want the label for the third level enumerate items to use parentheses:

\renewcommand*{\labelenumiii}{(\theenumiii)}

but when you cross-reference a third level enumerate item, \ref should use the format ⟨level1⟩.⟨level2⟩.⟨level3⟩:

\renewcommand*{\p@enumiii}{\theenumi.\theenumii.}

or, similarly setting \p@enumii:

\renewcommand*{\p@enumii}{\theenumi.}
\renewcommand*{\p@enumiii}{\p@enumii\theenumii.}

Example 36. Nested Enumeration

To reproduce the format shown at the start of this section, the standard \section command can be used for the first level (“Information About Us”, “Our Products” and “Refunds”). The levels below this can be created using nested enumerate environments, where the counter formats are defined as:

and the labels are defined as:

Since all the counter formats (\theenumi, …, \theenumiv) are now hierarchical, the internal commands used as a prefix by the cross-referencing mechanism need to be defined to do nothing:

The text can now be formatted as follows:

\section{Information About Us}

\begin{enumerate}
 \item This website is run by the Secret Lab of Experimental Stuff 
  (``We'', ``Our''). We operate from the University of Somewhere.
\end{enumerate}

\section{Our Products}

\begin{enumerate}
 \item All Products shown on our site are subject to availability.

 \item You may only purchase our products if you are at least  
  18 years old.
\end{enumerate}

\section{Refunds}

\begin{enumerate}
 \item You are entitled to a refund unless:
 \begin{enumerate}
   \item you have eaten the mind-controlling cookies;
   \item you have thrown the exploding chocolates;
   \item you have used the ray gun as:
   \begin{enumerate}
     \item a table chock;
     \item a weapon unless:
     \begin{enumerate}
       \item \label{permit}you have a ray gun permit;
       \item you are an extraterrestrial.
     \end{enumerate}
   \end{enumerate}
 \end{enumerate}
\end{enumerate}

I've labelled one of the items using \label, so I can reference it using:

See clause~\ref{permit}.

which produces:

See clause 3.1.3.2.1

You can download or view a complete document.


6.5.1.1 Delving Deeper

If your document is complicated enough to require deeper levels than the default maximum of four, it's possible to extend the maximum enumerate depth. In order to do this, it's necessary to:

  1. Modify the enumerate environment to allow more levels. This may additionally require modifying the underlying generic list environment that only allows a maximum of six nested list environments.

  2. Define a new enumn⟩ counter (using \newcounter) for each level ⟨n⟩, where ⟨n⟩ is the lower case Roman numeral representing the level index. (For example, enumv for the fifth level).

  3. Define a new \labelenumn⟩ command for the item label for each level ⟨n⟩.

  4. Define a new \leftmarginn⟩ length (using \newlength and \setlength) for the left margin for each level ⟨n⟩.

  5. Define a new \@listn⟩ command that sets up the margin for each level ⟨n⟩.

The counters and label commands are the easy part. For example, to allow a maximum of six levels, counters and label commands need to be defined for levels 5 (v) and 6 (vi):

\newcounter{enumv}[enumiv]
\newcounter{enumvi}[enumv]
\newcommand*{\labelenumv}{\theenumv.}
\newcommand*{\labelenumvi}{\theenumvi.}

(If necessary, you can also redefine the counter prefixes \p@⟨counter.)

The left margin lengths are already provided up to six levels, but supposing you needed a seventh (vii), this would be done using:

\newlength\leftmarginvii
\setlength{\leftmarginvii}{15pt}

(Change the length as required.)

The \@listn⟩ commands are more complicated. These commands need to set the length \leftmargin to the current level's left margin \leftmarginn⟩ and set the \labelwidth length to \leftmarginn⟩ less the value of \labelsep. Again, there are already up to six levels provided, but supposing you needed a seventh (vii), this would be done using:

\newcommand*{\@listvii}{%
  \setlength{\leftmargin}{\leftmarginvii}%
  \setlength{\labelwidth}{\leftmarginvii}%
  \addtolength{\labelwidth}{-\labelsep}%
}

Modifying the enumerate environment is slightly harder. This can be done using \renewenvironment (described in Volume 1) however, in this case, only the beginning of the environment needs changing. The \begin{env-name} command works by (amongst other things) using the command \⟨env-name so \begin{enumerate} calls the command \enumerate, and it's this command that needs modifying. Recall from §2.1.1 Macro Definitions that you can find out the definition of a command using either \show in your document or using the texdef script. If I run:

texdef -t latex enumerate

I get the response (tidied up a bit for legibility):

\enumerate:
macro:->\ifnum \@enumdepth >\thr@@
  \@toodeep 
\else
  \advance\@enumdepth\@ne
  \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
  \expandafter\list\csname label\@enumctr\endcsname{%
     \usecounter\@enumctr
     \def\makelabel##1{\hss\llap{##1}}%
   }%
\fi
The key part here is the TeX conditional:
\ifnum \@enumdepth >\thr@@
This tests if the number stored in the \@enumdepth register is greater than \thr@@ (which is defined in the LaTeX kernel to have the value 3). So the new definition of \enumerate needs to change \thr@@ to one less than the new maximum.

Since this code contains internal commands, the new definition should either be placed in a class or package or, if used in the document, be placed between \makeatletter and \makeatother. Therefore to set the maximum to six levels:

\makeatletter

\renewcommand*{\enumerate}{%
  \ifnum \@enumdepth > 5
    \@toodeep
  \else
    \advance\@enumdepth\@ne
    \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
    \expandafter\list\csname label\@enumctr\endcsname{%
       \usecounter\@enumctr
       \def\makelabel##1{\hss\llap{##1}}%
    }%
  \fi
}

\makeatother

If you really do need more than six levels (although I hope you don't), you similarly need to modify \list, which by default tests if \@listdepth is greater than five.

Exercise 20. Extending the Maximum enumerate Depth

For this exercise, extend the maximum enumerate depth to 6 levels (as described above), so that you can create the following:

The resulting output is approximately:

Information About Us

  1. This website is run by the Secret Lab of Experimental Stuff (“We”, “Our”). We operate from the University of Somewhere.

Our Products

  1. All Products shown on our site are subject to availability.
  2. You may only purchase our products if you are at least 18 years old.

Refunds

  1. You are entitled to a refund unless:
    1. you have eaten the mind-controlling cookies;
    2. you have thrown the exploding chocolates;
    3. you have used the ray gun as:
      1. a table chock;
      2. a weapon unless:
        1. you have a ray gun permit;
        2. you are an extraterrestrial and:
          1. are not a resident of the planet Earth;
          2. have a licence under Galactic Treaty 1024, unless:
            1. you come under Article 24, or
            2. you live on Saturn.

If your browser doesn't implement the CSS setting, each section heading is numbered and each nested level is in the form 1.1. (first level), 1.1.1. (second level), 1.1.1.1. (third level), 1.1.1.1.1. (fourth level), 1.1.1.1.1.1. (fifth level) and 1.1.1.1.1.1.1. (sixth level).

End of Image.


The choice of document class is up to you. For example, you can use the article or scrartcl classes. (If you use scrartcl, the class option numbers=endperiod will display a full stop after the section numbers.) You can download or view a solution.


This book is also available as A4 PDF or 12.8cm x 9.6cm PDF or paperback (ISBN 978-1-909440-07-4).

© 2015 Dickimaw Books. "Dickimaw", "Dickimaw Books" and the Dickimaw parrot logo are trademarks. The Dickimaw parrot was painted by Magdalene Pritchett.

Terms of Use Privacy Policy Cookies Site Map FAQs