我正在使用lstlisting
,并尝试在标识上添加垂直线,就像您使用包所做的那样algorithm
,但我找不到方法来实现它。
这真的可能吗?因为我没有找到任何关于此的帖子。
答案1
这是可以做到的,但我还没有找到任何自动完成的方法。
为了实现这一点,我定义了一个自定义命令来添加垂直标尺,然后在每次缩进后手动将其插入到代码中。这项工作很繁重,但确实达到了预期的效果。
清单内的代码格式如下:
new Thread(new Runnable() {
?\indentrule?@Override
?\indentrule?public void run() {
?\indentrule? ?\indentrule?System.out.println("Hello world!");
?\indentrule?}
}).start();
我定义了indentrule
一个简单的命令vrule
,并在其后添加了 2pt 的水平间距,以便将标尺移离实际代码一小段距离。在这里,我还为标尺使用了自定义颜色,这样它们就不会在列表中造成太多噪音。这导致以下命令:
\newcommand{\indentrule}{\color{code_indent}\vrule\hspace{2pt}}
使用该包定义颜色color
如下:
\definecolor{code_indent}{HTML}{CCCCCC}
定义列表时,您需要确保设置了转义字符,这样您就可以在列表中使用 latex 命令。在这种情况下,我使用了问号字符,但可以使用任何有效的转义字符来替换它。要设置转义字符,您应该使用escapechar
环境参数lstlisting
。例如在这种情况下:escapechar=?
。
答案2
自动化@FHannes答案的一种方法是使用LuaLaTeX预处理代码以添加缩进规则。在下面,我预处理整个文件因为在进行缓冲区处理时,尾随空格已被删除,但我们希望保留它们以进行缩进。
这里的主要任务是用缩进规则替换双倍空格。
在indentrule.lua
:
function add_indentrule(filename)
-- A table containing a "reader" function for reading a line.
local ret = {}
ret.file = io.open(filename)
ret.reformat = false
ret.reader =
function(t)
local line = t.file:read()
if line == nil then return line end
if (string.match (line, "begin{lstlisting}.*#i")) then
ret.reformat = true
return line:gsub ('#i', '')
elseif (string.match (line, "end{lstlisting}")) then
ret.reformat = false
return line
else
if (ret.reformat) then
return line:gsub(' ', '$\\indentrule$ ')
else
return line
end
end
end
return ret
end
luatexbase.add_to_callback('open_read_file', add_indentrule, 'add_indentrule')
假设您的主文件是main.tex
,我们现在必须编译master.tex
包含以下内容的文件:
\directlua{dofile('indentrule.lua')}
\input{main.tex}
现在如果main.tex
包含:
\documentclass{article}
\usepackage{listings,xcolor}
\newcommand{\indentrule}{\color{gray}\rlap{\smash{\hspace{6pt}\rule[-.35em]{1pt}{1.45em}}}}
\begin{document}
\lstset{mathescape=true}
\begin{lstlisting}#i
void f() {
if (i == 0) {
lorem;
while (true) {
check;
}
}
return test;
}
\end{lstlisting}
\end{document}
输出为: