9

Is there a base-LaTeX variable or macro by which one can access the title of a chapter or section?

The MWE below demonstrates a workaround, but it seems there might be a LaTeX variable or "command" already in existence?

The fact that LaTeX puts the chapter title into the header, suggests that this exists as a variable.

\documentclass{book}
\usepackage{verbatim}
\newcommand{\nowtitle}{}
\pagestyle{headings}
\begin{document}
\chapter{Stuff}

\verb!\theChapterTitle!  throws an error. 

\verb!\ChapterTitle!  throws an error.

\verb!\chaptertitle!  throws an error.

\verb!\today!
compiles as
\today

\verb!\thesection{}! compiles as \thesection{} 

\verb!\thechapter{}! compiles as \thechapter{}

\verb!\thepage{}! compiles as \thepage{} 

\verb!\nowtitle{}!  compiles as \nowtitle{}

\renewcommand{\nowtitle}{Lorem ipsum}\chapter{\nowtitle}

\verb!\nowtitle{}!  compiles as \nowtitle{}
\newpage One page 
\newpage
\verb!\nowtitle{}!  compiles as \nowtitle{}
\end{document}

2 Answers 2

8

No, there is no base LaTeX macro holding the title of the \chapter. Let's see why by looking at a call to \chapter{<title>}. Here's the definition of \chapter inside book.cls (similar inside report.cls):

\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
                    \thispagestyle{plain}%
                    \global\@topnum\z@
                    \@afterindentfalse
                    \secdef\@chapter\@schapter}

Note that \chapter doesn't take any argument. It merely conditions (via \secdef) on whether you called \chapter with/without a star *. If you called it \chapter*, it executes \@schapter, otherwise it executes \@chapter. Assuming you didn't use \chapter*, here's what \@chapter looks like:

\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
                         \refstepcounter{chapter}%
                         \typeout{\@chapapp\space\thechapter.}%
                         \addcontentsline{toc}{chapter}%
                                   {\protect\numberline{\thechapter}#1}%
                    \else
                      \addcontentsline{toc}{chapter}{#1}%
                    \fi
                    \chaptermark{#1}%
                    \addtocontents{lof}{\protect\addvspace{10\p@}}%
                    \addtocontents{lot}{\protect\addvspace{10\p@}}%
                    \if@twocolumn
                      \@topnewpage[\@makechapterhead{#2}]%
                    \else
                      \@makechapterhead{#2}%
                      \@afterheading
                    \fi}

Here argument #1 is the optional argument, while argument #2 is the mandatory argument you supplied as <title>. If you didn't supply the optional argument, this macro \secdef duplicates #2 for #1, effectively calling \chapter[<title>]{<title>}. It's at this point where one can swoop in and grab either #1 or #2 as your \nowtitle using en etoolbox patch:

\usepackage{etoolbox}

\makeatletter
\patchcmd{\@chapter}% <cmd>
  {\ifnum}% <search>
  {\edef\nowtitle{#1}\ifnum}% <replace>
  {}{}% <success><failure>
\makeatother

As you should see from the definition of \@chapter, #1 is used within \chaptermark and will therefore appear in the header, while #2 is used within \@makechapterhead to set the chapter heading. I chose #1 above, but you pick either (or store both).

\chapter* is a little different. A call to \chapter*{<title>} leads to calling \@schapter:

\def\@schapter#1{\if@twocolumn
                   \@topnewpage[\@makeschapterhead{#1}]%
                 \else
                   \@makeschapterhead{#1}%
                   \@afterheading
                 \fi}

Here there is no optional argument, only the mandatory {<title>}. It suffices to patch \@schapter as follows:

\usepackage{etoolbox}

\makeatletter
\patchcmd{\@schapter}% <cmd>
  {\if@twocolumn}% <search>
  {\edef\nowtitle{#1}\if@twocolumn}% <replace>
  {}{}% <success><failure>
\makeatother

Note that \chapter*[<other>]{<stuff>} is not allowed.

Here is a complete minimal example:

enter image description here

\documentclass{book}

\usepackage{etoolbox}

\makeatletter
\patchcmd{\@chapter}% <cmd>
  {\ifnum}% <search>
  {\edef\nowtitle{#1}\ifnum}% <replace>
  {}{}% <success><failure>
\patchcmd{\@schapter}% <cmd>
  {\if@twocolumn}% <search>
  {\edef\nowtitle{#1}\if@twocolumn}% <replace>
  {}{}% <success><failure>
\makeatother

\newcommand{\nowtitle}{}

\pagestyle{headings}

\begin{document}

\chapter[Other]{Stuff}
% \chapter*{Stuff}

\verb!\nowtitle{}!: \nowtitle

\end{document}

It would also be possible to achieve the above patch without etoolbox, if needed. Also, a similar method can be used to store the title used for (sub)\sections:

\usepackage{etoolbox}

\makeatletter
\patchcmd{\@sect}% <cmd>
  {\ifnum}% <search>
  {\edef\nowtitle{#7}\ifnum}% <replace>
  {}{}% <success><failure>
\patchcmd{\@ssect}% <cmd>
  {\@tempskipa}% <search>
  {\edef\nowtitle{#5}\@tempskipa}% <replace>
  {}{}% <success><failure>
\makeatother

Argument #7 and #8 respectively point to (sub)\section[<#7>]{<#8>}.


It is often better using packages which provide similar functionality. For example, nameref and titleref.

7

You can hook into the mechanism which builds the header to save the chapter title. You're right, it is already saved but not in an easily accessible manner.

\documentclass{book}

\newcommand*\nowtitle{}

\let\oldchaptermark=\chaptermark
\renewcommand*\chaptermark[1]{%
  \renewcommand*\nowtitle{#1}%
  \oldchaptermark{#1}}

\begin{document}

\chapter{Stuff}

\nowtitle

\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 .