我正在使用 process_input_buffer 回调来查看从 LuaLaTeX 输入中读取的行,然后再将它们传递给 TeX,以“逐字”文本的形式进行处理(代码和命令示例)。输入中有一些行我根本不想传递给 TeX。如果我返回“nil”,那么 TeX 会获得原始行(如文档所述)。如果我返回一个空字符串,则 TeX 输出中会出现一个空行,而这是我不想要的。我该如何安排回调完全丢弃该行而不将任何内容传递给 TeX?
(一种明显的方法是将整个示例读入缓冲区,然后简单地删除不需要的内容,然后将整个缓冲区整体传递给 TeX。由于其他考虑,这对我来说不起作用。)
我们的想法是,在这样的环境中
\begin{example}
# foo
bar
baz
\end{example}
»#« 行不应该传递给 TeX,但其他行应该传递。(在现实世界中,»#« 行有些复杂,但会在 Lua 端进行处理。)
(与此同时,我找到了一种解决方法,基本上就是在 Lua 端的 »#« 前面插入一个 control-B 字符,并将 ^^B 声明为 fancyvrb »commentchar«,这会导致 ^^B 之后的任何内容(包括换行符)被忽略。我仍然很想知道是否有更简单的方法。)
答案1
您可以返回一个空字符串,并且如果您处于垂直模式,则不会创建任何线。
另一种方法是设置\endlinechar
并-1
返回“不传递给 TeX”的空字符串或未^^M
过滤行的缓冲区加号。
答案2
因为可以endlinechar
从 Lua 本身进行设置,所以可以这样做:
%! TEX program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
luatexbase.add_to_callback("process_input_buffer", function(line)
tex.endlinechar=13
if line=="delete this" then
tex.endlinechar=-1
return ""
end
return line
end, "delete some lines")
\end{luacode*}
\begin{verbatim}
123
456
delete this
789
012
\end{verbatim}
\end{document}
输出正如您所期望的。
坏处,
如果在该行周围放置一些特殊的 TeX 代码,它可能能够检测到值的差异
\endlinechar
。(可能只有当某些代码向前查看内部标记
\everyeof
并且该行是文件的最后一行时才会发生这种情况 - 因为该行上根本没有标记?未经测试)它假设 endlinechar 的正常值为 13。(通过记住旧值可以使其更加复杂)
答案3
我不知道你的意思缓冲 在 LuaLaTeX 中。在 ConTeXt 中,缓冲区是将数据从 TeX 传递到 lua 并返回的最佳方式。下面是一个示例(在 ConTeXt 中),它删除以 开头的行#
并使用逐字 catcodes 对环境结果进行排版。
\def\startfoo
{\dostartbuffer[foo][startfoo][stopfoo]}
\def\stopfoo
{\ctxlua{thirddata.foo.clean_lines(buffers.getcontent('foo'))}}
\startluacode
thirddata = thirddata or {}
thirddata.foo = {}
function thirddata.foo.clean_lines(content)
local result = {}
local lines = string.splitlines(content)
for i = 1, #lines do
-- Change the test with a more complicated test.
if not string.find(lines[i], '^#') then
table.insert(result, lines[i])
end
end
result = table.concat(result, '\n')
tex.sprint("\\starttyping ")
tex.sprint(result)
tex.sprint("\\stoptyping ")
end
\stopluacode
\starttext
\startfoo
# foo
bar %verbatim # environment
bar
\stopfoo
\stoptext