列表注释样式不适用于语言运算符

列表注释样式不适用于语言运算符

我正在使用该listings包在我的文档中排版一些 Haskell 和 Scala 代码,并且定义了一个名为的简单样式ttt。我将注释设置为以红色显示以进行对比,但即使是不涉及颜色的简单样式仍然存在问题。

无论我在环境中使用 Scala 还是 Haskell 都lstlistings无关紧要。无论如何,我都会遇到同样的问题,即如果注释包含相应语言的特定运算符,则注释样式不适用于它们。举一个(有点简单的)例子,假设我想注释整行代码,如下所示(为了说明,无意义的代码)。

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}

\lstloadlanguages{Scala, Haskell}
\lstdefinestyle{ttt}
               {basicstyle=\ttfamily,
               columns=flexible,
               commentstyle=\color{red},
               frame=single}

\begin{document}    
    \begin{lstlisting}[style=ttt, language=Scala, caption=Scala]
      // def addone : Int => Int = x => x + 1
      val z = 1       // def f[a](x:a) : a = g[a](x)
      // val v2 = g[Int](z)
    \end{lstlisting}

    \begin{lstlisting}[style=ttt, language=Haskell, caption=Haskell]
    -- addone :: Eq a => a -> Bool
    -- addone x = x + 1
    \end{lstlisting}
\end{document}

上面的排版如下:

结果

=和符号=>是 Haskell 和 Scala 中的特殊运算符。

我期望(并希望实现)的是,在清单 1 中,第 1 行和第 3 行应完全为红色,而在第 2 行中,//注释分隔符后的所有内容应为红色。同样,在清单 2 中,第 1 行也应完全为红色。

我遇到了错误吗?有解决方案吗?

答案1

问题似乎是在 Scala 和 Haskell 定义中=>=被定义为otherkeyword,即使关键字在注释中,它们也会被处理。这似乎是一个错误。

作为一种解决方法,您可以使用提供的钩子系统listings。有许多钩子可以在特定情况下执行代码。可以在开发人员指南在第 69 页。其中一个钩子是AfterBeginComment在注释开始时执行的。您可以使用此钩子将文本颜色设置为红色。如果注释颜色已经是红色,这似乎是多余的,但此钩子中的颜色规范设置了一般颜色(而不是专门的注释颜色)。注释结束时会自动重置颜色。

设置钩子的命令\lst@AddToHook包含一个@符号,因此调用必须被\makeatletter和包围\makeatother

梅威瑟:

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}

\lstloadlanguages{Scala, Haskell}
\lstdefinestyle{ttt}
               {basicstyle=\ttfamily,
               columns=flexible,
               commentstyle=\color{red},
               frame=single}

\makeatletter
\lst@AddToHook{AfterBeginComment}{\color{red}}
\makeatother

\begin{document}    
    \begin{lstlisting}[style=ttt, language=Scala, caption=Scala]
      // def addone : Int => Int = x => x + 1
      val z = 1       // def f[a](x:a) : a = g[a](x)
      // val v2 = g[Int](z)
    \end{lstlisting}

    \begin{lstlisting}[style=ttt, language=Haskell, caption=Haskell]
    -- addone :: Eq a => a -> Bool
    -- addone x = x + 1
    \end{lstlisting}
\end{document}

结果:

在此处输入图片描述

答案2

凭借我有限的知识,我找到了一个不完善的解决方案,需要修改环境中编写的代码lstlisting。此解决方案使用literate包的选项。不过,如果能看到一个更干净的解决方案,不需要修改代码,那就太好了。我在问题中描述的行为仍然感觉像是一个错误。

我没有在注释中使用有问题的=和符号,而是分别使用和,然后使用将它们翻译成正常的对应部分。=>c=cc=>cliterate

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}

\lstloadlanguages{Scala, Haskell}
\lstdefinestyle{ttt}
               {basicstyle=\ttfamily,
               %columns=flexible,
               commentstyle=\color{red},
               frame=single,
               literate={c=c}{=}1 {c=>c}{=>}2}

\begin{document}

    \begin{lstlisting}[style=ttt, language=Scala, caption=Scala]
      // def addone : Int => Int c=c x c=>c x + 1
      val z = 1       // def f[a](x:a) : a c=c g[a](x)
      // val v2 = g[Int](z)
    \end{lstlisting}

    \begin{lstlisting}[style=ttt, language=Haskell, caption=Haskell]
    -- addone :: Eq a c=>c a -> Bool
    -- addone x = x + 1
    \end{lstlisting}

\end{document}

不幸的是,如果columns=flexible指定了,打印的代码中的间距将不正确,但literate可以通过对条目进行不均匀的调整来恢复:

literate={c=c}{= }2 {c=>c}{=> }3

columns=flexible上述未注释且带有适配选项的乳胶代码literate给出以下内容:

在此处输入图片描述

相关内容