当使用该titlesec
包定制部分标题时,计数器\thepart
会以某种方式递增,然后才能将其值用于例如运行标题:
\documentclass[oneside]{book}
\usepackage{titlesec}
% If you do not issue the \titleformat command, everything is fine
\titleformat{\part}[display]
{\bfseries\huge\filcenter}
{\partname\ \thepart%
% A working hack: set the mark here instead, expanding \thepart
% (note the lack of \protect)
%\markright{Part \thepart, page \protect\thepage}
}
{20pt}
{\Huge}
\titlespacing*{\part}{0pt}{*36}{*1}
\begin{document}
\part{Intro}
\pagestyle{myheadings}
% Remove this to see the hack work.
\markright{Part \protect\thepart, page \protect\thepage}
This page should have ``\textsl{Part \thepart, page \thepage}'' at the top.
\newpage
This page should have ``\textsl{Part \thepart, page \thepage}'' at the top.
\part{A Problem} % This command does the incrementing
\end{document}
第 3 页(第一部分的最后一页)是问题所在:
不知何故,第二个\part{A Problem}
是在计数器用于标题之前推进计数器。
问题到底是什么?建议的解决方法是什么?可以像所示的那样破解解决方案,\thepart
在排版部分时保存计数器的值,但这不是一个令人满意的解决方案,因为我希望用户能够在自定义标题等中使用计数器。
手册titlesec
指出,有些部分是独特的和非标准的,但在我看来这似乎是一个错误。
更新
针对@hugovdberg 的回答,我可以将问题追溯到以下定义titlesec.sty
:
\makeatletter\def\ttl@page@i#1[#2]#3{%
\gdef\ttl@savemark{\csname#1mark\endcsname{#3}}%
\def\ttl@savewrite{\ttl@write{#1}{#3}}% A default value. Not #2!
\def\ttl@savetitle{#3}%
\ttl@labelling{#1}{#2}%
\ttl@startargs\ttl@page@ii{#1}{#3}}
\clearpage
导致处理标题的命令位于调用内部, 而\ttl@startargs\ttl@page@ii{#1}{#3}
部分计数器在前一个调用中增加\ttl@labelling{#1}{#2}
。切换这些命令的顺序可以解决问题,但我不知道是否还有其他后果。对我来说这似乎是一个错误。
第二次更新
关于为什么我需要这样做,有一些疑问\protect\thepage
:这是因为\markright
扩展了它的参数,但由于标准类每次重置标题的方式,这迫使我\markright
在每个部分之后调用,因此使用扩展(不受保护)\thepart
似乎可以解决问题。这是第二个,而不是退出的 MWE,它用来fancyhdr
证明确实存在问题,并且它与保护无关:
\documentclass[oneside]{book}
\usepackage{titlesec}
\usepackage{fancyhdr}
% Now I can do this once and for all: no protection needed.
\chead{Part \thepart, page \thepage}
% If you do not issue the \titleformat command, everything is fine
\titleformat{\part}[display]
{\bfseries\huge\filcenter}
{\partname\ \thepart%
% A working hack: set the mark here instead, expanding \thepart
% (note the lack of \protect)
%\markright{Part \thepart, page \protect\thepage}
}
{20pt}
{\Huge}
\titlespacing*{\part}{0pt}{*36}{*1}
\begin{document}
\pagestyle{fancy}
\part{Intro}
This page should have ``\textsl{Part \thepart, page \thepage}'' at the top.
\newpage
This page should have ``\textsl{Part \thepart, page \thepage}'' at the top.
\part{A Problem} % This command does the incrementing
A new page
\end{document}
有关的
- 使用 titlesec 的部分标签存在问题:解决与零件标签相关的问题,并指出
titlesec
零件会出现一些奇怪的情况。那里的答案并没有解决这个问题。 - titlesec:\assignpagestyle 部分问题:还提到了一些零件问题,但显然与这个问题无关。
答案1
问题是,\part{A Problem}
在第一部分的最后一页上执行,并且的值\thepart
是结尾当前页。由于您从该页开始新的部分,因此即使部分标题打印在下一页,您的部分计数器也会增加。解决方案是手动输入一个\newpage
前页\part
。这不会创建多余的空白页,因为\part
只会插入空白页以到达右页。
编辑要自动插入每个部分接受的答案这个问题可用于。
\documentclass[oneside]{book}
\usepackage{titlesec}
% If you do not issue the \titleformat command, everything is fine
\titleformat{\part}[display]
{\bfseries\huge\filcenter}
{\partname\ \thepart%
% A working hack: set the mark here instead, expanding \thepart
% (note the lack of \protect)
%\markright{Part \thepart, page \protect\thepage}
}
{20pt}
{\Huge}
\titlespacing*{\part}{0pt}{*36}{*1}
\let\oldpart\part
\renewcommand{\part}{\clearpage\oldpart}
\begin{document}
\part{Intro}
\pagestyle{myheadings}
% Remove this to see the hack work.
\markright{Part \protect\thepart, page \protect\thepage}
This page should have ``\textsl{Part \thepart, page \thepage}'' at the top.
\newpage
This page should have ``\textsl{Part \thepart, page \thepage}'' at the top.
\part{A Problem} % This command does the incrementing
\end{document}
答案2
删除\protect
之前的\thepart
。标记机制依赖于标记时的扩展排放而不是在排版时。您正在保护它\thepart
,因此它会在标题中展开,但此时值可能是错误的。另一方面,\thepage
必须受到保护,因为它应该在排版标题时打印值,而不是在发出标记时打印值。
编辑出于同样的原因,\thepart
不能直接在标题/页脚中使用(当然,如果您使用titleps
,则可以,这会“隐藏”标记机制)。只需使用标记,这是将信息传递给标题的正确机制。请参阅下面的评论。