summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/fancyhdr/fancyhdr.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/fancyhdr/fancyhdr.dtx')
-rw-r--r--Master/texmf-dist/source/latex/fancyhdr/fancyhdr.dtx1122
1 files changed, 835 insertions, 287 deletions
diff --git a/Master/texmf-dist/source/latex/fancyhdr/fancyhdr.dtx b/Master/texmf-dist/source/latex/fancyhdr/fancyhdr.dtx
index f0666afc42b..60aa3469b23 100644
--- a/Master/texmf-dist/source/latex/fancyhdr/fancyhdr.dtx
+++ b/Master/texmf-dist/source/latex/fancyhdr/fancyhdr.dtx
@@ -22,11 +22,13 @@
%
% \begin{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\NeedsTeXFormat{LaTeX2e}
+% \changes{V5.2}{2025/01/15}{Require \LaTeX{} version at least 2018-04-01.}
+%<fancyhdr|extramarks|extramarks-v4>\NeedsTeXFormat{LaTeX2e}[2018-04-01]
+%<fancyheadings>\NeedsTeXFormat{LaTeX2e}
%<fancyhdr>\ProvidesPackage{fancyhdr}%
%<fancyheadings>\ProvidesPackage{fancyheadings}
%<extramarks|extramarks-v4>\ProvidesPackage{extramarks}
-%<fancyhdr|extramarks> [2025/01/07 v5.1.1
+%<fancyhdr|extramarks> [2025/02/07 v5.2
%<fancyhdr> Extensive control of page headers and footers]%
%<fancyheadings> [2022/11/09 v4.1
%<fancyheadings> Legacy package to call fancyhdr]
@@ -76,7 +78,7 @@
\usepackage{subcaption}
\usepackage[colorlinks,linktocpage]{hyperref}
\usepackage{ifthen}
-\usepackage{xparse}
+\ifdefined\NewDocumentCommand\else\usepackage{xparse}\fi
\usepackage{enumitem}
\setlist{itemsep=1pt}
\usepackage{fancyhdr}
@@ -134,14 +136,48 @@
}
% Our own page style:
+\NewMarkClass{whichpage}
+\newcommand\whichpage{}
+
+\newcommand\checkposinpage{
+ \ifthenelse{\lengthtest{\pagetotal<4\baselineskip}}%
+ {\renewcommand{\whichpage}{top\thepage}}%
+ {\renewcommand{\whichpage}{\thepage}}%
+}
+
\pagestyle{fancy}
\setlength{\headheight}{16.0pt}
\addtolength{\headwidth}{\marginparsep}
\addtolength{\headwidth}{0.5\marginparwidth}
+\newcommand\normalheader{%
+ \ifthenelse{\equal{\FirstMark{whichpage}}{\thepage}}%
+ {\TopMark{2e-right-nonempty}}%
+ % whichpage != page
+ {\IfMarksEqualTF{whichpage}{top}{first}%
+ {\TopMark{2e-right-nonempty}}% no mark on this page
+ {\rightmark}% title at/near the top of the page
+ }%
+}
+
\fancyhf{}
-\fancyhead[L]{\rightmark}
+\fancyhead[L]{\normalheader}
\fancyhead[R]{\textbf{\thepage}}
-\renewcommand{\sectionmark}[1]{\markright{\thesection\quad#1}}
+
+\AddToHook{cmd/section/before}{\checkposinpage}
+\AddToHook{cmd/subsection/before}{\checkposinpage}
+
+\newcommand\setmarks[1]{%
+ \InsertMark{whichpage}{\whichpage}%
+ \markright{#1}%
+}
+
+\renewcommand{\sectionmark}[1]{%
+ \setmarks{\thesection\quad#1}%
+}%
+
+\renewcommand{\subsectionmark}[1]{%
+ \setmarks{\thesubsection\quad#1}%
+}%
% Page style for demonstrating struts, \headruleskip and \footruleskip.
@@ -169,7 +205,7 @@
\fancyhead[L]{%
\ifthenelse{\value{page}=\getpagerefnumber{showstruts}}%
{\strutheader}%
- {\rightmark}%
+ {\normalheader}%
}
\fancyfoot[L]{%
\ifthenelse{\value{page}=\getpagerefnumber{showstruts}}%
@@ -188,6 +224,12 @@
}
}
+\fancypagestyle{copyright}{%
+ \fancyfoot[L]{%
+ Copyright \copyright~1994-2025 by Pieter van Oostrum. Distributed under the \LaTeX{}\\
+ Project Public License (LPPL), see \url{http://www.latex-project.org/lppl.txt}}
+}
+
\newcommand\exampleindex{}
\def\exampleindex#1#2#3\relax{%
\ifx \relax#2\relax \index{Example 0#1=Example #1}\else \index{Example #1#2#3}\fi}
@@ -378,7 +420,7 @@
% \maketitle
% \begin{abstract}
% This document describes how to customize the page layout of your LaTeX
-% documents, i.e., how to change page margings and sizes,
+% documents, i.e., how to change page margins and sizes,
% headers and footers, and the
% proper placement of figures and tables (collectively called floats) on
% the page.
@@ -389,11 +431,13 @@
% the \pkg{fancyhdr} and \pkg{extramarks} packages (except
% for the changes mentioned in sections~\ref{sec:version-4} and
% \ref{sec:version-5}).
-%
% \end{abstract}
%
% \tableofcontents
-% \markright{Contents}
+% \thispagestyle{copyright}
+% \newpage
+% \checkposinpage
+% \setmarks{Introduction}
%
% \begin{documentation}
% \part{Introduction}
@@ -404,8 +448,6 @@
% the user commands of the \pkg{fancyhdr} and \pkg{extramarks} packages.
%
% Part II contains elaborate documentation on page layout in \LaTeX.
-% This used to be the complete documentation of \pkg{fancyhdr} and
-% \pkg{extramarks} for several years.
%
% Part III contains Questions and Answers.
%
@@ -496,14 +538,19 @@
%
% \begin{function}{\fancyheadwidth,\fancyfootwidth,\fancyhfwidth}
% \begin{syntax}
-% \cmd{\fancyheadwidth}\oarg{places}\marg{length} \\
-% \cmd{\fancyfootwidth}\oarg{places}\marg{length} \\
-% \cmd{\fancyhfwidth}\oarg{places}\marg{length}
+% \cmd{\fancyheadwidth}\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyfootwidth}\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyhfwidth}\oarg{places}\oarg{alignment}\marg{length} \\[1ex]
+% \cmd{\fancyheadwidth}*\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyfootwidth}*\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyhfwidth}*\oarg{places}\oarg{alignment}\marg{length}
% \end{syntax}
-% These define widths for the header and footer fields. The fields will
-% be typeset in a \cs{parbox} of this width, which can be different for
-% each \emph{place}. If the width of a field is not specified, it
-% defaults to \cs{headwidth}, which may cause them to overlap. See
+% These define widths and optionally the alignments for the header and
+% footer fields. The fields will be typeset in a \cs{parbox} of this
+% width, which can be different for each \emph{place}. If the width of a
+% field is not specified, it defaults to \cs{headwidth}, which may cause
+% them to overlap. The alignment option and the \texttt{*} version are
+% available in \pkg{fancyhdr} version 5.2 and later. See
% section~\ref{sec:field-width} for more details.
% \end{function}
%
@@ -768,10 +815,6 @@
% \begin{verbatim}
% \usepackage{extramarks}[=v4]
% \end{verbatim}
-% or if you have an old \LaTeX{} system where the above doesn't work
-% \begin{verbatim}
-% \usepackage{extramarks-v4}
-% \end{verbatim}
% Please note that in that case the
% \cs{topleftxmark}, \cs{toprightxmark} and \cs{topxmark} commands may
% give you unexpected results.
@@ -816,7 +859,7 @@
% \LaTeX{} parameter but it has a different use (namely the indentation of
% lists).
% \item Most of the parameters should not be changed in the middle of a
-% document. Some changes might work at a pagebreak. If you want to change
+% document. Some changes might work at a page break. If you want to change
% the height of a single page, you can use the \cs{enlargethispage}
% command.
% \end{enumerate}
@@ -1200,24 +1243,39 @@
% now you can override this with the commands \cs{fancyheadwidth},
% \cs{fancyfootwidth} or \cs{fancyhfwidth}. These work exactly like the
% \cs{fancyhead} etc. commands but instead of a header/footer value they
-% have a \meta{length} as parameter.
+% have a \meta{length} and an optional alignment as parameters.
%
% \begin{syntax}
-% \cmd{\fancyheadwidth}\oarg{places}\marg{length} \\
-% \cmd{\fancyfootwidth}\oarg{places}\marg{length} \\
-% \cmd{\fancyhfwidth}\oarg{places}\marg{length}
+% \cmd{\fancyheadwidth}\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyfootwidth}\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyhfwidth}\oarg{places}\oarg{alignment}\marg{length} \\[1ex]
+% \cmd{\fancyheadwidth}*\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyfootwidth}*\oarg{places}\oarg{alignment}\marg{length} \\
+% \cmd{\fancyhfwidth}*\oarg{places}\oarg{alignment}\marg{length}
% \end{syntax}
% Field widths that are not specified default to \cs{headwidth}.
%
-% NOTE: The widths will be stored as expressions, not as calculated
-% values. The values will be calculated when the header or footer is
-% constructed. So they can change, for example when different pages have
-% different \cs{headwidth} and you use e.g., \texttt{0.3\cs{headwidth}}
-% or another expression with a `variable' as value. Note, however, that
-% at definition time, the width is assigned to a temporary length
-% variable, to check if it is a legal \meta{length}. So any variables
-% used in it should have a value, although this may be different from
-% the value at its final use.
+% NOTE: In the non-\texttt{*} versions of these commands, the widths
+% will be stored as expressions, not as calculated values. The values
+% will be calculated when the header or footer is constructed. So they
+% can change, for example when different pages have different
+% \cs{headwidth} and you use e.g., \texttt{0.3\cs{headwidth}} or another
+% expression with a `variable' as value. Note, however, that at
+% definition time, the width is assigned to a temporary length variable,
+% to check if it is a legal \meta{length}. So any variables used in it
+% should have a value, although this may be different from the value at
+% its final use.
+%
+% In the \texttt{*} versions of these commands, the width will be
+% calculated at the call of the command, and the calculated value will
+% be stored. So for example if you use an expression like
+% `\texttt{0.4\cs{headwidth}}', and \cs{headwidth} is 10~cm, the value
+% `4~cm' will be stored. If then then later \cs{headwidth} is changed to
+% 15~cm when the header or footer is constructed, the value
+% used for the field will still be 4~cm, which no longer is
+% `\texttt{0.4\cs{headwidth}}'. With the non-\texttt{*} version,
+% however, the value `6~cm' will be used, i.e. 0.4 of the then current
+% \cs{headwidth}.
%
% The fields are typeset in a \cs{parbox} with the specified width or
% the default \cs{headwidth}. It is still possible to get overlaps if
@@ -1331,6 +1389,52 @@
% }
% \smallskip
%
+% The \meta{alignment} optional parameter consists of two letters: a
+% vertical alignment, which indicates where the baseline of the
+% \cs{parbox} will be, followed by a horizontal alignment that specifies
+% how the lines will be positioned horizontally in the \cs{parbox}. The
+% alignment option is available in \pkg{fancyhdr} version 5.2 and later.
+% \\[1ex]
+% The possibilities for the vertical alignment are:
+% \begin{description}[font=\texttt]
+% \item[T] The baseline of the \cs{parbox} is on the top of the first line, i.e., just
+% where the top of the tallest character or item in the line is.
+% \item[t] The baseline of the \cs{parbox} is the baseline of the first line.
+% \item[c] The baseline of the \cs{parbox} is on the vertical center
+% of the \cs{parbox}.
+% \item[b] The baseline of the \cs{parbox} is the baseline of the last line.
+% \item[B] The baseline of the \cs{parbox} is on the bottom of the last line, i.e., just
+% where the bottom of the deepest character or item in the line is.
+% \item[-] Use the default vertical alignment.
+% \end{description}
+% The letters are the same as the vertical alignment in \cs{fancyhdrbox}
+% (see section~\ref{sec:fancyhdrbox} for examples). The \texttt{t},
+% \texttt{c} and \texttt{b} are the standard options for \cs{parbox}.
+% \\[1ex]
+% The horizontal alignment can be:
+% \begin{description}[font=\texttt]
+% \item[l] left aligned
+% \item[c] centered
+% \item[r] right aligned
+% \item[j] fully justified
+% \end{description}
+% These are the same as the horizontal alignment in \cs{fancyhdrbox},
+% except that the \texttt{j} option is extra. This one gives the default
+% behavior in a \cs{parbox}.
+%
+% The default for the vertical alignment is \texttt{b} for a header
+% field, and \texttt{t} for a footer field. The default for the
+% horizontal alignment is \texttt{l} for an \texttt{L} field, \texttt{c}
+% for a \texttt{C} field, \texttt{r} for an \texttt{R} field.
+%
+% Please note that a single \texttt{c} as the alignment counts as a
+% vertical alignment, and the horizontal alignment will then be the
+% default. If you want to specify only the horizontal alignment and take
+% the default for the vertical alignment, specify the vertical alignment
+% as \texttt{-}. For the horizontal alignment just omit it to get the default.
+%
+% See section~\ref{sec:with-fancyheadwidth} for examples.
+%
% \textbf{NOTE:} The \cs{fancyheadwidth},
% \cs{fancyfootwidth} and \cs{fancyhfwidth} commands are still
% experimental. This means that they have not been thoroughly tested, so
@@ -1346,7 +1450,7 @@
% package by Alexander I. Rozhenko.}.
%
% The fields in a fancy header and footer are prepared using \cs{parbox}
-% command. So, you can use multiline fields. In the header, they are
+% command. So, you can use multi-line fields. In the header, they are
% aligned to the bottom line, but, in the footer, they are aligned to
% the top line. The maximum width of every field is by default equal to the
% \cs{headwidth} (unless changed by the commands \cs{fancyheadwidth},
@@ -1410,11 +1514,11 @@
% document. Then \cs{linewidth} will be the width of the box or text in
% which it is used.
%
-% \section{The \cs{fancyhdrbox} command}
+% \section{The \Cmd{fancyhdrbox} command}
% \label{sec:fancyhdrbox}
%
% The \cs{fancyhdrbox} command can be used to align multi-line header
-% and footer fields and, for example, images. It is modeled after the
+% and footer fields and, for example, images. It is modelled after the
% \PKGindex{makecell}
% \pkg{makecell} package by Olga Lapko, but it is a bit simplified, and also has extra
% vertical alignments \texttt{T} and \texttt{B}. And the vertical
@@ -1468,7 +1572,7 @@
%
% The second optional parameter, \meta{width}, specifies the width of
% the box. If this is not given, the box has its ``natural'' width,
-% detemined by its contents. With the \meta{width} parameter, the width
+% determined by its contents. With the \meta{width} parameter, the width
% of the box is fixed to this value, independent of the contents. Note
% that there will be no automatic line breaking of the lines if they
% don't fit in the specified width. If a line is too long it will just
@@ -1594,7 +1698,7 @@
%
% The first box has an explicit \texttt{[c]} positioning, which implies
% both vertical and horizontal centering. The second one uses the
-% default positioning (i.e., it is not explicitely specified), which make
+% default positioning (i.e., it is not explicitly specified), which make
% it \texttt{[cl]}, i.e., horizontally left aligned.
%
% \begin{code}
@@ -1821,6 +1925,7 @@
% \begin{itemize}
% \item The header and footer fields in all variants (EO,LRC,HF) (12 items)
% \item The header and footer field widths in all variants (EO,LRC,HF) (12 items)
+% \item The header and footer field alignments in all variants (EO,LRC,HF) (12 items)
% \item The header and footer offsets (EO,LR,HF) (8 items), see
% section~\ref{sec:book-examples} and~\ref{sec:headwidth}
% \item The header and footer init values (2 items), see section~\ref{sec:curpagestyle}
@@ -1916,7 +2021,7 @@
% header and/or footer definitions, use
% \Cmd{fancypagestyle*\{fancydefault\}}\marg{your definitions}.
%
-%\subsection{The \cs{fancypagestyleassign} command}
+%\subsection{The \Cmd{fancypagestyleassign} command}
% \label{sec:fancypagestyleassign}
%
% The \cs{fancypagestyleassign} command is only available in
@@ -1951,7 +2056,7 @@
% \end{raggedright}
%
% \cs{fancypagestyleassign} comes especially handy if you want to
-% temporaryly redefine a page style, and later to restore it to its
+% temporarily redefine a page style, and later to restore it to its
% original value. For example, if we have a page style
% \texttt{special}, and we want temporarily to define page style
% \texttt{plain} to be equal to this, but later to restore it to its
@@ -2374,7 +2479,7 @@
% \fancyhead[R]{\leftmark\\\rightmark}
% \end{example}
%
-% Note that if you want to use header or footer layouts with multiline
+% Note that if you want to use header or footer layouts with multi-line
% parts that have to be aligned, you can do this with
% the \cs{fancyhdrbox} command. See section~\ref{sec:fancyhdrbox}.
%
@@ -2486,7 +2591,7 @@
% parameter \cs{footruleskip}. It
% defines the distance between the decorative line in the footer and the top
% of the footer text line. By default it is set to 30\% of the normal line
-% distance. You may want to adjust it if you use unusally large or small
+% distance. You may want to adjust it if you use unusually large or small
% fonts in the footer. Change it with \cs{renewcommand}.
%
% You can also change the distance between the baseline of the header text and the
@@ -2664,7 +2769,7 @@
% in the neighborhood of your header/footer definitions, unless you
% already use such an \texttt{\ldots offset} command, of course.
% \vspace{\baselineskip}
-% For the second example, we take the \ams/-\LaTeX{} book\footnote{George Gratzer,
+% For the second example, we take the \ams/-\LaTeX{} book\footnote{George Grätzer,
% \textit{Math into LaTeX, An Introduction to \LaTeX{} and \ams/-\LaTeX}, Birkhauser, Boston.}.
%
% Chapter pages have no headers or footers. So we declare
@@ -2735,8 +2840,8 @@
% \end{example}
%
%
-%\section{Summary of \cs{headwidth} calculation}
-%\label{sec:headwidth}
+% \section{Summary of \Cmd{headwidth} calculation}
+% \label{sec:headwidth}
%
% Here is a summary of the calculation of the widths of headers and
% footers, as illustrated in \smartref{sec:headwidth}{sec:book-examples}.
@@ -2750,7 +2855,7 @@
% for \cs{headwidth} is \cs{textwidth}. This is used for the width of
% both the header and the footer. It is possible to change the value of
% \cs{headwidth}, for example with \cs{setlength} or \cs{addtolength}.
-% The excess or deficit will be applied to the right for a onesided
+% The excess or deficit will be applied to the right for a one-sided
% document, and for a two-sided document to the right on odd pages and to
% the left on even pages. The header and the footer will have the same
% width, \cs{headwidth}.
@@ -2906,7 +3011,7 @@
%
% In technical documentation very often page numbers are used of the form
% 2-10 where the first number is the chapter number and the second is the
-% pagenumber relative to the chapter. Sometimes section is used rather than
+% page number relative to the chapter. Sometimes section is used rather than
% chapter. The package \PKGindex{chappg}\pkg{chappg} can be used to get this format.
%
% Basically this package redefines \cs{thepage} as
@@ -2938,7 +3043,7 @@
%
% In the frontmatter of your document (for example the Table of
% Contents) there will be no chapter numbers. Therefore a simple page
-% number will be used there. This may be confusing, so you might prefer to use roman pagenumbers
+% number will be used there. This may be confusing, so you might prefer to use roman page numbers
% in the front matter. Do this by using \verb+\pagenumbering{roman}+ in
% the beginning of the document and \verb+pagenumbering{bychapter}+
% after the first \cs{chapter} command. If you want to do it before the
@@ -3850,7 +3955,7 @@
% ``Continued'' information like in the previous examples. The
% \cs{extramarks} contain essentially the same information as in the
% previous examples, just formatted a little differently.
-% But the \cs{...leftxmark} is not put in the header, but is eventually used as
+% But the \Cmd{...leftxmark} is not put in the header, but is eventually used as
% the argument in \cs{afterpage} so that it will appear at the top of the
% next page body. This is also the reason for the \verb|\\[1ex]|, to
% separate it from the rest of the page text.
@@ -3954,7 +4059,7 @@
% fixed text as argument for \cs{afterpage} but by using a macro \cs{APcommand}
% as argument. When we want to stop the sequence of \cs{afterpage} calls,
% we make this macro empty. To get a proper timing we reset this macro
-% in the righthand footer field when this is empty, which indicates that
+% in the right-hand footer field when this is empty, which indicates that
% we are outside of a `Continued' block.
%
% We must then take care of restarting the \cs{afterpage} sequence when
@@ -4097,7 +4202,7 @@
% styles, especially if you also want the first page of these to have
% a special page style.
%
-% Supose you have defined a special page style \texttt{tocstyle} for the
+% Suppose you have defined a special page style \texttt{tocstyle} for the
% Table of contents. The Table of contents is generated by the command
% \cs{tableofcontents} and it can be several pages long, all generated
% by this simple command. So if you want this to have the page style
@@ -4114,7 +4219,7 @@
%
% If we use a chapter based documentclass, like the standard classes
% \pkg{report} and \pkg{book}, with this setup the first page of the Table
-% of Contents, and similar parts of the document will stil use the
+% of Contents, and similar parts of the document will still use the
% \texttt{plain} page style. Usually this is the best choice, but there
% may be cases where you want these also to use the \texttt{tocstyle}
% page style (or another special page style). The \texttt{plain} page
@@ -4270,7 +4375,7 @@
% the page number and that we use the \pkg{graphics} or \pkg{graphicx} package.
% \PKGindex{graphics}
% \PKGindex{graphicx}
-% To put the movie in the righthandside bottom corner the following will work:
+% To put the movie in the right-hand side bottom corner the following will work:
%
% \Example{30}
% \begin{example}
@@ -4306,7 +4411,7 @@
% requires some hand-tuning to get the blobs nicely spaced out vertically.
% For the application that I originally designed this for, there were 12 sections,
% so I made the blobs
-% 18 mm apart, i.e., 9~mm blob separated by 9~mm whitespace. In order to avoid
+% 18 mm apart, i.e., 9~mm blob separated by 9~mm white space. In order to avoid
% calculations they are set in a \texttt{picture} environment with the
% \cs{unitlength} set to 18~mm. Page numbers are set in the headers at the
% outer sides, and the blobs are attached to these. In this example the
@@ -4547,7 +4652,7 @@
% If in spite of all your attempts \LaTeX{} still moves your floats to the end
% of the document or the end of a chapter, you can insert a \cs{clearpage}
% command. This will start a new page and insert all pending floats before
-% continuing. If it is undesirable to have a pagebreak you can use the
+% continuing. If it is undesirable to have a page break you can use the
% \pkg{afterpage} package and the following command:
% \PKGindex{afterpage}\CmdIndex{afterpage}\CmdIndex{clearpage}%
% \begin{code}
@@ -4568,7 +4673,7 @@
% in the preamble. Now you will be able to
% specify \texttt{[H]} as the position parameter, which will mean ``HERE
% and only HERE''. This may cause an unwanted page break however.
-% If you want to avoid the unwanted pagebreak, i.e., let
+% If you want to avoid the unwanted page break, i.e., let
% \LaTeX{} move the float only if it doesn't fit on the page, then use the
% \pkg{afterpage} package with:
% \PKGindex{afterpage}\CmdIndex{afterpage}\CmdIndex{clearpage}%
@@ -4598,7 +4703,7 @@
% \\Also on Stackexchange:\\
% \url{https://tex.stackexchange.com/questions/39017/how-to-influence-the-position-of-float-environments-like-figure-and-table-in-lat}}.
%
-% \section{Multipage Floats}
+% \section{Multi-page Floats}
%
% \LaTeX's floats cannot be split across pages. Sometimes, however, you want
% to have a table or figure that doesn't fit on one page. The easiest way is
@@ -4676,14 +4781,14 @@
% \begin{figure}[!htbp]
% \centering
% \includegraphics[scale=0.5]{example-image-a}
-% \caption[This is a multipart figure] % For the list of figures
-% {This is a multipart figure (a)}
+% \caption[This is a multi-part figure] % For the list of figures
+% {This is a multi-part figure (a)}
% \label{fig:first}
% \end{figure}
% \begin{figure}[!htbp]
% \centering
% \includegraphics[scale=0.5]{example-image-b}
-% \fakecaption{fig:first}{This is a multipart figure (b)}
+% \fakecaption{fig:first}{This is a multi-part figure (b)}
% \end{figure}
% . . .
% \end{example}
@@ -4706,14 +4811,14 @@
% \begin{figure}[!htbp]
% \centering
% \includegraphics[scale=0.5]{example-image-a}
-% \caption[This is a multipart figure] % For the list of figures
-% {This is a multipart figure (a)}
+% \caption[This is a multi-part figure] % For the list of figures
+% {This is a multi-part figure (a)}
% \label{fig:second}
% \end{figure}
% \begin{figure}[!htbp]
% \centering
% \includegraphics[scale=0.5]{example-image-b}
-% \fakecaption{fig:second}{This is a multipart figure (b)}
+% \fakecaption{fig:second}{This is a multi-part figure (b)}
% . . .
% }
% . . .
@@ -4721,7 +4826,7 @@
% \end{example}
% \CmdIndex{afterpage}
%
-% If you want your multipage figure to start at a lefthand-side
+% If you want your multi-page figure to start at a left-hand side
% (even-numbered) page you can use a test in the \cs{afterpage} command
% (using the \PKGindex{ifthen}\pkg{ifthen} package):
% \CmdIndex{afterpage}
@@ -4734,7 +4839,7 @@
% \end{code}
%
% If there are too many floats on the skipped page, this may still fail to
-% start your multipage figure on an even page, however.
+% start your multi-page figure on an even page, however.
%
% But if there is enough space left on a page, some of the text will go
% between the figures. Also, if there is still some figure part of a
@@ -4763,14 +4868,14 @@
% \begin{figure}[p]
% \centering
% \includegraphics[scale=0.5]{example-image-a}
-% \caption[This is a multipart figure] % For the list of figures
-% {This is a multipart figure (a)}
+% \caption[This is a multi-part figure] % For the list of figures
+% {This is a multi-part figure (a)}
% \label{fig:third}
% \end{figure}
% \begin{figure}[p]
% \centering
% \includegraphics[scale=0.5]{example-image-b}
-% \fakecaption{fig:third}{This is a multipart figure (b)}
+% \fakecaption{fig:third}{This is a multi-part figure (b)}
% . . .
% }
% . . .
@@ -5010,7 +5115,7 @@
% \item Updated contact information.
% \item Restore \cs{newtoks}\cs{@temptokenb}
% \end{itemize}
-% \item Version 3.10, Januari 25, 2019
+% \item Version 3.10, January 25, 2019
% \begin{itemize}
% \item Distribution based on fancydhr.dtx.
% \item Use \cs{f@nch@ifundefined} instead of \cs{ifx} or \cs{@ifundefined}.
@@ -5157,16 +5262,20 @@
% \end{itemize}
% \item Version 5.1.1, Jan 7, 2025
% \begin{itemize}
-% \item Bugfix in save, clear and restore paragraph hooks in headers/footers.
+% \item Bug fix in save, clear and restore paragraph hooks in headers/footers.
+% \end{itemize}
+% \item Version 5.2, Jan 14-Feb 7, 2025
+% \begin{itemize}
+% \item Use official interface to reset the paragraph hooks.
+% \item Conditionally require package \pkg{xparse} in fancyhdr.
+% \item Require \LaTeX{} version 2018-04-01 or later,
+% \item therefore cleanup some pre-2018 code.
+% \item Implement \cs{fancyhfwidth} etc. \meta{alignment} option and
+% the \texttt{*} form of these commands.
+% \item Documentation updates.
% \end{itemize}
% \end{itemize}
%
-%
-%
-% \StopEventually{%
-% \PrintChanges
-% \PrintIndex}
-%
% \part{Questions \& Answers}
%
% This part contains answers to questions that have been emailed to me,
@@ -5207,7 +5316,7 @@
% \hrule height\headrulewidth width\textwidth}
% \bigskip
% \noindent which isn't very nice.
-% There are basically three options to solve this problem.
+% Here I give four options to solve this problem.
%
% \subsection{Using optional arguments}
%
@@ -5322,7 +5431,7 @@
% \fancyhead[LO,RE]{\nouppercase{%
% \truncate{0.5\headwidth}{\leftmark}}} % Chapter title
% \end{example}
-% We don't have to make any changes to the chaper and section titles
+% We don't have to make any changes to the chapter and section titles
% because \cs{truncate} will take care of this.
% This arrangement gives the following header when both titles are too
% big, like in the example above:
@@ -5347,6 +5456,72 @@
% if one of the header parts is small enough and then truncate the other
% one for the remaining space.
%
+% \subsection{Using \Cmd{fancyheadwidth}}
+% \label{sec:with-fancyheadwidth}
+%
+% For this solution we use the \cs{fancyheadwidth} command to give each
+% part a little less than half of the \cs{headwidth}. This command is
+% available in \texttt{fancyhdr} version 5.0 and later.
+% Of course it is also possible to make asymmetric arrangements.
+% \Example{34d}
+% \begin{example}
+% \setlength{\headheight}{35pt}
+% \fancyhead[LE,RO]{\nouppercase{\rightmark}} % Section title
+% \fancyhead[LO,RE]{\nouppercase{\leftmark}} % Chapter title
+% \fancyfoot[LE,RO]{\thepage}
+% \fancyheadwidth[L,R]{0.48\headwidth}
+% . . .
+% \chapter{This is a very long chapter title to see if we can
+% let fancyhdr fit it in the header}
+% \section{This is a very long section title that will not fit in the header}
+% \end{example}
+% We don't have to make any changes to the chapter and section titles.
+% This arrangement gives the following header when both titles are too
+% big, like in the example above:
+%
+% \bigskip
+% \showheader{
+% \setlength{\headheight}{35pt}
+% \fancyhead[L]{Chapter 1. This is a very long chapter title to see if we can
+% let fancyhdr fit it in the header}
+% \fancyhead[R]{1.1. This is a very long section title that will not fit in the header}
+% \fancyheadwidth[L,R]{0.48\headwidth}
+% }
+%
+% You may not like that the two parts of the header are aligned at the
+% bottom, which is the default for the header. We can use the second
+% optional parameter of \cs{fancyheadwidth} to specify a different
+% alignment (in \pkg{fancyhdr} version 5.2 or later). See the following example.
+% \Example{34e}
+% \begin{example}
+% \setlength{\headheight}{35pt}
+% \fancyhead[LE,RO]{\nouppercase{\rightmark}} % Section title
+% \fancyhead[LO,RE]{\nouppercase{\leftmark}} % Chapter title
+% \fancyfoot[LE,RO]{\thepage}
+% \fancyheadwidth*[L,R][tj]{0.48\headwidth}
+% \fancyfootwidth*[LE,RO][-c]{0.1\headwidth}
+% \end{example}
+% We use \texttt{t} for the vertical alignment, and also \texttt{j}
+% (justified) for the horizontal alignment. Just for fun we use the
+% \texttt{*} form of the command, and also add \cs{fancyfootwidth*}.
+% This puts the page number under the page a little bit away from the
+% edge of the text.
+%
+% The resulting header looks like:
+%
+% \bigskip
+% \showheader{
+% \setlength{\headheight}{35pt}
+% \fancyhead[L]{Chapter 1. This is a very long chapter title to see if we can
+% let fancyhdr fit it in the header}
+% \fancyhead[R]{1.1. This is a very long section title that will not fit in the header}
+% \fancyheadwidth*[L,R][tj]{0.48\headwidth}
+% }
+%
+% Please note, that these solutions also have disadvantages. The header
+% must be quite tall, and when a smaller title is used there is a gap
+% between the title and the line under the header.
+%
% \section{I lost my chapter/section titles}
%
% Some time ago I got a question like this (edited to get the
@@ -5453,14 +5628,17 @@
% extract the last left mark (\cs{leftmark}) and the first right mark
% (\cs{rightmark}). This means that if there are two or more sections on
% the page you get the last one, which can be counter-intuitive.
-% The newer \LaTeX{} releases (November 2022 or newer) have a command to
+% The newer \LaTeX{} releases (November 2022 or later) have a command
+% (\Cmd{FirstMark\{2e-left\}}) to
% get the first of the left marks, however. \textbf{We assume in the
% following code that your \LaTeX{} is recent enough.}
% \item \LaTeX{} uses \cs{markboth} at a section title in the
% \pkg{article} class. This also sets an empty right mark. So in
-% some cases you would get an empty subsection title in the header. To
-% avoid this, \LaTeX{} now also has a mark that saves the non-empty
-% right mark in a separate mark \texttt{2e-right-nonempty}
+% some cases you would get an empty subsection title in the header. Also
+% a \cs{part} command issues a \Cmd{markboth\{\}\{\}}, so it generates
+% empty marks too. To avoid this, \LaTeX{} now has an additional mark
+% \texttt{2e-right-nonempty} in which only the non-empty right marks are
+% saved. This is also set by \cs{markboth} and \cs{markright}.
% \end{itemize}
%
% If there is no \cs{section} command on the page, it `inherits' the
@@ -5480,11 +5658,11 @@
% \subsection{Subsection One}
% . . .
% \end{example}
-% This effectively solves the problem, but it has some undesirable
+% This mostly solves the problem, but it has some undesirable
% properties, see below. Therefore, some refinement is
-% possible. But we need an extra mark for this. So we are going
-% to use the \LaTeX{} marks directly, instead of using the standard
-% marks. This gives us a bit more control. We need two marks for this,
+% possible. But we need an extra mark for this. We are also going
+% to use new marks, instead of using the standard
+% marks to get more control. We need two marks for this,
% one for the section title, and one for the subsection title. We call
% these \texttt{section} and \texttt{subsection} respectively. We
% replace the marking code above with the following, which gives
@@ -5503,9 +5681,9 @@
% \InsertMark{subsection}{\thesubsection. #1}}
% \end{example}
%
-% When you have a \cs{section} command on a page, but it doesn't have a
-% subsection for an extended length, then, the
-% previous subsection title is `inherited'. This may be sub-optimal,
+% Now when you have a \cs{section} command on a page, but it doesn't
+% have a subsection for an extended length, then, the previous
+% subsection title is `inherited' on this page. This may be sub-optimal,
% because it combines the title of section $n$ with a subsection title
% that belongs to a previous section, so the subsection isn't even
% present on the page, which looks unnatural. You may want to
@@ -5538,7 +5716,7 @@
% the \meta{true code} is executed when there is no subsection title on the
% current page, and the \meta{false code} when there is at least one.
%
-% However, there is no command to see if the pagebreak is at the section
+% However, there is no command to see if the page break is at the section
% or subsection level, because the two are independent. And we
% cannot use \LaTeX{} variables for this, because of the asynchronous
% processing of the page breaking. But we can do this if we introduce a
@@ -5548,14 +5726,20 @@
% indicates if the page ends within a subsection or not. And as the
% topmark on the following page is the same as lastmark on the previous
% page, we can use this topmark to see whether the text at the beginning
-% of the page comes from a subsection (topmark = 1 means yes).
-%
-% There is one caveat, however. If the page begins immediately with a
-% section title, the topmark may indicate that the previous page ended
-% with a subsection, but that subsection did not extend past the
-% pagebreak. It is tricky to detect this situation, but we will propose
-% a solution at the end of the current section.
-% So the new code for the right header becomes the following. We use the
+% of the page comes from a section or a subsection (topmark = 0 means
+% section, 1 means subsection).
+%
+% So the interim new code for the right header becomes the following.\\
+% \textbf{if} there is no subsection on the page\\
+% \textbf{then}\\
+% \hspace*{2em}\textbf{if} the previous page ended in a subsection\\
+% \hspace*{2em}\textbf{then} use (inherit) that subsection\\
+% \hspace*{2em}\textbf{else} use an empty header\\
+% \hspace*{2em}\textbf{fi}\\
+% \textbf{else} (there is at least one subsection on the page)\\
+% \hspace*{2em}use the first subsection\\
+% \textbf{fi}\\[1ex]
+% We use the
% package \PKGindex{ifthen}\pkg{ifthen} for the test.
%
% \Example{35}[(continued)]
@@ -5567,8 +5751,8 @@
% \IfMarksEqualTF{subsection}{top}{first}
% {% no subsection mark on this page
% \ifthenelse{\TopMark{which}=1} % previous page ended in a subsection
-% % then use that subsection
-% {\TopMark{subsection}}% = \FirstMark{subsection}
+% % then use (inherit) that subsection
+% {\TopMark{subsection}}%
% {}% otherwise empty right header
% }
% {% there is a subsectionmark on the page, use it
@@ -5585,19 +5769,23 @@
% }
% \end{example}
%
-% Now we want to suppress the `inheritance' of the subsection if there
+% There is one caveat, however. If the page begins immediately with a
+% section title, the topmark may indicate that the previous page ended
+% with a subsection, but that subsection did not extend past the
+% page break.
+% So we want to suppress the `inheritance' of the subsection if there
% is a section title at the top of the page and the page contains no
% subsection title. The information whether a section title is at the
% top of the page is not available in the marks, so we need some other
% way to detect this.
%
% \TeX{} has two variables that can help us, \cs{pagegoal} is the vertical size
-% that is still available on the page, and \cs{pagetotal} is the amount we
+% that is available on the page, and \cs{pagetotal} is the amount we
% have used so far\footnote{This doesn't include floats and footnotes.}.
% So if \cs{pagetotal}=\texttt{0pt} we are at the top of
% the page, otherwise somewhat further down. We can use this information to
% communicate to the header that no inheritance should take place. In
-% reality, sometimes there is already a small amount of whitespace on
+% reality, sometimes there is already a small amount of white space on
% the page, so the test should be less strict than
% \cs{pagetotal}=\texttt{0pt}. We might even choose to not inherit the
% subsection title if only a few lines of the previous subsection are
@@ -5607,80 +5795,227 @@
% \cs{pagetotal}$<$0.33\cs{pagegoal}. In the code below we choose a few
% lines as the limit.
%
-% We have to do the test just before the \cs{section} command is
-% processed. This can be done with a \LaTeX{} \emph{hook}.
+% We have to do the test at the beginning of the \cs{section} command
+% processing. This can be done with a \LaTeX{} \emph{hook}.
%
% The next question is how to communicate the fact that the section
-% starts at (or near) to top of the page to the header. A simple way to
-% do this is to set the `\texttt{which}' mark to $-1$ instead of 0.
-% (Another way could be to define a special page style that does not do
-% the inheritance, and activate that with \cs{thispagestyle}.)
+% starts at (or near) the top of the page to the header. A simple way to
+% do this could be to set the `\texttt{which}' mark to a different value, e.g,
+% $-1$ instead of 0. However, below we will present a better way.
%
% \begin{code}
% \AddToHook{cmd/section/before}{%
% % use whatever test your design requires
% \ifthenelse{\lengthtest{\pagetotal<4\baselineskip}}
-% {\InsertMark{which}{-1}}
-% {\InsertMark{which}{0}}
+% {indicate section at top of page}
+% {indicate section somewhere else}
% }
% \end{code}
%
-% It appears, however that this is the wrong place to set the mark. A
-% pagebreak could occur between this code and the actual section title,
-% so that the mark is put on the wrong page. The proper place for setting the
-% mark is in the \cs{sectionmark} command, as that is guaranteed to
-% always be together with the section title. So we must put the required
-% value for the mark in a variable.
-%
% There is another situation where a section title could end up at the
% top of the page: when it is processed at the bottom of the page, but
% there isn't enough space left to place it there. It will then be
% pushed to the next page. In that case the \cs{pagetotal} will be in
-% the neighbourhood of \cs{pagegoal}. In the code below we test for
-% \cs{pagetotal}$>$0.9\cs{pagegoal}, but some experimentation may be
-% necessary to find a proper value.
-% In the example 35 file you can see this in section~6.
+% the neighbourhood of \cs{pagegoal}. However, it is very difficult to
+% find a proper value for the cutoff of \cs{pagetotal}. In many cases it
+% will be too small or too big, depending on the size of the section
+% title. So we need a different way.
+%
+% If the section title is pushed to the next page, the page number of
+% the page where the section title is processed will be different from
+% the page number that is current when the header is created. (We assume
+% that all page numbers are different.) So by storing the page number
+% atvthe time of processing the section title, and then comparing it in the header with
+% the \texttt{page} counter, we can check that the header was
+% moved to another page from an earlier page. This doesn't have
+% to be \textbf{the} next page, as there could be float pages in
+% between. The test has to be done while we are in the header, not while
+% we are processing the section title. And it is not enough to store the page
+% number in a variable because there can be subsequent section titles on
+% the next page and these would overwrite the saved value. So it must be stored in
+% yet another mark. Let's call this mark \texttt{whichpage}. We can save
+% this in the \cs{sectionmark} command.
+%
+% Now, in the right header, we can check if \Cmd{FirstMark\{whichpage\}}
+% is equal to \cs{thepage}. If they are different, the section title was
+% pushed across a page boundary, so it is at the top of the page. Note
+% that this test makes only sense if there is a section title on the
+% page, so we have to include a test for this also. This can be done
+% with \Cmd{IfMarksEqualTF\{section\}\{top\}\{first\}}. A compact way to
+% do this is:
+% \begin{code}
+% \equal{\IfMarksEqualTF{section}{top}{first}
+% {\thepage}{\FirstMark{whichpage}}}{\thepage}}%
+% \end{code}
+%
+% So if there is no section on the page, we don't compare
+% \texttt{whichpage} to \cs{thepage}, but instead compare \cs{thepage}
+% with itself, which gives \emph{true}, i.e. no section at the top of the page.
%
-% \emph{(Another way could be to put the current page number in a mark
-% and then check in the header if this is the same as the page number
-% where the header is put on the page. If different, don't
-% inherit. This is left as an exercice for the reader.)}
+% We use a string comparison for the page number, not a numerical
+% comparison, because page numbers can be non-numeric, for example roman
+% numbers, which can't be compared numerically.
+%
+% This gives us now a way to indicate the previous case for a section
+% title at the top of the page: Just put a value in the
+% \texttt{whichpage} mark that is different from the actual page number.
+% But as the test is done in the hook, and the setting of the mark in
+% \cs{sectionmark}, we must communicate this through a variable. Let's
+% call this variable \cs{whichpage}. I have chosen to just put the text
+% ``top'' in front of the page number to make it different, but any
+% value that can't be a page number would be good.
%
% \Example{35}[(continued)]
% \begin{example}
-% \newcommand{\which}{}
+% \NewMarkClass{whichpage}
+% \newcommand\whichpage{}
+%
% \AddToHook{cmd/section/before}{%
-% \ifthenelse{\lengthtest{\pagetotal<4\baselineskip}\or
-% \lengthtest{\pagetotal>0.9\pagegoal}}{%
-% {\renewcommand\which{-1}}%
-% {\renewcommand\which{0}}%
+% % use whatever test your design requires
+% \ifthenelse{\lengthtest{\pagetotal<4\baselineskip}}
+% {\renewcommand{\whichpage}{top\thepage}}%
+% {\renewcommand{\whichpage}{\thepage}}%
% }
+%
% \renewcommand{\sectionmark}[1]{%
% \InsertMark{section}{\thesection\ #1}%
-% \InsertMark{which}{\which}%
-% }%
+% \InsertMark{which}{0}%
+% \InsertMark{whichpage}{\whichpage}%
+% }
% \end{example}
%
+% In the example 35 file you can see this in section~6.
+%
% The final code for the right header will now be:
+%
% \Example{35}[(continued)]
% \begin{example}
% \fancyhead[R]{%
-% \IfMarksEqualTF{subsection}{top}{first}
-% {% no subsection mark on this page
-% \ifthenelse{\TopMark{which}=1}{%
-% % use previous subsection unless suppressed by which = -1
-% \ifthenelse{\FirstMark{which}<0} % -1
-% {\FirstMark{subsection}}% = \TopMark{subsection}
+% \IfMarksEqualTF{subsection}{top}{first}
+% {% no subsection mark on this page
+% \ifthenelse{%
+% % previous page ended in a subsection
+% \TopMark{which}=1\and
+% % Is there a section on the page?
+% \equal{\IfMarksEqualTF{section}{top}{first}
+% {\thepage}{\FirstMark{whichpage}}}{\thepage}}%
+% {
+% % use previous subsection unless suppressed by section on top
+% \TopMark{subsection}%
+% }
+% % otherwise use empty right header
+% {}%
% }
-% }
-% {% if there is a subsectionmark on the page, use it
-% \FirstMark{subsection}%
-% }%
+% {% if there is a subsectionmark on the page, use it
+% \FirstMark{subsection}%
+% }%
% }
% \end{example}
% In the actual code in the Example 35 file there is also some debugging
% code added.
%
+% \subsection{The headers in this document}
+%
+% Now we will describe how the headers in the \pkg{fancyhdr}
+% documentation (this document) are constructed. This documentation
+% consists of a number of sections, some of which have one or more
+% subsections. There is only one title in the header, which is the
+% title of the [sub]section that is current at the top of the page. In
+% other words, the last one on a previous page. This asks for a `top mark'.
+%
+% Because both sections and subsections are treated the same, we use a
+% single mark for both, and we put the common code in macros. We could
+% have chosen a new mark for the titles, but \LaTeX's standard right
+% mark is sufficient for this\footnote{This is better than the left mark, bcause that
+% doesn't have a way to filter out empty ones which are generated by the
+% \cs{part} commands in the document, and also \cs{leftmark} will
+% produce the last title of the current page, which isn't useful.}.
+%
+% When a [sub]section title is at or near the top of the page, we will
+% use that title in the header instead of the one from the previous
+% page, because this look more natural (the previous one does have no or
+% very little text on the current page), just like in the previous
+% example (35). We use the same mechanism, with a mark \texttt{whichpage} to
+% achieve this. Because we put sections and subsections together, we
+% don't need a mark to distinguish them. Example~36 has essentially the
+% same headers as this documentation.
+%
+% The macro \cs{checkposinpage} checks whether the [sub]section starts
+% at or near the top of the page, and puts this information in the
+% variable \cs{whichpage}, just like in example~35. The macro
+% \cs{setmarks}, sets the marks, both the right mark for the title (with
+% \cs{markright}), and the extra mark \texttt{whichpage}.
+%
+% \Example{36}
+% \begin{example}
+% \NewMarkClass{whichpage}
+% \newcommand\whichpage{}
+%
+% \newcommand\checkposinpage{
+% \ifthenelse{\lengthtest{\pagetotal<4\baselineskip}}%
+% {\renewcommand{\whichpage}{top\thepage}}%
+% {\renewcommand{\whichpage}{\thepage}}%
+% }
+%
+% \AddToHook{cmd/section/before}{\checkposinpage}
+% \AddToHook{cmd/subsection/before}{\checkposinpage}
+%
+% \newcommand\setmarks[1]{%
+% \InsertMark{whichpage}{\whichpage}%
+% \markright{#1}%
+% }
+%
+% \renewcommand{\sectionmark}[1]{%
+% \setmarks{\thesection\quad#1}%
+% }%
+%
+% \renewcommand{\subsectionmark}[1]{%
+% \setmarks{\thesubsection\quad#1}%
+% }%
+% \end{example}
+%
+% Finally, the header code. For the last title of the/a previous page we
+% use \Cmd{TopMark\{2e-right-nonempty\}}, for a title that is at/near
+% the top of the page we use \cs{rightmark}. The algorithm is similar to
+% example~35, but simplified:\\[1ex]
+% ^^A
+% \textbf{if} \texttt{whichpage} = \verb|\thepage| (i.e., no [sub]section at or near top)\\
+% \textbf{then}\\
+% \hspace*{2em} use last [sub]section from a previous page\\
+% \textbf{else} (\texttt{whichpage} $\ne$ \verb|\thepage|)\\
+% \hspace*{2em} \textbf{if} there is no \texttt{whichpage} mark on this page\\
+% \hspace*{3em} (this means the \texttt{whichpage} mark is not valid for this page)\\
+% \hspace*{2em} \textbf{then} use last [sub]section from a previous page\\
+% \hspace*{2em} \textbf{else} (there is a [sub]section title at/near the top of the page)\\
+% \hspace*{3em} use first [sub]section of current page\\
+% \textbf{fi}
+%
+% \Example{36}[(Continued)]
+% \begin{example}
+% \fancypagestyle*{fancy}{%
+% \fancyhf{}
+% \fancyhead[L]{%
+% \ifthenelse{\equal{\FirstMark{whichpage}}{\thepage}}%
+% {\TopMark{2e-right-nonempty}}%
+% % whichpage != page
+% {\IfMarksEqualTF{whichpage}{top}{first}%
+% {\TopMark{2e-right-nonempty}}% no mark on this page
+% {\rightmark}% title at/near the top of the page
+% }%
+% }
+% \fancyhead[R]{\textbf{\thepage}}
+% }
+% \end{example}
+%
+% In the example~36 file there is some additional code for debugging
+% that we don't show here.
+%
+% In this documentation there are some cases that aren't covered by this
+% code: the \Cmd{part} commands do not have a corresponding
+% \Cmd{partmark}, and there are some hidden \Cmd{section*} commands that
+% do not call \Cmd{sectionmark}. In these cases we manually add the
+% \cs{checkposinpage} and \cs{setmarks} commands.
+%
% \section{How to change shapes and traits of horizontal lines in headers/footers?}
% \label{sec:headrules}
%
@@ -5720,7 +6055,7 @@
% \smash{\color{blue}\rule{\headwidth}{2.5pt}}%
% }
% \end{code}
-% The \cs{interlineskip} is to prevent \LaTeX{} to insert the normal
+% The \cs{nointerlineskip} is to prevent \LaTeX{} to insert the normal
% vertical space between lines, and the \cs{smash} to let the
% \cs{headrule} not occupy any vertical space. Whether you want that is
% up to you, but if it occupies vertical space it may distort the page layout.\\
@@ -5817,7 +6152,16 @@
% Of course you would have to make sure not to place anything in the
% right part of the header.
%
+% \MaybeStop{%
+% \setmarks{Change History}\PrintChanges
+% \setmarks{Index}
+% ^^A Temporary workaround for mark problems in `multicol'
+% \fancyhead[L]{Index}
+% \PrintIndex
+% }
+%
% \newpage
+% \checkposinpage\setmarks{Implementation}
% \part{Implementation}
%
% \begin{implementation}
@@ -5900,7 +6244,7 @@
% \changes{fancyhdr v1.99a}{1996/05/10}{Added a few more \% signs.}
%
% \changes{fancyhdr v1.99b}{1996/05/10}{Changed the syntax of
-% \cs{f@nch@for} to be resistent to catcode changes of \texttt{:!=}.\protect\\
+% \cs{f@nch@for} to be resistant to catcode changes of \texttt{:!=}.\protect\\
% Removed the \texttt{[1]} from the defs of \cs{lhead} etc. because the parameter is
% consumed by the \cs{@[xy]lhead} etc. macros.}
%
@@ -5940,7 +6284,7 @@
% \changes{fancyhdr v2.1x=fancyhdr v2.1}{2002/12/09}{The defaults for
% \cs{footrulewidth}, \cs{plainheadrulewidth} and
% \cs{plainfootrulewidth} are changed from \cs{z@skip} to 0pt. In this
-% way when someone inadvertantly uses \cs{setlength} to change any of these, the value
+% way when someone inadvertently uses \cs{setlength} to change any of these, the value
% of \cs{z@skip} will not be changed, rather an errormessage will be given.}
%
% \changes{fancyhdr v3.0}{2004/03/03}{Release of version 3.0.}
@@ -5980,13 +6324,8 @@
% \changes{fancyhdr v3.9}{2016/10/11}{Put everything in a \texttt{.dtx} file.}
% \changes{fancyhdr v3.9}{2016/10/12}{Rename some macros to have 'f@nch@'
% in their names, to get a more uniform naming scheme for internal macros.}
-%
-% \begin{macro}[internal]{\if@nch@mpty}
-% This macro tests if its argument is empty.
-% \begin{macrocode}
-\newcommand\if@nch@mpty[1]{\def\temp@a{#1}\ifx\temp@a\@empty}
-% \end{macrocode}
-% \end{macro}
+% \changes{fancyhdr v5.2}{2025/01/15}{Conditionally require package \pkg{xparse}.}
+\ifdefined\NewDocumentCommand\else\RequirePackage{xparse}\fi
%
% \begin{macro}[internal]{\iff@nch@check}
% Boolean for the \texttt{nocheck} option.
@@ -6045,48 +6384,29 @@
% \end{macro}
%
% \begin{macro}[internal]{\f@nch@def}
-% This macro defines another macro (usually a header or footer field).
+% This macro defines another macro (a header or footer field).
% Depending on the value of \cs{f@nch@gbl} the definition will be
% global or local.
% Default it is always local. But with the \texttt{compatV3} option it
% is \cs{global} in the normal definitions, and local in \cs{fancypagestyle}.
% The \cs{global} case is now considered a bug (or at least undesirable).
%
-% If the value (argument 2) is empty, a \cs{leavevmode} will be substituted.
-% If it is not empty, a \cs{strut} will be added.
-%
-% \begin{macrocode}
-\newcommand\f@nch@def[2]{\if@nch@mpty{#2}\f@nch@gbl\def#1{\leavevmode}\else
- \f@nch@gbl\def#1{#2\strut}\fi}
-% \end{macrocode}
-% \end{macro}
+% If the value (argument 2) is not empty, a \cs{strut} will be added.
+% \changes{fancyhdr v5.2}{2025/02/07}{Inline \cs{if@nch@mpty}.}
+% \changes{fancyhdr v5.2}{2025/02/07}{Remove \cs{leavevmode}, because
+% the initialisation code also inserts a \cs{leavevmode}.}
%
-% \begin{macro}[internal]{\f@nch@ifundefined}
-% This macro tests if a command is undefined. Older versions of
-% fancyhdr used \cs{@ifundefined}, but this had an undesired side effect
-% in the original \LaTeX{} (the command was made equal to \cs{relax} if
-% it was undefined). Another way was\\
-% \verb+\ifx\thecommand\undefined ...+ or \verb+\ifx\thecommand\@undefined ...+
-% but that could conflict with packages that use the \cs{@ifundefined}
-% method. \LaTeX{} versions later than 2018 have a definition of
-% \cs{@ifundefined} that avoids these problems, but not everybody may
-% have such a version installed. Therefore we define our own version
-% \cs{f@nch@ifundefined}.
-% This definition is copied from the \PKGindex{tocloft}\pkg{tocloft} package by Peter
-% Wilson and Will Robertson.
% \begin{macrocode}
-\newcommand{\f@nch@ifundefined}[1]{%
- \begingroup\expandafter\expandafter\expandafter\endgroup
- \expandafter\ifx\csname #1\endcsname\relax
- \expandafter\@firstoftwo
- \else
- \expandafter\@secondoftwo
- \fi}
+\newcommand\f@nch@def[2]{%
+ \def\temp@a{#2}\ifx\temp@a\@empty\f@nch@gbl\def#1{}%
+ \else\f@nch@gbl\def#1{#2\strut}\fi}
% \end{macrocode}
% \end{macro}
%
% \changes{fancyhdr v4.0}{2019/03/17}{Added \texttt{headings} and
% \texttt{myheadings} options.}
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% Standard styles are redefined optionally. These definitions are
% borrowed from the \PKGindex{nccfancyhdr}\pkg{nccfancyhdr} package
% by by Alexander I. Rozhenko.
@@ -6099,7 +6419,7 @@
% \OPTindex{myheadings}\PSindex{myheadings}
% \begin{macrocode}
\DeclareOption{myheadings}{%
- \f@nch@ifundefined{chapter}{%
+ \@ifundefined{chapter}{%
% \end{macrocode}
% An article-like class without chapters:
% \begin{macrocode}
@@ -6136,9 +6456,11 @@
% \cs{@mkboth} from \cs{let}\cs{@mkboth}\cs{markboth} to
% \cs{def}\Cmd{@mkboth\{\cs{protect}\cs{markboth}\}} so that it will pick up changes
% to \cs{markboth}}
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% \begin{macrocode}
\DeclareOption{headings}{%
- \f@nch@ifundefined{chapter}{%
+ \@ifundefined{chapter}{%
\if@twoside
% \end{macrocode}
% An article in two-side mode:
@@ -6222,9 +6544,9 @@
% Execute the body for each character in \texttt{charstring} bound
% to \cs{var}.
% This is similar to \LaTeX's \cs{@tfor}, but it expands the \texttt{charstring}.
-% \begin{macrocode}
% \changes{fancyhdr v3.10}{2019/01/25}{Use \cs{newcommand} instead of \cs{def}.}
% \changes{fancyhdr v4.0.2}{2021/05/29}{Make \cs{f@nch@rc} \cs{long}.}
+% \begin{macrocode}
\newcommand{\f@nch@forc}[3]{\expandafter\f@nchf@rc\expandafter#1\expandafter{#2}{#3}}
\newcommand{\f@nchf@rc}[3]{\def\temp@ty{#2}\ifx\@empty\temp@ty\else
\f@nch@rc#1#2\f@nch@rc{#3}\fi}
@@ -6401,12 +6723,18 @@
% The commands for field widths.
% \changes{fancyhdr v5.0}{2025/01/01}{New commands \cs{fancyheadwidth},
% \cs{fancyfootwidth} and \cs{fancyhfwidth}.}
+% \changes{fancyhdr v5.2}{2025/01/25}{Second optional parameter \meta{alignment}.}
+% \changes{fancyhdr v5.2}{2025/01/27}{Implement \texttt{*} version of
+% these commands.}
% Pick up the parameters,
% and supply an 'h' (\cs{fancyheadwidth}) or 'f' (\cs{fancyfootwidth}).
% \begin{macrocode}
-\newcommand{\fancyheadwidth}[2][]{\f@nch@fancyhfwidth\fancyheadwidth h[#1]{#2}}%
-\newcommand{\fancyfootwidth}[2][]{\f@nch@fancyhfwidth\fancyfootwidth f[#1]{#2}}%
-\newcommand{\fancyhfwidth}[2][]{\f@nch@fancyhfwidth\fancyhfwidth {}[#1]{#2}}%
+\NewDocumentCommand {\fancyheadwidth}{ s O{} O{} m }
+ {\f@nch@fancyhfwidth{#1}\fancyheadwidth h[#2][#3]{#4}}%
+\NewDocumentCommand {\fancyfootwidth}{ s O{} O{} m }
+ {\f@nch@fancyhfwidth{#1}\fancyfootwidth f[#2][#3]{#4}}%
+\NewDocumentCommand {\fancyhfwidth} { s O{} O{} m }
+ {\f@nch@fancyhfwidth{#1}\fancyhfwidth {}[#2][#3]{#4}}%
% \end{macrocode}
% \end{macro}
%
@@ -6414,39 +6742,79 @@
% This macro interprets the parameters for the header and footer field
% widths.\\
% Parameters:\\
-% (1) The user command that was used (like \cs{fancyheadwidth}). This is used
+% (1) The optional \texttt{*} argument.\\
+% (2) The user command that was used (like \cs{fancyheadwidth}). This is used
% for errors/warnings.\\
-% (2) \texttt{h} (for \cs{fancyheadwidth}), \texttt{f} (for \cs{fancyfootwidth}),
+% (3) \texttt{h} (for \cs{fancyheadwidth}), \texttt{f} (for \cs{fancyfootwidth}),
% or \texttt{\{\}} (for \cs{fancyhfwidth}).\\
-% (3) The optional parameter that was given to these commands (default \texttt{[]}).\\
-% (4) The required parameter that was given to these commands.\\
+% (4-5) The two optional parameters that were given to these commands
+% (default for each \texttt{[]}).\\
+% (6) The required parameter that was given to these commands.\\
% The header and footer field widths are stored in command sequences with
% names of the form: \cs{f@nch@width@}\meta{x}\meta{y}\meta{z} with \meta{x} from
% \texttt{[eo]}, \meta{y} from \texttt{[lcr]} and \meta{z} from \texttt{[hf]}.
+% The header and footer alignments are stored (after defaults have
+% been applied) in command sequences with names of the form:
+% \cs{f@nch@align@}\meta{x}\meta{y}\meta{z} with \meta{x} from
+% \texttt{[eo]}, \meta{y} from \texttt{[lcr]} and \meta{z} from
+% \texttt{[hf]}.
%
% First we assign the \meta{width} argument to a temporary length
-% variable, to check if it is a legal \meta{length}. Then we store the
-% \meta{width} in variables for all the specified places.
+% variable, to check if it is a legal \meta{length}.
%
% \begin{macrocode}
-\def\f@nch@fancyhfwidth#1#2[#3]#4{%
- \setlength\@tempdima{#4}%
+\def\f@nch@fancyhfwidth#1#2#3[#4][#5]#6{%
+ \setlength\@tempdima{#6}%
\def\temp@c{}%
- \f@nch@forc\tmpf@ra{#3}%
+ \f@nch@forc\tmpf@ra{#4}%
{\expandafter\f@nch@ifin\tmpf@ra{eolcrhf,EOLCRHF}%
{}{\edef\temp@c{\temp@c\tmpf@ra}}}%
\ifx\@empty\temp@c\else \PackageError{fancyhdr}{Illegal char `\temp@c' in
- \string#1 argument: [#3]}{}%
- \fi \f@nch@for\temp@c{#3}%
+ \string#2 argument: [#4]}{}%
+ \fi
+ \f@nch@for\temp@c{#4}%
{\f@nch@default\f@nch@@eo{eo}\temp@c
- \f@nch@fancyhf@Echeck{#1}%
+ \f@nch@fancyhf@Echeck{#2}%
\f@nch@default\f@nch@@lcr{lcr}\temp@c
- \f@nch@default\f@nch@@hf{hf}{#2\temp@c}%
+ \f@nch@default\f@nch@@hf{hf}{#3\temp@c}%
\f@nch@forc\f@nch@eo\f@nch@@eo
{\f@nch@forc\f@nch@lcr\f@nch@@lcr
{\f@nch@forc\f@nch@hf\f@nch@@hf
- {\expandafter\def\csname
- f@nch@width@\f@nch@eo\f@nch@lcr\f@nch@hf\endcsname {#4}}}}}}
+% \end{macrocode}
+% Then we store the \meta{width} in variables for all the specified
+% places. If the \texttt{*} form was given we use the calculated value,
+% otherwise the bare argument.
+% \begin{macrocode}
+ {%
+ \IfBooleanTF{#1}{%
+ \expandafter\edef\csname
+ f@nch@width@\f@nch@eo\f@nch@lcr\f@nch@hf\endcsname{\the\@tempdima}%
+ }%
+ {%
+ \expandafter\def\csname
+ f@nch@width@\f@nch@eo\f@nch@lcr\f@nch@hf\endcsname{#6}%
+ }%
+% \end{macrocode}
+% Then we apply the defaults to the \meta{alignment} argument.
+% The defaults are:
+% \begin{itemize}
+% \item for the vertical alignment (v): \texttt{b} in a
+% header, and \texttt{t} in a footer. This is done by executing a
+% corresponding macro.
+% \item for the horizontal alignment (h): l, c, r: the same as the
+% field. Just copy the field letter.
+% \end{itemize}
+% If the optional parameter is empty, we leave it at these defaults,
+% otherwise we process the arguments with \cs{f@nchdrwdt@align}.
+% Finally we store the result in variables for the specified places.
+% \begin{macrocode}
+ \csname f@nchdrwdt@align@v@\f@nch@hf\endcsname
+ \edef\f@nch@align@@h{\f@nch@lcr}%
+ \def\temp@a{#5}%
+ \ifx\temp@a\@empty \else \f@nchdrwdt@align#5\@nil{#2}\fi
+ \expandafter\edef\csname
+ f@nch@align@\f@nch@eo\f@nch@lcr\f@nch@hf\endcsname
+ {\f@nch@align@@v\f@nch@align@@h}}}}}}
% \end{macrocode}
% \end{macro}
%
@@ -6492,6 +6860,88 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}[internal]{\f@nch@align@elh}
+% \begin{macro}[internal]{\f@nch@align@ech}
+% \begin{macro}[internal]{\f@nch@align@erh}
+% \begin{macro}[internal]{\f@nch@align@olh}
+% \begin{macro}[internal]{\f@nch@align@och}
+% \begin{macro}[internal]{\f@nch@align@orh}
+% \begin{macro}[internal]{\f@nch@align@elf}
+% \begin{macro}[internal]{\f@nch@align@ecf}
+% \begin{macro}[internal]{\f@nch@align@erf}
+% \begin{macro}[internal]{\f@nch@align@olf}
+% \begin{macro}[internal]{\f@nch@align@ocf}
+% \begin{macro}[internal]{\f@nch@align@orf}
+%
+% Alignment parameters for the widths.
+%
+% \begin{macrocode}
+\def\f@nch@align@elh{bl}
+\def\f@nch@align@ech{bc}
+\def\f@nch@align@erh{br}
+\def\f@nch@align@olh{bl}
+\def\f@nch@align@och{bc}
+\def\f@nch@align@orh{br}
+\def\f@nch@align@elf{tl}
+\def\f@nch@align@ecf{tc}
+\def\f@nch@align@erf{tr}
+\def\f@nch@align@olf{tl}
+\def\f@nch@align@ocf{tc}
+\def\f@nch@align@orf{tr}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[internal]{\f@nchdrwdt@align@v@h, \f@nchdrwdt@align@v@f, \f@nchdrwdt@align}
+% \cs{f@nchdrwdt@align@v@h}: set v to \texttt{b}\\[1ex]
+% \cs{f@nchdrwdt@align@v@f}: set v to \texttt{t}\\[1ex]
+% \cs{f@nchdrwdt@align}\marg{vert}\marg{hor}\texttt{\cs{@nil}}\marg{originating command}\\[1ex]
+% The internal processing for \meta{alignment} parameter in \cs{fancyhfwidth},
+% etc.\\
+% ALGORITHM \cs{f@nchdrwdt@align}:\\
+% (v = vertical position; h = horizontal position)\\
+% These have been set to their defaults before calling us.\\
+% \textbf{IF} \texttt{\#1} in \texttt{\{T,t,c,b,B,-\}} \\
+% \textbf{THEN} \textbf{if} \texttt{\#1} $\ne$ `\texttt{-}' \textbf{then}
+% v := \texttt{\#1} \textbf{fi}\\
+% \hspace*{1em} \textbf{if} \texttt{\#2} is not empty \textbf{then} h := \texttt{\#2}
+% \textbf{fi}\\
+% \textbf{ELSE} (\texttt{\#1} not in \texttt{\{T,t,c,b,B,-\}} -- it must be
+% a horizontal alignment)\\
+% \hspace*{1em} h := \texttt{\#1}\\
+% \textbf{FI}\\
+% \textbf{if} h not in \texttt{\{l,c,r,j\}} \textbf{then} ERROR \textbf{fi}\\
+%
+% The result can be found in the variables \cs{f@nch@align@@v} and \cs{f@nch@align@@h}.
+% \begin{macrocode}
+\def\f@nchdrwdt@align@v@h{\def\f@nch@align@@v{b}}%
+\def\f@nchdrwdt@align@v@f{\def\f@nch@align@@v{t}}%
+\long\def\f@nchdrwdt@align#1#2\@nil#3{%
+ \f@nch@ifin{#1}{TtcbB-}{%
+ \f@nch@ifin{#1}{-}{}{\def\f@nch@align@@v{#1}}%
+ \def\@tempa{#2}%
+ \ifx\@tempa\@empty \else \def\f@nch@align@@h{#2}\fi
+ }%
+ {\def\f@nch@align@@h{#1}}%
+ \expandafter\f@nch@ifin\expandafter{\f@nch@align@@h}{lcrj}{}%
+ {\PackageError{fancyhdr}
+ {\string#3: Illegal char `\f@nch@align@@h'\MessageBreak
+ in alignment argument}{}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\lhead}
% \changes{fancyhdr v3.9}{2016/10/12}{Let \cs{newcommand} do the
% handling of the optional parameter.}
@@ -6552,8 +7002,8 @@
% \changes{fancyhdr v4.0.2}{2021/03/27}{Change the offset length variables
% \cs{f@nch@O@xyz} to \cs{f@nch@offset@xyz}}
% Length parameter to be used for \cs{headwidth}. We use this rather
-% than defining \cs{headwidth} as a length paramater directly to protect
-% ourself to someone saying: \verb+\let\headwidth\textwidth+.
+% than defining \cs{headwidth} as a length parameter directly to protect
+% ourselves to someone saying: \verb+\let\headwidth\textwidth+.
% \begin{macrocode}
\newlength{\f@nch@headwidth} \let\headwidth\f@nch@headwidth
% \end{macrocode}
@@ -6598,8 +7048,10 @@
% \begin{macro}{\headruleskip}
% Don't define \cs{headruleskip} if it is already defined.
% \changes{fancyhdr v4.0}{2019/03/22}{Parameter \cs{headruleskip}.}
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% \begin{macrocode}
-\f@nch@ifundefined{headruleskip}%
+\@ifundefined{headruleskip}%
{\newcommand{\headruleskip}{0pt}}{}
% \end{macrocode}
% \end{macro}
@@ -6607,8 +7059,10 @@
% \begin{macro}{\footruleskip}
% Memoir also defines \cs{footruleskip}.
% Don't define \cs{footruleskip} if it is already defined.
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% \begin{macrocode}
-\f@nch@ifundefined{footruleskip}%
+\@ifundefined{footruleskip}%
{\newcommand{\footruleskip}{.3\normalbaselineskip}}{}
% \end{macrocode}
% \end{macro}
@@ -6686,8 +7140,10 @@
% \changes{fancyhdr v5.1}{2025/01/06}{A new way to disable the paragraph
% hooks in headers and footers.}
% \changes{fancyhdr v5.1.1}{2025/01/07}{Use low-level commands to reset
-% paragraph hooks to prevent LaTeX error when ruinning with latex3
+% paragraph hooks to prevent LaTeX error when running with latex3
% debugging.}
+% \changes{fancyhdr v5.2}{2025/01/14}{Use official interface to reset
+% the paragraph hooks.}
% The way we do this now: Every hook consists of 4 global `variables':
% \begin{itemize}
% \item \cs{__hook \meta{name}}
@@ -6699,26 +7155,23 @@
% \texttt{para/end}, and \texttt{para/after}). At the beginning of a
% header/footer, i.e., before any init code and hooks, all these variables are
% locally saved into variables with the same name, prefixed with
-% `\texttt{f@nch@}', and then globally reset to their `empty' value. At
-% the end of the header/footer they are globally restored to the saved value.
+% `\texttt{f@nch@}', and then clear the hook. At the end of the
+% header/footer they are globally restored to the saved value.
% So we do only global assignments to them to avoid problems.
% Save a (paragraph) hook locally and and clear it globally.
% Restore it globally at the end of header/footer processing.
% \begin{macrocode}
- \prop_new:N \f@nch@empty_code_prop
\def\f@nch@saveclr@parhook #1{
\expandafter\let\csname f@nch@__hook~#1\expandafter\endcsname
\csname __hook~#1\endcsname
- \expandafter\gdef\csname __hook~#1\endcsname { }
\expandafter\let\csname f@nch@__hook_toplevel~#1\expandafter\endcsname
\csname __hook_toplevel~#1\endcsname
- \expandafter\gdef\csname __hook_toplevel~#1\endcsname { }
\expandafter\let\csname f@nch@__hook_next~#1\expandafter\endcsname
\csname __hook_next~#1\endcsname
- \expandafter\gdef\csname __hook_next~#1\endcsname { }
\expandafter\let\csname f@nch@g__hook_#1_code_prop\expandafter\endcsname
\csname g__hook_#1_code_prop\endcsname
- \global\expandafter\let\csname g__hook_#1_code_prop\endcsname \f@nch@empty_code_prop
+ \RemoveFromHook{#1}[*]
+ \ClearHookNext{#1}
}
\def\f@nch@restore@parhook #1{
\global\expandafter\let\csname __hook~#1\expandafter\endcsname
@@ -6767,7 +7220,7 @@
% We want \cs{nouppercase} to work with the various evolutionary stages of
% \cs{MakeUppercase}. The current version (2022/11/09) accepts an optional
% argument with a language specification. Therefore we define a dummy macro
-% \cs{f@nch@noUppercase} which copies its mandatory agument, as a
+% \cs{f@nch@noUppercase} which copies its mandatory argument, as a
% replacement for \cs{MakeUppercase} while \cs{nouppercase} is active.
% \begin{macrocode}
\newcommand\f@nch@noUppercase[2][]{#2}
@@ -6781,10 +7234,10 @@
% Also reset the catcodes that are changed in verbatim environments,
% \cs{makeatother} and \cs{ExplSyntaxOn}. It also
% defines a \cs{nouppercase} command that disables \cs{uppercase} and
-% \cs{Makeuppercase}. It can only be used in the headers and footers. Set
+% \cs{MakeUppercase}. It can only be used in the headers and footers. Set
% \cs{hsize} to \cs{headwidth} (this helps for multicol); reset
% \bsbs, \cs{raggedleft}, \cs{raggedright} and \cs{centering} to
-% their default values (for tabu), and \cs{everypar} to empty.\\
+% their default values (for \pkg{tabu}), and \cs{everypar} to empty.\\
% The font is reset to \cs{normalfont}. Actually this is done in the
% \LaTeX{} output routine, so we don't have to do it here.
% \changes{fancyhdr v4.1}{2022/11/09}{Change \cs{nouppercase} to work with
@@ -6794,6 +7247,8 @@
% is active. (Issue \# 8 \url{https://github.com/pietvo/fancyhdr/issues/8}.)}
% \changes{fancyhdr v4.3}{2024/05/08}{Remove pre-NFSS stuff}
% \changes{fancyhdr v4.3}{2024/07/17}{Replace \cs{f@nch@everypar} by \cs{f@nch@resetpar}.}
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% \begin{macrocode}
\def\f@nch@reset{\f@nch@resetpar\restorecr\endlinechar=13
\catcode`\\=0\catcode`\{=1\catcode`\}=2\catcode`\$=3\catcode`\&=4
@@ -6811,7 +7266,7 @@
\expandafter\def\csname MakeUppercase\space\space\space\endcsname
[####1]####2{####2}%
##1}}%
- \f@nch@ifundefined{@normalsize} {\normalsize} % for ucthesis.cls
+ \@ifundefined{@normalsize} {\normalsize} % for ucthesis.cls
{\@normalsize}%
}
% \end{macrocode}
@@ -6952,7 +7407,7 @@
%
% \begin{macro}[internal]{\f@nch@height}
% \changes{fancyhdr v5.0}{2021/02/20}{Length variable \cs{f@nch@height} added}
-% Length variable to store heigth of header/footer for use in \cs{fancyhdrsettoheight}
+% Length variable to store height of header/footer for use in \cs{fancyhdrsettoheight}
% \begin{macrocode}
\newlength\f@nch@height
% \end{macrocode}
@@ -7077,7 +7532,7 @@
% However, if the \texttt{[nocheck]} options is given, we just make the
% height of the header/footer equal to the reserved space, so that no
% warning about ``Overfull vbox'' will be given. So we pretend that it
-% fits, and it is the users's responsibility to make sure no unwanted
+% fits, and it is the user's responsibility to make sure no unwanted
% effects take place.
% \begin{macrocode}
\else
@@ -7102,6 +7557,8 @@
% \cs{fancyfootwidth} and \cs{fancyhfwidth}.}
% \changes{fancyhdr v5.1}{2025/01/06}{Add paragraph hook restore code
% (\cs{f@nch@restorepar}).}
+% \changes{fancyhdr v5.2}{2025/01/25}{Implement \cs{fancyhfwidth} etc.
+% \meta{alignment} option.}
% Put together a header (\cs{f@nch@head}) or footer (\cs{f@nch@foot})
% given the left, center and right text and their widths,
% fillers at left and right and a rule. The \cs{xlap} commands put
@@ -7118,7 +7575,7 @@
% This is the right component. \\
% 5. RIGHTSIDE BEARING. This is always \cs{relax} or \cs{hss}
% (after expansion).\\
-% 6-8. The specified widths for the left, center and right fields.
+% 6. Even (\texttt{e}) or odd (\texttt{o}).
%
% Before constructing the header or footer, the environment is reset to
% a known state, the appropriate hooks (\texttt{fancyhdr/before} and
@@ -7133,14 +7590,14 @@
% \TTindex{fancyhdr/after}%
% \texttt{fancyhdr/after}) are run.
% \begin{macrocode}
-\newcommand\f@nch@head[8]{%
+\newcommand\f@nch@head[6]{%
\f@nch@reset
\ifdefined\UseHook\UseHook{fancyhdr/before}\UseHook{fancyhdr/head/begin}\fi
\f@nch@headinit\relax
#1%
\hbox to\headwidth{%
\f@nch@vbox\headheight{%
- \f@nch@hfbox{#2}{#3}{#4}{b}{#6}{#7}{#8}%
+ \f@nch@hfbox{#2}{#3}{#4}{#6}{h}%
\vskip\headruleskip\relax
\headrule
}%
@@ -7170,13 +7627,15 @@
% \cs{fancyfootwidth} and \cs{fancyhfwidth}.}
% \changes{fancyhdr v5.1}{2025/01/06}{Add paragraph hook restore code
% (\cs{f@nch@restorepar}).}
+% \changes{fancyhdr v5.2}{2025/01/25}{Implement \cs{fancyhfwidth} etc.
+% \meta{alignment} option.}
% We put the \cs{footrule} in a \cs{vbox} to accommodate for flexible
% footrules (e.g., using \cs{hrulefill}), so that the \cs{headwidth} will
% be used as the line width. But to preserve the vertical spacing we
% then \cs{unvbox} this box.
%
% \begin{macrocode}
-\newcommand\f@nch@foot[8]{%
+\newcommand\f@nch@foot[6]{%
\f@nch@reset
\ifdefined\UseHook\UseHook{fancyhdr/before}\UseHook{fancyhdr/foot/begin}\fi
\f@nch@footinit\relax
@@ -7185,7 +7644,7 @@
\f@nch@vbox\footskip{%
\setbox0=\vbox{\footrule}\unvbox0
\vskip\footruleskip
- \f@nch@hfbox{#2}{#3}{#4}{t}{#6}{#7}{#8}%
+ \f@nch@hfbox{#2}{#3}{#4}{#6}{f}%
% \end{macrocode}
% \changes{fancyhdr v5.0}{2024/05/13}{\cs{vskip}\meta{length}
% added if \cs{fancyfootalign}\protect\marg{length} was given.}
@@ -7213,12 +7672,12 @@
%
% \end{macro}
% \begin{macro}[internal]{\f@nch@hfbox}
-% This macro constructs the box with the header or footer. It has 7 parameters:\\
+% This macro constructs the box with the header or footer. It has 5 parameters:\\
% 1. Left field\\
% 2. Center field\\
% 3. Right field\\
-% 4. Vertical alignment: \texttt{b} for the header or \texttt{t} for the footer\\
-% 5-7. Widths for the left, center and right fields.
+% 4. Even (\texttt{e}) or odd (\texttt{o}).\\
+% 5. Header (\texttt{h}) or footer (\texttt{f}).
%
% Algorithm:\\
% First we store the field widths in length variables.\\
@@ -7232,12 +7691,14 @@
% put the center field centered between the left and right field, i.e.,
% with equal gaps on both sides. This is done by the macro
% \cs{f@nch@hfbox@fit}.
+% \changes{fancyhdr v5.2}{2025/01/25}{Implement \cs{fancyhfwidth} etc.
+% \meta{alignment} option.}
%
% \begin{macrocode}
-\newcommand\f@nch@hfbox[7]{%
- \setlength\f@nch@widthL{#5}%
- \setlength\f@nch@widthC{#6}%
- \setlength\f@nch@widthR{#7}%
+\newcommand\f@nch@hfbox[5]{%
+ \setlength\f@nch@widthL{\csname f@nch@width@#4l#5\endcsname}%
+ \setlength\f@nch@widthC{\csname f@nch@width@#4c#5\endcsname}%
+ \setlength\f@nch@widthR{\csname f@nch@width@#4r#5\endcsname}%
\let\@tempa\f@nch@hfbox@center
\ifdim \dimexpr \f@nch@widthL+\f@nch@widthC+\f@nch@widthR>\headwidth
\else
@@ -7248,7 +7709,7 @@
\let \@tempa\f@nch@hfbox@fit
\fi
\fi
- \@tempa{#1}{#2}{#3}{#4}%
+ \@tempa{#1}{#2}{#3}#4#5%
}
% \end{macrocode}
% \end{macro}
@@ -7260,15 +7721,18 @@
% 1. Left field\\
% 2. Center field\\
% 3. Right field\\
-% 4. Vertical alignment: \texttt{b} for the header or \texttt{t} for the footer\\
+% 4. Even (\texttt{e}) or odd (\texttt{o}).\\
+% 5. Header (\texttt{h}) or footer (\texttt{f}).
+% \changes{fancyhdr v5.2}{2025/01/25}{Implement \cs{fancyhfwidth} etc.
+% \meta{alignment} option.}
% \begin{macrocode}
-\newcommand\f@nch@hfbox@center[4]{%
+\newcommand\f@nch@hfbox@center[5]{%
\hbox to \headwidth{%
- \rlap{\parbox[#4]{\f@nch@widthL}{\raggedright\leavevmode\ignorespaces#1}}%
+ \rlap{\f@nch@parbox{#1}\f@nch@widthL{#4}l{#5}}%
\hfill
- \parbox[#4]{\f@nch@widthC}{\centering\leavevmode\ignorespaces#2}%
+ \f@nch@parbox{#2}\f@nch@widthC{#4}c{#5}%
\hfill
- \llap{\parbox[#4]{\f@nch@widthR}{\raggedleft\leavevmode\ignorespaces#3}}%
+ \llap{\f@nch@parbox{#3}\f@nch@widthR{#4}r{#5}}%
}%
}
% \end{macrocode}
@@ -7280,34 +7744,108 @@
% 1. Left field\\
% 2. Center field\\
% 3. Right field\\
-% 4. Vertical alignment: \texttt{b} for the header or \texttt{t} for the footer\\
+% 4. Even (\texttt{e}) or odd (\texttt{o}).\\
+% 5. Header (\texttt{h}) or footer (\texttt{f}).
+% \changes{fancyhdr v5.2}{2025/01/25}{Implement \cs{fancyhfwidth} etc.
+% \meta{alignment} option.}
% \begin{macrocode}
-\newcommand\f@nch@hfbox@fit[4]{%
+\newcommand\f@nch@hfbox@fit[5]{%
\hbox to \headwidth{%
- \parbox[#4]{\f@nch@widthL}{\raggedright\leavevmode\ignorespaces#1}%
+ \f@nch@parbox{#1}\f@nch@widthL{#4}l{#5}%
\hfill
- \parbox[#4]{\f@nch@widthC}{\centering\leavevmode\ignorespaces#2}%
+ \f@nch@parbox{#2}\f@nch@widthC{#4}c{#5}%
\hfill
- \parbox[#4]{\f@nch@widthR}{\raggedleft\leavevmode\ignorespaces#3}%
+ \f@nch@parbox{#3}\f@nch@widthR{#4}r{#5}%
}%
}%
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\MakeUppercase}
-% Define \MakeUppercase for old \LaTeX{}en. Note: we used \cs{def} rather
-% than \cs{let}, so that \verb+\let\uppercase\relax+ (from the version 1
-% documentation) will still work.
+% \begin{macro}[internal]{\f@nch@parbox}
+% This macro constructs one \cs{parbox} in the header or footer.
+% It has 4 parameters:\\
+% 1. The contents\\
+% 2. The width for the \cs{parbox}.\\
+% 3. Even (\texttt{e}) or odd (\texttt{o}).\\
+% 4. Left (\texttt{l}), center (\texttt{c}) or right (\texttt{r}).\\
+% 5. Header (\texttt{h}) or footer (\texttt{f}).\\
+% Result: the proper \cs{parbox}\\[1ex]
+% First we get (with \Cmd{csname}) the proper alignment parameter. Then we
+% expand this so that \cs{f@nch@parbox@align} gets the two alignment letters
+% as separate arguments. Then \cs{f@nch@parbox@align} is called to set
+% up the alignment variables. After that we construct the \cs{parbox}
+% with the calculated variables.
+% \begin{macrocode}
+\newcommand\f@nch@parbox[5]{%
+ \expandafter\expandafter\expandafter\f@nch@parbox@align
+ \csname f@nch@align@#3#4#5\endcsname
+ \parbox[\f@nch@align@@v]{#2}%
+ {%
+ \f@nch@align@@pre
+ \f@nch@align@@h\leavevmode\ignorespaces#1%
+ \f@nch@align@@post
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\f@nch@parbox@align}
+% The macro \cs{f@nch@parbox@align} sets the alignment variables for \cs{f@nch@parbox}.
+% It has 2 parameters, the two letters for the vertical and horizontal
+% alignment, with the defaults applied.\\
+% 1. Vertical (\texttt{T, t, c, b, B}).\\
+% 2. Horizontal (\texttt{l, c, r, j}).\\
+% Result variables:
+% \begin{description}
+% \item[\cs{f@nch@align@@v}] The vertical alignment for the \cs{parbox}:
+% \texttt{t}, \texttt{c} or \texttt{b}.
+% \item[\cs{f@nch@align@@h}] The horizontal alignment for the
+% \cs{parbox}: \cs{raggedright}, \cs{centering}, \cs{raggedleft} or
+% empty for \texttt{l, c, r, j}, respectively.
+% \item[\cs{f@nch@align@@pre}] code before the contents of the
+% \cs{parbox}: \Cmd{vspace\{0pt\}} for \texttt{T} alignment, otherwise empty.
+% \item[\cs{f@nch@align@@post}] code after the contents of the
+% \cs{parbox}: \Cmd{vspace\{0pt\}} for \texttt{B} alignment, otherwise empty.
+% \end{description}
+% First we set the defaults for \cs{f@nch@align@@pre} and
+% \cs{f@nch@align@@post} (empty). Then we call the proper macros for the
+% alignment parameters.
+% \begin{macrocode}
+\newcommand\f@nch@parbox@align[2]{%
+ \def\f@nch@align@@pre{}%
+ \def\f@nch@align@@post{}%
+ \csname f@nch@parbox@align@v#1\endcsname
+ \csname f@nch@parbox@align@h#2\endcsname
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\f@nch@parbox@align@vT,
+% \f@nch@parbox@align@vt, \f@nch@parbox@align@vc, \f@nch@parbox@align@vb, \f@nch@parbox@align@vB, \f@nch@parbox@align@hl, \f@nch@parbox@align@hc, \f@nch@parbox@align@hr, \f@nch@parbox@align@hj}
%
+% The macro \cs{f@nch@parbox@align@\meta{v$|$h}\meta{x}} sets the variables for the
+% vertical or horizontal alignment option \texttt{\meta{x}}.
% \begin{macrocode}
-\f@nch@ifundefined{MakeUppercase}{\def\MakeUppercase{\uppercase}}{}%
+\def\f@nch@parbox@align@vT{\def\f@nch@align@@v{t}\def\f@nch@align@@pre{\vspace{0pt}}}
+\def\f@nch@parbox@align@vt{\def\f@nch@align@@v{t}}
+\def\f@nch@parbox@align@vc{\def\f@nch@align@@v{c}}
+\def\f@nch@parbox@align@vb{\def\f@nch@align@@v{b}}
+\def\f@nch@parbox@align@vB{\def\f@nch@align@@v{b}\def\f@nch@align@@post{\vspace{0pt}}}
+\def\f@nch@parbox@align@hl{\def\f@nch@align@@h{\raggedright}}
+\def\f@nch@parbox@align@hc{\def\f@nch@align@@h{\centering}}
+\def\f@nch@parbox@align@hr{\def\f@nch@align@@h{\raggedleft}}
+\def\f@nch@parbox@align@hj{\def\f@nch@align@@h{}}
% \end{macrocode}
% \end{macro}
%
+% \changes{fancyhdr v5.2}{2025/01/28}{Remove fallback definition of \cs{MakeUppercase}.}
+%
% \begin{macro}[internal]{\@chapapp}
% Define \cs{@chapapp} for classes that don't have it, e.g., amsbook
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% \begin{macrocode}
-\f@nch@ifundefined{@chapapp}{\let\@chapapp\chaptername}{}%
+\@ifundefined{@chapapp}{\let\@chapapp\chaptername}{}%
% \end{macrocode}
% \end{macro}
% \begin{macro}[internal]{\f@nch@initialise}
@@ -7323,9 +7861,11 @@
% \begin{macro}{\sectionmark}
% \begin{macro}{\subsectionmark}
% Standard definitions for \cs{chaptermark}, \cs{sectionmark} and \cs{subsectionmark}.
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
%
% \begin{macrocode}
- \f@nch@ifundefined{chapter}%
+ \@ifundefined{chapter}%
{\def\sectionmark##1{\markboth{\MakeUppercase{\ifnum \c@secnumdepth>\z@
\thesection\hskip 1em\relax
\fi ##1}}{}}%
@@ -7369,8 +7909,8 @@
% Initialisation of the head and foot text.
%
% The default values still contain \cs{fancyplain} for compatibility:
-% lefthead empty on ``plain'' pages, \cs{rightmark} on even, \cs{leftmark} on odd pages;
-% evenhead empty on ``plain'' pages, \cs{leftmark} on even, \cs{rightmark} on odd pages.
+% left head empty on ``plain'' pages, \cs{rightmark} on even, \cs{leftmark} on odd pages;
+% right head empty on ``plain'' pages, \cs{leftmark} on even, \cs{rightmark} on odd pages.
% \begin{macrocode}
\fancyhf{}%
\if@twoside
@@ -7463,6 +8003,8 @@
% \changes{fancyhdr v4.1}{2022/09/06}{Implement \texttt{twoside} option.}
% \changes{fancyhdr v5.0}{2025/01/01}{Support for \cs{fancyheadwidth},
% \cs{fancyfootwidth} and \cs{fancyhfwidth}.}
+% \changes{fancyhdr v5.2}{2025/01/25}{Implement \cs{fancyhfwidth} etc.
+% \meta{alignment} option.}
% The actual implementation of page style \texttt{fancy}. For amsbook/amsart, which do
% strange things with \cs{topskip}, we start with \cs{f@nch@ps@empty}. We
% construct the even and odd headers and footers from all the parts that
@@ -7471,8 +8013,7 @@
\def\ps@f@nch@fancycore{%
\f@nch@ps@empty
\def\@mkboth{\protect\markboth}%
- \def\f@nch@oddhead{\f@nch@head\f@nch@Oolh\f@nch@olh\f@nch@och\f@nch@orh\f@nch@Oorh
- \f@nch@width@olh\f@nch@width@och\f@nch@width@orh}%
+ \def\f@nch@oddhead{\f@nch@head\f@nch@Oolh\f@nch@olh\f@nch@och\f@nch@orh\f@nch@Oorh{o}}%
\def\@oddhead{%
\iff@nch@twoside
\ifodd\c@page
@@ -7484,8 +8025,7 @@
\f@nch@oddhead
\fi
}
- \def\f@nch@oddfoot{\f@nch@foot\f@nch@Oolf\f@nch@olf\f@nch@ocf\f@nch@orf\f@nch@Oorf
- \f@nch@width@olf\f@nch@width@ocf\f@nch@width@orf}%
+ \def\f@nch@oddfoot{\f@nch@foot\f@nch@Oolf\f@nch@olf\f@nch@ocf\f@nch@orf\f@nch@Oorf{o}}%
\def\@oddfoot{%
\iff@nch@twoside
\ifodd\c@page
@@ -7497,10 +8037,8 @@
\f@nch@oddfoot
\fi
}
- \def\@evenhead{\f@nch@head\f@nch@Oelh\f@nch@elh\f@nch@ech\f@nch@erh\f@nch@Oerh
- \f@nch@width@elh\f@nch@width@ech\f@nch@width@erh}%
- \def\@evenfoot{\f@nch@foot\f@nch@Oelf\f@nch@elf\f@nch@ecf\f@nch@erf\f@nch@Oerf
- \f@nch@width@elf\f@nch@width@ecf\f@nch@width@erf}%
+ \def\@evenhead{\f@nch@head\f@nch@Oelh\f@nch@elh\f@nch@ech\f@nch@erh\f@nch@Oerh{e}}%
+ \def\@evenfoot{\f@nch@foot\f@nch@Oelf\f@nch@elf\f@nch@ecf\f@nch@erf\f@nch@Oerf{e}}%
}
% \end{macrocode}
% \end{macro}
@@ -7679,12 +8217,14 @@
% Declare it as a fancyhdr-based page style.
% \changes{fancyhdr v4.0}{2019/09/05}{Make the definition of \cs{f@nch@pagestyle} \cs{long}.}
% \changes{fancyhdr v5.0}{2021/02/17}{Add \cs{fancypagestyle*}}
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% \begin{macrocode}
\long\def\f@nch@@pagestyle#1[#2]#3{%
- \f@nch@ifundefined{ps@#2}{%
+ \@ifundefined{ps@#2}{%
\PackageError{fancyhdr}{\string\fancypagestyle: Unknown base page style `#2'}{}%
}{%
- \f@nch@ifundefined{f@nch@ps@#2-is-fancyhdr}{%
+ \@ifundefined{f@nch@ps@#2-is-fancyhdr}{%
\PackageError{fancyhdr}{\string\fancypagestyle: Base page style `#2' is not fancyhdr-based}{}%
}%
{%
@@ -7714,6 +8254,10 @@
% \changes{fancyhdr v5.0}{2021/03/27}{Also save the offset length variables
% \cs{f@nch@offset@xyz} with \cs{setlength}}
% \changes{fancyhdr v5.0}{2022/01/24}{Replace \cs{myname} with \cs{temp@a}}
+% \changes{fancyhdr v5.0}{2025/01/02}{Implement \cs{fancyhfwidth} etc.,
+% store \meta{width}.}
+% \changes{fancyhdr v5.2}{2025/01/27}{Implement \cs{fancyhfwidth} etc.,
+% store \meta{alignment}.}
% \begin{macrocode}
\newcommand\f@nch@pagestyle@setup{%
\iff@nch@pagestyle@star
@@ -7723,8 +8267,9 @@
% \begin{macrocode}
\iff@nch@check\@temptokenb={\f@nch@checktrue}\else\@temptokenb={\f@nch@checkfalse}\fi
% \end{macrocode}
-% Save values of all relevant macros (26 in total):\\
+% Save values of all relevant macros (50 in total):\\
% headers and footers (12), header and footer widths (12),
+% header and footer alignments (12),
% header and footer offsets (8), header and footer inits (2),
% \cs{headrule} and \cs{footrule} and \texttt{...width} (4)
% \begin{macrocode}
@@ -7734,6 +8279,9 @@
\f@nch@width@elh\f@nch@width@ech\f@nch@width@erh\f@nch@width@olh
\f@nch@width@och\f@nch@width@orh\f@nch@width@elf\f@nch@width@ecf
\f@nch@width@erf\f@nch@width@olf\f@nch@width@ocf\f@nch@width@orf
+ \f@nch@align@elh\f@nch@align@ech\f@nch@align@erh\f@nch@align@olh
+ \f@nch@align@och\f@nch@align@orh\f@nch@align@elf\f@nch@align@ecf
+ \f@nch@align@erf\f@nch@align@olf\f@nch@align@ocf\f@nch@align@orf
\f@nch@Oolh\f@nch@Oorh\f@nch@Oelh\f@nch@Oerh
\f@nch@Oolf\f@nch@Oorf\f@nch@Oelf\f@nch@Oerf
\f@nch@headinit\f@nch@footinit
@@ -7782,6 +8330,8 @@
% \end{macro}
% \begin{macro}{\fancypagestyleassign}
% \changes{fancyhdr v5.0}{2024/12/25}{Macro \cs{fancypagestyleassign} added}
+% \changes{fancyhdr v5.2}{2025/01/15}{Use \cs{@ifundefined} instead of
+% \cs{f@nch@ifundefined}.}
% \begin{syntax}
% \cs{fancypagestyleassign}\marg{ps1}\marg{ps2}
% \end{syntax}
@@ -7791,26 +8341,18 @@
% command, like \cs{let}\cs{ps@\meta{ps1}}\cs{ps@\meta{ps2}}.
% \begin{macrocode}
\newcommand\fancypagestyleassign[2]{%
- \f@nch@ifundefined{ps@#2}{%
+ \@ifundefined{ps@#2}{%
\PackageError{fancyhdr}{\string\fancypagestyleassign: Unknown page style `#2'}{}%
}{%
\expandafter\let
\csname ps@#1\expandafter\endcsname
\csname ps@#2\endcsname
% \end{macrocode}
-% If \meta{ps2} is not fancyhdr-based, \meta{ps1} will also be
-% fancyhdr-based, otherwise it will not. If \meta{ps2} is not
-% fancyhdr-based, but \meta{ps1} is, give a warning that it is
-% overwritten, which could give unexpected problems.
-% \begin{macrocode}
- \f@nch@ifundefined{f@nch@ps@#2-is-fancyhdr}{%
- \f@nch@ifundefined{f@nch@ps@#1-is-fancyhdr}{}{%
- \PackageNote{fancyhdr}{%
- \string\fancypagestyleassign: You overwrite the\MessageBreak
- fancyhdr-based page style `#1' with the\MessageBreak
- non-fancyhdr-based page style `#2'.\MessageBreak
- This could cause unexpected problems if you\MessageBreak
- use `#1' as the base style in \string\fancypagestyle}}%
+% If \meta{ps2} is fancyhdr-based, \meta{ps1} will also be
+% fancyhdr-based, otherwise it is not.
+% \changes{fancyhdr v5.2}{2025/01/27}{Remove \Cmd{PackageNote}.}
+% \begin{macrocode}
+ \@ifundefined{f@nch@ps@#2-is-fancyhdr}{%
\expandafter\let\csname f@nch@ps@#1-is-fancyhdr\endcsname\@undefined
}{%
\@namedef{f@nch@ps@#1-is-fancyhdr}{}%
@@ -7928,7 +8470,7 @@
% \begin{macro}[internal]{\f@nchdrbox@cr, \@f@nchdrbox@xcr,
% \@f@nchdrbox@argc, \@f@nchdrbox@xargc, \@f@nchdrbox@yargc}
% This is the definition for \cmd{\\} inside \cs{fancyhdrbox},
-% \cmd{\\*} does nothing special here, but we acccept it anyway.
+% \cmd{\\*} does nothing special here, but we accept it anyway.
% The code is mostly copied from the \env{tabular} code from the
% \LaTeX{} kernel, but simplified, and the names of the macros are
% changed so that we don't rely on internals in the \LaTeX{} kernel that
@@ -7988,6 +8530,8 @@
% \end{macro}
%
% \begin{macro}[internal]{\f@nchdrbox@align}
+% \changes{fancyhdr v5.2}{2025/01/23}{Check for legal alignment
+% argument added.}
% \cs{f@nchdrbox@align}\marg{vert}\marg{hor}\texttt{\cs{@nil}}\marg{lines}\\[1ex]
% The internal processing for the \cs{halign} in a vertical box.\\
% ALGORITHM \cs{f@nchdrbox@align}:\\
@@ -8001,10 +8545,11 @@
% \hspace*{1em} v := \texttt{c}\\
% \hspace*{1em} h := \texttt{\#1}\\
% \textbf{FI}\\
+% \textbf{if} h not in \texttt{\{l,c,r\}} \textbf{then} ERROR \textbf{fi}\\
% Set the \cs{halign} in a \cs{vtop} (for \texttt{T/t} alignment) or
% \cs{vbox} (for others). This box is put into \cs{box0} because we have
% to change it for the vertical alignment \texttt{c}. For the others it
-% isn't necesary, but it just makes the code easier to do it anyway.
+% isn't necessary, but it just makes the code easier to do it anyway.
% We also insert the \cs{f@nchdrbox@@pre},
% \cs{f@nchdrbox@@postx} and \cs{f@nchdrbox@@posty} variables in the
% proper places. The rest of the code is roughly based on the
@@ -8017,6 +8562,9 @@
\ifx\@tempa\@empty\else \def\f@nchdrbox@@h{#2}\fi
}%
{\def\f@nchdrbox@@v{c}\def\f@nchdrbox@@h{#1}}%
+ \expandafter\f@nch@ifin\expandafter{\f@nchdrbox@@h}{lcr}{}%
+ {\PackageError{fancyhdr}{\string\fancyhdrbox: Illegal char `\f@nchdrbox@@h'\MessageBreak
+ in alignment argument}{}}%
\let\\\f@nchdrbox@cr
\setbox0=\if \f@nchdrbox@@v t\vtop
\else \vbox
@@ -8095,12 +8643,12 @@
%
% \changes{extramarks v5.0}{2024/05/14}{New implementation with
% independent marks, and fallback option to earlier version 4.}
-% Provide a rollback to earlier version
+% Provide a rollback to earlier version.
+% \changes{extramarks v5.2}{2025/01/15}{Assume \cs{DeclareRelease} is
+% present (\LaTeX{} version at lease 2018-04-01).}
% \begin{macrocode}
-\providecommand\DeclareRelease[3]{}
-\providecommand\DeclareCurrentRelease[2]{}
\DeclareRelease{v4}{2024/11/30}{extramarks-v4.sty}
-\DeclareCurrentRelease{}{2025/01/07}
+\DeclareCurrentRelease{v5}{2025/02/07}
\@ifundefined{NewMarkClass}
{\PackageWarningNoLine{extramarks}{%
**************************************************\MessageBreak