我正在beamer
使用代码集构建幻灯片listings
,我想绘制指向代码部分的箭头。为了实现这一点,我有一个零宽度命令,它定义了一个命名的 PGF 坐标(作为参数给出),这里称为libraryCommand
。
现在的问题是:我想要一个漂亮的语法,所以我使用escapeinside
,它应该请允许我编写QhereW
创建一个名为的坐标here
。而不是编写完整的命令。
传递给的参数libraryCommand
必须包装在两个命令之间,为此我使用环境。它在 之外有效lstlisting
。但在 内部,我得到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}
那么,我该如何让它工作呢?我看不出他们在 DTX 中做了什么特别的事情……
答案1
而在类似的 plainTeX 环境下
\def\wrapThat#1\endWrapThat{\libraryCommand{#1}}
它会失败File ended while scanning use of \wrapThat
。
似乎结束标记不是由 直接插入的listings
。相反,Q
和W
可能处于活动状态并扩展到escapebegin
和escapeend
代码。因此\wrapThat
永远不会找到,\endWrapThat
因为W
尚未扩展。使用您的初始代码,它\end
找到的将是\end{lstlisting}
!
您需要定义一个宏来扫描活动对象W
:
\begingroup
\catcode`W=\active
\gdef\wrapThat#1W{\libraryCommand{#1}}%
\endgroup
如果您需要任何其他代码的结束标记,那么您可以在命令后escapeend
重新添加活动标记:W
\gdef\wrapThat#1W{\libraryCommand{#1}W}%
答案2
Martin Scharrer 评论的解决方案:
\documentclass{scrartcl}
\usepackage{listings}
\lstset{
escapeinside={Q}{W},
escapebegin=\wrapThat,
escapeend=%
}
\newcommand{\libraryCommand}[1]{((#1))}
\begingroup%
\catcode`W=\active%
\gdef\wrapThat#1W{\libraryCommand{#1}W}%
\endgroup
\begin{document}
\begin{lstlisting}
foo QbarW baz
\end{lstlisting}
\end{document}