我有一份文档,我想\sectionmark
在其中缩短标题,但将较长的章节标题保留在目录中。不幸的是,如果页面从某处开始(我不太明白这一点,抱歉描述得不好),那么这样做是错误的(长标题会输出为标题)。
因此按照sectionmark 问题 • 页面布局 • LaTeX 社区,我尝试将 加倍\sectionmark
,但是这会破坏文档(“超出 TeX 容量”,或“!\@sect 的参数有一个多余的 }。”)。
最后我找到了一个带有\texorpdfstring
并\protect
通过了编译的构造:
\documentclass[a4paper]{book}
\usepackage{lipsum}
\usepackage{hyperref}
\usepackage{fancyhdr}
\begin{document}
\section{A first section is ok}
\lipsum[1-12]
\makeatletter
\@starttoc{toc}
\makeatother
% %this construct breaks in my doc ("TeX capacity exceeded"), in this MWE breaks with "! Argument of \@sect has an extra }.":
% \section{A new, very very very long, impossibly long, title, with no intention of being shorter\sectionmark{A new, very very very long, impossibly long, title}}
% \sectionmark{A new, very very very long, impossibly long, title}
\section{A new, very very very long, impossibly long, title, with no intention of being shorter%
\texorpdfstring{\protect\sectionmark{A new, very very very long, impossibly long, title}}{}}%
\label{sect:ahaa}
\sectionmark{A new, very very very long, impossibly long, title}
\lipsum[4]
\end{document}
...但是现在标题中的章节编号是错误的:
如您所见,标题写着“0.1。一个新的,非常非常……”,而应该写着“0.2。一个新的,非常非常……”。
我怎样才能显示正确的章节编号,同时也显示在该章节首先出现的页面上?
答案1
尝试为\section
宏添加一个可选的附加参数,并保存\sectionmark
。
\documentclass[a4paper]{book}
\usepackage{blindtext}
\usepackage{fancyhdr}
\usepackage{xpatch}%
\usepackage{xparse}
\usepackage{hyperref}
\let\LaTeXStandardSection\section
\newif\ifinternalsectionmark
\internalsectionmarkfalse
\xpatchcmd{\@sect}{%
\csname #1mark\endcsname{#7}%
}{%
\ifinternalsectionmark
\csname #1mark\endcsname{#7}%
\fi
\internalsectionmarktrue
}{}{}
\RenewDocumentCommand{\section}{s+o+m+o}{%
\IfBooleanTF{#1}{%
\LaTeXStandardSection*{#3}
}{%
\IfValueTF{#2}{%
\LaTeXStandardSection{#2}%
}{%
\IfValueTF{#4}{%
\internalsectionmarkfalse
\LaTeXStandardSection{#3}%
\sectionmark{#4}%
}{%
\LaTeXStandardSection{#3}%
}%
}%
}%
}
\begin{document}
\section{A first section is ok}
\blindtext[12]
\makeatletter
\@starttoc{toc}
\makeatother
% %this construct breaks in my doc ("TeX capacity exceeded"), in this MWE breaks with "! Argument of \@sect has an extra }.":
\section{A new, very very very long, impossibly long, title, with no intention of being shorter}[A shorter sectionmark]
\blindtext[10]
\clearpage
\section{A new, very very very long, impossibly long, title, with no intention of being shorter%
\texorpdfstring{\protect\sectionmark{A new, very very very long, impossibly long, title}}{}}%
\label{sect:ahaa}
\blindtext[10]
\end{document}
答案2
编辑:买者自慎:这个答案似乎是错误的 - 即它起作用的唯一原因是因为目录是在该部分之前转储的;如果你更早地移动该部分,那么它将不起作用。
呃,显然我们可以使用旧的\let\oldcmd\cmd ... \let\cmd\oldcmd
黑客技术,但这里使用计数器(所以如果有人有更好的解决方案,我很乐意听到)。
也就是说,我们可以暂时增加“内部”部分计数器\sectionmark
,然后减少它 - 因为这最终会写入文件中,所以我们也必须慷慨地添加s:.aux
.toc
\protect
\documentclass[a4paper]{book}
\usepackage{lipsum}
\usepackage{hyperref}
\usepackage{fancyhdr}
\begin{document}
\section{A first section is ok}
\lipsum[1-12]
\makeatletter
\@starttoc{toc}
\makeatother
% %this construct breaks in my doc ("TeX capacity exceeded"), in this MWE breaks with "! Argument of \@sect has an extra }.":
% \section{A new, very very very long, impossibly long, title, with no intention of being shorter\sectionmark{A new, very very very long, impossibly long, title}}
% \sectionmark{A new, very very very long, impossibly long, title}
\section{A new, very very very long, impossibly long, title, with no intention of being shorter%
\texorpdfstring{\protect\addtocounter{section}{1}%
\protect\sectionmark{A new, very very very long, impossibly long, title}%
\protect\addtocounter{section}{-1}}{}}%
\label{sect:ahaa}
\sectionmark{A new, very very very long, impossibly long, title}
\lipsum[4-16]
\end{document}
输出看起来不错: