在 LuaLaTeX 中进行标记过滤时如何避免 TeX 环境?

在 LuaLaTeX 中进行标记过滤时如何避免 TeX 环境?

这是以下问题的后续:在 Lua 中计算字符串的字符数时如何排除 TeX 宏?

感谢@Henri Menke 对该问题的出色回答(如下),我知道如何像\textit{abc}使用 Lua 一样过滤掉宏。但是,下面的这种方法似乎在这样的环境中失效了\begin{quote}...\end{quote}

\documentclass{article}
\usepackage{luacode}

\begin{luacode}
local function rndstring()
    local toks = token.scan_toks()

for n, t in ipairs(toks) do
    if t.cmdname == "letter" then
        -- random number from printable ASCII range
        local r = math.random(33, 126)
        -- create new token with that character and catcode 12
        local letter = token.create(r, 12)
        -- replace old token
        toks[n] = letter
    end
end

token.put_next(toks)
end

local lft = lua.get_functions_table()
lft[#lft + 1] = rndstring
token.set_lua("rndstring", #lft, "global")
\end{luacode}
\begin{document}
\ttfamily

\rndstring{This string works.}

\rndstring{\textit{This string works}}

\rndstring{\begin{quote}This String Does not work\end{quote}}

\end{document}

答案1

在此处输入图片描述

这会设置一个布尔标志,并且仅在为真时更改字母。如果看到\begin或,\end则该标志设置为假,直到}看到a,这样环境名称就不会被破坏。

\documentclass{article}
\usepackage{luacode}

\begin{luacode}
local function rndstring()
    local toks = token.scan_toks()
    local on = true
for n, t in ipairs(toks) do
    if t.csname == "begin" or t.csname == "end" then
       on = false
    end
   if not(on) and t.cmdname == "right_brace" then
     on = true
   end
    if on and t.cmdname == "letter" then
        -- random number from printable ASCII range
        local r = math.random(33, 126)
        -- create new token with that character and catcode 12
        local letter = token.create(r, 12)
        -- replace old token
        toks[n] = letter
    end
end

token.put_next(toks)
end

local lft = lua.get_functions_table()
lft[#lft + 1] = rndstring
token.set_lua("rndstring", #lft, "global")
\end{luacode}
\begin{document}
\ttfamily

\rndstring{This string works.}

\rndstring{\textit{This string works}}

\rndstring{\begin{quote}This String Does not work\end{quote}}

\end{document}

相关内容