# Using listings' escapebegin/escapeend with short commands

I'm building beamer slides with code set using listings and I want to draw arrows to parts of the code. To achieve that I have a zero width command that defines a named PGF coordinate (given as the argument), here called libraryCommand.

Now the problem: I want to have a pretty syntax, so I use escapeinside, which should allow me to write QhereW to create a coordinate called here. Instead of writing the full command.

The argument that's passed to libraryCommand has to be wrapped between two commands, I use the environment for that. It works outside the lstlisting. But inside, I get Missing \endcsname inserted: \end{^lstlisting}.

\documentclass{scrartcl}
\usepackage{listings}
\lstset{
% escapeinside={Q}{W}, % uncommenting this fails.
escapebegin=\begin{wrapThat},
escapeend=\end{wrapThat}
}
\newcommand{\libraryCommand}[1]{((#1))}
\newenvironment{wrapThat}{\wrapToEnd}{}
\long\def\wrapToEnd#1\end{\libraryCommand{#1}\end}
\begin{document}
foo \begin{wrapThat}bar\end{wrapThat} baz
\begin{lstlisting}
foo QbarW baz
\end{lstlisting}
\end{document}


So, how could I get this to work? I can't see what special thing they do in the DTX...

-
About the wrapThat environment: Have a look at the environ package which allows the definition of (pseudo-)environments which collect the body and provide it as \BODY in the end-code. Also using a plainTeX style envrionment like \wrap ... \endwrap would be better. –  Martin Scharrer Jun 24 '11 at 17:56
Ah, forgot about that... But it doesn't work either: Using \NewEnviron{wrapThat}{\libraryCommand{\BODY}} it fails with \begin{wrapThat} ended by \end{lstlisting}. (but works outside lstlisting) –  pascal Jun 24 '11 at 18:05
And with plainTeX environments like \def\wrapThat#1\endWrapThat{\libraryCommand{#1}} it fails with File ended while scanning use of \wrapThat. –  pascal Jun 24 '11 at 18:14
@pascal: It seems that the endmarker is not inserted directly by listings. Rather the Q and W are probably active and expand to the escapebegin and escapeend codes. Therefore \wrapThat never finds \endWrapThat because W isn't expanded yet. With your initial code the \end it finds would be then the \end{lstlisting}! –  Martin Scharrer Jun 24 '11 at 19:37
@pascal: Yes, you most likely need to use \begingroup\catcodeW=\active\gdef\wrapThat#1W{\libraryCommand{#1}}\endgroup. Then escapeend can actually be empty. Or you simply add W after \libraryCommand{#1}. –  Martin Scharrer Jun 24 '11 at 21:25
show 1 more comment

And with plainTeX environments like \def\wrapThat#1\endWrapThat{\libraryCommand{#1}} it fails with File ended while scanning use of \wrapThat.

It seems that the endmarker is not inserted directly by listings. Rather the Q and W are probably active and expand to the escapebegin and escapeend codes. Therefore \wrapThat never finds \endWrapThat because W isn't expanded yet. With your initial code the \end it finds would be then the \end{lstlisting}!

You need to define a macro which scannes for an active W instead:

\begingroup
\catcodeW=\active
\gdef\wrapThat#1W{\libraryCommand{#1}}%
\endgroup


If you need the endmarker for any other escapeend code, then you can readd the active W after your command:

\gdef\wrapThat#1W{\libraryCommand{#1}W}%

-

Solution from Martin Scharrer's comment:

\documentclass{scrartcl}
\usepackage{listings}
\lstset{
escapeinside={Q}{W},
escapebegin=\wrapThat,
escapeend=%
}
\newcommand{\libraryCommand}[1]{((#1))}
\begingroup%
\catcodeW=\active%
\gdef\wrapThat#1W{\libraryCommand{#1}W}%
\endgroup
\begin{document}
\begin{lstlisting}
foo QbarW baz
\end{lstlisting}
\end{document}
`
-