我正在尝试在包中创建一个语言定义listings
,以精确模仿 Windows 版 POV-Ray 3.6 中的语法高亮显示(http://www.povray.org/download/)。下面是 POV 的截图,我试图模仿它:
(包中的POV语言定义listings
不一样。)
下面列出了我迄今为止的尝试,但它存在一些缺陷。首先,尽管我尝试过,但我还是无法让它将数字变成绿色。其次,尽管我尝试过,但我还是无法让它将尖括号(或其他运算符)变成红色。相比之下,我尝试让花括号显示为蓝色,效果很好,尽管它与尖括号问题/解决方案相似。我显然做错了什么,但阅读软件包的参考手册listings
并没有消除我的困惑。
这是我的错误结果的一个例子:
有小费吗?
\documentclass[12pt]{article}
\usepackage{listings}
\usepackage{color}
\definecolor{povcodered}{rgb}{0.75,0.25,0.25}
\definecolor{povcodegreen}{rgb}{0.25,0.75,0.25}
\definecolor{povcodeblue}{rgb}{0.25,0.25,0.75}
\definecolor{povcodepurple}{rgb}{0.5,0,0.35}
\definecolor{povcodebluegreen}{rgb}{0,0.5,0.5}
\lstdefinelanguage{myPOV}{
alsoletter={\#\{\}\<\>},
keywords={
sphere, cone, and, so, on,
\#include, \#declare, \#version},
keywords={[2]\{,\}},
keywords={[3]\<,\>},
sensitive=true,
string=[b]{"},
comment=[l]{//},
morecomment=[s]{/*}{*/}}
\lstset{language=myPOV,
basicstyle=\ttfamily\bfseries,
keywordstyle=\color{povcodepurple},
keywordstyle=[2]\color{povcodeblue},
keywordstyle=[3]\color{povcodered},
stringstyle=\color{povcodered},
commentstyle=\color{povcodegreen},
numberstyle=\color{povcodebluegreen}}
\begin{document}
\begin{lstlisting}
#include "somefile.inc"
// now let's add a shape
sphere {
<0,0,0>, 1
translate <5,3,2>
}
\end{lstlisting}
\end{document}
答案1
基于你自己回答,看来您已经快完成了。剩下的最后一个问题是突出显示/
和//
不同之处,并确保//
开始注释。
如何以不同方式突出显示/
(//
不破坏注释)
正如您所注意到的,任何文字替换/
都会阻止您在注释分隔符中使用它;因此,您必须采用文字替换 以外的其他方法/
。下面代码中显示的方法解决了该问题。
警告:如果//
前面紧接着一个listings
被视为“其他”的字符(例如*//
),//
仍然会开始注释,但不会在注释样式中突出显示。
附注:不要将{
and定义}
为“字母”
{
通过以下方式将和定义}
为“字母”
alsoletter = {\{\}},
不是一个好主意,至少对你的情况来说是这样。下面是它可能出错的地方的示例:listings
如果它遇到字符序列(请注意和sphere{
之间没有空格),它会将其识别为sphere
{
单身的标识符;该sphere
部分不会被识别为关键字,因此不会突出显示。这里,最好使用{
和的文字替换。}
\documentclass{article}
\usepackage[T1]{fontenc} %<--- for nice braces in typewriter font
\usepackage{lmodern}
\usepackage{listings}
\usepackage{xcolor}
\lstdefinelanguage{myPOVlanguage}
{
alsoletter = {\#},
keywords =
{
\#include, \#declare, \#version,
assumed_gamma,
background, box,
camera, color, color_map, cone, cylinder,
direction,
function,
global_settings, gradient,
light_source, location, look_at,
matrix,
no_shadow,
object,
pigment, pow,
rgb, right, rotate,
scale, sphere,
translate,
x, y, z,
},
sensitive = true,
string = [b]{"},
comment = [l]{//},
morecomment = [s]{/*}{*/},
}
% --- color definitions ---
\definecolor{povcodered}{rgb}{0.75,0.25,0.25}
\definecolor{povcodegreen}{rgb}{0.25,0.75,0.25}
\definecolor{povcodeblue}{rgb}{0.25,0.25,0.75}
\definecolor{povcodepurple}{rgb}{0.5,0,0.35}
\definecolor{povcodebluegreen}{rgb}{0,0.5,0.5}
\lstdefinestyle{myPOVstyle}
{
language = myPOVlanguage,
frame = single,
framextopmargin = 3mm,
framexbottommargin = 3mm,
basicstyle = \ttfamily\bfseries,
keywordstyle = \color{povcodepurple},
stringstyle = \color{povcodered},
commentstyle = \color{povcodegreen}\itshape,
literate =*
{0}{{{\color{povcodebluegreen}0}}}1
{1}{{{\color{povcodebluegreen}1}}}1
{2}{{{\color{povcodebluegreen}2}}}1
{3}{{{\color{povcodebluegreen}3}}}1
{4}{{{\color{povcodebluegreen}4}}}1
{5}{{{\color{povcodebluegreen}5}}}1
{6}{{{\color{povcodebluegreen}6}}}1
{7}{{{\color{povcodebluegreen}7}}}1
{8}{{{\color{povcodebluegreen}8}}}1
{9}{{{\color{povcodebluegreen}9}}}1
{+}{{{\color{povcodered}+}}}1
{-}{{{\color{povcodered}-}}}1
{*}{{{\color{povcodered}*}}}1
{<}{{{\color{povcodered}<}}}1
{>}{{{\color{povcodered}>}}}1
{\{}{{{\color{povcodeblue}\{}}}1
{\}}{{{\color{povcodeblue}\}}}}1
}
% --- patch to get proper highlighting of / and // ---
\makeatletter
\lst@AddToHook{OutputOther}
{%
\edef\@tempa{\the\lst@token\relax}%
%
% apply \color{povcodered} if / is found
\expandafter\expandafter\expandafter\ifx\expandafter\@firstoftwo\@tempa/%
\def\lst@thestyle{\color{povcodered}}%
%
% apply comment style if // is found
\expandafter\expandafter\expandafter\ifx\expandafter\@secondoftwo\@tempa/%
\def\lst@thestyle{\lst@commentstyle}%
\fi
\fi
}
\makeatother
\lstset{style=myPOVstyle}
\begin{document}
\begin{lstlisting}
#include "somefile.inc"
// now let's add a shape
sphere {
<0,0,0>, 1
translate <5,3,2>
sdf/sdf
}
\end{lstlisting}
\end{document}
答案2
我认为我已经基本回答了自己的问题。通过阅读其他一些相关问题,我拼凑了以下 POV 语言定义文件,它可以完成我想要的大部分工作,或者至少具有足够的可扩展性,在完成开发后可以完成我想要的大部分工作。
关键的解决办法是,以一种并非真正预期用途的方式使用literate
它,而只是将其作为一种通用机制,用于用任何其他字符序列替换任何字符序列。这允许我选择特定的数字、运算符等,并为它们分配颜色。
这是 POV 代码,它并不完整(不是所有的运算符和关键字),但当我遇到不在此列表中的新运算符和关键字时,我会对其进行扩展。你明白了。代码如下。
有一件事不是但此方法解决的问题是,单行注释的双斜线现在被视为两个相邻的单斜线,因此不再存在单行注释。这似乎凌驾于literate
其他一切之上。因此,这个问题仍然存在。
\lstdefinelanguage{myPOV}{
alsoletter={\#\{\}},
keywords={
sphere, cone, cylinder, box, object,
rotate, translate, scale, matrix,
camera, location, direction, right, look_at,
pigment, gradient, color_map, color, rgb,
x, y, z, pow, function,
light_source, background, no_shadow,
global_settings, assumed_gamma,
\#include, \#declare, \#version},
keywords={[2]\{,\}},
sensitive=true,
string=[b]{"},
comment=[l]{//},
morecomment=[s]{/*}{*/},
literate=%
*{0}{{{\color{povcodebluegreen}0}}}1
{1}{{{\color{povcodebluegreen}1}}}1
{2}{{{\color{povcodebluegreen}2}}}1
{3}{{{\color{povcodebluegreen}3}}}1
{4}{{{\color{povcodebluegreen}4}}}1
{5}{{{\color{povcodebluegreen}5}}}1
{6}{{{\color{povcodebluegreen}6}}}1
{7}{{{\color{povcodebluegreen}7}}}1
{8}{{{\color{povcodebluegreen}8}}}1
{9}{{{\color{povcodebluegreen}9}}}1
{+}{{{\color{povcodered}+}}}1
{-}{{{\color{povcodered}-}}}1
{*}{{{\color{povcodered}*}}}1
{/}{{{\color{povcodered}/}}}1
{<}{{{\color{povcodered}<}}}1
{>}{{{\color{povcodered}>}}}1}
\lstset{language=myPOV, frame=single,
basicstyle=\ttfamily\bfseries,
keywordstyle=\color{povcodepurple},
keywordstyle=[2]\color{povcodeblue},
stringstyle=\color{povcodered},
commentstyle=\color{povcodegreen},
framextopmargin=3mm,
framexbottommargin=3mm
}