如何从 LuaTeX process_input_buffer 回调中完全抑制一行?

如何从 LuaTeX process_input_buffer 回调中完全抑制一行?

我正在使用 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

相关内容