我正在使用该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=c
c=>c
literate
\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
给出以下内容: