考虑 MWE 示例。
\documentclass{article}
\begin{document}
\def\toot#1{%
\def\content{#1}%
\meaning\content%
}
\toot{\textsc{1}}
s
\end{document}
\meaning\toto
为什么是\toot{\textsc {1}}
和不是的结果\toot{\textsc{1}}
(会对Reledmac/Reledmac:重复索引条目
答案1
TeX 并不在内存中保存字符串,而是保存标记。当\toot
示例中的参数
\toot{\textsc{1}}
扫描后,标记器会创建标记“textsc”、“{”、“1”和“}”。当要求 TeX 打印标记(\meaning
在您的示例中使用)时,它必须解决如何打印控制序列类型的标记的问题。如果打印的标记控制序列名称由字母组成,则 TeX 会在此类标记前面打印一个反斜杠,并在其后打印一个空格。这是 TeX 作者的决定。原因:标记“relax”、“a”被打印为 ,\relax a
这比 更好\relaxa
。
编辑如果您想用 catcodes 进行详细说明,下面是一个示例。\toot
当反斜杠和空格的 catcodes 为 12(正常)时,将读取(并标记)宏的参数。因此,您可以检测到重复的空格并且没有控制序列。一旦读取参数,标准 catcodes 就会被设置回(在\egroup
)。然后使用准备参数的第二个“正常”变体,\scantokens
因为我们预计宏程序员需要使用两个变体进行操作:“正常”和“尊重空间”。最后\tootB
启动宏。它获得两个参数,第一个是参数的“正常”变体,第二个是“尊重空间”变体(其中没有控制序列)。
\def\toot{\bgroup \catcode`\\=12 \catcode`\ =12 \tootA}
\long\def\tootA#1{\egroup
\scantokens{\def\tmp{#1}}%
\expandafter\tootB\expandafter{\tmp}{#1}%
}
\long\def\tootB#1#2{%
\def\tmp{#1}%
\message{normal: "\meaning\tmp"}
\def\tmp{#2}%
\message{space-respected: "\meaning\tmp"}
}
\toot{\textsc{1}}
\toot{\textsc{ a b c \par a\par1 \textbf {a}a}}
\toot{\textsc{ a b c \hskip1em a\space 1 \textbf {a}a}}
\bye
答案2
通过使用一个宏,您可以得到想要的结果,该宏会占用控制序列后面的每个空格(因此宏名仅由字母组成),而其(一次)扩展参数中后面没有字母。不过,如果您自己输入它,它也会占用空格。
编辑:可以逐字逐句地读取宏的参数,然后用宏替换所有应该是宏的内容。因此\toottwo
不能在另一个宏的参数中使用。
\documentclass[preview,border=2mm]{standalone}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_maieul_tl
\NewDocumentCommand \eatmacrospace { m }
{
\tl_set:No \l_maieul_tl { #1 }
\regex_replace_all:nnN
{ (\\[A-Za-z]+)\s([^A-Za-z]) } { \1\2 } \l_maieul_tl
\l_maieul_tl
}
\str_new:N \l_maieul_str
\int_new:N \l_maieul_int
\NewDocumentCommand \toottwo { +v }
{
\tl_set:Nn \l_maieul_tl { #1 }
\regex_replace_all:nnN { \\([A-Za-z]+) } { \c{\1} } \l_maieul_tl
\regex_replace_all:nnN { \\([^A-Za-z]) } { \c{\1} } \l_maieul_tl
\exp_args:NnV \regex_count:nnN { \{ } \l_maieul_tl \l_maieul_int
\int_step_inline:nnnn { \c_one } { \c_one } { \l_maieul_int }
{
\regex_replace_all:nnN { \cO{(.*)\cO} } { \cB{\1\cE} } \l_maieul_tl
}
%\tl_show_analysis:N \l_maieul_tl % for debugging
\let\content\l_maieul_tl
\str_set:Nn \l_maieul_str { #1 }
\texttt{macro:->\l_maieul_str}
}
\ExplSyntaxOff
\long\def\toot#1{%
\def\content{#1}%
\texttt{\meaning\content}\\%
\texttt{\eatmacrospace{\meaning\content}}%
}
\begin{document}
\toot{\textsc{1}}
\toot{\textsc{ a b c \par a\par1 \textbf {a}a}}
\toottwo{\textsc{ a b c \hskip1em a\space 1 \textbf {a}a}}
\content% content is expandable
s
\end{document}