Porting the luatex/ConTeXt module "translate" to lualatex
This is more a proof-of-concept than a real bulletproof style file, but it does what you request:
The style file (filterltx.sty
)
\ProvidesPackage{filterltx}
\RequirePackage{luatexbase,luacode}
\begin{luacode*}
do
local replace = {}
local filter = function ( buf )
local start,stop,init,pos
local positions = {}
for k,v in pairs(replace) do
local init = 1
repeat
start,stop = string.find(string.lower(buf),k,init,true)
if start then
init = stop
pos = string.find(v,"|*|",1,plain)
positions[#positions + 1] = pos + start - 2
end
until start == nil
end
table.sort(positions)
for i = #positions,1,-1 do
buf = string.sub(buf,1,positions[i] ) .. [[\penalty10000\discretionary{-}{}{\kern.03em}\nobreak \hskip 0pt plus0pt minus0pt]] .. string.sub(buf, positions[i] + 1)
end
return buf
end
function enablefilter()
luatexbase.add_to_callback('process_input_buffer', filter, 'filter')
end
function disablefilter()
luatexbase.remove_from_callback('process_input_buffer', 'filter')
end
function translateinput( arg1,arg2 )
replace[arg1] = arg2
end
end
\end{luacode*}
\newcommand\enableinputtranslation{
\directlua{enablefilter()}
}
\newcommand\disableinputtranslation{
\directlua{disablefilter()}
}
\newcommand\translateinput[2]{
\directlua{translateinput("\luatexluaescapestring{#1}","\luatexluaescapestring{#2}")}
}
and the test document (test.tex
):
\documentclass{article}
\usepackage{filterltx}
\translateinput{shelfful}{shelf|*|ful}
\translateinput{selfish}{self|*|ish}
\translateinput{halflife}{half|*|life}
\translateinput{cufflink}{cuff|*|link}
\begin{document}
Ligatures not disabled:\\
shelfful selfish halflife cufflink
\medskip
\enableinputtranslation
Ligatures disabled:\\
shelfful selfish halflife cufflink\\
Shelfful Selfish Halflife Cufflink
\medskip
\disableinputtranslation
Ligatures not disabled:\\
shelfful selfish halflife cufflink
% to make sure the words still hyphenate:
% \showhyphens{shelfful selfish halflife cufflink}
% yields: shelf- ful self- ish half- life cuff- link
\end{document}
Run with lualatex test
.
The output:
The basic functionality is part of luatex. For example, the following code (in luatex plain format) changes "hello" to "hi".
\directlua{
local gsub = string.gsub
local function translate(line)
return gsub(line, "hello", "hi")
end
callback.register("process_input_buffer", translate)
}
hello world
why say hello
\bye
The ConTeXt code just provides syntax sugar so that you can easily define multiple translations. I tried to translate this code to lualatex
but in lualatex I get an error
uatexbase-mcb error: function callback.register has been trapped,
(luatexbase-mcb) please use luatexbase.add_to_callback instead.
stack traceback:
[C]: in function 'error'
.../share/texmf-dist/tex/luatex/luatexbase/modutils.lua:26: in function 'modul
e_error_int'
.../share/texmf-dist/tex/luatex/luatexbase/modutils.lua:45: in function 'err'
/usr/share/texmf-dist/tex/luatex/luatexbase/mcb.lua:85: in function 'register'
<\directlua >:7: in main chunk.
\luacode@execute ...oup \luatexbase@directlua {#1}
l.11 \end{luacode}
but I could not get the code to work with luatexbase.add_to_callback
either.
The above plain TeX code shows that basic functionality is part of luatex and should be easily accessible in lualatex
as well (once you figure out the appropriate renaming done by luacode
package).