我有以下疑问:是否有可能定义一个命令,以一个单词作为参数并执行具有相同名称的命令?
例如,
\newcommand{\wrapper}[1]{%
\@nameuse{#1}%
}
这样,调用\wrapper{hrule}
就转换成了\hrule
。
动机
我这样做的主要目的是将值“分配”给先前定义的命令,因为我使用以下命令通过 CSV 文件加载其值datatools
:
\assignto{somevar}{value}
-->\renewcommand{\somevar}{value}
\assignto{othervar}{command}
-->\renewcommand{\othervar}{\command}
这段代码片段是我最初的想法,但它不起作用。
\newcommand{\assignto}[2]{%
\@ifundefined{#2}{%
\renewcommand{\@nameuse{#1}}{#2}%
}{%
\renewcommand{\@nameuse{#1}}{\@nameuse{#2}}%
}%
}
错误输出示例:
! LaTeX Error: \@nameuse {unidad} undefined.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
答案1
第一个问题的答案来自 LaTeX 内核,它\@namedef
专门为此提供了答案。因此,在你的序言中,你可以使用
\makeatletter
\let\wrapper\@namedef
\makeatother
然后使用
\wrapper{abc}{def}% --> \def\abc{def}
不过,你的用法\assignto
似乎有所不同,因为它应该将第二个参数转换为值(可能是文本)或命令。为此,可以使用一些 e-TeX:
\documentclass{article}
\makeatletter
\newcommand{\assignto}[2]{%
\ifcsname #2\endcsname
\@namedef{#1}{\csname #2\endcsname}%
\else
\@namedef{#1}{#2}%
\fi
}
\makeatother
\begin{document}
\newcommand{\abc}{ABC}
\assignto{AAA}{aaa}\AAA
\assignto{BBB}{abc}\BBB
\end{document}
要使用更类似 LaTeX 的方法,您可以使用etoolbox
它提供了大量的包装宏:
\documentclass{article}
\usepackage{etoolbox}
\newcommand{\assignto}[2]{%
\ifcsdef{#2}{%
\csdef{#1}{\csuse{#2}}%
}{%
\csdef{#1}{#2}%
}%
}
\begin{document}
\newcommand{\abc}{ABC}
\assignto{AAA}{aaa}\AAA
\assignto{BBB}{abc}\BBB
\end{document}
答案2
我会避免对两个不同的作业使用相同的接口。在你提出的语法中,\assignto{\foo}{text}
会看到\text
被定义(假设你加载amsmath
),并且你不你想要\foo
扩展为某个神秘的值吗?
\documentclass{article}
\makeatletter
\newcommand\assignto{\@ifstar\assignto@expand\assignto@simple}
\newcommand{\assignto@simple}[2]{\@namedef{#1}{#2}}
\newcommand{\assignto@expand}[2]{%
\expandafter\expandafter\expandafter\assignto@expand@aux
\expandafter\expandafter\expandafter{\csname#2\endcsname}{#1}}
\newcommand\assignto@expand@aux[2]{\assignto@simple{#2}{#1}}
\makeatother
\begin{document}
\newcommand{\abc}{ABC}
\assignto{AAA}{aaa}\AAA
\assignto{BBB}{abc}\BBB
\assignto*{CCC}{abc}\CCC
\end{document}
现在你对于应该是什么意思已经没有任何歧义了abc
。