Migrating from XeTeX to LuaTeX
Draft
Improve this page! Feel free to draft a pull request on GitHub.
In many languages and scripts, particularly Latin, Greek and Cyrillic,
a document written for xetex should work with luatex without
changes.
See also the companion guide Migrating from pdfTeX to LuaTeX if you are switching from pdfTeX.
It is worth noting that, contrary to what is sometimes assumed, the use
of luatex does not require any programming knowledge in Lua (only
certain advanced functions not available in other engines).
Fonts
By default, the font renderer in xetex is Harfbuzz (the only
available). With luatex the default renderer was Node, but in
version
≥24.14
is Harfbuzz, except scripts of the ‘Greek family’ (including Latin and
Cyrillic). So, in versions ≤24.13 you may need to
replace something like
\babelfont{rm}{FreeSerif}
with
\babelfont{rm}[Renderer=Harfbuzz]{FreeSerif}
RTL scripts
The xetex and luatex models are quite different (actually, xetex
lacks a true RTL model). The main change is to replace the package
option bidi=bidi with bidi=basic. If you were using bidi=default,
no change is necessary.
Note xetex only ‘reverses’ the text, while luatex ‘reverses’ also
margins, columns, and so on, so with these elements expect different
results.
Mapping
This font feature is not available in luatex, but it can be replaced
advantageously with
transforms. There are
already some transforms to transliterate a few languages. Native digits
are already handled by babel out of the box.
In some cases, a better option are font features, but there aren’t
available with Harfbuzz. (However,
‘constructors’ are,
although they can be cumbersome.) As a reference, here are some basic
patterns taken from luaotfload (lowercase means ‘from’ and uppercase
‘to’; note the ligature type is, in some sense, ‘reversed’). See sec.
15 in Font
extensions
for further info (focused on context, but pure Lua examples are valid
in lualatex):
fonts.handlers.otf.addfeature {
name = "stest",
type = "substitution",
data = {
a = "X",
b = "P",
}
}
fonts.handlers.otf.addfeature {
name = "mtest",
type = "multiple",
data = {
a = { "X", "Y" },
b = { "P", "Q" },
}
}
fonts.handlers.otf.addfeature {
name = "ltest",
type = "ligature",
data = {
X = { "a", "b" },
Y = { "d", "a" },
}
}
fonts.handlers.otf.addfeature {
name = "ktest",
type = "kern",
data = {
a = { b = -500 },
}
}
‘Interchar’ mechanism
It can be replaced with transforms, too.
The package ucharclasses can be replaced in most cases with the
babel option onchar. The latter, unlike the former, works with RTL
scripts.