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}
  • 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". – Reinstate Monica - M. Schröder Aug 20 '14 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 '14 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 '14 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 '14 at 17:40
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.

  • 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 '14 at 17:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.