如何提取命令的名称和内容?

如何提取命令的名称和内容?

我意识到标题可能难以理解。我想要一个\printit{}接受 1 个参数的命令,并在进行一些测试后显示它。\printit我想在里面测试它是否#1只是一段文本,或者它本身是否是一个宏。为简单起见,我可以假设以下情况:

  • #1 只是一些文字,例如 hallo
  • #1 的形式为\mycomA{content}
  • #1 的形式为\mycomB{content}

其中\mycomA{}\mycomB{}是我自己定义的命令。根据情况,我想\printit{}排版hallo,或content根据情况使用某种格式。为简单起见,我还可以假设\mycomA 和的参数\mycomB是简单文本。

我该怎么做?这是空的 MWE :)

\documentclass{article}
\newcommand{\mycomA}[1]{\textbf{#1}}% just for the example
\newcommand{\mycomB}[1]{\textit{#1}}% just for the example
\newcommand{\printit}[1]{%
% If #1 has the form mycomA(...) THEN 
 case A : content = % extract the content of mycomA
% ElseIf #1 has the form mycomB(...) THEN 
 case B : content = % extract the content of mycomB
% Else THEN 
 case C : content = #1 

\begin{document}
    \printit{hallo}
    \printit{\mycomA{123}}
    \printit{\mycomB{qweqwe}}
    \printit{hallo}

\end{document}

答案1

如果可能出现在参数中的命令是以下形式\mycomA或类似形式,即带参数的命令,则可以准备它们的列表:

\makeatletter
\newcommand{\roy@disable}{%
  \let\mycomA\@firstofone
  \let\mycomB\@firstofone
  % other similar commands
}
\newcommand{\printit}[1]{%
  \begingroup\roy@disable
  #1
  \endgroup
}
\makeatother

这是有效的,因为分组之后命令将恢复其以前的定义,并\@firstofone简单地从参数中去掉括号。

如果对宏的控制较少,就必须采取更复杂的方法。

编辑

让我猜一下。您希望\printit根据 和 的“外部”定义以不同的方式处理传递给它的参数\mycomA\mycomB假设它必须更改\mycomA为“以红色打印”并返回“状态 A”,并\mycomB以绿色打印其参数并返回“状态 B”:

\makeatletter
\newcommand{\roy@change}{%
  \def\mycomA##1{\gdef\roy@status{A}\textcolor{red}{##1}}
  \def\mycomB##1{\gdef\roy@status{B}\textcolor{green}{##1}}
  % possibly other similar definitions
}
\newcommand{\printit}[1]{\gdef\status{0}% in case no command appears
  \begingroup
  \roy@change
  #1%
  \endgroup
}
\makeatother

答案2

我只需分别重新定义\mycomA\mycomB,以便按照以下方式打印它们\printit

\newcommand\printit[1]{%
  \begingroup
     \renewcommand\mycomA[1]{\textcolor{red}{##1}}%
     \renewcommand\mycomB[1]{\textcolor{blue}{##1}}%
     #1%
  \endgroup
}%

相关内容