我是 XeLaTeX 用户,经常需要排版英语-希腊语文档。xgreek 或 polyglossia 等软件包很棒,但为了应用正确的连字规则,您必须声明属于第二语言的文本。从长远来看,这可能会变得很麻烦。
在 XeLaTeX 中我使用XeTeXinterchartoks
机制,可以让我自动更改连字规则和/或字体,而无需明确声明它们。程序涉及将 Unicode 块的字形组合在一起,然后在从一个组转换到另一个组时自动应用 tex 命令。
对于那些不熟悉XeTeXinterchartoks
,可以在xetex-参考第 13-14 页。
最近我对 Lua(La)Tex 产生了兴趣。我想知道是否有办法在 LuaTex 中实现类似的结果。正如上一个问题所指出的那样,在 LuaTeX 中没有直接类似的东西XeTeXinterchartoks
但有人提出,还有其他更有效的方法来实现同样的目标。
所以问题是
- 如何才能根据所使用的字形自动更改连字规则/字体而无需声明它们?
- 有人可以提供一个最小的工作示例或至少给我指出一些参考资料吗?
- 缺点之一
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}
不是很漂亮,但是证明这是可以做到的......