![如何在 LuaTeX 中自动设置连字参数?](https://linux22.com/image/327025/%E5%A6%82%E4%BD%95%E5%9C%A8%20LuaTeX%20%E4%B8%AD%E8%87%AA%E5%8A%A8%E8%AE%BE%E7%BD%AE%E8%BF%9E%E5%AD%97%E5%8F%82%E6%95%B0%EF%BC%9F.png)
在下面的例子中,我们需要用连字符连接“aa-aa”,但不需要连接“bbbb”。
righthyphenmin=2
如果单词的所有字母都是“a”,如何自动设置,并在所有其他情况下保持默认值?
\language255
%\righthyphenmin=2
\hyphenation{aa-aa}
\hyphenation{bb-bb}
\parindent=0pt
\hsize=1pt
\hfuzz=100pt
aaaa
bbbb
\bye
LuaTeX 有tex.righthyphenmin
。并且在文章中LuaTEX:如何写一个段落在“插入可自由支配项”部分中,提到了hyphenate
回调。是否可以使用这些功能来解决此问题?
答案1
这里有一些完整的示例,它加载所请求语言的连字模式,并可以从字符 unicode 值中检测使用的语言。
languages.lua
使用简单的Lua库:
kpse.set_program_name "luatex"
local M = {}
local languages = require "language.dat"
M.languages = languages
local ranges = {default = "english"}
local function load_patterns(pat)
if not pat then return "" end
local fname = kpse.find_file(pat)
if not fname then return "" end
local file = io.open(fname, "r")
local patterns = file:read("*all")
file:close()
return patterns or ""
end
function M.get_lang(l)
local language = languages[l]
if not language then return nil end
local id= language.id
-- English is built in
if l == "english" then id = 0 end
if id then return language end
local langobj = lang.new()
id = lang.id(langobj)
local patterns = load_patterns(language.patterns)
lang.patterns(langobj,patterns)
language.id = id
languages[l] = language
return language
end
local function convert_num(num)
if type(num) == "number" then return num end
return tonumber(num, 16)
end
function M.add_range(lang, min, max)
print("add range", lang, min, max)
ranges[#ranges+1] = {lang = lang, min = convert_num(min), max = convert_num(max)}
end
function M.default(lang)
ranges.default = lang
end
function M.test_range(ucode)
for _,v in ipairs(ranges) do
local min = v.min
local max = v.max
if ucode >= min and ucode <= max then
return v.lang
end
end
return ranges.default
end
return M
该库加载文件language.dat.lua
,该文件是包含有关语言的各种信息的表格:
['russian'] = {
loader = 'loadhyph-ru.tex',
lefthyphenmin = 2,
righthyphenmin = 2,
synonyms = { },
patterns = 'hyph-ru.pat.txt',
hyphenation = 'hyph-ru.hyp.txt',
},
有用的信息是patterns
和righthyphenmin
字段。我们必须使用lang.patterns
函数加载模式,才能使连字符起作用。
我们需要一些来自 TeX 的辅助宏minilang.tex
:
\directlua{
languages = require "languages"
}
\def\loadlang#1{%
\directlua{languages.get_lang "#1"}%
}
\def\definerange#1#2#3{%
\directlua{languages.add_range("#1","#2","#3")}%
}
\def\defaultrange#1{\directlua{languages.default "#1"}}
\directlua{
local GLYF = node.id("glyph")
local uchar = unicode.utf8.char
function show_nodes (head)
for item in node.traverse(head) do
local i = item.id
if i == GLYF then
local langname = languages.test_range(item.char)
local l = languages.get_lang(langname) or {}
item.lang = l.id
item.right = l.righthyphenmin
item.left = l.lefthyphenmin
end
% texio.write(i .. " ")
end
return head
end
luatexbase.add_to_callback("hyphenate",
function (head, tail)
head = show_nodes(head)
% tex.righthyphenmin=2
lang.hyphenate(head)
return head
end, "find script")
luatexbase.add_to_callback("pre_linebreak_filter", function(head)
for n in node.traverse(head) do
if n.id == GLYF then
print(uchar(n.char), n.lang, n.right)
end
end
return head
end, "print nodes")
}
宏\loadlang
定义新语言,\definerange
定义语言的 unicode 范围并\defaultrange
定义当字符与定义的范围不匹配时要使用的语言。
hyphenate
使用了来自测试文件的修改后的回调,我们用languages.test_range(item.char)
它来获取角色的语言,然后加载语言数据并将节点和字段languages.get_lang
设置为语言数据中的正确值。lang
right
一些完整的样本:
\nopagenumbers
\input luaotfload.sty
\font\libertine= {Linux Libertine O} at 10pt
\libertine
\input minilang.tex
\loadlang{russian}
\loadlang{english}
\definerange{russian}{0400}{052F}
\defaultrange{english}
\wlog{the language: \the\language}
%\righthyphenmin=2
\hyphenation{aa-aa}
\hyphenation{bb-bb}
\parindent=0pt
\hsize=6em
\hfuzz=100pt
The development of Cyrillic typography passed directly from the medieval stage to the late Baroque, without a Renaissance phase as in Western Europe. Late Medieval Cyrillic letters (still found on many icon inscriptions today) show a marked tendency to be very tall and narrow, with strokes often shared between adjacent letters.
Peter the Great, Czar of Russia, mandated the use of westernized letter forms in the early 18th century. Over time, these were largely adopted in the other languages that use the script. Thus, unlike the majority of modern Greek fonts that retained their own set of design principles for lower-case letters (such as the placement of serifs, the shapes of stroke ends, and stroke-thickness rules, although Greek capital letters do use Latin design principles), modern Cyrillic fonts are much the same as modern Latin fonts of the same font family. The development of some Cyrillic computer typefaces from Latin ones has also contributed to the visual Latinization of Cyrillic type.
Около 863братья Константин (Кирилл) Философ и Мефодий из Солуни (Салоники) по приказу византийского императора Михаила III упорядочили письменность для старославянского языка и использовали новую азбуку для перевода на славянский язык греческих религиозных текстов[2]:44. Долгое время дискуссионным оставался вопрос, была ли это кириллица (и в таком случае глаголицу считают тайнописью, появившейся после запрещения кириллицы) или глаголица — азбуки, различающиеся почти исключительно начертанием. В настоящее время в науке преобладает точка зрения, согласно которой глаголица первична, а кириллица вторична (в кириллице глаголические буквы заменены на известные греческие). Так, большинство учёных склонны считать, что глаголицу создал Константин (Кирилл) Философ, а кириллицу — его ученик Климент Охридский[3]. Глаголица длительное время в несколько изменённом виде употреблялась у хорватов (до XVII в).
bbbb
\bye
我们必须使用luaotfload
合适的 opentype 字体来获取西里尔文。重要的部分是:
\input minilang.tex
\loadlang{russian}
\loadlang{english}
\definerange{russian}{0400}{052F}
\defaultrange{english}
定义 unicode 范围内的字符 0400..052F
以使用俄语。要使用的值\definerange
可以在unicode 块文档。
结果:
答案2
以下代码按要求工作:
callback.register("hyphenate",
function (head, tail)
for item in node.traverse(head) do
if item.id == node.id("glyph") and item.char > 1025 and item.char < 1105 then
item.right=2
end
end
lang.hyphenate(head)
end)