我正在尝试定义一种列表样式,以便获得看起来像 vim 样式颜色的 fortran 源代码。
例如,我想赋予end program
或end module
或double precision
等特定的颜色...
对于没有空格字符的关键字很容易,但我不知道如何对上述关键字进行操作。
正如您在下面的例子中看到的,的颜色program
是好的颜色,但是的颜色 end program
不是好的颜色。
\documentclass{article}
\usepackage{xcolor}
\definecolor{keycolor}{RGB}{172, 42, 42}
\definecolor{vimvert}{RGB}{46, 139, 87}
\usepackage{listings}
% global parameters
\lstdefinestyle{global}{
basicstyle=\ttfamily\scriptsize\color{black!90},%
stringstyle=\itshape\color{magenta},%
showstringspaces=false,%
keywordstyle=\bfseries\color{keycolor},%
commentstyle=\color{gray}\slshape,%
}
% fortran style
\lstdefinestyle{fortranstyle}{
language=Fortran,%
style=global,%
emph=[1]{implicit none, integer, real, double precision, character, len, parameter, structure, common},%
emphstyle=[1]\bfseries\color{vimvert},%
emph=[2]{program,end program, module, end module, subroutine, end subroutine, function, end function},%
emphstyle=[2]\color{violet}\bfseries\slshape,%
emph=[3]{call, true, false},%
emphstyle=[3]\color{teal}\slshape%
}
\begin{document}
\begin{lstlisting}[style=fortranstyle]
program calcPi
implicit none
integer :: i, nbreDansCercle
integer, parameter :: npts = 1000000000
double precision :: x, y, r, pi
nbreDansCercle = 0
do i = 1, npts, 1
call random_number(x)
call random_number(y)
x = 2.d0 * x - 1.d0
y = 2.d0 * y - 1.d0
r = x**2 + y**2
if (r < 1.d0) then
nbreDansCercle = nbreDansCercle + 1
end if
end do
pi = 4.d0 * dble(nbreDansCercle) / dble(npts)
write(*,"('pi = ', F20.17)") pi
end program calcPi
\end{lstlisting}
\end{document}
答案1
一种解决方案是使用moredelim
密钥(参见包装手册第 3.3 节“分隔符”)
我又定义了两个分隔符:
moredelim=[is][emphstyle]{|>}{<|}
因为implicit none
并且double precision
也不会像您可能想要定义的那样突出显示。moredelim=[is][emphstyle2]{|<}{>|}
对于end program
和end module
有一个缺点:这必须手动完成或者通过搜索替换和正则表达式完成,但仍然不能简单地从源代码复制粘贴代码或将其包含在内\lstinputlisting
。
代码
\documentclass{article}
\usepackage{xcolor}
\definecolor{keycolor}{RGB}{172, 42, 42}
\definecolor{vimvert}{RGB}{46, 139, 87}
\usepackage{listings}
% global parameters
\lstdefinestyle{global}{
basicstyle=\ttfamily\scriptsize\color{black!90},%
stringstyle=\itshape\color{magenta},%
showstringspaces=false,%
keywordstyle=\bfseries\color{keycolor},%
commentstyle=\color{gray}\slshape,%
}
% fortran style
\lstdefinestyle{fortranstyle}{
language=Fortran,%
style=global,%
emph={[1]integer, real, character, len, parameter, structure, common},%
emphstyle=[1]\bfseries\color{vimvert},%
emph={[2]program, module, subroutine, function},%
emphstyle=[2]\color{violet}\bfseries\slshape,%
emph={[3]call, true, false},%
emphstyle=[3]\color{teal}\slshape,%
moredelim=[is][emphstyle]{|>}{<|},%
moredelim=[is][emphstyle2]{|<}{>|}%
}
\begin{document}
\begin{lstlisting}[style=fortranstyle]
program calcPi
|>implicit none<|
integer :: i, nbreDansCercle
integer, parameter :: npts = 1000000000
|>double precision<| :: x, y, r, pi
nbreDansCercle = 0
do i = 1, npts, 1
end do
pi = 4.d0 * dble(nbreDansCercle) / dble(npts)
write(*,"('pi = ', F20.17)") pi
|<end program>| calcPi
\end{lstlisting}
\end{document}
输出
附言:您也可以使用moredelim=[s][emphstyle]{implicit}{none}
(请注意缺少i
),但这仅在您使用implicit
后跟时才有效none
。这同样适用于double precision
和 ,最重要的是end program
。
当它遇到 时会失败,end do
因为end
仍然是一个未找到 的分隔符program
,并且它将全部设置在 中emphstyle
。