使用 LuaTeX 替换框内的字形

使用 LuaTeX 替换框内的字形

我想在 LuaTeX 中使用 Lua 中的字符替换函数。以下是第一次尝试,也是对 中示例的改编chickenize,但它不适用于 TeX 徽标框内的内容或连字符。实现这种替换的正确方法是什么?

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
local glyph_id = node.id("glyph")
function everything_is_e(head)
    for n in node.traverse(head) do
        if n.id == glyph_id then
            n.char = 101
        end
    end
    return head
end

luatexbase.add_to_callback("pre_linebreak_filter",everything_is_e,"replace every character by e")
\end{luacode*}
\begin{document}
\textbf{\input knuth}
\end{document}

我使用未注册的帐户提出了同样的问题,并且我无法再访问我原来的问题,所以我再次提问。

答案1

你的方法是正确的,但你忘了递归地进入子列表。另一个问题是pre_linebreak_filter仅在 和 之后运行hyphenateligaturing因此要在字符被连字符之前替换它们,你必须改为连接到连字符。要处理显示数学材料,你还必须连接到mlist_to_hlist。由于我们对实际的数学列表不感兴趣,而只对排版结果感兴趣,我们还可以使用 ,post_mlist_to_hlist_filter它只接收结果hlist

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
local glyph_id = node.id("glyph")
local hlist_id = node.id("hlist")
local vlist_id = node.id("vlist")
local function everything_is_e_impl(head)
    for n in node.traverse(head) do
        if n.id == hlist_id or n.id == vlist_id then
            everything_is_e_impl(n.list)
        elseif n.id == glyph_id then
            n.char = 101
        end
    end
    return head
end

local function everything_is_e(head)
    everything_is_e_impl(head)
    -- normally you'd do
    --
    --     return node.ligaturing(head)
    --
    -- but since everything is e, applying ligatures is a bit
    -- pointless.  It also allows us to reuse this callback in
    -- post_mlist_to_hlist_filter.
    return head
end 

luatexbase.add_to_callback("ligaturing", everything_is_e, "replace every character by e")
luatexbase.add_to_callback("post_mlist_to_hlist_filter", everything_is_e, "replace every character by e")
\end{luacode*}
\newsavebox\mybox
\begin{document}
\section{This is section before \#2}

\savebox\mybox{Box content $1^{2^3}$}

This is a test 123 $y = mx_j^2$
\begin{equation}
  E = mc^2
\end{equation}
Back to \textit{italic}, \textbf{bold}, and \textsc{Small Caps} text.

\usebox{\mybox}
\end{document}

答案2

tokcycle以下是使用循环遍历伪环境中的标记的方法\monotone。任何 catcode 11 都将被替换为e。任何数字都将被替换为0。可以使用平衡转义代码|...|以避免上述替换,例如\begin{|equation|},否则将被音译为\begin{eeeeeeee}。宏和空格将原封不动地传递。宏的参数(即组)通过音译器处理。

显然,诸如章节编号和方程式编号之类的内容不受影响,因为它们不会在 LaTeX 输入中以明确的字形出现。

在 MWE 中,我\savebox先排版了 a,然后在文档中稍后使用它。可以看出,音译也应用于框内。

\documentclass{article}
\usepackage{tokcycle}
\tokcycleenvironment\monotone
{\tctestifcatnx A##1{\addcytoks{e}}%
  {\tctestifcatnx 0##1{\tctestifnum{`##1>`/}{\tctestifnum{`##1<`:}%
    {\addcytoks{0}}{\addcytoks{##1}}}%
    {\addcytoks{##1}}}{\addcytoks{##1}}}%
}
{\processtoks{##1}}
{\addcytoks{##1}}
{\addcytoks{##1}}
\newsavebox\mybox
\begin{document}
\monotone
\section{This is section before \#2}

\savebox\mybox{Box content $1^{2^3}$}

This is a test 123 $y = mx_j^2$
\begin{|equation|}
  E = mc^2
\end{|equation|}
Back to \textit{italic}, \textbf{bold}, and \textsc{Small Caps} text.

\usebox{\mybox}
\endmonotone
\end{document}

在此处输入图片描述

相关内容