我希望能够通过连接命令名称的两个(或更多)部分来执行“索引”分配,既用于创建新命令,也用于引用现有命令。下面是显示我需要的示例。当然,不起作用。
\documentclass[10pt]{article}
\usepackage{mathtools}
\usepackage{fontspec}
\usepackage{unicode-math}
\usepackage{lualatex-math}
\setmainfont{STIX Two Text}
\setmathfont{STIX Two Math}
\usepackage{logix} % Load logix font for additional symbols.
\newCommand oldabc 123 % Existing value.
\newcommand indexedSet[1] { % Macro to do an indexed assign and an indexed reference.
\newcommand val##1 {old##1}
}
\indexedSet{abc} % Defines valabc as 123
\begin{document}
\end{document}
答案1
这在一定程度上是一个观点\csdef
问题,但最简单的方法是使用\csuse
电子工具箱包。至少使用这些命令更容易我你可以将其定义\IndexedSet
为
\newcommand\indexedSet[1]{\csdef{val#1}{\csuse{old#1}}}
根据您在这些命令中输入的内容以及更改它们的频率,您可能实际使用
\newcommand\indexedSet[1]{\csxdef{val#1}{\csuse{old#1}}}
因为这会强制“旧”命令扩展为其当前值。最后,您还应该检查以确保旧命令确实已定义,您可以使用以下命令执行此操作\ifcsdef
:
\newcommand\indexedSet[1]{\csxdef{val#1}{\ifcsdef{old#1}{\csuse{old#1}}{???}}}
因此,如果未定义“旧”命令,则新命令设置为???
。
以下是完整的 MWE:
\documentclass[10pt]{article}
\usepackage{etoolbox}
\newcommand\oldabc{123} % initial value.
% Macro to do an indexed assign and an indexed reference.
\newcommand\indexedSet[1]{\csxdef{val#1}{\ifcsdef{old#1}{\csuse{old#1}}{???}}}
\begin{document}
abc: \indexedSet{abc} \valabc
pqf: \indexedSet{pqf} \valpqf
\end{document}
产生预期的输出:
答案2
感谢 marmot 的建议,以下操作有效。
\documentclass[10pt]{article}
\usepackage{mathtools}
\usepackage{fontspec}
\usepackage{unicode-math}
\usepackage{lualatex-math}
\setmainfont{STIX Two Text}
\setmathfont{STIX Two Math}
\usepackage{logix} % Load logix font for additional symbols.
\newcommand \oldabc {123} % Existing value.
\newcommand\indexedSet[1] {
\expandafter\def\csname val#1\endcsname{\csname old#1\endcsname} }
\indexedSet{abc} % Defines valabc as 123
\begin{document}
\valabc
\end{document}
答案3
\csname
只需与适当的扩展一起使用即可。
\documentclass{article}
\newcommand{\indexedSet}[1]{%
\expandafter\let\csname val#1\expandafter\endcsname\csname old#1\endcsname
}
\newcommand\oldabc{123}
\begin{document}
\indexedSet{abc}
\valabc
\end{document}
您etoolbox
可以缩短定义:
\usepackage{etoolbox}
\newcommand{\indexedSet}[1]{\csletcs{val#1}{old#1}}
答案4
\documentclass[10pt]{article}
%----------------------------------------------------------------------
% \name <tokens not nested in braces>{macroname}
% -> <tokens not nested in braces>\macroname
% Examples:
% \name{foo} -> \foo
% \name\string{foo} -> \string\foo
% \name\meaning{foo} -> \meaning\foo
% \name\newcommand*{foo}... -> \newcommand*\foo...
% \name\name\let{foo}={bar} -> \name\let\foo={bar} -> \let\foo=\bar
%......................................................................
\newcommand\name{}%
\long\def\name#1#{\romannumeral0\innername{#1}}%
\newcommand\innername[2]{%
\expandafter\exchange\expandafter{\csname #2\endcsname}{ #1}%
}%
\newcommand\exchange[2]{#2#1}%
\usepackage{mathtools}
%\usepackage{fontspec}
%\usepackage{unicode-math}
%\usepackage{lualatex-math}
%\setmainfont{STIX Two Text}
%\setmathfont{STIX Two Math}
%\usepackage{logix} % Load logix font for additional symbols.
\newcommand\oldabc{123} % Existing value.
\newcommand\indexedSet[1]{% % Macro to do an indexed assign and an indexed reference.
\name\name{@ifdefinable}{val#1}{%
\name\name\let{val#1}={old#1}%
}%
}%
\indexedSet{abc} % Defines valabc as 123
\begin{document}
\texttt{\string\oldabc: \meaning\oldabc}
\texttt{\string\valabc: \meaning\valabc}
\texttt{\name\string{valabc}: \name\meaning{valabc}}
\end{document}
\valabc
如果已定义或未定义,则添加一些错误消息,\oldabc
如下所示:
\documentclass[10pt]{article}
%----------------------------------------------------------------------
% \name <tokens not nested in braces>{macroname}
% -> <tokens not nested in braces>\macroname
% Examples:
% \name{foo} -> \foo
% \name\string{foo} -> \string\foo
% \name\meaning{foo} -> \meaning\foo
% \name\newcommand*{foo}... -> \newcommand*\foo...
% \name\name\let{foo}={bar} -> \name\let\foo={bar} -> \let\foo=\bar
%......................................................................
\newcommand\name{}%
\long\def\name#1#{\romannumeral0\innername{#1}}%
\newcommand\innername[2]{%
\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}%
}%
\newcommand\exchange[2]{#2#1}%
%----------------------------------------------------------------------
% \PreambleMacroError{\macro}{<error text>}{<immediate-help-text>}
%......................................................................
\begingroup\makeatletter\@firstofone{%
\endgroup
\newcommand*\PreambleMacroError[3]{%
\GenericError{%
\space\space\space\@spaces\@spaces\@spaces
}{%
LaTeX Error: Inapproriate usage of macro \string#1\on@line.\MessageBreak
(\string#1 is defined in the document's preamble.)\MessageBreak
Problem: #2%
}{%
Have a look at the comments in the preamble of this document.%
}{#3}%
}%
}%
%----------------------------------------------------------------------
\usepackage{mathtools}
%\usepackage{fontspec}
%\usepackage{unicode-math}
%\usepackage{lualatex-math}
%\setmainfont{STIX Two Text}
%\setmathfont{STIX Two Math}
%\usepackage{logix} % Load logix font for additional symbols.
\newcommand\oldabc{123} % Existing value.
\newcommand\indexedSet[1]{% % Macro to do an indexed assign and an indexed reference.
\name{@ifundefined}{old#1}{%
\PreambleMacroError{\indexedSet}%
{Macro \name\string{old#1} undefined}%
{Setting \name\string{val#1} to \name\string{old#1}
does only make sense when\MessageBreak
\name\string{old#1} is defined.}%
\name{@ifundefined}{val#1}{}{%
\PreambleMacroError{\indexedSet}%
{Macro \name\string{val#1} already defined}%
{Setting \name\string{val#1} to \name\string{old#1} should not
override an existing definition of\MessageBreak
\name\string{val#1}.}%
}%
}{%
\name{@ifundefined}{val#1}{%
\name\name\let{val#1}={old#1}%
}{%
\PreambleMacroError{\indexedSet}%
{Macro \name\string{val#1} already defined}%
{Setting \name\string{val#1} to \name\string{old#1} should not
override an existing definition of\MessageBreak
\name\string{val#1}.}%
}%
}%
}%
\indexedSet{abc} % Defines valabc as 123
\begin{document}
\texttt{\string\oldabc: \meaning\oldabc}
\texttt{\string\valabc: \meaning\valabc}
\texttt{\name\string{valabc}: \name\meaning{valabc}}
\end{document}