为了开发类文件,我尝试对字符串(可能包含 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