为什么这个宏不能在 \caption 中起作用?

为什么这个宏不能在 \caption 中起作用?

我创建了一个宏,以便轻松切换到打字机模式,就像 markdown 或 fancyvrb 的“简短逐字”命令一样。它在除 之外的任何地方都有效\captions。在这种情况下,TeX 会失败,说我已超出容量。我的方法站不住脚吗?下面是一个 MWE。 外面的示例\caption,,!+foo+!工作正常。里面的示例\caption失败了。

\chardef\plus=`+\chardef\bang=`!
\catcode`!=\active\catcode`+=\active
\def\startTTA{\futurelet\next\startTTB} 
\long\def\startTTB#1{\ifx\next+\expandafter\startTTC\else\bang\expandafter#1\fi}
\def\startTTC{\begingroup\ttfamily\global\let+=\stopTTA\global\let!=\bang}
\def\stopTTA{\futurelet\next\stopTTB}
\long\def\stopTTB#1{\ifx\next!\expandafter\stopTTC\else\plus\expandafter#1\fi}
\def\stopTTC{\endgroup\global\let+=\plus\global\let!=\startTTA}
\let!=\startTTA\let+=\plus
\documentclass{article}
\begin{document}
!+foo+!
\begin{figure}
\tracingmacros=1\tracingcommands=2
\caption{!+foo.+!}
\tracingmacros=0\tracingcommands=0
\end{figure}
\end{document}

也欢迎提出改进此宏的建议!

答案1

问题在于带有参数的\startTTB和的定义;此外,活动的和应该受到保护以免在写操作中扩展:\stopTTB!+

\makeatletter
\chardef\plus=`+\chardef\bang=`!
\catcode`!=\active\catcode`+=\active
\def\startTTA{\futurelet\next\startTTB}
\def\startTTB{\ifx\next+\expandafter\startTTC\expandafter\@gobble\else\bang\fi}
\def\startTTC{\begingroup\ttfamily\protected\def+{\stopTTA}\protected\def!{\bang}}
\def\stopTTA{\futurelet\next\stopTTB}
\def\stopTTB{\ifx\next!\expandafter\stopTTC\expandafter\@gobble\else\plus\fi}
\def\stopTTC{\endgroup}
\protected\def!{\startTTA}\protected\def+{\plus}
\makeatother

没有必要进行全局重新定义。使用这两个\@gobble命令,+!字符将被吞掉。

一组较短的宏将发挥同样的效果:

\chardef\plus=`+\chardef\bang=`!
\catcode`!=\active\catcode`+=\active
\protected\def!{\startTTA}\protected\def+{\plus}
\def\startTTA{\futurelet\next\startTTB}
\def\startTTB{\ifx\next+\expandafter\startTTC\else\bang\fi}
\long\def\startTTC+#1+!{\begingroup\ttfamily
  \let+\plus\let!\bang#1\endgroup}

然而,我不认为这比声明更有效

\def\?+#1+?{\texttt{#1}}

和写作

\?+foo+?
\caption{\?+foo+?}

相关内容