我正在尝试编写一个宏来更改 \thesection、\thechapter 和其他命令的节前缀定义。我想根据用户对命令的输入重新定义其中一个命令。我尝试过类似这样的方法:
\documentclass{report}
\usepackage{etoolbox}
\usepackage{titlesec}
\newcommand{\changeprefix}[2]{
%\renewcommand\csname the#1\endcsname{#2} % ! Extra \endcsname.
%\renewcommand \the#1{#2} %! Argument of \rem@pt has an extra }.
%\def\headername{\csuse{the#1}}
%\renewcommand \headername {#2} % compiles but has no effect
%\renewcommand \csuse{the#1} {#2} % compiles but prints the value of #2
\makeatletter
\expandafter\renewcommand \@nameuse{the#1} {#2} % compiles but prints everything after \@
\makeatother
}
\begin{document}
\changeprefix{section}{test prefix - }
\section{Test section}
Some text...
\end{document}
我的尝试不太成功。对于下面两个(实际上可以编译)我得到了以下输出:
我的灵感来自于这个答案也这个,但我还没有完全理解。是否可以完成这项工作并获得以下调用输出\section{Test section}
?
测试前缀 - 测试部分
答案1
第一次尝试
\renewcommand\csname the#1\endcsname{#2}
你试图重新\csname
定义t
第二次尝试
\renewcommand \the#1{#2}
您正在尝试重新定义\the
以扩展到第一个标记#1
第三次尝试
\def\headername{\csuse{the#1}}
\renewcommand \headername {#2} % compiles but has no effect
你正在重新定义\headername
第四次尝试
\renewcommand \csuse{the#1} {#2}
你正在重新定义\csuse
第五次尝试
\makeatletter
\expandafter\renewcommand \@nameuse{the#1} {#2}
\makeatother
您尝试定义\spacefactor
,因为您正在扩展\@
。请注意\makeatletter
和\makeatother
应该围绕外部\newcommand
,而不是在替换文本内。但这不会修复代码,因为
\makeatletter
\newcommand\changeprefix[2]{
\expandafter\renewcommand \@nameuse{the#1} {#2}
}
\makeatother
将尝试重新定义\csname
,这是 扩展中的第一个标记\@nameuse
。
正确版本
\makeatletter
\newcommand{\changeprefix}[2]{%
\@namedef{the#1}{#2}%
}
\makeatother
或者
\newcommand{\changeprefix}[2]{%
\expandafter\renewcommand\csname the#1\endcsname{#2}%
}
答案2
由于etoolbox
已经加载,因此可以使用\csdef
或 的更快捷方式\csgdef
,具体取决于组中所需的“可持续性”:
\makeatletter...\expandafter...\makeatother
这里不能使用任何“奇怪”的结构:
\documentclass{report}
\usepackage{etoolbox}
\newcommand{\changeprefix}[2]{%
\csdef{the#1}{#2}%
}
\begin{document}
\changeprefix{section}{test prefix - }
\section{Test section}
Some text...
\end{document}
答案3
经过一些额外的实验后,我设法通过对问题的第一次尝试进行修改使其工作,因此:
\renewcommand\csname the#1\endcsname{#2}
变成:
\expandafter\renewcommand\csname the#1\endcsname{#2}
如果我理解正确的话,\renewcommand
宏在输入完成之前就被扩展了。通过此更改,的求值\renewcommand
将暂停,直到\csname ... \endcsname
求值完成。
我仍然不太清楚其他尝试出了什么问题,欢迎提出任何意见。但我的问题现在已经解决了。