改进 listings 包中的 POV 定义

改进 listings 包中的 POV 定义

我正在尝试在包中创建一个语言定义listings,以精确模仿 Windows 版 POV-Ray 3.6 中的语法高亮显示(http://www.povray.org/download/)。下面是 POV 的截图,我试图模仿它:

correct syntax highlighting

(包中的POV语言定义listings不一样。)

下面列出了我迄今为止的尝试,但它存在一些缺陷。首先,尽管我尝试过,但我还是无法让它将数字变成绿色。其次,尽管我尝试过,但我还是无法让它将尖括号(或其他运算符)变成红色。相比之下,我尝试让花括号显示为蓝色,效果很好,尽管它与尖括号问题/解决方案相似。我显然做错了什么,但阅读软件包的参考手册listings并没有消除我的困惑。

这是我的错误结果的一个例子:

incorrect syntax highlighting

有小费吗?

\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部分不会被识别为关键字,因此不会突出显示。这里,最好使用{和的文字替换。}

enter image description here

\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
    }

相关内容