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
|