5

I wanted to define a macro which makes a program listing, and finds out a program language from an optional argument. The output I receive from the MWE below is

Language set = 'Verilog'

Passed argument is 'Verilog'

So, is looks like that in both calls to '\lstset' the same argument is passed. However, if the argument is produced from optional, rather than a mandatory argument, I am presented with the error message: "language Verilog undefined". What do I wrong?

\documentclass{article}
\usepackage{listingsutf8}
\usepackage{xkeyval}

\makeatletter
\define@key{MESourceFile}{language}{\def\pb@language{#1}}
\setkeys{MESourceFile}{language={[ANSI]C}}%
\newcommand\MESourceFile[4][]{
   \begingroup%
    \setkeys{MESourceFile}{#1}
        Passed argument is '\pb@language'\\
    \lstset{language={\pb@language}}    
    \endgroup
}
\makeatother

\newcommand\MESetListingFormat[2][] 
{
    Language set = '#2' 
    \lstset{language={#2}}  e   
}

\begin{document}
        \MESetListingFormat{Verilog}
        \MESourceFile[language=Verilog]{lst/TestHello.c}{A hello világ program}{lst:TestHello.c}
\end{document}
4
  • Welcome to TeX.SX! Usually, we don't put a greeting or a “thank you” in our posts. While this might seem strange at first, it is not a sign of lack of politeness, but rather part of our trying to keep everything very concise. Accepting and upvoting answers is the preferred way here to say “thank you” to users who helped you. A suggestion: Do us a favour and change your username to something more telling than "user1234". Aug 20, 2014 at 15:41
  • 4
    Try, instead of \lstset{language={\pb@language}}, the code \begingroup\edef\x{\endgroup\noexpand\lstset{language=\pb@language}}\x
    – egreg
    Aug 20, 2014 at 15:45
  • @ Martin Schröder Sorry for being unpolite, but: I could not find out how to register, or change user name. From your homepage I learned "No registration required". In the Help center, I took the "2-minute tour", which takes back to the Help center. Even Google takes to the "No registration required" page. When asking, I do not see an obvious possibility to register or provide username. Some hint on the homepage would be great. @egreg Many thanks, it works. Is there a more elegant method, than checking for empty string, for absence of an argument? A link to your info source would be great.
    – katang
    Aug 20, 2014 at 17:32
  • @user11708 It's true that “no registration is required”, but a registered user can better enjoy the site. The \begingroup\edef\x trick is very common; you need nothing special if the argument is empty, as \setkeys happily accepts an empty argument.
    – egreg
    Aug 20, 2014 at 17:40

1 Answer 1

4

It's an expansion problem: when the key is set, no expansion is performed, so you have to pass the expanded \pb@language macro:

\documentclass{article}
\usepackage{listingsutf8}
\usepackage{xkeyval}

\makeatletter
\define@key{MESourceFile}{language}{\def\pb@language{#1}}
\setkeys{MESourceFile}{language={[ANSI]C}}
\newcommand\MESourceFile[4][]{%
  \begingroup
  \setkeys{MESourceFile}{#1}
%    Passed argument is '\pb@language'\\% uncomment for debugging
  \begingroup\edef\x{\endgroup
    \noexpand\lstset{language={\pb@language}}}\x
  \lstinputlisting{#2}%
  \endgroup
}
\makeatother

\begin{document}

\MESourceFile[language=Verilog]{helloworld.v}{A hello világ program}{helloworld.v}

\end{document}

However, it would be easier to do it using \lstset directly:

\documentclass{article}
\usepackage{listingsutf8}

\makeatletter
\newcommand{\MESourceFile}[4][]{%
  \begingroup
  \lstset{#1}%
  \lstinputlisting{#2}%
  \endgroup
}
\makeatother

\begin{document}

\MESourceFile[language=Verilog]{helloworld.v}{A hello világ program}{helloworld.v}

\end{document}

enter image description here

Source of the listing: http://www.asic-world.com/verilog/first1.html

See Explanations about \begingroup\edef\x{\endgroup for an explanation of the trick.

1
  • I do use \lstset in \MESetListingFormat directly. I do work on multi-language document, and I want to do a uniform look for the listings (the MWE is oversimplified). This default argument looks to be a better idea than adding an extra mandatory parameter.
    – katang
    Aug 20, 2014 at 17:50

You must log in to answer this question.

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