#!/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>
--      VERSION:  1.0
--      CREATED:  04/23/2013 12:42:17 PM CEST
-----------------------------------------------------------------------
-- interesting thread on the Context list:
-- http://www.ntg.nl/pipermail/ntg-context/2008/029057.html
-----------------------------------------------------------------------


-----------------------------------------------------------------------
--                              config
-----------------------------------------------------------------------
local glyphfile     = "./glyphlist.txt"
local font_age      = "./luaotfload-glyphlist.lua"
local glyph_source  = "http://partners.adobe.com/public/developer/en/opentype/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.200,
  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
    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 glyphdata = http.request(glyph_source)
    if glyphdata then
      local fh = io.open(glyphfile, "wb")
      if not fh then
        print"error: glyph file not writable"
        os.exit(-1)
      end
      fh:write(glyphdata)
      fh:close()
      return get_raw(true)
    end
    print"error: download failed"
    os.exit(-1)
  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()