使用 lstlisting 包强调代码中以大写字母开头的单词

使用 lstlisting 包强调代码中以大写字母开头的单词

嗨,我正在使用 lstlisting 包来格式化我的 tex 文件中的 Prolog 代码。在 Prolog 中,所有变量都以大写字母开头。我想强调它们。有没有办法将所有大写字母添加到关键字列表中或调整它们的样式。我想有这样的事情:

\lstset{emph={\wordsbeginninguppercase},emphstyle=\bfseries}

我试过

\lstset{identifierstyle=\bfseries}.

这使得除了字符串之外的所有内容都变为粗体。

该解决方案也应该仅适用于实际的编程语言,字符串和注释中的大写单词不会改变。

在下面的例子中,FoundClass 和 Message 会被强调,但 Find 和 Found 不会,因为它们要么在注释中,要么在字符串中。

somerule(消息,FoundClass):-
    %查找属性
    look_for_class_with_property(找到类),
    atomic_list_concat(['找到满足属性的类:',FoundClass],Message)。

感谢您的帮助。

答案1

没有什么比这更简单的了。但是,你可以将自己的宏作为参数传递给identifierstyle并检查\lst@token标记列表以查看列表是否以大写字母开头。不过我不确定这个解决方案有多可靠。

\lstset{identifierstyle=\idstyle}

\makeatletter
\newcommand*\idstyle{%
        \expandafter\id@style\the\lst@token\relax
}
\def\id@style#1#2\relax{%
        \ifcat#1\relax\else
                \ifnum`#1=\uccode`#1%
                        \bfseries
                \fi
        \fi
}
\makeatother

我只测试了快速排序维基百科上的例子。

这个答案有点难以弄清楚它到底在做什么,所以让我试着解释一下。每当包尝试排版标识符时,它listings都会使用执行宏,而实际文本将位于令牌寄存器中。所以它所做的就是使用扩展令牌寄存器,然后进行扩展。\idstyle\lst@token\idstyle\the\lst@token\id@style

\is@style有一个分隔参数 ( #2),它将收集到\relax标记之前的所有内容。也就是说,#1将包含第一个标记,并将#2包含所有其余标记。然后,将的类别代码#1与的类别代码进行比较\relax。如果#1是控制序列,则为真,否则为假。第二个 if 检查标记是否与其自己的大写代码匹配;也就是说,它检查标记是否为大写字符。如果是,则\bfseries执行。

答案2

把这个放在这里是因为有同样的问题,发现了这个问题并使用了已接受答案中的代码,但随后对其进行了扩展;可能对其他人有用

这是一个使用LaTeX3 的实验性正则表达式。当然,这对于这个问题来说有点过分了,但通过将标记与正则表达式进行匹配,它的功能就强大得多。在这里,我使用它来区分 camelCase 和 snake_case 标识符。

\documentclass{article}
\usepackage{listings,xparse,l3regex}

\ExplSyntaxOn

% compile the expression
\regex_new:N \l_pascal_camelcase_regex
\regex_set:Nn \l_pascal_camelcase_regex { ^ [a-z]* [A-Z]+ [a-zA-Z]* $ } 

% a variant that expands the input fully
\cs_generate_variant:Nn \regex_match:NnTF {No}

\NewDocumentCommand \ifcamelcase { m m }
{
    % expand to actual underscore
    \cs_set_eq:Nc \__pascal_camelcase_um { lst@um_ }
    \tl_set:cn { lst@um_ } { _ }
    % match the current token
    \regex_match:NoTF \l_pascal_camelcase_regex {\the\use:c{lst@token}} {#1} {#2}
    % reset
    \cs_set_eq:cN { lst@um_ } \__pascal_camelcase_um
}

\ExplSyntaxOff

\lstset{
    alsoletter={?_},
    columns=fullflexible,
    identifierstyle=\ifcamelcase{\bfseries}{\itshape}
}

\begin{document}

\begin{lstlisting}
thisIsCamelCase
UppercaseCamel
this_is_snake_case
Uppercase_Snake
_
\end{lstlisting}

\end{document}

我们\lst@um_在扩展令牌之前重新定义以避免这个错误:

./snakecase.tex:37: Extra \else.
\lst@PrintToken ...@Output \lst@letterfalse \else 
                                                  \lst@OutputOther \let \lst...
l.37 _

结果:

两行粗体,后接两行斜体

相关内容