当存在 \tableofcontents 时,为什么重新定义 \contentsname 与重新定义 \section 会冲突?

当存在 \tableofcontents 时,为什么重新定义 \contentsname 与重新定义 \section 会冲突?

我尝试修改目录的标题,使每个部分的标题都大写。但出现了奇怪的编译错误。

.tex 文件如下所示:

\documentclass{article}
\usepackage{szx}
\begin{document}
    \section*{fgh}
        vbn
    \tableofcontents
    \section{zxc}
        qwe
\end{document}

我尝试了 3 个不同的 szx.sty 文件,但都没有用。

第一个使用 xparser 包:

\ProvidesPackage{szx}

\usepackage{xparse}
\RequirePackage{titlecaps}

\let\@szx@oldsection\section
\newcommand{\@szx@sectionstar}[1]{\@szx@oldsection*{\titlecap{#1}}}
\newcommand{\@szx@section}[1]{\@szx@oldsection{\titlecap{#1}}}
\RenewDocumentCommand{\section}{s}{\IfBooleanTF{#1}{\@szx@sectionstar}{\@szx@section}}

\let\@szx@TocName\contentsname
\renewcommand*{\contentsname}{\centering{\@szx@TocName}}

第二个用途\DeclareRobustCommand

\ProvidesPackage{szx}

\RequirePackage{titlecaps}

\let\@szx@oldsection\section
\DeclareRobustCommand{\@szx@sectionstar}[1]{\@szx@oldsection*{\titlecap{#1}}}
\DeclareRobustCommand{\@szx@section}[1]{\@szx@oldsection{\titlecap{#1}}}
\DeclareRobustCommand{\section}{\@ifstar\@szx@sectionstar\@szx@section}

\let\@szx@TocName\contentsname
\DeclareRobustCommand*{\contentsname}{\centering{\@szx@TocName}}

最后一个使用 makerobust 包:

\ProvidesPackage{szx}

\RequirePackage{makerobust}
\RequirePackage{titlecaps}

\let\@szx@oldsection\section
\newcommand{\@szx@sectionstar}[1]{\@szx@oldsection*{\titlecap{#1}}}
\newcommand{\@szx@section}[1]{\@szx@oldsection{\titlecap{#1}}}
\MakeRobustCommand{\@szx@sectionstar}
\MakeRobustCommand{\@szx@section}
\renewcommand{\section}{\@ifstar\@szx@sectionstar\@szx@section}
\MakeRobustCommand{\section}

\let\@szx@TocName\contentsname
\renewcommand*{\contentsname}{\centering{\@szx@TocName}}
\MakeRobustCommand{\contentsname}

错误信息相同,如下所示:

\titlecap 的使用与其定义不符。\tableofcontents

\@firstoftwo 的参数有一个额外的 }。\tableofcontents

段落在 \@firstoftwo 完成之前结束。\tableofcontents

出了点问题——可能缺少 \item。\tableofcontents

未定义控制序列。\tableofcontents

\the@@@string 定义中的参数编号非法。\tableofcontents

未定义控制序列。\tableofcontents

不完整 \iffalse;第 12 行后的所有文本都被忽略。

答案1

在进行这些重新定义时你需要更加小心。

此外,该\titlecap命令似乎与 相冲突\centering。无论如何,将格式指令添加到\contentsname都是错误的。如果您希望内容名称大写,请明确定义它。

\documentclass{article}
\usepackage{titlecaps}
\usepackage{etoolbox}
\usepackage{xparse}

\let\latexsection\section
\RenewDocumentCommand{\section}{som}{%
  \IfBooleanTF{#1}
    {%
     \latexsection*{\titlecap{#3}}%
    }%
    {
     \IfNoValueTF{#2}
       {%
        \latexsection{\titlecap{#3}}%
       }%
       {%
        \latexsection[\titlecap{#2}]{\titlecap{#3}}%
       }%
    }%
}
\patchcmd{\tableofcontents}
  {\section}
  {\latexsection}
  {}{}
\patchcmd{\tableofcontents}
  {\contentsname}
  {\centering\contentsname}
  {}{}
\makeatother

%% no babel
\renewcommand{\contentsname}{Table of Contents}
%% babel
%\addto\captionsenglish{%
%  \renewcommand{\contentsname}{Table of Contents}%
%}

\begin{document}

\tableofcontents

\section*{fgh fgh, fgh}
vbn

\section{zxc zxc, zxc}
qwe

\section[sh]{zxc zxc, zhc}
qwe

\end{document}

在此处输入图片描述

答案2

根据@egreg 的建议,我寻找了另一种使目录标题居中的方法。

只需将重新定义替换\contentsname

\renewcommand*{\contentsname}{\hfill\@szx@TocName\hfill\hfill}

将解决冲突。

附言

将章节标题大写: https://tex.stackexchange.com/a/129682/101988

相关内容