如何连接命令名称

如何连接命令名称

我希望能够通过连接命令名称的两个(或更多)部分来执行“索引”分配,既用于创建新命令,也用于引用现有命令。下面是显示我需要的示例。当然,不起作用。

\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}

在此处输入图片描述

相关内容