第一次尝试

第一次尝试

我正在尝试编写一个宏来更改 \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}

我的尝试不太成功。对于下面两个(实际上可以编译)我得到了以下输出:

无视觉变化

打印 #2 的值和一些废话文本

打印 \@ 中的所有内容

我的灵感来自于这个答案这个,但我还没有完全理解。是否可以完成这项工作并获得以下调用输出\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求值完成。

我仍然不太清楚其他尝试出了什么问题,欢迎提出任何意见。但我的问题现在已经解决了。

相关内容