章节标记转义和编号问题

章节标记转义和编号问题

我有一份文档,我想\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}

...但是现在标题中的章节编号是错误的:

测试.png

如您所见,标题写着“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}

输出看起来不错:

测试.png

相关内容