我用\secname
它来存储章节标题并在 中调用它\section
。但有些章节需要不同的标题。我以为我可以更新此命令,但我无法在 内执行此操作\section{...}
。
我知道要解决这个问题,我可以将 renew 移出\section
,但这里的代码只是一个过于简单的示例。实际问题更复杂,有其他库,因此将其移出并不可行。相反,我想了解为什么会\renewcommand
失败,\section
以及是否有办法修复它。
\documentclass[12pt]{article}
\begin{document}
\newcommand{\secname}{A Section}
\section{\renewcommand{\secname}{A Big Section}\secname}
\end{document}
! Argument of \@sect has an extra }.
<inserted text>
\par
l.4 ...ewcommand{\secname}{A Big Section}\secname}
更新 1
下面的一个评论给出了\protect
解决方案。但这并不能完全解决问题,如以下更新的示例所示:
\documentclass[12pt]{book}
\begin{document}
\tableofcontents
\newcommand{\secname}{A Section}
\section{\secname}
\section{\protect\renewcommand{\secname}{A Big Section}\secname}
\section{\secname}
\end{document}
编译两次,第二次将会失败。
更新 2
在一些讨论中,我倾向于更多地关注\renewcommand
失败的原因,\section
而不是解决这个具体的\secname
问题。这引出了一个更有趣的例子:
\documentclass[12pt]{book}
\newcommand{\mycolor}{red}
\begin{document}
\tableofcontents
\section{\renewcommand{\mycolor}{blue}} % fails in round 1;
\section{\protect\renewcommand{\mycolor}{blue}} % fails in round 2;
\section{\protect\renewcommand{\protect\mycolor}{blue}} % fails in round 1;
\end{document}
即使\renewcommand
受到保护也会失败。
答案1
正如您已经指出的,(正确)修复此问题的方法是移动\renewcommand
部分标题的外部。如果您无法做到这一点(无论出于何种原因),则可以提供一个不使用命令更新的替代可选参数;类似于
\section[A section]{\renewcommand{\secname}{A section}\secname}
也许吧。但是,这是一种不好的做法,因为分段单元的参数很脆弱。它们通常出现在目录和标题中,因此必须小心处理。
如果您仍然坚持这个想法,也许可以重新定义\section
以自动化方式管理事物:
\documentclass{article}
\usepackage{xparse}
\let\oldsection\section
\RenewDocumentCommand{\section}{s o m}{%
\renewcommand{\secname}{#3}% Store \section name in \secname
\IfBooleanTF{#1}
{\oldsection*{#3}}% \section*{..}
{\IfValueTF{#2}
{\oldsection[#2]{#3}}% \section[.]{..}
{\oldsection{#3}}% \section{..}
}%
}
\newcommand{\secname}{}% Define first \secname
\begin{document}
\tableofcontents
\section{A section}
This is \secname.
\section{A big section}
This is \secname.
\end{document}
还有其他选择。例如,nameref
提供通过以下方式提取部门名称的方法\nameref
:
\documentclass{article}
\usepackage{nameref}
\begin{document}
\tableofcontents
\section{A section}\label{sec:first}
This is \nameref{sec:first}.
\section{A big section}\label{sec:second}
This is \nameref{sec:second}, but also see \nameref{sec:first}.
\end{document}
由于\nameref
功能与常规的 一样\ref
(附带\label
),您可以在通常使用 的任何地方使用它\ref
,这使得它的用途非常广泛。相比之下,\secname
只有从那时起才有效,因此不能在前向引用中使用。