命令参数中添加的空格

命令参数中添加的空格

考虑 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}

在此处输入图片描述

相关内容