3

This is a follow-up to: How can I exclude TeX macros when counting a string's characters in Lua?

Thanks to @Henri Menke's excellent answer to that question (below), I know how to filter out macros like \textit{abc} with Lua. However, this approach below seems to break down with environments like \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}

David Carlisle
  • 757,742

1 Answers1

3

enter image description here

This sets a boolean flag and only changes letters while it is true. if \begin or \end is seen the flag is set false until a } is seen so the environment name is not mangled.

\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}

David Carlisle
  • 757,742