修补 \part 以使用可选和强制参数执行某些操作

修补 \part 以使用可选和强制参数执行某些操作

我基本上是想尝试\part使用scrreprt可选参数(如果存在)或强制参数来做一些事情。在下面的例子中,短标题将以红色添加到目录中,长标题将以蓝色添加(在其相应部分下方)。

但是下面的代码基本上什么都没做。这似乎与这个问题,我也尝试过类似的方法regexpatch,但没有成功。我正在尝试找到一种解决方案,让\part其他软件包可以使用,例如hyperref不受干扰。

\documentclass{scrreprt}

\usepackage{xcolor}
\usepackage{xpatch}

\makeatletter

\catcode`\#=12

\xapptocmd{\@part}%
    {#1}%
    {\addcontentsline{toc}{chapter}{\textcolor{red}{#1}}}%  
    {}%

\xapptocmd{\@part}%
    {#2}%
    {\addcontentsline{toc}{chapter}{\textcolor{blue}{#2}}}% 
    {}%

\catcode`\#=6

\makeatother

\begin{document}

\tableofcontents

\part{Only Long Caption}

\part[Short Caption]{Long Caption}

\end{document}

答案1

为了使修补工作按预期进行,您需要了解修补函数的构造方式。\@part它的定义如下scrreprt.cls

\def\@part[#1]#2{%
  \ifnum \scr@osectarg=\z@
    \@scr@tempswafalse
  \else
    \scr@istest#1=\@nil
  \fi
  \if@scr@tempswa
    \setkeys{KOMAarg.section}{tocentry={#2},head={#2},#1}%
  \else
    \ifcase \scr@osectarg\relax
      \setkeys{KOMAarg.section}{tocentry={#1},head={#1}}%
    \or
      \setkeys{KOMAarg.section}{tocentry={#2},head={#1}}%
    \or
      \setkeys{KOMAarg.section}{tocentry={#1},head={#2}}%
    \or
      \setkeys{KOMAarg.section}{tocentry={#1},head={#1}}%
    \fi
  \fi
  \ifnumbered{part}{%
    \refstepcounter{part}%
    \@maybeautodot\thepart%
    \ifx\scr@ds@tocentry\@empty\else
      \addparttocentry{\thepart}{\scr@ds@tocentry}%
    \fi
  }{%
    \ifx\scr@ds@tocentry\@empty\else
      \addparttocentry{}{\scr@ds@tocentry}%
    \fi
  }%
  \begingroup
    \setparsizes{\z@}{\z@}{\z@\@plus 1fil}\par@updaterelative
    \raggedpart
    \interlinepenalty \@M
    \normalfont\sectfont\nobreak
    \ifnumbered{part}{%
      \size@partnumber{\partformat}%
      \partheadmidvskip
    }{}%
    \size@part{#2}\strut
    \ifx\partmark\@gobble
      \@mkboth{}{}\par
    \else
      \expandafter\partmark\expandafter{\scr@ds@head}\par
    \fi
  \endgroup
  \@endpart
}

最好插入\@part在问题发生时,新的 ToC 相关条目\begingroup。为此,我们只需要etoolbox按以下方式修补:

\usepackage{etoolbox}
\makeatletter
% \pdfstrcmp{<string1>}{<string2>}
% \pdfstrcmp compares two strings and expands to 0 if the strings are equal, to -1 if the first string
%   ranks before the second, and to 1 otherwise
\patchcmd{\@part}% <cmd>
    {\begingroup}% <search>
    {\ifnum\pdfstrcmp{#1}{#2}=0
       \addcontentsline{toc}{chapter}{\protect\textcolor{blue}{#2}}%
     \else
       \addcontentsline{toc}{chapter}{\protect\textcolor{red}{#1}}%
     \fi%
     \begingroup}%  
    {}{}%

\makeatother

上述代码\addcontentsline立即插入两个宏 \begingroup。它们取决于是否#1匹配#2(使用 e-TeX 的\pdfstrcmp)。如果它们相同,则意味着用户没有提供可选参数。

请注意,写入目录的内容是如何\protect编辑的,以避免扩展。这在写入文件时很常见,以确保事情不会出错。

这是一个完整的最小示例:

在此处输入图片描述

\documentclass{scrreprt}

\usepackage{etoolbox,xcolor}

\makeatletter
% \pdfstrcmp{<string1>}{<string2>}
% \pdfstrcmp compares two strings and expands to 0 if the strings are equal, to -1 if the first string
%   ranks before the second, and to 1 otherwise
\patchcmd{\@part}% <cmd>
    {\begingroup}% <search>
    {\ifnum\pdfstrcmp{#1}{#2}=0
       \addcontentsline{toc}{chapter}{\protect\textcolor{blue}{#2}}%
     \else
       \addcontentsline{toc}{chapter}{\protect\textcolor{red}{#1}}%
     \fi%
     \begingroup}%  
    {}{}%

\makeatother

\begin{document}

\tableofcontents

\part{Only Long Caption}

\part[Short Caption]{Long Caption}

\end{document}

如果你希望上述内容适用于hyperref,您需要修补\H@old@part而不是\@part

相关内容