summaryrefslogtreecommitdiff
path: root/scripts/mkglyphlist
blob: b9d5309d5294e64f8fcce952e3045529cd92d405 (plain)
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
#!/usr/bin/env texlua
-----------------------------------------------------------------------
--         FILE:  mkglyphlist.lua
--        USAGE:  ./mkglyphlist.lua 
--  DESCRIPTION:  part of the luaotfload package
-- REQUIREMENTS:  lua, lpeg, luasocket, the lualibs package
--       AUTHOR:  Philipp Gesang (Phg), <phg42.2a@gmail.com>
-----------------------------------------------------------------------
-- interesting thread on the Context list:
-- http://www.ntg.nl/pipermail/ntg-context/2008/029057.html
--
-- N.B. this script assumes network connectivity!
-----------------------------------------------------------------------


-----------------------------------------------------------------------
--                              config
-----------------------------------------------------------------------
local glyphfile     = "./build/glyphlist.txt"
local font_age      = "./build/luaotfload-glyphlist.lua"
local glyph_source  = "https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt"

-----------------------------------------------------------------------
--                             fallbacks
-----------------------------------------------------------------------
--- Hans adds a small list of mappings that are not in the original
--- glyph list but seem to be normalizations of some sort. I trust his
--- experience, so I’ll just include them here. Background:
--- http://www.ntg.nl/pipermail/ntg-context/2013/073089.html

local fallbacks = {
  ["SF10000"]=9484, ["SF20000"]=9492, ["SF30000"]=9488,
  ["SF40000"]=9496, ["SF50000"]=9532, ["SF60000"]=9516,
  ["SF70000"]=9524, ["SF80000"]=9500, ["SF90000"]=9508,
  ["afii208"]=8213,
}

-----------------------------------------------------------------------
--                             includes
-----------------------------------------------------------------------
require"lpeg"
require"socket"

kpse.set_program_name"luatex"
for _, lib in next, { "lualibs-lua.lua",
                      "lualibs-lpeg.lua",
                      "lualibs-table.lua", } do
  local found = assert(kpse.find_file(lib, "lua"),
                       "Could not locate " .. lib)
  require(found)
end

local C, Cf, Cg, Ct, P, R =
  lpeg.C, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R

local http = socket.http

-----------------------------------------------------------------------
--                           functionality
-----------------------------------------------------------------------

local dec_of_hex = function (hex) return tonumber(hex, 16) end

local separator    = P";"
local gartenzaun   = P"#"
local eol          = P"\n\r" + P"\r\n" + P"\r" + P"\n"
local space        = P" "
local alphanum     = R("az", "AZ", "09")
local hexdigit     = R("af", "AF", "09")
local eof_tag      = gartenzaun * P"END"
local header_line  = gartenzaun * (1-eol)^0 * eol
local codepoint    = hexdigit^1
local glyphname    = alphanum^1

local definition   = Cg(C(glyphname) * separator * (C(codepoint)/ dec_of_hex))
                   --- With combined glyphs we take only the first
                   --- value as char-def and font-age do, and skip
                   --- the rest.
                   * (space * codepoint)^0
                   * eol
local definitions  = Cf(Ct"" * definition^1, rawset)

local p_glyphs     = header_line^0 * definitions * eof_tag

local get_glyphs = function (data)
  local res = lpeg.match(p_glyphs, data)
  if not res then
    print("error: could not parse glyph list")
    os.exit(-1)
  end
  for name, glyph in next, fallbacks do
    res[name] = res[name] or glyph
  end
  return res
end

local file_header = [==[
if not modules then modules = { } end modules ["font-age"] = {
  version     = 2.400,
  comment     = "part of the luaotfload package",
  author      = "luaotfload team / mkglyphlist",
  copyright   = "derived from %s",
  original    = "Adobe Glyph List, version 2.0, September 20, 2002",
  dataonly    = true,
}

if context then
  logs.report("fatal error","this module is not for context")
  os.exit(-1)
end

--[[doc--
Everything below has been autogenerated. Run mkglyphlist to rebuild
luaotfload-glyphlist.lua.
--doc]]--

]==]

local writedata = function (data)
  data = table.serialize(data, true)
  data = string.format(file_header, glyph_source) .. data
  local fh = io.open(font_age, "wb")
  if not fh then
    print(string.format("error: %s not writable", font_age))
    os.exit(-1)
  end
  print(string.format("saving %d bytes to %s", #data, font_age))
  fh:write(data)
  fh:close()
end


local get_raw get_raw = function (retry)
  local fh = io.open(glyphfile, "rb")
  if fh then
    print ("info: reading glyph list from", glyphfile)
    local data = fh:read"*all"
    fh:close()
    if data then return data end
  elseif not retry then --- attempt download
    print"info: retrieving glyph list from"
    print(glyph_source)
    local cmd = string.format("wget '%s' -o '%s'", glyph_source, glyphfile)
    local st = os.execute(string.format("wget '%s' -O '%s'", glyph_source, glyphfile))
    if st ~= 0 then
      print(string.format("error: download failed; status: %d, command: %q", st, cmd))
      os.exit(-1)
    end
  end
  print("error: could not obtain glyph data from "..glyphfile)
  os.exit(-1)
end

local main = function ()
  if arg[1] then glyphfile = arg[1] end
  if arg[2] then font_age  = arg[2] end

  local data    = get_raw()
  local parsed  = get_glyphs(data)
  writedata(parsed)
  return 0
end


return main()

--- vim:ft=lua:ts=2:et:sw=2