如何将宏的内容传递给命令?

如何将宏的内容传递给命令?

为了开发类文件,我尝试对字符串(可能包含 latex 命令)执行一些基本检查。为此,我使用教学循环包裹。

当我直接传递字符串时,一切都按预期进行。由于各种原因(我们使用以下方式存储参数)鍵盤并在以后撤销这些值(如果它们存在)我需要处理内容宏。

如何将宏的内容传递给命令?或者获取教学循环由于我们想要检测输入字符串中的宏(例如“Test\test”),因此可以在不扩展宏的情况下处理宏的内容。

例子:

\documentclass{article}

\usepackage{tokcycle}

\newcommand\checkstring[1]{%
  \typeout{CHECKING -----------  #1}%
  \tokcycle{\typeout{CHARACTER: ##1}}%
           {\typeout{GROUP: ##1}}%
           {\typeout{MACRO: \string##1}}%
           {\typeout{SPACE: ##1}}%
           {#1}%
}

\newcommand\good[1]{%
  \checkstring{#1}%
}

\newcommand\problem[1]{%
  \def\tmp{#1}%
  \checkstring{\tmp}%
}

\begin{document}
\good{Test.}
\problem{Test.}
\end{document}

得出:

CHECKING ----------- Test.
CHARACTER: T
CHARACTER: e
CHARACTER: s
CHARACTER: t
CHARACTER: .
CHECKING ----------- Test.
MACRO: \tmp

我希望两种情况下的输出相同。

答案1

您可以使用 跳过标记的扩展\expandafter。您还需要跳过左括号才能获得所需内容,这就是您需要 的原因\expandafter\checkstring\expandafter{\tmp}

如果您所需要的只是出于调试目的列出参数的内容,我建议使用内置函数,expl3\tl_analysis_log:n不是使用tokcycle包构建您自己的版本:

\documentclass{article}

\ExplSyntaxOn
\cs_new_eq:NN \checkstring \tl_analysis_log:n
\ExplSyntaxOff

\newcommand\good[1]{%
  \checkstring{#1}%
}

\newcommand\problem[1]{%
  \def\tmp{#1}%
  \expandafter\checkstring\expandafter{\tmp}%
}

\begin{document}
\good{Test.}
\problem{Test.}
\end{document}

它将打印以下内容到你的日志文件:

The token list contains the tokens:
>  T (the letter T)
>  e (the letter e)
>  s (the letter s)
>  t (the letter t)
>  . (the character .)
The token list contains the tokens:
>  T (the letter T)
>  e (the letter e)
>  s (the letter s)
>  t (the letter t)
>  . (the character .)

答案2

一条评论正确地建议采用 的方法\expandafter。但是,这种方法不能盲目使用,因为如果参数包含多个标记,其中第一个是宏(例如\expandafter\checkstring\expandafter{\today ABC}),它将无法正常工作。

这里,\checkstring宏将测试参数是否是单个标记(例如,宏),如果是,则在处理之前将其展开。

\documentclass{article}

\usepackage{tokcycle}

\def\ckstringtest{\relax}
\def\checkstringaux{%
  \tokcycle{\typeout{CHARACTER: ##1}}%
           {\typeout{GROUP: ##1}}%
           {\typeout{MACRO: \string##1}}%
           {\typeout{SPACE: ##1}}%
}

\makeatletter
\newcommand\checkstring[1]{%
  \typeout{CHECKING -----------  #1}%
%  
  \expandafter\ifx\expandafter\ckstringtest\@gobble#1\ckstringtest
    \expandafter\checkstringaux\expandafter{#1}%
  \else
    \checkstringaux{#1}%
  \fi
}
\makeatother

\begin{document}
\checkstring{Test.\today}

\def\tmp{Test.\today}
\checkstring{\tmp}

Done.
\end{document}

日志文件的内容包括:

CHECKING ----------- Test.August 23, 2023
CHARACTER: T
CHARACTER: e
CHARACTER: s
CHARACTER: t
CHARACTER: .
MACRO: \today
CHECKING ----------- Test.August 23, 2023
CHARACTER: T
CHARACTER: e
CHARACTER: s
CHARACTER: t
CHARACTER: .
MACRO: \today

相关内容