为了简化我的合著者的一些 LaTeX 工作,我创建了一个自定义环境,它设置了一个表格。这会从环境中读取输入,对其进行处理并将其吐回到 TeX 中。我这里的问题是,在将输入传递给 Lua 之前,我似乎没有对其进行转义。下面有一个最小示例。
自定义环境中的结果是,Lua 缓冲区中存储的输入似乎缺少“\”(或者,它获取“\S”并删除了反斜杠,因为它不是可识别的转义序列)。我是否需要进行特殊调用才能让 Lua 在尝试解析文本之前对其进行转义?
顺便提一下,我在 Lua 中无法匹配环境的结束语句。我似乎只能匹配初始部分。这可能与缺少转义序列有关。
LaTeX 文件 (“document.tex”)
\documentclass[a4paper,openany,oneside]{memoir}
\usepackage{luacode}
\usepackage{siunitx}
\luadirect{dofile("env.lua")}
\newenvironment{test-env}
{
% Register the callback.
\luadirect{test_start_recording()}
}
{
% Remove the callback.
\luadirect{test_stop_recording()}
}
\begin{document}
\noindent Test document in normal TeX mode: \SI{30}{s}.
\begin{test-env}
Line 1 \\
\SI{30}{s} \\
Line 3
\end{test-env}
\end{document}
对于 lua 文件 (“env.lua”)
local end_verb_orig = "%s*\\end{test-env}"
local end_verb = "%s*\\end{"
mybuf = ""
function trim(s)
return s:match'^%s*(.*%S)' or ''
end
function test_readbuf( buf )
if buf:find(end_verb) then
return buf
end
mybuf = mybuf .. buf .. "\n"
return ""
end
function test_start_recording()
-- Register callback to catch the input.
luatexbase.add_to_callback('process_input_buffer', test_readbuf, 'test_readbuf')
end
function test_stop_recording()
-- Remove callback.
luatexbase.remove_from_callback('process_input_buffer', 'test_readbuf')
-- Print the result.
test_print()
end
function test_print()
-- Iterate over all the lines in the buffer. We match on the TeX linebreaks.
for line in mybuf:gmatch("[^\\\\]+") do
test_print_line(line)
end
-- Reset variables.
mybuf = ""
end
function test_print_line(line)
-- Trim whitespace.
line = trim(line)
-- If the line is empty, do nothing.
if line == "" then
return
end
-- Here Lua magic may happen.
-- Print the result.
tex.print(line .. "\\\\")
end
编辑
看来这是我匹配换行符的方式出了问题。texio.write(line)
按照评论中 topskip 的建议使用。