5

I'm trying to replicate a part of a scanned book. Book is about programming (pure C).
I need to use many commands with a same name but with different surrounding, for example, background color etc. I'm using listings package. I created with newcommand, something like an alias for \lstinline. Later, maybe, I'll surround it with background color or different font/size or something like that. I want to be able to do this kind of things on-the-fly (to tweak every thing later easy).

Main problem is with a source code in the book (specifically reserved or special characters, like # or \). At the moment, I just use different names for a plain commands, which I'm going to define (expand) later, something like this:

\usepackage{listings}
\newcommand{\test}[1]{\lstinline{#1}}

\test{"\nA marathon is %f kilometers.\n\n"}
\lstinline{"\nA marathon is %f kilometers.\n\n"}

problem is with this command:

\test{"\nA marathon is %f kilometers.\n\n"}

while this command, as expected, works fine:

\lstinline{"\nA marathon is %f kilometers.\n\n"}

I get errors (Undefined Control Sequence. \nA), but soon as I remove (La)TeX special characters (#, \), everything runs normally.

My question is, is there a clean way to create newcommands (or an aliases) which are dealing with source code, or, there is some other, more elegant way that you know?

Any help apreciated.

Werner
  • 603,163
aksr
  • 847

1 Answers1

6

This is a very similar to problem the idea behind passing arguments containing verbatim content. Once an argument has been gobbled (using a definition like \newcommand{\test}[1]), you cannot change the category codes associated with each element of the input. As such, the verbatim interpretation is completely lost.

In your instance, the most convenient way around this would be to make \test do exactly what \lstinline does through something like

\let\test\lstinline

(perhaps safer to use \LetLtxMacro from letltxmacro; see When to use \LetLtxMacro?) or

\newcommand{\test}{\lstinline}

This works since \lstinline doesn't gobble it's (mandatory) argument. It leaves that for processing later on. The above solution literally inserts \lstinline wherever it finds \test, providing an easy alias for \lstinline.

Werner
  • 603,163
  • 1
    As an aside: xparse can also deal with this usinv \NewDocumentCommand{\test}{v}{\lstinline{#1}}. – Joseph Wright May 29 '13 at 18:17
  • Given that \lstinline{bla $a$} does not work but that \lstinline|bla $a$| does, is there anyway to get something like \test{bla $a$} to be replaced with \lstinline|bla $a$|? – Abdallah Jan 22 '14 at 05:39
  • @Abdallah: You can use \test{bla $a$} if you \newcommand{\test}{\lstinline}. – Werner Jan 22 '14 at 05:56
  • @Werner Ah ok. But then, doesn't it get replaced with \lstinline{bla $a$} instead of \lstinline|bla $a$|? Oh... perhaps I should try \test|bla $a$|! – Abdallah Jan 22 '14 at 06:01
  • @Abdallah: Yes it does, and \lstinline is specifically designed to work with {...}. Read the listings documentation (4.2 Typesetting listings, p 27: "An experimental implementation..."). However, you can also use \test|...|. – Werner Jan 22 '14 at 06:15
  • @Werner Yes, I have spent some time on the documentation but \lstinline{bla $a$} does specifically not work as I intend (in a tabular). Fortunately, \test|bla $a$| does the trick. – Abdallah Jan 22 '14 at 07:09