我希望面包屑导航每页的页眉均有超链接。单击每个部分、章节、节将带您到该部分/章节/节的开头。
我已经在使用hyperref
它来链接目录。
答案1
如何在每个部分/章节/节自动插入标签?请注意此解决方案(仿照如何通过章节编号获取章节标题?) 要求您至少使用部分/章节/节各一次。
编辑3:仍在开发中,但尝试通过首先将面包屑作为数据按顺序保存,将内容与呈现分开来实现通用化。这种基本跟踪将为面包屑提供更多可扩展的功能和不同的外观。有兴趣的请继续关注GitHub了解更多信息。(这里没有显示堆栈代码,但可以浏览这里。
编辑2:仍在开发中,但在 egreg 的帮助下已移至 LaTeX3 语法。正在研究上一个。前沿技术GitHub。
编辑:仍处于 WIP 阶段,但现在面包屑的长度根据评论而变化。仍在努力通过挖掘来源来反转chapterpage
、等的偏好顺序。我还希望页面开头的当前部分成为面包屑的一部分,除非页面开头sectionpage
fancyhdr
是节标题。
bredcrmb.sty
% GOAL: introduce a \pagestyle "breadcrumb" that will place the breadcrumb as a header.
\RequirePackage{xparse}
\RequirePackage{everypage
\RequirePackage{atbegshi}
\RequirePackage{fancyhdr}
\let\myhook\AtBeginShipout % playing with the two to see if I can get the desired output
% All credit to egreg for the following generalization: (#122823)
% My only additions were the booleans and related stuff.
\ExplSyntaxOn
% Macro to insert labels at the end of other macros
\NewDocumentCommand{\labelize}{mm}
{
\breadcrumbs_labelize:Nn #1 { #2 }
}
\myhook{\pagestyle{breadcrumb}}
\cs_new_protected:Npn \breadcrumbs_labelize:Nn #1 #2 {
% LaTeX3-ify
\bool_new:c { g_breadcrumbs_in_#2 }
\myhook{
\bool_gset_false:c { g_breadcrumbs_in_#2 }
}
\cs_set_eq:cN { original_ \cs_to_str:N #1 } #1
\RenewDocumentCommand #1 { som }
{
% Put page style stuff here
\bool_gset_true:c { g_breadcrumbs_in_#2 }
\thispagestyle{#2:style}
\IfBooleanTF{##1}
{
\use:c { original_ \cs_to_str:N #1 }*{##3}
}
{
\IfNoValueTF{##2}
{
\use:c { original_ \cs_to_str:N #1 } {##3}
}
{
\use:c { original_ \cs_to_str:N #1 } [##2]{##3}
}
\label{#2: \use:c{the\cs_to_str:N #1} }%
}
}
}
% Much nicer syntax. Thanks, egreg!
\labelize {\part} {breadcrumb:part}
\labelize {\chapter} {breadcrumb:chapter}
\labelize {\section} {breadcrumb:section}
\fancypagestyle{breadcrumb:part:style}{
\fancyhf{}
}
\fancypagestyle{breadcrumb:chapter:style}{
\fancyhf{}
\chead{
\nameref{breadcrumb:part:\thepart}
}
}
\fancypagestyle{breadcrumb:section:style}{
\fancyhf{}
\chead{
\nameref{breadcrumb:part:\thepart}~$\rightarrow$~
\nameref{breadcrumb:chapter:\thechapter}
}
}
\fancypagestyle{breadcrumb}{
\fancyhf{}
\chead{
\nameref{breadcrumb:part:\thepart}~$\rightarrow$~
\nameref{breadcrumb:chapter:\thechapter}~$\rightarrow$~
\nameref{breadcrumb:section:\thesection}
}
}
\ExplSyntaxOff
test.tex
\documentclass{memoir}
\let\footruleskip\relax
\usepackage{bredcrmb} % Moved code to style file
\usepackage{fancyhdr}
\usepackage[colorlinks]{hyperref}
\pagestyle{breadcrumb}
\usepackage{mwe}
\begin{document}
\part{Part the First}
\chapter{Chapter Primo}
\section{Section A}
\lipsum
\section{Section B}
\lipsum
\chapter{Chapter Secundo}
\section{Section A}
\lipsum
\section{Section B}
\lipsum
\part{Part the Second}
\chapter{Chapter Primo}
\section{Section A}
\lipsum
\section{Section B}
\lipsum
\chapter{Chapter Secundo}
\section{Section A}
\lipsum
\section{Section B}
\lipsum
\end{document}
答案2
以下示例利用了这样一个事实:在构建标题行之前,部分命令的锚点已设置并已知。这意味着,只要仔细计时,就可以避免在第二次运行 LaTeX 时出现引用系统。
示例使用类book
,其中\chaptermark
,\sectionmark
和\subsectionmark
被重新定义为包含\hyperlink
当前锚点,该锚点在 via或\@currentHref
之前定义,用于未编号的节命令。需要进行一些修补才能插入或支持带星号的节命令或命令。此外,使用 的命令(如)也需要进行修补才能获得。\refstepcounter
\phantomsection
\partmark
\tableofcontents
\@markboth
\chaptermark
示例中的章节标题取自用户手册pgf
以获得更接近真实文件的感觉。
\documentclass{book}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{ragged2e}
\usepackage{etoolbox}
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyfoot{}
\fancyhead{}
\cfoot{\thepage}
\lhead{%
\RaggedRight
% \HeaderFont
\hypersetup{linkcolor=blue}%
\rightmark
}
\newcommand*{\HeaderFont}{%
\usefont{T1}{qhv}{c}{n}%
\small
}
\makeatletter
\DeclareRobustCommand*{\BreadSep}{%
\,\textbf{\guilsinglright}\hspace{0pt}\,%
}
\newcount\breadnav@level
\breadnav@level=0 %
\newcommand*{\breadnav@starmark}[2]{%
\begingroup
\c@secnumdepth=-9 %
#1{#2}%
\endgroup
}
\patchcmd{\@part}{\markboth}{%
\partmark{#1}\@gobbletwo
}{}{}
\patchcmd{\@spart}{\normalfont}{%
\breadnav@starmark\partmark{#1}%
\normalfont
}{}{}
\newcommand*{\partmark}[1]{%
\protected@xdef\CurrentPart{%
\protect\hyperlink{\@currentHref}{%
\ifnum\value{secnumdepth}>-2 %
\thepart\@~%
\fi
#1%
}%
}%
\markright{%
\CurrentPart
}%
}
\newcommand*{\CurrentPart}{}
\patchcmd{\@schapterhead}{\normalfont}{%
\breadnav@starmark\chaptermark{#1}%
\normalfont
}{}{}
\patchcmd{\tableofcontents}{\@mkboth}{%
\breadnav@starmark\chaptermark{\contentsname}%
\@gobbletwo
}
\renewcommand*{\chaptermark}[1]{%
\protected@xdef\CurrentChapter{%
\protect\hyperlink{\@currentHref}{%
\ifnum\value{secnumdepth}>-1 %
\if@mainmatter
%\@chapapp~
\thechapter.\@~%
\fi
\fi
#1%
}%
}%
\markright{%
\ifx\CurrentPart\@empty
\else
\CurrentPart\BreadSep
\fi
\CurrentChapter
}%
}
\newcommand*{\CurrentChapter}{}
\patchcmd{\@startsection}{\@ifstar}{%
\edef\CurrentSectionType{#1}%
\@ifstar
}{%
\patchcmd{\@ssect}{\@tempskipa}{%
\expandafter\breadnav@starmark
\csname\CurrentSectionType mark\endcsname{#5}%
\@tempskipa
}{}{}%
}{}
\renewcommand*{\sectionmark}[1]{%
\protected@xdef\CurrentSection{%
\protect\hyperlink{%
\@currentHref
}{%
\ifnum\value{secnumdepth}>0 %
\thesection.\@~%
\fi
#1%
}%
}%
\markright{%
\ifx\CurrentPart\@empty
\else
\CurrentPart\BreadSep
\fi
\ifx\CurrentChapter\@empty
\else
\CurrentChapter\BreadSep
\fi
\CurrentSection
}%
}
\newcommand*{\CurrentSection}{}
\renewcommand*{\subsectionmark}[1]{%
\protected@xdef\CurrentSubsection{%
\protect\hyperlink{\@currentHref}{%
\ifnum\value{secnumdepth}>1 %
\thesubsection.\@~%
\fi
#1%
}%
}%
\markright{%
\ifx\CurrentPart\@empty
\else
\CurrentPart\BreadSep
\fi
\ifx\CurrentChapter\@empty
\else
\CurrentChapter\BreadSep
\fi
\ifx\CurrentSection\@empty
\else
\CurrentSection\BreadSep
\fi
\CurrentSubsection
}%
}
\newcommand*{\CurrentSubsection}{}
\let\ps@plain\ps@fancy
\makeatother
\usepackage[colorlinks]{hyperref}
\usepackage{bookmark}
\bookmarksetup{numbered,open}
\usepackage{lipsum}
\addtolength{\textheight}{\headheight}
\setlength{\headheight}{21pt}
\addtolength{\textheight}{-\headheight}
\begin{document}
\title{Test document}
\author{Me}
\date{\today}
\maketitle
\tableofcontents
\chapter{Introduction}
\lipsum
\section{Structure of the System}
\lipsum
\section{Comparison with Other Graphics Packages}
\lipsum
\section{Utility Packages}
\lipsum
\section{How to Read This Manual}
\lipsum
\section{Authors and Acknowledgements}
\lipsum
\section{Getting Help}
\lipsum
\part{Tutorials and Guidelines}
\chapter{Tutorial: A Picture for Karl's Students}
\lipsum
\section{Problem Statement}
\lipsum
\section{Setting up the Environment}
\lipsum
\subsection{Setting up the Environment in \LaTeX}
\lipsum
\subsection{Setting up the Environment in Plain \TeX}
\lipsum
\subsection{Setting up the Environment in Con\TeX t}
\lipsum
\section{Straigt Path Construction}
\lipsum
\section{Curved Path Construction}
\lipsum
\section{Circle Path Construction}
\lipsum
\section{Rectangle Path Construction}
\lipsum
\end{document}
结果,第 8 页:
和第 25 页:
讨论
我认为主要的问题是面包屑标题占用了太多空间,如第二张快照所示,其中标题已经需要三行。
可以通过以下方式减少位置:
该示例使用较短的分隔符号,
\guilsinglright
而不是较大的分隔符号\rightarrow
。较小的字体大小(
\small
或\footnotesize
)。压缩字体。遗憾的是,这些字体通常不适用于所需的字体系列。
以下快照显示了在 中启用\small
压缩字体 Tex Gyre Hermes 后的结果。这会将上面第二张屏幕截图中的三行缩减为两行:\HeaderFont
\lhead
变体
如果将级别显示在单独的行中并缩进,导航路径的排列会更加清晰。这可以通过以下定义来实现\BreadSep
(不支持需要多行的过长标题):
\DeclareRobustCommand*{\BreadSep}{%
\\%
\advance\breadnav@level by 1 %
\hspace*{\breadnav@level\dimexpr1em\relax}%
\textbf{\guilsinglright}\,%
}
使用此定义的屏幕截图并\small
使用\HeaderFont
:
但是,这需要与支持的部分级别一样多的行数。
如果标题较小,可以将不需要的空间还给正文,那就太好了。但页面构建前标题及其可用空间是已知的。请记住,标签中的标题大小会引发一个问题,即如果重新排列页面材料,标题可能会发生变化。与包装类似,varioref
这会导致文档永远不稳定。
答案3
编辑1:从所需包中删除不需要的包,以防止控制台中出现烦人的警告(反正也没做任何事情)
我知道这几乎是一篇遗留帖子,但我还是会这样做,以防将来有人碰到它。
我根据以下特点定制了@SeanAllred 的代码(接受的答案),并觉得我应该分享该代码:
它仅打印最低可用的部分级别。
如果您当前处于 中
\part
,但尚未开始\chapter
或\section
,那么它将打印Part Name
在标题中而不是Part Name → ??? → ???
。如果您已启动
\part
and\chapter
,但没有\section
,那么它将打印Part Name → Chapter Name
而不是Part Name → Chapter Name → ???
。它将打印页面当前可用的最低文档部分。
如果您的页面以 开头
\chapter
,那么它将Part Name → Chapter Name
在开始时打印,而不是像以前的版本那样什么都不打印*。使得更改面包屑分隔符变得稍微容易一些。
应用面包屑之前不重置页脚。
以前它会重置页眉和页脚,现在它只会重置页眉。
由于我的代码远非完美,因此在使用时应注意以下几点:
* 目前,这将打印页面上的最后一部分。因此,如果您的页面有两个部分,则打印的是页面结束前的最后一部分。这可能是您想要的,也可能是不需要的,具体取决于您想要什么。如果您\section
在一页上有多个 s,请记住这一点。
此外,页面样式会自动应用于全部 \part
、\chapter
和\section
命令。(只要它们没有星号,例如\chapter*{Some Chapter}
)如果您只希望将其应用于某些分段命令,那么您将必须修改此代码。
最后,当调用其中一个分节命令(\part
、\chapter
或\section
)时,它将为所有后续页面设置页面样式。如果您希望之后将页面样式恢复为其他样式,则必须调用该\pagestyle
宏。
这是breadcrumb.sty
:
%! suppress = EscapeHashOutsideCommand
%! Package = breadcrumb
%! Author = vermiculus (Sean Allred), egreg, solonovamax, Heiko Oberdiek
%! Date = 2021-04-06
% Credits:
% - vermiculus: Put things together & made shit work
% - egreg: Contributed logic improvements
% - solonovamax: added some minor tweaks + doc comments. All comments by solonovamax are signed with ``-s'' at the end.
% - Heiko Oberdiek: stole their code for the seperator from their SO answer, since I [solonovamax] think it looks nicer.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{breadcrumb}[2021/04/05]
\RequirePackage{xparse}
\RequirePackage{atbegshi}
\RequirePackage{fancyhdr}
% If you want to change the header style, use this:
%\DeclareRobustCommand*{\BreadSep}{%
% ~\ensuremath{\rightarrow}~%
%}
% -s
\DeclareRobustCommand*{\BreadSep}{ % This seperator is stolen from Heiko Oberdiek.
\,{\LARGE\textbf{\guilsinglright}}\hspace{0pt}\,%
}
\let\myhook\AtBeginShipout % playing with the two to see if I can get the desired output
\myhook{\pagestyle{breadcrumb}}
% All credit to egreg for the following generalization: (#122823)
% My [vermiculus's] only additions were the booleans and related stuff.
\ExplSyntaxOn
% Defines macro that allows you to hack the document sectioning commands. -s
\NewDocumentCommand{\labelize}{mm}{\breadcrumbs_labelize:Nn#1{#2}}
\cs_new_protected:Npn\breadcrumbs_labelize:Nn#1#2{
% LaTeX3-ify
\bool_new:c{g_breadcrumbs_in_#2}
\myhook{
\bool_gset_false:c{g_breadcrumbs_in_#2}
}
\cs_set_eq:cN{original_\cs_to_str:N#1}#1
\RenewDocumentCommand#1{som}{% Put page style stuff here
\bool_gset_true:c{g_breadcrumbs_in_#2}
% \thispagestyle{#2:style} % This is redundant now, but didn't do much before, anyways.
% (It only affected the \section command, since \part and \section print a new page at the start of the macro.)
% -s
\IfBooleanTF{##1}{
\use:c{original_\cs_to_str:N#1}*{##3}
}{
\IfNoValueTF{##2}
{\use:c{original_\cs_to_str:N#1}{##3}}
{\use:c{original_\cs_to_str:N#1}[##2]{##3}}
%
\label{#2:\use:c{the\cs_to_str:N#1}}%
\thispagestyle{#2:style}% Set the style of this page, because SOME things (looking at you, \chapter) reset the style. -s
\pagestyle{#2:style}% Set the style of all future pages. -s
% This means:
% All future pages will have the right level
% BUT this affects the entire document.
% -s
}
}
}
% Much nicer syntax. Thanks, egreg!
% page styles are defined in the syntax: ``breadcrumb:[style name]:style''. You can copy & paste to define any new ones. -s
\fancypagestyle{breadcrumb:part:style}{
\fancyhead{} % reset header -s
\chead{\large\nameref{breadcrumb:part:\thepart}}
}%
\fancypagestyle{breadcrumb:chapter:style}{
\fancyhead{} % reset header -s
\chead{\large\nameref{breadcrumb:part:\thepart}\BreadSep\nameref{breadcrumb:chapter:\thechapter}}
}%
\fancypagestyle{breadcrumb:section:style}{
\fancyhead{} % reset header -s
\chead{\large\nameref{breadcrumb:part:\thepart}\BreadSep\nameref{breadcrumb:chapter:\thechapter}\BreadSep\nameref{breadcrumb:section:\thesection}}
}
\fancypagestyle{breadcrumb}{
\fancyhead{} % reset header -s
\chead{\large\nameref{breadcrumb:part:\thepart}\BreadSep\nameref{breadcrumb:chapter:\thechapter}\BreadSep\nameref{breadcrumb:section:\thesection}}
}
% This hacks the \part, \chapter, and \section commands. If you want more levels, define the new page styles and then labelize them.
\labelize{\part} {breadcrumb:part}
\labelize{\chapter} {breadcrumb:chapter}
\labelize{\section} {breadcrumb:section}
\ExplSyntaxOff
要使用它,只需包括
\usepackage{breadcrumb}
在您的文档序言中。它将完成其他所有工作。
根据对原始答案的编辑,可以在 GH 上找到 SO 上发布的代码的更新版本,但无论我尝试什么,我都无法让 GH 上的代码正常工作,所以我只是坚持使用原始修改后的版本。