![当存在 \tableofcontents 时,为什么重新定义 \contentsname 与重新定义 \section 会冲突?](https://linux22.com/image/343681/%E5%BD%93%E5%AD%98%E5%9C%A8%20%5Ctableofcontents%20%E6%97%B6%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E9%87%8D%E6%96%B0%E5%AE%9A%E4%B9%89%20%5Ccontentsname%20%E4%B8%8E%E9%87%8D%E6%96%B0%E5%AE%9A%E4%B9%89%20%5Csection%20%E4%BC%9A%E5%86%B2%E7%AA%81%EF%BC%9F.png)
我尝试修改目录的标题,使每个部分的标题都大写。但出现了奇怪的编译错误。
.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}
将解决冲突。
附言