消耗/吸收代币

消耗/吸收代币

TeX 中如何使用/吸收/从标记流中删除标记?

我正在使用@ifnextchar并且想删除它匹配的字符。

答案1

\@ifnextchar使用\futurelet保留令牌。可以使用 删除令牌\let\afterassignment在分配和删除令牌后,有助于获取控制权。示例:

\documentclass{article}
\usepackage{ltxcmds}

\makeatletter
\newcommand{\removeifnextchar}[3]{%
  \begingroup
  \ltx@LocToksA{\endgroup#2}%
  \ltx@LocToksB{\endgroup#3}%
  \ltx@ifnextchar{#1}{%
    \def\next{\the\ltx@LocToksA}%
    \afterassignment\next
    \let\scratch= %
  }{%
    \the\ltx@LocToksB
  }%
}
\makeatother

\newcommand*{\removeA}{%
  \removeifnextchar{A}{[A is removed]}{[no A]}%
}

\begin{document}

\removeA ABC

\removeA abc

\end{document}

结果

\ltx@ifnextchar\@ifnextchar跳过空格。如果要检测空格,请使用\ltx@ifnextchar@nospace

移除/重新插入

一般来说这是不可能的,因为\futurelet不区分隐式和显式标记。例如,下一个标记可以是左花括号{,也可以是命令\bgroup或具有含义的命令。这无法通过或\bgroup来区分。花括号可以通过上面的技巧删除。但是重新插入要困难得多。后一种情况或具有相同含义的其他命令要容易得多,它们可以被捕获为宏并重新插入,而无需修改标记。\futurelet\let\let\bgroup

下面的示例定义了一个宏\embrace,它分析以下标记并根据标记的类型执行不同的操作:

  • 字母(类别代码 11)放在括号中。
  • 其他字符(catcode 12)放在方括号中。
  • 空格被下划线代替。
  • 任何其他标记均被删除。
  • \par 终止分析。

示例文件:

\documentclass{article}
\usepackage{ltxcmds}
\usepackage{xstring}

\makeatletter

\newcommand{\embrace}{%
  \futurelet\embrace@token\@embrace
}
\newcommand{\embrace@test}[1]{%
  \ifx\embrace@token#1%
    \expandafter\ltx@firstoftwo
  \else
    \expandafter\ltx@secondoftwo
  \fi
}
\newcommand*{\@embrace}{%
  \embrace@test\@sptoken{%
    \textunderscore
    \afterassignment\embrace
    \let\embrace@token= %
  }{%
    \expandafter\IfBeginWith\expandafter*%
    \expandafter{\meaning\embrace@token}{the letter }{%
      \embrace@letter
    }{%
      \expandafter\IfBeginWith\expandafter*%
      \expandafter{\meaning\embrace@token}{the character }{%
        \embrace@character
      }{%
        \ifx\embrace@token\par
        \else
          \@latex@warning{embrace: Token [\meaning\embrace@token] removed}%
          \afterassignment\embrace
        \fi
        \let\embrace@token= %
      }%
    }%
  }%
}
\newcommand*{\embrace@letter}[1]{%
  (#1)%
  \embrace
}
\newcommand*{\embrace@character}[1]{%
  [#1]%
  \embrace
}

\begin{document}

\embrace ABC 123\par

\embrace a 1{!}#&$x% 

\end{document}

\embrace 的结果

删除的 token 如下:

LaTeX Warning: embrace: Token [begin-group character {] removed on input line 54.
LaTeX Warning: embrace: Token [end-group character }] removed on input line 54.
LaTeX Warning: embrace: Token [macro parameter character #] removed on input line 54.
LaTeX Warning: embrace: Token [alignment tab character &] removed on input line 54.
LaTeX Warning: embrace: Token [math shift character $] removed on input line 54.

相关内容