嗨,我正在使用 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 _
结果: