TeX - LaTeX Asked by user220694 on August 30, 2021
I want to use a character replacement function from Lua in LuaTeX. The following is a first attempt and an adaptation from an example in chickenize
, but it doesn’t work for content inside boxes in TeX logo nor ligatures. What is the right way to implement such a replacement?
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}
I made the same question with an unregistered account and I cannot access to my original question anymore so I’m asking again.
Here is an approach using tokcycle
to cycle through the tokens in the monotone
pseudo-environment. Anything catcode 11 is replaced with e
. Any numerical digit is replaced with 0
. Code can be escaped with balanced |...|
to avoid the above substitutions, such as begin{|equation|}
, otherwise it gets transliterated as begin{eeeeeeee}
. Macros and spaces are passed through untouched. Arguments to macros (i.e., groups) are processed through the transliterator.
Obviously, things like section numbers and equation numbers are untouched, because they do not appear as explicit glyphs in the LaTeX input.
In the MWE, I typeset a savebox
early on and then use it later in the document. As can be seen, the transliteration is applied inside the box, as well.
documentclass{article}
usepackage{tokcycle}
tokcycleenvironmentmonotone
{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}}
newsaveboxmybox
begin{document}
monotone
section{This is section before #2}
saveboxmybox{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}
Answered by Steven B. Segletes on August 30, 2021
You approach was on the right track but you forgot to recursively descend into sublists. Another issue is that pre_linebreak_filter
runs only after hyphenate
and ligaturing
have already been applied, so to replace characters before they are ligatured, you have to hook into ligaturing instead. To process display math material you additionally have to hook into mlist_to_hlist
. Since we are not interested in the actual math list, but only the typeset result, we may also use the post_mlist_to_hlist_filter
which only receives the resulting 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*}
newsaveboxmybox
begin{document}
section{This is section before #2}
saveboxmybox{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}
Answered by Henri Menke on August 30, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP