lstnewenvironment/lstset:有条件地使用颜色 emph/emphstyle - SAS: (in=_x) 与 if x in (1,2)

lstnewenvironment/lstset:有条件地使用颜色 emph/emphstyle - SAS: (in=_x) 与 if x in (1,2)

我用它lstnewenvironment来为我的 SAS 数据步骤着色。我使用 emph/emphstyle 来添加新关键字(因为我没有使用 morekeyword 和 otherkeyword)。

如果我在数据集名称后使用(in=...),则应该将其视为关键字(蓝色)

如果我在(1,2)中使用 x,那么 in 不应被视为关键字。

当 in 后面跟着等号(或空白 + 等号)时,如何有条件地为其分配颜色,而当 in 后面没有等号时,如何有条件地为其分配黑色?

在此先非常感谢您的帮助。

现在我得到的唯一解决方案是使用escapeinside={(*@}{@*)},并在本地手动分配颜色。

以下是一个例子:

\documentclass[a4paper,12pt]{报告}

\usepackage{xcolor}
\usepackage{列表}
\usepackage{textcomp}

    \definecolor{sasdarkblue} {RGB}{0,0,114} %#000072
    \definecolor{sasblue} {RGB}{21,23,206} %#1517CE
    \definecolor{sasviolet} {RGB}{109,23,110} %#6D176E

\lstnewenvironment{sasdatastep}{%
\lstset{%
    basicstyle =\small\ttfamily,%
    语言=SAS,%
    keywordstyle =\color{sasblue}\ttfamily,%
    转义字符 =|,%
    escapeinside ={(*@}{@*)},%
    stringstyle =\color{sasviolet}\ttfamily,%
    显示字符串空间=false,%
    保留空间 =true,%
    敏感=false,%
    emph =[1]{运行,数据,\%宏,\%修补}, %
    emphstyle =[1]\color{sasdarkblue}\ttfamily\textbf, %
    emph =[2]{in,indsname,point,nobs},%
    风格 =[2]\color{sasblue}, %
emph =[3]{indsname,point,nobs},%
    上引号 =true%
}
}{}

\开始{文档}

\开始{sasdatastep}
數據新;
    设置一个 (in=_one)
        二 (in=_two);
跑步;

数据一;
   设置一个(其中=(x 在(1,2)中));
跑步;
\结束{sasdatastep}
\结束{文档}

答案1

这种条件语句很难与 一起使用listings。简单地说,listings它只从左到右读取(有点),因此当它匹配并突出显示 时in,它还不知道 是否=跟在它后面。

在您的示例中,该设置似乎keywordsprefix={in=}起了作用,但它具有严重的局限性:

  • 根据文档,keywordsprefix仍有缺陷。我甚至不确定它是否应该在这种情况下工作。
  • 您一次只能使用一个keywordsprefix,因此无法匹配两者in =in=有和没有空格)。

以下是一个技巧,包括匹配所有出现的in=in =,隐藏它们,然后使用正确的突出显示重新插入它们。可能有更简洁的方法来做到这一点。

\documentclass[a4paper,12pt]{report}

\usepackage{xcolor}
\usepackage{listings}
\usepackage{textcomp}

    \definecolor{sasdarkblue}   {RGB}{0,0,114}      %#000072
    \definecolor{sasblue}       {RGB}{21,23,206}    %#1517CE
    \definecolor{sasviolet}     {RGB}{109,23,110}   %#6D176E

\newcommand{\highlightIn}{%
    \textcolor{sasblue}{in}=%
}
\newcommand{\highlightInWithSpace}{%
    \textcolor{sasblue}{in} =%
}

\lstnewenvironment{sasdatastep}{%
\lstset{%
    basicstyle      =\small\ttfamily,%
    language        =SAS,%
    keywordstyle    =\color{sasblue}\ttfamily,%
    escapechar      =|,%
    escapeinside    ={(*@}{@*)},%
    stringstyle     =\color{sasviolet}\ttfamily,%
    showstringspaces=false,%
    keepspaces      =true,%
    sensitive       =false,%
    emph            =[1]{run,data,\%macro,\%mend}, %
    emphstyle       =[1]\color{sasdarkblue}\ttfamily\textbf, %
    emph            =[2]{indsname,point,nobs},%
    emphstyle       =[2]\color{sasblue}, %
emph            =[3]{indsname,point,nobs},%
    upquote         =true,%
    moredelim=**[il][\highlightIn]{in=}, % `**` is needed so that `in=` is only reinserted once
    moredelim=**[il][\highlightInWithSpace]{in\ =},
    columns=flexible % the replaced text wouldn't fit correctly with fixed columns
}
}{}

\begin{document}

\begin{sasdatastep}
data new;
    set one (in=_one)
        two (in=_two);
run;

data one;
   set one (where=(x in (1,2)));
run;
\end{sasdatastep}
\end{document}

输出:

突出显示的代码


为了扩展 daleif 的评论,其他工具如minted可能更适合这种情况。但是,在这种情况下,minted/Pygments不会考虑 的不同用途in,它每次都会突出显示。您需要一个全新的词法分析器来解决 的问题minted

相关内容