在 LuaTex 中,是否可以根据所使用的脚本/字形更改字体/语言?

在 LuaTex 中,是否可以根据所使用的脚本/字形更改字体/语言?

我是 XeLaTeX 用户,经常需要排版英语-希腊语文档。xgreek 或 polyglossia 等软件包很棒,但为了应用正确的连字规则,您必须声明属于第二语言的文本。从长远来看,这可能会变得很麻烦。

在 XeLaTeX 中我使用XeTeXinterchartoks机制,可以让我自动更改连字规则和/或字体,而无需明确声明它们。程序涉及将 Unicode 块的字形组合在一起,然后在从一个组转换到另一个组时自动应用 tex 命令。

对于那些不熟悉XeTeXinterchartoks,可以在xetex-参考第 13-14 页。

最近我对 Lua(La)Tex 产生了兴趣。我想知道是否有办法在 LuaTex 中实现类似的结果。正如上一个问题所指出的那样,在 LuaTeX 中没有直接类似的东西XeTeXinterchartoks但有人提出,还有其他更有效的方法来实现同样的目标。

所以问题是

  1. 如何才能根据所使用的字形自动更改连字规则/字体而无需声明它们?
  2. 有人可以提供一个最小的工作示例或至少给我指出一些参考资料吗?
  3. 缺点之一XeTeXinterchartoks是设置是全局的。LuaTeX 中是否有办法打开或关闭此功能(如果存在),从而提供更大的灵活性?

答案1

这是在 luatex 中执行等效操作的概念证明\XeTeXinterchartoks

首先,一个样式文件:

    % luatexinterchartoks.sty
\newcount\XeTeXinterchartokenstate

\newcount\charclasses
\def\newXeTeXintercharclass#1%
  {\global\advance\charclasses1\relax
   \newcount#1
   \global#1=\the\charclasses
   }

\newcount\cchone
\newcount\cchtwo

\def\dodoXeTeXcharclass
    {\directlua{setcharclass(\the\cchone,\the\cchtwo)}}

\def\doXeTeXcharclass%
   {\afterassignment\dodoXeTeXcharclass\cchtwo }

\def\XeTeXcharclass%
   {\afterassignment\doXeTeXcharclass\cchone }

\protected\def\XeTeXdointerchartoks%
   {\directlua{setinterchartoks(\the\cchone,\the\cchtwo,\the\allocationnumber)}}

\protected\def\dodoXeTeXinterchartoks%
   {\newtoks\mytoks\afterassignment\XeTeXdointerchartoks\global\mytoks }

\protected\def\doXeTeXinterchartoks%
   {\afterassignment\dodoXeTeXinterchartoks\cchtwo }

\def\XeTeXinterchartoks%
   {\afterassignment\doXeTeXinterchartoks\cchone }

\luatexdirectlua{dofile('luatexinterchartoks.lua')}

\endinput

以及匹配的lua文件:

% luatexinterchartoks.lua

charclasses = charclasses or {}

function setcharclass (a,b)
   charclasses[a] = b
end

local i = 0
while i < 65536 do
  charclasses[i]  = 0
  i = i + 1
end

interchartoks =  interchartoks or {}

function setinterchartoks (a,b,c)
   interchartoks[a] = interchartoks[a] or {}
   interchartoks[a][b] = c
end

local nc, oc
oc = 255

function do_intertoks () 
  local tok = token.get_next() 
  if tex.count['XeTeXinterchartokenstate'] == 1 then
      if tok[1] == 11 or  tok[1] == 12 then
        nc = charclasses[tok[2]] 
        newchar = tok[2]
      else 
        nc = 255
        newchar = ''
      end
      local insert  = ''
      if interchartoks[oc] and interchartoks[oc][nc] then
          insert = interchartoks[oc][nc] 
          local newtok = tok
          if insert<100 then
            local dec = math.floor(insert / 10) + 48;
            local unit = math.floor(insert % 10) + 48;
            newtok = {
              -- \XeTeXinterchartokenstate=0 \the\toks<n> \XeTeXinterchartokenstate=1
              token.create('XeTeXinterchartokenstate'),
              token.create(string.byte('='),12),
              token.create(string.byte('0'),12),
              token.create(string.byte(' '),10),
              token.create('the'),
              token.create('toks'),
              token.create(dec,12),
              token.create(unit,12),
              token.create(string.byte(' '),10),
              token.create('XeTeXinterchartokenstate'),
              token.create(string.byte('='),12),
              token.create(string.byte('1'),12),
              token.create(string.byte(' '),10),
              {tok[1], tok[2], tok[3]}}               
          end
          tok = newtok
      end
      oc = nc
  end
  return tok
end

callback.register ('token_filter', do_intertoks)

以及一份测试文档:

\documentclass{article}

\usepackage{luatexinterchartoks}
\usepackage{color}

\begin{document}

\newXeTeXintercharclass \mycharclassa
\newXeTeXintercharclass \mycharclassA
\newXeTeXintercharclass \mycharclassB
\XeTeXcharclass `\a \mycharclassa
\XeTeXcharclass `\A \mycharclassA
\XeTeXcharclass `\B \mycharclassB
% between "a" and "A":
\XeTeXinterchartoks \mycharclassa \mycharclassA = {[\itshape}
\XeTeXinterchartoks \mycharclassA \mycharclassa = {\upshape]}
% between " " and "B":
\XeTeXinterchartoks 255 \mycharclassB = {\bgroup\color{blue}}
\XeTeXinterchartoks \mycharclassB 255 = {\egroup}
% between "B" and "B":
\XeTeXinterchartoks \mycharclassB \mycharclassB = {.}

\begingroup
\XeTeXinterchartokenstate = 1
aAa A a B aBa BB
\endgroup

\end{document}

不是很漂亮,但是证明这是可以做到的......

相关内容