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

7
  • 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. Mar 9, 2016 at 13:59
  • You could do \newcommand\code{\lstinline[mathescape=true]} so that the argument was not scanned before listinline starts. Mar 9, 2016 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. Mar 9, 2016 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. Mar 9, 2016 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? Mar 9, 2016 at 14:32

1 Answer 1

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}
3
  • 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. Mar 9, 2016 at 15:38
  • @user2357463 see update:-) Mar 9, 2016 at 15:52
  • Wow, thanks a lot! Now it's exactly what I need! I'll try to understand this code someday. Mar 9, 2016 at 16:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .