将 luatex/ConTeXt 模块“translate”移植到 lualatex

将 luatex/ConTeXt 模块“translate”移植到 lualatex

这个问题几周前,我在 TeX Stack Exchange 上发布了一篇文章,其中我询问了如何自动禁用预定义单词列表中的特定连字符(例如fffiflffl)。我收到的答案基于 ConTeXt,它可以直接访问 lua(tex) 命令。特别是,@Aditya 提出的代码包括命令

\usemodule[translate]
\translateinput[halflife][half|*|life]

ConTeXt 命令\usemodule类似于 LaTeX 命令\usepackage。模块\translateinput提供的命令translate(包含在文件中m-translate.mkiv)依赖于lua函数resolvers.openers.helpers.textlineactions,该函数挂接到用于读取文件的函数中luatex。据@Aditya 所述,

没有人为 编写过类似的功能lualatex。也许,你可以将其作为一个单独的问题提出,其中一位lualatex专家将能够回答并提供解决方案。

那么,我的问题是:有人可以提供lualatex以下 ConTeXt 代码的等效内容吗(这可能涉及重写/调整模块translatelualatex

\usemodule[translate]

\translateinput[shelfful][shelf|*|ful] 
\translateinput[selfish][self|*|ish]
\translateinput[halflife][half|*|life] 
\translateinput[cufflink][cuff|*|link] 

\definetextmodediscretionary * {\prewordbreak\discretionary{-}{}%
     {\kern0.0pt}\prewordbreak}

\starttext

Ligatures not disabled:\\
shelfful selfish halflife cufflink 

\medskip
\enableinputtranslation 
Ligatures disabled:\\
shelfful selfish halflife cufflink
\stoptext

在此处输入图片描述

(请注意,虽然 0 字距分隔符似乎适合使用 CM 排版的单词 shelfful 和 selfish,但它并不完全适合和f-lff-l字。不过,我将如何定义允许对各种连字字母组合使用不同字距调整量的命令的问题留待以后再研究……)

答案1

这更像是一个概念验证,而不是真正的防弹风格文件,但它可以满足您的要求:

样式文件 ( 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}")}
}

以及测试文档(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}

用 运行lualatex test

输出:过滤输出

答案2

基本功能是 luatex 的一部分。例如,以下代码(luatex 纯格式)将“hello”更改为“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

ConTeXt 代码只是提供了语法糖,以便您可以轻松地定义多个翻译。我尝试将此代码翻译为,lualatex但在 lualatex 中我收到错误

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}

但我无法让代码正常工作luatexbase.add_to_callback

上面的纯 TeX 代码显示基本功能是 luatex 的一部分,并且lualatex也应该可以轻松访问(一旦您弄清楚了luacode包所做的适当重命名)。

相关内容