当模式表达式中添加“.”时,LuaTeX 会卡住

当模式表达式中添加“.”时,LuaTeX 会卡住

今天在 SE 上我受到启发尝试了 LuaTeX。

我遇到一个问题:如果我在模式匹配表达式中添加一个“。”,编译过程就会在某个时候停止。

简而言之,这是有效的:

line = string.gsub ( line , "^(%s*)"    ,   "%1" )

这不:

line = string.gsub ( line , "^(%s*)."   ,   "%1" )

(我知道这种模式没有太多意义,但它是一个较长表达式的简化版本)

编译停止于:

This is LuaTeX, Version beta-0.80.0 (TeX Live 2015/Debian) (rev 5238) 
restricted \write18 enabled.
(./mwe4.tex 
LaTeX2e <2015/01/01> patch level 2
[...]
(/usr/share/texlive/texmf-dist/tex/luatex/luatexbase/cctb.lua))
(/usr/share/texlive/texmf-dist/tex/luatex/luatexbase/luatexbase-mcb.sty
(/usr/share/texlive/texmf-dist/tex/luatex/luatexbase/mcb.lua))))  (./mwe4.aux))
*

完整的 MWE 在这里(关键行是#6):

\documentclass{article}
\usepackage{luacode,luatexbase}

\begin{luacode}
function replacetext2 ( line )    
line = string.gsub ( line , "^(%s*)"    ,   "%1" )
return ( line )
end 
\end{luacode}

\newenvironment{haystack}{%
  \directlua{luatexbase.add_to_callback(
      "process_input_buffer",
      replacetext2, "replacetext2")}}{%
  \directlua{luatexbase.remove_from_callback(
      "process_input_buffer",
      "replacetext2")}}

\begin{document}
\begin{haystack}
a
 b
\end{haystack}
\end{document}

答案1

模式^(%s*).

line = string.gsub ( line , "^(%s*)."    ,   "%1" )

在行首查找任何空格(可以为空),后跟一个字符(.)。这将被空格(%1)替换,并删除匹配的非空格字符。因此 LuaTeX 将不再看到\end{haystack},而是end{haystack}继续查找环境的结尾。

带有一些调试输出的示例,显示替换之前和之后括号中的行:

\documentclass{article}
\usepackage{luacode,luatexbase}

\begin{luacode}
function replacetext2 ( line )
  texio.write_nl('')
  texio.write('[', line, '] --> [')
  line = string.gsub ( line , "^(%s*)."    ,   "%1" )
  texio.write(line, "]")
  texio.write_nl('')
  return ( line )
end
\end{luacode}

\newenvironment{haystack}{%
  \directlua{luatexbase.add_to_callback(
      "process_input_buffer",
      replacetext2, "replacetext2")}}{%
  \directlua{luatexbase.remove_from_callback(
      "process_input_buffer",
      "replacetext2")}}

\begin{document}
\begin{haystack}
a
 b
\end{haystack}
\end{document}

结果:

[a] --> []
[ b] --> [ ]
[\end{haystack}] --> [end{haystack}]
[\end{document}] --> [end{document}]

如果只想删除行首的真正点,则需要将点转义为魔法字符%.,因为纯点.表示任何字符。

相关内容