# Why won't this macro work in a \caption?

I created a macro to easily shift into typewriter mode, ala markdown or fancyvrb's "short verbatim" command. It works everywhere but in \captions. In that case, TeX fails saying I've exceeded capacity. Is my approach untenable? Below is a MWE. The example outside \caption, !+foo+!, works fine. The example inside \caption fails.

\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}


Suggestions for improving this macro are welcome as well!

-
Perhaps you might enlighten us as to the aim of all of this. –  Joseph Wright Oct 10 '11 at 16:55
!+foo+! should be an abbreviation for \texttt{foo}. I guess that \let\?\texttt and \?{foo} is quite simpler. –  egreg Oct 10 '11 at 17:35
@JosephWright I am writing a document with a lot of typewriter type (for code samples). I found myself using fancyvrb's "DefineShortVerb" command with the hash symbol (#) so I could write things like "#int x = 0#" and have it come out in typewriter. That breaks in captions, though, and I have to resort to \texttt{...}. \texttt isn't so burdensome, but I thought it would be fun to figure out how do it "markdown" style, and delimit typewriter text using something "!+ ... +!". –  Justin Bailey Oct 10 '11 at 19:29

The problem is in the definition of \startTTB and \stopTTB with an argument; moreover, the active ! and + should be protected against expansion in write operations:

\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


It's not necessary to do global redefinitions. With the two \@gobble commands, the + or ! characters are swallowed.

A shorter set of macros will do the same:

\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}


However, I don't see where this is more efficient than declaring

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


and writing

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

-
But the output for !+foo+! yields \texttt{+foo!} instead of \texttt{foo}. –  Werner Oct 10 '11 at 16:49
@Werner Yes, you're right. –  egreg Oct 10 '11 at 17:03
That pretty much worked -- I needed to add a command to gobble the trailing + or ! (on start and stop) to \startTTC and \stopTTA, or extra characters showed up in the output. Thanks very much! –  Justin Bailey Oct 10 '11 at 18:33
"That" in my previous comment refers to the first block of code given by @egreg. While the last macro given does the same thing, I still want to use my silly markdown syntax. –  Justin Bailey Oct 10 '11 at 20:48
@JustinBailey Does the shorter version work? It should, but I've not made extensive testing. –  egreg Oct 10 '11 at 20:49