如何定义宏以便重用键值参数?

如何定义宏以便重用键值参数?

我使用该listings包在我的文档中排版代码。我定义了一个新环境,在\lstnewenvironment其中\lstset通过键值列表设置大量选项。它如下所示:

\lstnewenvironment{mycodebox}[1][]                                                                                                                      
{
  \lstset{
     key1=val1,
     key2=val2,
     % some more options are set
     #1 % so that it can accept more options
  }
}{}   

我主要在两个变体中使用这个新环境,每个变体中我都需要覆盖一些现有(或添加新)选项。例如:

% variant 1
\begin{mycodebox}[newkey=newval, key1=newval]
 % my code
\end{mycodebox}

% variant 2
\begin{mycodebox}[anotherkey=newval, key2=newval]
 % my code
\end{mycodebox}

这两个变体有很多共同的选项,但它们是不同的。我可以定义两个宏/命令,例如和\variant1settings\variant2settigns并可以像下面这样以某种方式使用吗?

\begin{mycodebox}[\variant1settings]
 % my code
\end{mycodebox}

我知道\lstset{options...}每次使用环境之前我都可以这样做,但是

  1. 当我没有在后续实例之前指定这些选项时,我不希望这些选项运行完毕;
  2. 我希望选项采用宏(或类似的)形式,以便可以从一个中心位置进行调整。

答案1

可选参数 #1 的内容的扩展必须推迟,否则宏\optionstocodebox将被扩展,让keyval宏认为其内容是一个完整的键名,当然事实并非如此。

使用

\begingroup\edef\x{\endgroup\noexpand\lstset{numbers=right,language={C},#1}}\x

将防止过早扩张,随后再进行扩张。

\begingroup...\endgroup是一个巧妙的技巧,让重新定义\x在扩展后被遗忘(这是}}\x

简而言之:首先阻止 \lstset 的扩展,然后通过调用来应用\x

然而,没有不可扩展的东西,例如\textbf\textcolor然而,没有微调就不允许使用或 之类的不可扩展的东西。这可以通过蛮力 \unexpanded{stuff}作为键分配。第二个示例\otheroptionstocodebox显示了方法的用法\unexpanded

\documentclass{article}

\usepackage{xcolor}
\usepackage{listings}


\lstnewenvironment{mycodebox}[1][]                                                                                                                      
{
  \begingroup\edef\x{\endgroup\noexpand\lstset{numbers=right,language={C},#1}}\x
}{}   


\begin{document}

\newcommand{\optionstocodebox}{language={Pascal},numbers=left}%



\newcommand{\otheroptionstocodebox}{language={C},numbers=left,stepnumber=3,numberstyle={\unexpanded{\color{red}\tiny}}}%


\begin{mycodebox}[language={C}]
#include<stdio.h>
int main(int argc,char **argv)
{
  printf("Hello World!\n");
}
\end{mycodebox}

\begin{mycodebox}[numbers=left,\optionstocodebox]
program first

BEGIN
WriteLn('Hello World');
END.
\end{mycodebox}


\begin{mycodebox}[language={C},\otheroptionstocodebox]
#include<stdio.h>
int main(int argc,char **argv)
{
  printf("Hello World!\n");
}
\end{mycodebox}


\end{document}

在此处输入图片描述

答案2

listings允许您定义可应用于单个列表的样式style=<stylename>

\documentclass{article}
\usepackage{listings,xcolor}
\lstdefinestyle{style1}{basicstyle=\ttfamily\color{red}}
\lstdefinestyle{style2}{basicstyle=\scshape\color{blue},frame=single}

\lstnewenvironment{mycodebox}[1][]                                                                                                                      
{
  \lstset{
     basicstyle=\itshape,
     #1
  }
}{}  

\begin{document}
\begin{mycodebox}[style=style1]
This is some text
\end{mycodebox}

\begin{mycodebox}
This is some text
\end{mycodebox}

\begin{mycodebox}[style=style2] 
This is some text
\end{mycodebox}
\end{document}

在此处输入图片描述

相关内容