如何强制 fancyhdr 标记页面上的子部分?

如何强制 fancyhdr 标记页面上的子部分?

我正在尝试使用fancyhdr为我正在写的一些笔记(课堂、单面)创建标题article。我希望在左侧显示章节名称和编号,在右侧显示子章节名称和编号。我的问题是子章节标题未显示在某些页面上。这是我的代码:

\usepackage[utf8]{inputenc}
\usepackage{amsthm, amsmath, amssymb, amsfonts, enumitem, mathtools, etoolbox, mathrsfs, fancyhdr}
\usepackage[margin=1in]{geometry}

\pagestyle{fancy} 
\fancyhead{} 
\fancyfoot{}
\fancyfoot[C]{\thepage}
\fancyhead[L]{\nouppercase{\leftmark}}
\fancyhead[R]{\rightmark} 
\headheight 15pt

以下是输出。前两张图片显示了我希望每个页面的外观: 在此处输入图片描述

在此处输入图片描述

这两个显示了我遇到的问题:

在此处输入图片描述 在此处输入图片描述

如您所见,在最后两张图片中,尽管这些页面上开始了新的子部分,但子部分并未出现在页眉中。有办法解决这个问题吗?

编辑:这是该问题的一个工作示例:

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsthm, amsmath, amssymb, amsfonts, enumitem, mathtools, etoolbox, mathrsfs, fancyhdr, extramarks}
\usepackage[margin=1in]{geometry}
\usepackage{blindtext}

\pagestyle{fancy}
\fancyhead{}
\fancyfoot{}
\fancyfoot[C]{\thepage}
\fancyhead[L]{\nouppercase{\firstleftmark}}
\fancyhead[R]{\firstrightmark} 
\headheight 15pt

\renewcommand{\subsectionmark}[1]{\markright{\thesubsection.\ #1}}

\title{test}
\date{September 2019}

\begin{document}
\section{Intro}
\subsection{Subsection 1}

\blindtext[3]
\pagebreak

\subsection{Subsection 2}

\blindtext[3]
\pagebreak

\section{Another section}
\subsection{Sub 3}
\blindtext[1]

\subsection{Sub 4}
\blindtext[1]
\end{document}

编译后,第一页和第三页缺少子节标题。似乎只有当新节在页面上首先开始时才会发生这种情况。

答案1

不幸的是,@ejmastnak 提出的解决方案并不总是有效。我有几个失败的例子。问题是 TeX 的分页算法可以处理比页面容纳的更多的文本,然后它可以稍后决定将该文本放在下一页。因此,设置“变量”来向标题传达信息可能会导致这些变量设置在错误的页面上。事实上,这正是开发“标记”机制的原因。只有在某些受限情况下,“变量”才能正常工作。

以下是解决方案失败的示例。我省略了注释的版本 2 代码,并\message在命令中添加了一些语句\[sub]sectionmark来显示发生了什么。

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{fancyhdr}
\usepackage[margin=1in, headheight=15pt]{geometry}
\usepackage{blindtext}

% begin header configuration
\pagestyle{fancy}

% Start fancyhdr settings
\fancyhf{}
\fancyhead[L]{\leftmark}  % section
\fancyhead[R]{\rightmark}  % subsection
\fancyfoot[C]{\thepage} 
% End fancyhdr settings

% Redefine sectionmark to produce desired behavior --- VERSION 1
% This version sets the FIRST subsection on a page as the right mark,
%   even if there are multiple subsections on a page
\renewcommand{\sectionmark}[1]{%
    \markboth{\thesection. \ #1}
    {\noexpand\firstsubsectiontitle}%
    \global\firstsubsectionmarktrue
    \message{section #1 on page \thepage}} % first subsection mark set
\renewcommand{\subsectionmark}[1]{% ensures the first subsection is displayed even if multiple subsections occur on a given page
    \markright{\thesubsection. \, #1}%
    \iffirstsubsectionmark
        \edef\firstsubsectiontitle{\thesubsection. \, #1}%
    \fi
    \message{subsection #1 on page \thepage}%
    \global\firstsubsectionmarkfalse
    }
\newif\iffirstsubsectionmark
\def\firstsubsectiontitle{}
% End VERSION 1

% End header configuration

\newcommand{\sometext}{Lots of text. Lots of text. Lots of text. Lots of text.
Lots of text. Lots of text.}
\newcommand{\lotsoftext}{\sometext \sometext \sometext
\sometext \sometext \sometext \par}

\begin{document}

\section{First section}

\subsection{First subsection}

\lotsoftext \lotsoftext \lotsoftext \lotsoftext \lotsoftext \lotsoftext
\lotsoftext \lotsoftext

\section{Second section}

\subsection{Second subsection}

\begin{figure}[h]
  \centering
  \fbox{\rule{0pt}{420pt}\hspace{10cm}}
  \caption{A figure}
\end{figure}

\section{Third section}

\subsection{Third subsection}

\blindtext[3]

\end{document}

在此处输入图片描述

如您所见,第 2 页获得了第 3 页第一部分的标题。这是因为和都\section{Third section}\subsection{Third subsection}第 2 页进行了处理(如日志文件中的消息所示),但由于它们在第 2 页放不下,因此被推送到第 3 页。

现在,使用当前的 LaTeX 很难解决这个问题。这是有可能的,但这需要对 LaTeX 内核进行大量修改。我不知道什么时候(或是否)会发生这种情况,但我希望它会发生。

有一种情况可以使用标记来解决,即如果每个\section命令后面都紧跟着一个\subsection命令。LaTeX 永远不会在这两个命令之间分页,因此它们始终会保持在同一页上。那么你只需要一个“标记”命令就可以解决这两个命令的问题。

然后我们要做的是将章节标题放入一个变量中,然后使用它将\subsectionmark其放入左边的标记中。

\newcommand\sectiontitle{}

\renewcommand{\sectionmark}[1]{%
    \renewcommand\sectiontitle{\thesection. \ #1}}
\renewcommand{\subsectionmark}[1]{%
    \markboth{\sectiontitle}{\thesubsection. \, #1}%
    }

但如果页面上有多个部分,则最后的节标题而不是第一个标题(@ejmastnak 的解决方案也是这种情况)。我们可以使用包\firstleftmark中的命令获取第一个左标记extramarks

\usepackage{extramarks}
 . . .
\fancyhead[L]{\firstleftmark}  % section
\fancyhead[R]{\firstrightmark}  % subsection

(\firstrightmark是 的同义词\rightmark)

@ejmastnak 的解决方案只有在一种情况下才能可靠地工作:当每个\section命令都从新页面开始时,并且紧接着一个\subsection命令(或至少非常接近该命令)。但在这些情况下,我的解决方案也有效,并且在更多情况下有效。

答案2

编辑:感谢@彼得·范·奥斯特鲁姆指出此解决方案不适用于非平凡的节/子节排列。请参阅他的回答以获取更可靠的解决方案。

我知道这是一个老问题,但看到它仍然没有答案,我想我会为那些可能在谷歌搜索中偶然发现同样问题的人提供我的解决方案。解决方案基于埃格尔的精彩回答由于小节原因,标题在章节页面上显示不正确,它回答了类似的问题,但针对的是report文档类而不是类article

下面的代码生成所需的输出,即在页面subsection上的标题中显示的名称section,对于articleOP 问题中的文档类。我提供了两个版本---更强大的第一个版本显示第一的即使一个页面上有多个子部分(见第二张图片),第二个版本也会显示最后的子部分,这对于具有多个子部分的页面来说可能是不受欢迎的。埃格尔的回答由于小节原因,标题在章节页面上显示不正确已经解释了新的命令,所以我没有在这里重写相同​​的解释。

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{fancyhdr}
\usepackage[margin=1in]{geometry}
\usepackage{blindtext}

% begin header configuration
\pagestyle{fancy}

% Start fancyhdr settings
\fancyhf{}
\fancyhead[L]{\leftmark}  % section
\fancyhead[R]{\rightmark}  % subsection
\fancyfoot[C]{\thepage} 
% End fancyhdr settings


% Redefine sectionmark to produce desired behavior --- VERSION 1
% This version sets the FIRST subsection on a page as the right mark,
%   even if there are multiple subsections on a page
\renewcommand{\sectionmark}[1]{%
    \markboth{\thesection. \ #1}
    {\noexpand\firstsubsectiontitle}%
    \global\firstsubsectionmarktrue} % first subsection mark set
\renewcommand{\subsectionmark}[1]{% ensures the first subsection is displayed even if multiple subsections occur on a given page
    \markright{\thesubsection. \, #1}%
    \iffirstsubsectionmark
        \edef\firstsubsectiontitle{\thesubsection. \, #1}%
    \fi
    \global\firstsubsectionmarkfalse
    }
\newif\iffirstsubsectionmark
\def\firstsubsectiontitle{}
% End VERSION 1

% Redefine sectionmark to produce desired behavior --- VERSION 2
% This version sets the LAST subsection on a page as the right mark
% If there is only one subsection on a page, it gives the same result as the more complicated version above
% Intentionally commented out because this is less robust, but feel free to experiment

% \renewcommand{\sectionmark}[1]{\markboth{\thesection. \ #1}
%   {\noexpand\firstsubsectiontitle}}
% \renewcommand{\subsectionmark}[1]{%
%   \markright{\thesubsection\ \, #1}\gdef\firstsubsectiontitle{#1}}
% \newcommand\firstsubsectiontitle{}

% End VERSION 2

% End header configuration

\begin{document}

\section{First section}
\subsection{Subsection on a section page}

\blindtext[3]
\pagebreak

\subsection{Second subsection}

\blindtext[3]
\pagebreak

\section{Another section}
\subsection{First subsection on a section page}
\blindtext[1]

\subsection{Second subsection on a section subsection}
\blindtext[1]

\end{document}

标题中显示的子部分

相关内容