1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
#!/usr/bin/env texlua
-----------------------------------------------------------------------
-- FILE: mkcharacters.lua
-- USAGE: ./mkcharacters.lua
-- DESCRIPTION: import parts of char-def.lua
-- REQUIREMENTS: lua, ConTeXt, the lualibs package
-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>
-----------------------------------------------------------------------
-- We create a stripped-down version of char-def.lua, suitable for use
-- with the generic font loader.
-----------------------------------------------------------------------
-----------------------------------------------------------------------
-- config
-----------------------------------------------------------------------
local mkivpath = arg[1]
local charfile = arg[2] or "./build/luaotfload-characters.lua"
--- for every code point char-def.lua provides a set of fields. they
--- are:
---
--- * adobename
--- * category
--- * cjkwd
--- * comment
--- * contextname
--- * description
--- * direction
--- * lccode
--- * linebreak
--- * mathclass
--- * mathextensible
--- * mathfiller
--- * mathname
--- * mathspec
--- * mathstretch
--- * mathsymbol
--- * mirror
--- * shcode
--- * specials
--- * textclass
--- * uccode
--- * unicodeslot
--- * variants
local import = {
"direction", "mirror", --> πολυγλωσσία/uax9
"category", --> https://gist.github.com/phi-gamma/5812290
"textclass", --> https://gist.github.com/phi-gamma/6488187
}
-----------------------------------------------------------------------
-- includes
-----------------------------------------------------------------------
kpse.set_program_name"luatex"
require "lualibs"
local chardef
local charini
if not mkivpath then
mkivpath = assert (kpse.expand_path
"~/context/tex/texmf-context/tex/context/base/mkiv/",
"Failed to locate ConTeXt.")
end
chardef = mkivpath .. "/char-def.lua"
charini = mkivpath .. "/char-ini.lua"
--- we could grab the files from contextgarden but as Context is part
--- of TL it’s not worth bothering
if not (chardef and lfs.isfile(chardef)) then
chardef = assert(kpse.find_file("char-def.lua", "lua"),
"Failed to locate file char-def.lua from ConTeXt.")
end
if not (charini and lfs.isfile(charini)) then
charini = assert(kpse.find_file("char-ini.lua", "lua"),
"Failed to locate file char-ini.lua from ConTeXt.")
end
io.write(string.format("extracting data from char-def.lua at %s\n",
chardef))
io.write(string.format("loading code from char-ini.lua at %s\n",
charini))
-----------------------------------------------------------------------
-- functionality
-----------------------------------------------------------------------
local get_characters = function ( )
local data
local inchan = io.open(chardef, "r")
if not inchan then
io.write("Could not open file for reading: "..chardef.."\n.")
goto fail
end
data = inchan:read "*all"
inchan:close()
data = loadstring(data)
if data then
data() --> characters.data
data = nil
collectgarbage "collect"
if characters.data and next(characters.data) then
return characters.data
end
io.write "Character table empty.\n"
goto fail
end
io.write(chardef .. " is not a valid Lua file.\n")
::fail::
io.write "Emergency exit.\n"
os.exit(1)
end
local extract_fields_indeed
extract_fields_indeed = function (data, acc, lastidx)
local idx, char = next(data, lastidx)
if idx then
local imported = { }
for i=1, #import do
local field = import[i]
imported[field] = char[field]
end
acc[idx] = imported
return extract_fields_indeed(data, acc, idx)
end
return acc
end
local extract_fields = function (data)
return extract_fields_indeed(data, {}, nil)
end
--[[ extract_classifiers : from luatex-basics-prepare.tex ]]
local extract_classifiers = function (chardata)
dofile (charini)
local s_init = 1 local s_rphf = 7
local s_medi = 2 local s_half = 8
local s_fina = 3 local s_pref = 9
local s_isol = 4 local s_blwf = 10
local s_mark = 5 local s_pstf = 11
local s_rest = 6
local mappers = {
l = s_init, -- left
d = s_medi, -- double
c = s_medi, -- joiner
r = s_fina, -- right
u = s_isol, -- nonjoiner
}
local first_arabic, last_arabic = characters.blockrange("arabic")
local first_syriac, last_syriac = characters.blockrange("syriac")
local first_mandiac, last_mandiac = characters.blockrange("mandiac")
local first_nko, last_nko = characters.blockrange("nko")
local classifiers = { }
for k, c in next, chardata do
if k > 0 then
local c = chardata[k]
if c then
local arabic = c.arabic
if arabic then
classifiers[k] = mappers[arabic]
elseif k >= first_arabic and k <= last_arabic or k >= first_syriac and k <= last_syriac or
k >= first_mandiac and k <= last_mandiac or k >= first_nko and k <= last_nko then
if c.category == "mn" then
classifiers[k] = s_mark
else
classifiers[k] = s_rest
end
end
end
end
end
return classifiers
end
local amend_table_fields = function (data, classifiers)
--- installed by luatex-basics-prepare.tex
data.characters = { }
data.classifiers = classifiers
return data
end
local writedata = function (data)
local outchan = io.open(charfile, "w")
if not outchan then
io.write("Could not open "..charfile.." for writing.\n")
return false
end
outchan:write(data)
outchan:close()
return true
end
do
local chardata = get_characters()
local classifiers = extract_classifiers(chardata)
local stripped = extract_fields(chardata)
local amended = amend_table_fields(stripped, classifiers)
local serialized = table.serialize(amended, true, {
compact = true,
noquotes = true,
hexify = true, --- for consistency with char-def
})
if writedata(serialized) then
goto done
end
goto fail
end
::done::
os.exit(0)
::fail::
io.write "Emergency exit.\n"
os.exit(1)
--- vim:ft=lua:ts=2:et:sw=2
|