9

In a document I'm currently working on, we often change the hierarchy of chapters/sections etc. So within the text I would like to reference the current level of hierarchy in a sentence like

In this chapter we will talk about ...

As the structure changes often, I would like to add the name of the current hierarchy level ("chapter" in the example above) to some command, so that it adapts automatically, when we change the structure again.

I could not find, however, a command for this. Most commands are focused towards getting either the current section's title or the reference to some other section including the section number.

So given this example, what would I need to write as \someCommand to get the current chapter/section/subsection/etc. name?

\documentclass[a4paper]{memoir}
\begin{document}

\chapter{Example-Chapter}

Current level: \someCommand - should be "chapter" and not "Example-Chapter"

\section{Example-Section}

Current level: \someCommand - should be "section" and not "Example-Section"

\end{document}

4 Answers 4

7

You can use the fact that \chapter resets the linked counters and the same happens for \section.

\documentclass[a4paper]{memoir}

\newcommand{\someCommand}{%
  \ifnum\value{section}=0
    chapter%
  \else
    \ifnum\value{subsection}=0
      section%
    \else
      subsection%
    \fi
  \fi
}
\setsecnumdepth{subsection}

\begin{document}

\chapter{Example chapter}

Current level: \someCommand, should be ``chapter''

\section{Example section}

Current level: \someCommand, should be ``section''

\subsection{Example subsection}

Current level: \someCommand, should be ``subsection''

\section{Example section}

Current level: \someCommand, should be ``section''

\end{document}

enter image description here

6

This version also works for unnumbered structure levels. The structure macro definitions \chapter, \section etc. are extended at the begin with the definition of the structure level name and number.

\documentclass{report}
\setcounter{secnumdepth}{-1}

\usepackage{etoolbox}
\newcommand*{\tmp}[3]{%
  \pretocmd#1{%
    \gdef\StructureLevelNumber{#2}%
    \gdef\StructureLevelName{#3}%
  }{}{%
    \errmessage{Cannot patch \string#1}%
  }%
}
\tmp\part{-1}{part}
\tmp\chapter{0}{chapter}
\tmp\section{1}{section}
\tmp\subsection{2}{subsection}
\tmp\subsubsection{3}{subsubsection}
\tmp\paragraph{4}{paragraph}
\tmp\subparagraph{5}{subparagraph}

\newcommand*{\test}{%
  We are in structure level ``\StructureLevelName'' %
  (\StructureLevelNumber).%
}

\begin{document}
\part{Part title}
\test
\chapter{Chapter title}
\test
\section{Section title}
\test
\subsection{Subsection title}
\test
\subsubsection{Subsubsection title}
\test
\paragraph{Paragraph title.}
\test
\subparagraph{Subparagraph title.}
\test
\end{document}

Third page:

Page 3

References with structure levels

Package zref supports the definition of new properties that can be stored in labels (\zlabel, \zref@label...) and referenced (\zref, \zref@extract...).

The following example only used integer numbers to identify the structure levels and generates the name for the structure level via macro \StructureLevelName.

\documentclass{report}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{color}
\setcounter{secnumdepth}{-1}

\usepackage{etoolbox}
\newcommand*{\tmp}[2]{%
  \pretocmd#1{%
    \gdef\StructureLevel{#2}%
  }{}{%
    \errmessage{Cannot patch \string#1}%
  }%
}
\tmp\part{-1}
\tmp\chapter{0}
\tmp\section{1}
\tmp\subsection{2}
\tmp\subsubsection{3}
\tmp\paragraph{4}
\tmp\subparagraph{5}
\newcommand*{\StructureLevel}{-2}

\newcommand*{\StructureLevelName}[1]{%
  \ifcase\numexpr(#1)\relax
    chapter%
  \or
    section%
  \or
    subsection%
  \or
    subsubsection%
  \or
    paragraph%
  \or
    subparagraph%
  \else
    \ifnum\numexpr(#1)\relax=-1 %
      part%
    \else
      unknown%
    \fi
  \fi
}

\usepackage{zref-base, zref-titleref, zref-user}
\makeatletter
\zref@newprop{StructureLevel}[-2]{\StructureLevel}
\zref@addprop{main}{StructureLevel}
\newcommand*{\zrefStructureLevelName}[1]{%
  \zref@refused{#1}%
  \StructureLevelName{%
    \zref@extractdefault{#1}{StructureLevel}{-2}%
  }%
}
\makeatother

\newcommand*{\test}{%
  We are in structure level
  ``\textcolor{red}{\StructureLevelName{\StructureLevel}}'' %
  (\textcolor{blue}{\StructureLevel}).%
}
\newcommand*{\testref}[1]{%
  \texttt{\textbackslash zlabel\{#1\}}:
  Structure element is ``\textcolor{red}{\zrefStructureLevelName{#1}}'',
  title: \textcolor{blue}{\ztitleref{#1}}\par
}


\begin{document}
\part{Part title}
\zlabel{a}
\test
\chapter{Chapter title}
\zlabel{b}
\test
\section{Section title}
\zlabel{c}
\test
\subsection{Subsection title}
\zlabel{d}
\test
\begin{equation}
  \zlabel{eq}
  E=mc^2
\end{equation}
\subsubsection{Subsubsection title}
\zlabel{e}
\test
\paragraph{Paragraph title.}
\zlabel{f}
\test
\subparagraph{Subparagraph title.}
\zlabel{g}
\test
\newpage
\testref{a}
\testref{b}
\testref{c}
\testref{d}
\testref{e}
\testref{f}
\testref{g}
\texttt{\textbackslash zlabel\{eq\}}:
  Equation \zref{eq} is in structure element
  ``\textcolor{red}{\zrefStructureLevelName{eq}}''.
\end{document}

Last page with the references:

Last page

4

While not being a unique new answer, I wanted to add this for reference:

After experimenting a little with the answer of @egreg, I also removed the "static" sectioning labels and replaced them by the ones hyperref uses, so it stays consistent with the use of \autoref in the document.

\documentclass[a4paper]{memoir}
\usepackage{hyperref}

\newcommand{\structuringLevel}{%
  \ifnum\value{section}=0
    \chapterautorefname%
  \else
    \ifnum\value{subsection}=0
      \sectionautorefname%
    \else
      \subsectionautorefname%
    \fi
  \fi
}
\setsecnumdepth{subsection}

\begin{document}

\chapter{Example chapter}

Current level: \someCommand, should be ``chapter''

\section{Example section}

Current level: \someCommand, should be ``section''

\subsection{Example subsection}

Current level: \someCommand, should be ``subsection''

\section{Example section}

Current level: \someCommand, should be ``section''

\end{document}
0

Here a solution based on the cleveref package.

Advantages:

  • It needs no low-level code. That makes the LaTeX code easier to read.
  • It distinguishes between capitalized (e.g., "Section") and not capitalized (e.g., "section"). It also provides plurals, just in case ;).
  • We use a standard package: no need to define own functions.

Disadvantages:

  • We have to label the sections \label (however, this is the usual procedure when writing a doc)

Example code

\documentclass[a4paper]{memoir}

\usepackage{cleveref}

%Redefining the names associated to the 'chapter' counter
\crefname{chapter}{chapter}{chapters} %uncapitalized
\Crefname{chapter}{Chapter}{Chapters} %capitalized
%Redefining the names associated to the 'section' counter
\crefname{section}{section}{sections}
\Crefname{section}{Section}{Sections}
%Redefining the names associated to the 'subsection' counter
\crefname{subsection}{subsection}{subsections}
\Crefname{subsection}{Subsection}{Subsections}
%... 
%You can name as many sectioning commands as you want
%...
%Redefining the names associated to the 'subparagraph' counter
\crefname{subparagraph}{subparagraph}{subparagraphs}
\Crefname{subparagraph}{Subparagraph}{Subparagraphs}

%Here set the name of the lowest section that has to be named
\setsecnumdepth{subparagraph}

\begin{document}

\chapter{Example chapter}\label{sec:level01}

Current level: \namecref{sec:level01}, should be ``chapter''.\\ %Uncapitalized name
\nameCref{sec:level01} is the current level. %Capitalized name

\section{Example section}\label{sec:level02}

Current level: \namecref{sec:level02}, should be ``section''.\\
\nameCref{sec:level02} is the current level.

\subsection{Example subsection}\label{sec:level03}

Current level: \namecref{sec:level03}, should be ``subsection''.\\
\nameCref{sec:level03} is the current level.

\subparagraph{Example subparagraph}\label{sec:level05}
Current level: \namecref{sec:level05}, should be ``subparagraph''.
\nameCref{sec:level05} is the current level.

\section{Example section}\label{sec:level04}

Current level: \namecref{sec:level04}, should be ``section''.\\
\nameCref{sec:level04} is the current level.

\end{document}

enter image description here

You must log in to answer this question.

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