使用“newcommand”在执行调用的命令之前修改其名称

使用“newcommand”在执行调用的命令之前修改其名称

前几天我在思考以下问题。假设我有两个命令,\mycommand\mycommandSpecial

\newcommand{\mycommand}
    {A simple phrase.}
\newcommand{\mycommandSpecial}
    {A special phrase!}

现在假设我还有另一个命令,如下所示(当然这不起作用,但它可以让您了解我在寻找什么):

\newcommand{\mynewcommand}[1]
    {First this one: #1 -- and then the special one: #1Special}

我希望如果我现在输入的话\mynewcommand{\mycommand}会得到以下输出:

首先是这个:一个简单的短语。——然后是特殊的一个:一个特殊的短语!

正如你所见,我只想\mynewcommand(因为)的论点[1],但援引两个都其他命令,利用它们的类似名称,因为特殊命令只是在其名称中添加了一些内容。

不管我想实现什么(以及这是否合理),我一般想知道 LaTeX 是否可以做到这一点,以某种方式修改命令中的命令执行它们。

我正在研究\expandafter\csname … \endcsname尝试以下方法:

 \newcommand{\mynewcommand}[1]
    {First this one: #1 -- and then the special one: \expandafter#1\csname#1Special\encsname}

但您立即就会发现它不起作用。

答案1

据我了解,这就是你想要的:

\documentclass{article}
\newcommand{\mycommand}
    {A simple phrase.}
\newcommand{\mycommandSpecial}
    {A special phrase!}

\newcommand{\executeBoth}[1]{Here is firs: ``\csname#1\endcsname''\par Here is second: ``\csname#1Special\endcsname''}

\newcommand{\executeSelected}[1][0]{\ifnum#1=0 Fisrt command selected:``\mycommand''\else Second selected: ``\mycommandSpecial''\fi}

\newcommand{\myscommand}[1]
    {A simple phrase. And a \emph{#1}}
\newcommand{\myscommandSpecial}[1]
    {A special phrase! And no \emph{#1}}

\newcommand{\executesBoth}[2][pig]{Here is firs: ``\csname#2\endcsname{#1}''\par Here is second: ``\csname#2Special\endcsname{#1}''}

\newcommand{\executesSelected}[2][0]{\ifnum#1=0 Fisrt command selected:``\myscommand{#2}''\else Second selected: ``\myscommandSpecial{#2}''\fi}


\begin{document}

One command will execute both:

\executeBoth{mycommand}\vspace{20pt}

Next command without argument will execute first:

\executeSelected\vspace{20pt}

Next command with optional non zero will execute second:

\executeSelected[8]\vspace{40pt}




{\bfseries with arguments}\vspace{10pt}

One command will execute both:

\executesBoth{myscommand}\vspace{20pt}

Next command without argument will execute first:

\executesSelected{ball}\vspace{20pt}

Next command with optional non zero will execute second:

\executesSelected[8]{ball}

\end{document}

输出:

在此处输入图片描述

答案2

你可以通过\csname...\endcsname或 来做到这一点\@nameuse。但是,由于你传递的是控制序列而不是字符串,所以你必须remove反击bs第一的:

在此处输入图片描述

\documentclass{article}

% https://tex.stackexchange.com/a/42337/5764
\begingroup\lccode`\|=`\\
\lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}}
\newcommand{\macroname}[1]{\expandafter\removebs\string#1}

\newcommand{\mycommand}
  {A simple phrase.}
\newcommand{\mycommandSpecial}
  {A special phrase!}
\newcommand{\mynewcommandA}[1]
  {First this one: #1{} -- and then the special one: \csname\macroname{#1}Special\endcsname}
\makeatletter
\newcommand{\mynewcommandB}[1]
  {First this one: #1{} -- and then the special one: \@nameuse{\macroname{#1}Special}}
\makeatother

\begin{document}

\verb|\mycommand|: \mycommand

\verb|\mycommandSpecial|: \mycommandSpecial

\verb|\mynewcommandA{\mycommand}|: \mynewcommandA{\mycommand}

\verb|\mynewcommandB{\mycommand}|: \mynewcommandB{\mycommand}

\end{document}

\@nameuse类似于\csname... \endcsname,但如果在常规文档中使用,则需要\makeatletter...对。此外,不会检查传递给的宏是否存在。如果结果宏不存在,则默认为...因此不会打印任何内容。如果需要,可以内置检查。\makeatother\mynewcommand\csname\endcsname\relax


一个更直观的替代方案可能\macroname\@gobble\

\makeatletter
\newcommand{\macroname}[1]{\expandafter\@gobble\string#1}
\makeatother

答案3

这迫切需要*-variant。

\usepackage{xparse}

\NewDocumentCommand{\mycommand}{s}{%
  \IfBooleanTF{#1}{A simple phrase.}{A special phrase!}%
}

\newcommand{\mynewcommand}[1]{%
  First this one: #1 -- and then the special one: #1*%
}

第一个命令可以称为\mycommand\mycommand*

相关内容