传递可选参数和强制参数之间有什么区别?

传递可选参数和强制参数之间有什么区别?

我想定义一个宏来列出程序,并从可选参数中找出程序语言。我从下面的 MWE 收到的输出是

语言设置 = 'Verilog'

传递的参数是“Verilog”

因此,看起来在对 '\lstset' 的两次调用中传递了相同的参数。但是,如果参数是由可选参数而不是强制参数生成的,则会出现错误消息:“语言 Verilog 未定义”。我做错了什么?

\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}

答案1

这是一个扩展问题:当设置键时,不会执行任何扩展,因此您必须传递扩展的\pb@language宏:

\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}

但是,直接使用以下命令会更容易\lstset

\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}

在此处输入图片描述

清单来源:http://www.asic-world.com/verilog/first1.html

关于 \begingroup\edef\x{\endgroup了解这个技巧的解释。

相关内容