我正在尝试使用该listings
包来格式化自定义语言,但遇到了分隔符问题。
我需要将以“C”开头、后跟一个或多个空格的任何行标记为注释。以“C”开头且任何非空格字符的行都算作有效代码,不应被注释。
\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\lstset{%
basicstyle=\small\ttfamily,
frame=single,
morecomment=[f][\color{red}][0]{C\ },
}
\begin{document}
\begin{lstlisting}
C FM184 0.03827 100 51
C21 -0.95 -0.9 -0.85 -0.8 -0.75 -0.7 -0.65 -0.6 -0.55 -0.5 &
C This is cos(theta) in one-degree increments from 180 to 0 degrees
C
C Error in previous computation - now corrected here
C -----------------------------------------------------------------
\end{lstlisting}
\end{document}
我的 MWE 让我接近,但无法注释掉仅包含分隔符本身的行,即使有多个尾随空格。
但是,将我的分隔符切换为其他变体,例如
morecomment=[f][\color{red}][0]{C },
morecomment=[f][\color{red}][0]{C},
导致这些行被注释,但是任何以“C”开头的行都会被注释掉:
我尝试在分隔符中添加换行符,但这会导致编译崩溃。我不希望通过在“C”行中添加字符来打断我的空白行,只是为了让它们被注释。有人能给我指出正确的方向吗?
答案1
有点晚了,但这里有一个解决方案,也可以修复空注释行。
当 TeX 从输入文件中读取一行时,它会删除行尾出现的所有显式空格字符(字符代码 32)。这是内部发生的,无法通过更改 catcode 或其他技巧来绕过。因此,您的输入行
C␣␣␣<newline>
将被listings
视作
C<newline>
因此,您匹配的评论在C\
这里不起作用。
literate
然而,我们可以做的是为C<newline>
(在 TeX 中)添加匹配项,如果它出现在输入行的第一列,则将C\^^M
相应的颜色染成红色,否则仅输出正常内容。C
C
这种方法的问题在于,listings
然后就看不到行尾字符了,因为它被处理吞噬了literate
,从而阻止了换行的正常工作。因此,每当找到匹配的空注释行时,我们都必须模拟换行。为了指示这种假换行,我们使用一个开关,\iflst@fakeEOL
该开关在调用时设置,并在输出任何标记后literate
在钩子中检查。如果设置,我们会发出,这是每次正常换行时发生的略微修改的版本。在钩子中,每次开始一行时都会重置开关。PostOutput
\lst@fakeEOL
InitVarBOL
完整示例代码:
\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\makeatletter
\newif\iflst@fakeEOL
\lst@AddToHook{PostOutput}{%
\iflst@fakeEOL
\aftergroup\lst@fakeEOL
\fi
\global\lst@fakeEOLfalse
}
\lst@AddToHook{InitVarBOL}{%
\global\lst@fakeEOLfalse
}
\newcommand\lst@fakeEOL{%
\lst@EOLUpdate \lsthk@InitVarsBOL
\global\advance\lst@lineno\@ne
\ifnum \lst@lineno>\lst@lastline
\lst@ifdropinput \lst@LeaveMode \fi
\ifx\lst@linerange\@empty
\expandafter\expandafter\expandafter\lst@EndProcessListing
\else
\lst@interrange
\lst@GetLineInterval
\expandafter\expandafter\expandafter\lst@SkipToFirst
\fi
\else
\expandafter\lst@BOLGobble
\fi
}
\lstset{%
basicstyle=\small\ttfamily,
numbers=left,
numberstyle=\ttfamily\footnotesize\color{gray},
morecomment=[f][\color{red}][0]{C\ },
literate=*{C\^^M}{\empty@line@comment}1
}
\newcommand\empty@line@comment{%
\lst@CalcColumn
\ifnum\@tempcnta>1
C%
\else
\textcolor{red}{C}%
\fi
\global\lst@fakeEOLtrue
}
\makeatother
\begin{document}
%\tracingmacros=2
\begin{lstlisting}
C FM184 0.03827 100 51
C FM184 0.03827 100 51
C21 -0.95 -0.9 -0.85 -0.8 -0.75 -0.7 -0.65 -0.6 -0.55 -0.5 &
C This is cos(theta) in one-degree increments from 180 to 0 degrees
C
C Error in previous computation - now corrected here
C -----------------------------------------------------------------
C
CC
C C
CCC C
\end{lstlisting}
\end{document}
输出