与上一个问题相关(在 LuaLaTeX 中进行标记过滤时如何避免 TeX 环境?),我一直在尝试创建一个使用 Lua 来审查文本的包(尽管它还处于早期阶段,并且需要做大量工作才能信任敏感信息)。
但是,我一直难以让软件包过滤 TeX 数学命令,因为数学模式似乎完全取代了原本强大的toks
过滤器。有没有办法克服下面出现的问题?
\documentclass{article}
\usepackage{luacode}
\newcommand{\onething}{ • }
\begin{luacode}
--fulsome thanks to TeX.SE users Henri Menke and David Carlisle, without whom none of this would be possible
local function rndstring()
local toks = token.scan_toks(s)
local on = true
for n, t in ipairs(toks) do
if on and t.cmdname == "letter" or t.cmdname == "other_char" then
local letter = token.create'onething'
toks[n] = letter
end end
--Drop the token in and move on
token.put_next(toks)
end
local lft = lua.get_functions_table()
--make a global command
lft[#lft + 1] = rndstring
token.set_lua("rndstring", #lft, "global")
\end{luacode}
\begin{document}
\rndstring{Test of a thing 1234}
$\epsilon \gamma \delta \div 1234$
\end{document}
答案1
这个答案确实不是回答了你的问题的关键,“我如何使用 Lua toks 过滤数学?”。然而,它确实解决了审查文本的问题,包括数学。
我的censor
包(可以在 pdflatex 中运行)最近进行了改进 [2022-02-09],以处理\blackout
和\xblackout
的参数令牌循环(tokcycle
详情请参阅软件包)。此重做提供了解决标记流中宏被审查的可能性的能力。尽管如此,没有考虑直接处理数学,尽管可以找到几种解决方法。
然而,在此回答中,我扩展了改进后的功能\blackout
,以尝试以更自动化的方式解决数学审查问题。应注意以下几点:下标/上标参数必须位于明确的括号使审查起作用;不需要审查的文本(例如,环境名称)必须使用tokcycle
将转义文本括在|
标记之间的方法进行转义(默认情况下);因为审查本质上是基于文本的,所以审查的下标/上标将以文本大小(而不是脚本大小)显示,这可能会影响间距。
我将考虑将这些方面的更改纳入到软件包的未来版本中censor
。
\documentclass{article}
\usepackage{censor}[2022-02-09]
\makeatletter
\xtokcycleenvironment\blackoutenv
{\ifx.##1\@dump\censored@word\addcytoks[1]{\censordot}\else
\ifx$##1\@dump\censored@word\addcytoks{##1}\else
\ifx^##1\@dump\censored@word\addcytoks{##1}\else
\ifx_##1\@dump\censored@word\addcytoks{##1}\else
\@append\censored@word{##1}%
\tcpeek\@next\ifx\@next\@tcEscapeptr\@dump\censored@word
\fi\fi\fi\fi\fi}
{\tctestifcon\ifexpandarg{\expandafter\processtoks\expandafter
{\expanded{##1}}\@dump\censored@word}{\groupedcytoks{\processtoks{##1}%
\@dump\censored@word}}\expandargfalse}
{\tctestifx{~##1}{\@append\censored@word{##1}}%
{\tctestifx{\expanded##1}{\@dump\censored@word\expandargtrue}%
{\test@chars{##1}\ifchar\ifmathgreek
\@append\censored@word{\ensuremath{##1}}\else
\@append\censored@word{##1}\fi\else
\test@accents{##1}\ifaccent\@append\censored@word{##1}\tcpop\tc@popped
\expandafter\@append\expandafter\censored@word\expandafter{\tc@popped}%
\else\@dump\censored@word\addcytoks{##1}\fi\fi}}}
{\@dump\censored@word\addcytoks{##1}}
{\stripgroupingtrue\def\censored@word{}}
{\@dump\censored@word}
\renewcommand\test@chars[1]{\charfalse\mathgreekfalse
\ifx\$#1\chartrue\else
\ifx\\chartrue\else
\ifx\##1\chartrue\else
\ifx\%#1\chartrue\else
\ifx\_#1\chartrue\else
\ifx\o#1\chartrue\else
\ifx\O#1\chartrue\else
\ifx\oe#1\chartrue\else
\ifx\OE#1\chartrue\else
\ifx\aa#1\chartrue\else
\ifx\AA#1\chartrue\else
\ifx\ae#1\chartrue\else
\ifx\AE#1\chartrue\else
\ifx\l#1\chartrue\else
\ifx\L#1\chartrue\else
\ifcensormathgreek\testmathgreek{#1}\ifmathgreek\chartrue\fi\fi%
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}
\newif\ifmathgreek
\newcommand\testmathgreek[1]{%
\ifx\alpha#1\mathgreektrue\else
\ifx\beta#1\mathgreektrue\else
\ifx\gamma#1\mathgreektrue\else
\ifx\delta#1\mathgreektrue\else
\ifx\epsilon#1\mathgreektrue\else
\ifx\varepsilon#1\mathgreektrue\else
\ifx\zeta#1\mathgreektrue\else
\ifx\eta#1\mathgreektrue\else
\ifx\theta#1\mathgreektrue\else
\ifx\vartheta#1\mathgreektrue\else
\ifx\iota#1\mathgreektrue\else
\ifx\kappa#1\mathgreektrue\else
\ifx\lambda#1\mathgreektrue\else
\ifx\mu#1\mathgreektrue\else
\ifx\nu#1\mathgreektrue\else
\ifx\xi#1\mathgreektrue\else
\ifx\pi#1\mathgreektrue\else
\ifx\varpi#1\mathgreektrue\else
\ifx\rho#1\mathgreektrue\else
\ifx\varrho#1\mathgreektrue\else
\ifx\sigma#1\mathgreektrue\else
\ifx\varsigma#1\mathgreektrue\else
\ifx\tau#1\mathgreektrue\else
\ifx\upsilon#1\mathgreektrue\else
\ifx\phi#1\mathgreektrue\else
\ifx\varphi#1\mathgreektrue\else
\ifx\chi#1\mathgreektrue\else
\ifx\psi#1\mathgreektrue\else
\ifx\omega#1\mathgreektrue\else
\ifx\Gamma#1\mathgreektrue\else
\ifx\Delta#1\mathgreektrue\else
\ifx\Theta#1\mathgreektrue\else
\ifx\Lambda#1\mathgreektrue\else
\ifx\Xi#1\mathgreektrue\else
\ifx\Pi#1\mathgreektrue\else
\ifx\Sigma#1\mathgreektrue\else
\ifx\Upsilon#1\mathgreektrue\else
\ifx\Phi#1\mathgreektrue\else
\ifx\Psi#1\mathgreektrue\else
\ifx\Omega#1\mathgreektrue
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}
\newif\ifcensormathgreek
\censormathgreektrue
\makeatother
\begin{document}
%\censormathgreekfalse
%\StopCensoring
\blackoutenv
Test of a thing 1234
$\epsilon \gamma \delta \div 1234$
\[
y \ne mx + \zeta b
\]
\begin{|equation|}
y \ne \frac{m_{1}}{m_{2}}x + b^{3}
\end{|equation|}
\endblackoutenv
\end{document}
取消注释宏后\StopCensoring
,结果变为
另一方面,如果进行审查但\censormathgreekfalse
不进行注释,则可以节省一些计算时间,如果不介意希腊字符不受审查的话: