如何提取宏的名称?

如何提取宏的名称?

对于 TeX 专家来说,这可能很明显,但这里是:

我想创建一个命令,以控制序列(无参数)作为输入并打印该控制序列的名称(不带前导反斜杠)。该怎么做?

答案1

正如一些评论所指出的那样,有各种方法。有几个“尴尬”的情况需要解决:如果转义字符不可打印,以及如果控制序列以空格开头(例如\csname\space awkward\endcsname)。在expl3,我们用一个名为的函数来解决这个问题\cs_to_str:N,在原语中可以写成

\catcode`\@=11 %
\def\cs@to@str{%
  \romannumeral\if\string\ \cs@to@str@aux@i\fi
    \expandafter\cs@to@str@aux@ii\string
}
\long\def\cs@to@str@aux@i#1\cs@to@str@aux@ii{%
  -\number\fi\expandafter\z@
}
\long\def\cs@to@str@aux@ii#1{\z@}

并用作

\cs@to@str\foo % => "foo"
\expandafter\cs@to@str\csname\space foo\endcsname % => " foo"

为了解释其工作原理,有三种情况

  1. 转义符是可打印的,而不是空格。在本例中,\string\给出了两个标记(转义符和空格),它们具有不同的 catcode。\if因此测试为假,因此\string可以安全地使用第二个标记,但要\cs@to@str@aux@ii删除转义符。

  2. 转义符不可打印。在这种情况下,\string\仅产生一个标记,测试继续,扩展\cs@to@str@aux@i。插入-强制测试为假,\string可直接用于给出所需的输出。

  3. 转义符是一个空格。在本例中,\if测试为真,并\cs@to@str@aux@i导致插入 ,-\z@\number变为-0。这并非“终止”,因此 会\romannumeral寻找可选空格。它在转义符中找到了它,因此将其删除,只留下控制序列名称。

在这三种情况下,请注意,我们永远无法从名称本身删除前导空格,因为我们永远不会删除非转义字符的标记。


由于这一切都是内置的expl3,我只需创建一个文档级别名:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\newcommand{\CsToStr}[1]{\cs_to_str:N #1}
\ExplSyntaxOff
\begin{document}
\CsToStr{\LaTeX}

\CsToStr{\def} 

\CsToStr{\newcommand}

\CsToStr{\MacroName}
\end{document}

xparse(当然,您可以使用 来做到这一点)。

答案2

您还可以使用该xstring包以及\string

在此处输入图片描述

代码:

\documentclass{article}
\usepackage{xstring}

\newcommand*{\MacroName}[1]{\StrGobbleLeft{\string#1}{1}}%

\begin{document}
\MacroName{\LaTeX}

\MacroName{\def} 

\MacroName{\newcommand}

\MacroName{\MacroName}
\end{document}

相关内容