1

I use the listings package to render code in LaTeX documents. I am trying to define a new command or a new environment that uses \lstinline inside. I have read numerous questions about this on StackExchange, but have not found a solution to my problem.

I want a macro \code such that this code:

\code{a $\leq$ b}

expands to this:

\begin{definition}
  \lstinline[mathescape=true]{a $\leq$ b}
\end{definition}

The NewDocumentCommand from the xparse package seemed promising but this doesn't compile.

\NewDocumentCommand\code{v}{\lstinline[mathescape=true]{#1}}
\code{a $\leq$ b}

The error:

ERROR: Undefined control sequence.

--- TeX said ---
\lst@arg ->a $\
               leq$ b
l.6 \code{a $\leq$ b}

So, my question is: is it possible to warn LaTeX that the argument of \code should not be expanded until it is passed to \lstinline?

Thank you,

Pierre

  • you can not use verbatim commands (including listings commands) in the argument of another command, this is just a basic rule about how tex parsing works. – David Carlisle Mar 09 '16 at 13:59
  • You could do \newcommand\code{\lstinline[mathescape=true]} so that the argument was not scanned before listinline starts. – David Carlisle Mar 09 '16 at 14:01
  • Yes I have seen this solution elsewhere. However, it doesn't allow me to wrap this inside a definition environment for example. – user2357463 Mar 09 '16 at 14:03
  • verbatim changes the way that characters are tokenized it has no effect on tokens that have already been read. that is just how tex works. – David Carlisle Mar 09 '16 at 14:15
  • I understand that what I have tried does not work. Are you saying that there is no way (even with obscure voodoo TeX black magic) to achieve the macro expansion I described in my question? – user2357463 Mar 09 '16 at 14:32
  • there is no way to do what you ask, you can however always do something for example arrange (using something like the first comment) to grab the argument verbatim but then save it in a box rather than immediately typeset, then use that box in your real command. – David Carlisle Mar 09 '16 at 14:38
  • OK that seems to be an interesting solution. Can you provide some code or documentation to the relevant commands to "save it in a box rather than immediately typeset" and then to "use that box"? Thanks a lot – user2357463 Mar 09 '16 at 14:52

1 Answers1

0

I made it a bit simpler by requiring double {{ it's probably possible to avoid that with some more effort, or use an environment form or explicit end marker eg \code ... \stopcode which would be easier.

enter image description here

\documentclass{article}

\usepackage{listings}

\begin{document}

%\code{a $\leq$ b}



\hrule
\begin{quote}
  \lstinline[mathescape=true]{a $\leq$ b \zzz}
\end{quote}
\hrule

\bigskip

% gobble a {
\def\code{\afterassignment\xcode\let\tmp}

% run lstinline and save inside box0, call \setcode when done
\def\xcode{\setbox0\hbox\bgroup\aftergroup\setcode
 \lstinline[mathescape=true]}

% does the environment required, using \usebox0 to use the saved text

\def\setcode{\hrule\begin{quote}\usebox0\end{quote}\hrule}

\code{{a $\leq$ b \zzz}}

\end{document}

or with an argument as requested in comments

\documentclass{article}

\usepackage{listings}

\begin{document}

%\code{a $\leq$ b}



\hrule
\begin{quote}
  \lstinline[mathescape=true]{a $\leq$ b \zzz}
\end{quote}
\hrule

\bigskip

% gobble a {
\def\code#1{\def\savedlabel{#1}\afterassignment\xcode\let\tmp}

% run lstinline and save inside box0, call \setcode when done
\def\xcode{\setbox0\hbox\bgroup\aftergroup\setcode
 \lstinline[mathescape=true]}

% does the environment required, using \usebox0 to use the saved text

\def\setcode{\hrule\begin{quote}\label{\savedlabel}\fbox{\savedlabel}\\%
    \usebox0\end{quote}\hrule}

\code{hmm}{{a $\leq$ b \zzz}}

\end{document}
David Carlisle
  • 757,742
  • Thank you very much for this answer, David. This does exactly what I asked for. However, I'm afraid I didn't ask what I really wanted ;) I would like \code to take as a parameter a label name to place inside the definition. I've tried naive stuff, but since I don't understand the TeX code you posted, I'm not sure how to do this. Thanks. – user2357463 Mar 09 '16 at 15:38
  • @user2357463 see update:-) – David Carlisle Mar 09 '16 at 15:52
  • Wow, thanks a lot! Now it's exactly what I need! I'll try to understand this code someday. – user2357463 Mar 09 '16 at 16:10