-- $Id: fntbuild-build.lua 10818 2025-02-19 05:44:13Z cfrees $ 
-------------------------------------------------
-- fntbuild-build
-------------------------------------------------
-------------------------------------------------
-- buildinit_hook
---@return 0
---@usage public
local function buildinit_hook () return 0 end
-------------------------------------------------
-- buildinit {{{
-- hack copy of checkinit()
---@return 0 on success, error level otherwise
---@see 
---@usage public
local function buildinit ()
  cleandir(fnt.fntdir)
  -- l3build never cleans this by default?
  cleandir(localdir)
  fnt.dep_install (fnt.builddeps)
  -- is this a appropriate? better not?
  for i,j in ipairs(filelist(localdir)) do
    cp(j,localdir,fnt.fntdir)
  end
  print("Unpacking ...\n")
  -- direct usage is legitimate ...
  -- https://chat.stackexchange.com/transcript/message/66617079#66617079
  assert(unpack(),"Unpacking failed in buildinit()!") 
  for i,j in ipairs(fnt.buildfiles) do
    cp(j,unpackdir,fnt.fntdir)
  end
  if #fnt.buildsuppfiles_sys ~= 0 then
    for _,j in ipairs(fnt.buildsuppfiles_sys) do
      if fileexists(j) then
        cp(basename(j),dirname(j),fnt.fntdir)
      else
        local jpath = kpse.find_file(j)
        if jpath == nil then
          jpath = kpse.lookup(j)
        end
        if jpath == nil then
          fnt.gwall("Locating ",j,1)
        end
        local jdir = dirname(jpath)
        cp(j,jdir,fnt.fntdir)
      end
    end
  end
  if fnt.needs_fontinst then
    local path = kpse.var_value("TEXMFDIST") .. "/tex/fontinst"
    local t = fnt.lsrdir(path)
    for _,i in ipairs(t) do
      local s = i
      if string.match(i,"^fontscripts%-") then
        s = (string.gsub(i,"^fontscripts%-",""))
      end
      local file = kpse.find_file(i)
      if not fileexists(fnt.fntdir .. "/" .. i) then
        cp(basename(file),dirname(file),fnt.fntdir)
        if i ~= s and not fileexists(fnt.fntdir .. "/" .. s) then 
          ren(fnt.fntdir,i,s) 
          table.insert(fnt.buildsuppfiles_sys,s)
        else
          table.insert(fnt.buildsuppfiles_sys,i)
        end
      end
    end
    print("Copied fontinst files to " .. fnt.fntdir)
  end
  -- if not fnt.buildsearch then
  --   -- we aren't typesetting, so we really don't need a map file
  --   -- not sure this is really needed - do any tools use this anyway?
  --   -- https://rosettacode.org/wiki/Create_a_file
  --   io.open(fnt.fntdir .. "/pdftex.map", "w"):close()
  -- end
  print("Initialised build.")
  return fnt.buildinit_hook()
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- build_tidy {{{
---@usage public
---@return 0 on success, errorlevel otherwise
local function build_tidy ()
  print("Tidying up build directory ...\n")
  for _,i in ipairs(fnt.buildsuppfiles_sys) do
    local errorlevel = rm(fnt.fntdir,i) 
    fnt.gwall("Removal of ",fnt.fntdir .. "/" .. i,errorlevel)
  end
  return 0
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- build_fnt {{{
---@param file string
---@param cmd string
---@param file string
---@return 0 on success, error level otherwise
---@see 
---@usage public
local function build_fnt (dir,cmd,file)
  file = file or ""
  cmd = cmd or ""
  dir = dir or fnt.fntdir
  local build_fnt_env = fnt.build_fnt_env or {} 
  local build_fnt_envset = ""
  if #build_fnt_env ~= 0 then
    for _,i in ipairs(build_fnt_env) do
      build_fnt_envset = build_fnt_envset .. os_concat .. os_setenv .. " " .. i
    end
  end
  -- steal from l3build-check.lua
  local preamble =
    -- would it be simpler to copy the typesetting sandbox here?
    -- paths in the logs don't matter and copying localdir complicates things a bit
    -- No use of localdir here as the files get copied to testdir:
    -- avoids any paths in the logs
    os_setenv .. " TEXINPUTS=." .. fnt.localtexmf()
    .. (fnt.buildsearch and os_pathsep or "")
    .. os_concat ..
    -- no need for LUAINPUTS here
    -- but we need to set more variables ...?!
    (fnt.buildsearch and "" or 
      (os_setenv .. " TEXMFAUXTREES={}"
      .. os_concat .. os_setenv .. " TEXMFHOME={}"
      .. os_concat .. os_setenv .. " TEXMFLOCAL={}"
      .. os_concat .. os_setenv .. " TEXMFCONFIG=."
      .. os_concat .. os_setenv .. " TEXMFVAR=."
      .. os_concat .. os_setenv .. " VFFONTS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " TFMFONTS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " TEXFONTMAPS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " T1FONTS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " AFMFONTS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " TTFFONTS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " OPENTYPEFONTS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " LIGFONTS=${TEXINPUTS}"
      .. os_concat .. os_setenv .. " ENCFONTS=${TEXINPUTS}")
    )
    .. build_fnt_envset
    .. os_concat
  local errorlevel = runcmd(
    preamble .." " ..  cmd .. " " .. file, dir
  )
  fnt.gwall(cmd,file,errorlevel)
  return errorlevel
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- fntkeeper {{{
---@param dir string 
---@return 0 on success, error level otherwise
---@see 
---@usage public
local function fntkeeper (dir)
  dir = dir or fnt.fntdir
  if fileexists(dir .. "/pdftex.map") then
    local errorlevel = rm(dir,"pdftex.map") 
    fnt.gwall("Removing ","pdftex.map",errorlevel)
  end
  local rtn = direxists(fnt.keepdir)
  if not rtn then
    local errorlevel = mkdir(fnt.keepdir)
    if errorlevel ~= 0 then
      print("DO NOT BUILD STANDARD TARGETS WITHOUT RESOLVING!!\n")
      fnt.gwall("Attempt to create directory ", fnt.keepdir, errorlevel)
    end
  else
    local errorlevel = cleandir(fnt.keepdir)
    if errorlevel ~= 0 then
      print("KEEP CONTAMINATED!\n")
      fnt.gwall("Attempt to clean directory ",fnt.keepdir,errorlevel)
    end
  end
  local keepdir = abspath(fnt.keepdir) -- abspath requires existence
  if fnt.keepfiles ~= {} then
    for i,j in ipairs(fnt.keepfiles) do
      local rtn = cp(j, dir, keepdir)
      if rtn ~= 0 then
        fnt.gwall("Copy ", j, errorlevel)
        print("DO NOT BUILD STANDARD TARGETS WITHOUT RESOLVING!\n")
      end
    end
  else
    print("ARE YOU SURE YOU DON'T WANT TO KEEP THE FONTS??!!\n")
  end
  if fnt.keeptempfiles ~= {} then
    rtn = direxists(fnt.keeptempdir)
    if not rtn then
      local errorlevel = mkdir(fnt.keeptempdir)
      if errorlevel ~= 0 then
        fnt.gwall("Attempt to create directory ", fnt.keeptempdir, errorlevel)
      end
    else
      local errorlevel = cleandir(fnt.keeptempdir)
      if errorlevel ~= 0 then
        print("keeptemp contaminated!\n")
        fnt.gwall("Attempt to clean directory ",fnt.keeptempdir,errorlevel)
      end
    end
    for i,j in ipairs(fnt.keeptempfiles) do 
      local errorlevel = cp(j,dir,fnt.keeptempdir)
      if errorlevel ~= 0 then
        fnt.gwall("Copy ", j, errorlevel)
      end
    end
  end	
  return fnt.nifergwall
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- fnt_subset {{{
---@params fd, family, fnt.subset
---@usage private
local function fnt_subset (fd,fam,subset)
  local defn = string.gsub(fnt.subsettemplate,"%$FONTFAMILY",fam)
  defn = string.gsub(defn,"%$SUBSET",subset)
  local f = assert(io.open(fnt.fntdir .. "/" .. fd, "rb"))
  local content = f:read("*all")
  f:close()
  local patt
  if string.match(content, "\\endinput") then
    patt = "(\\endinput)"
  else
    patt = "()$"
  end
  f = assert(io.open(fnt.fntdir .. "/" .. fd, "w"))
  f:write("%% Encoding subset declaration added by fontscripts\n",
    (string.gsub(content,patt,"\n\n" .. defn .. "\n\n%1"))
  )
  f:close()
  return 0    -- how to make this return an error level?
end
-- }}}
-------------------------------------------------
-- fntsubsetter {{{
---@param  
---@description add encoding fnt.subset definitions for TS1 if applicable and requested
---@return 0 on success, error level or 1 otherwise
---@see 
---@usage public
local function fntsubsetter ()
  local tcsubset = tcsubset or "9"
  if fnt.subset == nil or fnt.subset == false then return 0 end
  local subsetfiles = fnt.subsetfiles or {}
  if type(subsetfiles) == "string"  and subsetfiles ~= "auto" then
    local s = subsetfiles
    subsetfiles = { s }
  end
  if #subsetfiles == 0 then
    for i in lfs.dir(fnt.fntdir) do
      -- we avoid using filelist() here because it doesn't support char sets
      if string.match(i, "^[Tt][Ss]1.*%.fd$") then
        table.insert(subsetfiles,i)
      end
    end
  end
  if #subsetfiles == 0 then return 0 end
  for _, i in ipairs(subsetfiles) do
    local fam = string.gsub(i, "^[Tt][Ss]1(.+)%.fd$", "%1")
    local s = fnt.subsetdefns[fam] or tcsubset
    local errorlevel = fnt_subset(i,fam,s)
    fnt.gwall("Inserting TS1 subset definition ",i,errorlevel)
  end
  return fnt.nifergwall
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- uniquify {{{
-- oherwydd fy mod i bron ag anfon pob un ac mae'n amlwg fy mod i wedi anfon 
-- bacedi heb ei wneud hwn yn y gorffennol, well i mi wneud rhywbeth (scriptiau 
-- gwneud-cyhoeddus a make-public yn argraffu rhybudd os encs yn y cymysg
-- (cymraeg yn ofnadwy hefyd)
---@param tag string 
---@return 0 on success, error level or 1 otherwise
---@see 
---@usage public
local function uniquify (tag)
  local dir = ""
  tag = tag or fnt.encodingtag or ""
  local pkgbase = fnt.pkgbase or ""
  local pkglist = {}
  if fnt.standalone then
    dir = fnt.keepdir
  else
    dir = fnt.fntdir
  end
  -- if fileexists(dir .. "/pdftex.map") then
  --   print("\nRemoving temporary pdftex.map from ", dir, "...\n")
  --   local errorlevel = rm(dir,"pdftex.map")
  --   fnt.gwall("Removing ","pdftex.map",errorlevel)
  -- end
  if pkgbase == "" then 
    print("pkgbase unspecified. Trying to guess ... ")
    if not fnt.standalone then 
      pkglist = filelist(dir,"*.sty")
      if #pkglist == 0 then
        pkglist = filelist(unpackdir,"*.sty")
      end
      if #pkglist ~= 0 then
        pkgbase = string.gsub(pkglist[1], "%.sty", "")
        print("Guessing ", pkgbase)
      end
    end
  end
  if pkgbase == "" then
    if ctanpkg ~= module and module ~= "" and module ~= nil then
      print("Guessing ", module)
      pkgbase = module
    else
      pkgbase = string.gsub(ctanpkg, "adf$", "")
      if pkgbase ~= "" then
        print("Guessing ", pkgbase)
      end
    end
  end
  if pkgbase == "" then 
    pkgbase = "NotAMatchAtAll" 
    fnt.gwall("Guessing pkgbase ","",1)
  end
  local encs = encs or filelist(dir,"*.enc")
  local maps = maps or filelist(dir,"*.map")
  print("Uniquifying encodings ... ")
  for _,i in ipairs(encs) do print(" ", i) end
  print("\nUniquifying maps ... ")
  for _,i in ipairs(maps) do print(" ", i) end
  print(" ...\n")
  if #encs == 0 then
    return 0
  elseif tag == "" then 
    if #maps ~= 0  then
      if #maps == 1 then
        tag = string.gsub(maps[1],"%.map$","")
      else
        local t = "" 
        local tt = ""
        for i,j in ipairs(maps) do
          if tt == t then 
            tt = string.gsub(j,"%w%.map$","")
          elseif t == "" then
            t = string.gsub(j,"%w%.map$","")
          end
        end
        if t == tt then
          tag = tt
        else
          fnt.gwall("Attempt to find tag ","",1)
        end
      end
    end
    if tag ~= "" then  
      for i, j in ipairs(encs) do
        if string.match(j,"-" .. tag .. "%.enc$") 
          or  string.match(j, module) 
          or string.match(j,ctanpkg) 
          or string.match(j,pkgbase) 
          or string.match(j, string.gsub(module, "adf", "")) then
          print(j, "... OK\n")
        else
          local targenc = (string.gsub(j,"%.enc$","-" .. tag .. ".enc"))
          print("Target encoding is", targenc, "\n")
          if fileexists(dir .. "/" .. targenc) then
            fnt.gwall("Target encoding exists !! ", targenc, 1)
            return 1
          else
            local f = assert(io.open(dir .. "/" .. j,"rb"))
            local content = f:read("*all")
            f:close()
            local new_content = (string.gsub(content,
            "(\n%%%%BeginResource: encoding fontinst%-autoenc[^\n ]*)( *\n/fontinst%-autoenc[^ %[]*)( %[)",
              "\n%% Encoding renamed by fontscripts\n\n%1-" 
              .. tag .. "%2-" .. tag .. "%3"
            ))
            if new_content ~= content then
              print("Writing unique encoding to ", targenc)
              f = assert(io.open(dir .. "/" .. targenc,"w"))
              -- remove the second value returned by string.gsub
              f:write((string.gsub(new_content,"\n",fnt.os_newline_cp)))
              f:close()
              if fileexists(dir .. "/" .. targenc) then
                local errorlevel = rm(dir,j)
                if errorlevel ~= 0 then
                  fnt.gwall("Attempt to rm old encoding ",j,errorlevel)
                end
                if #maps ~= 0 then
                  local jpatt = string.gsub(j,"%-","%%-")
                  jpatt = string.gsub(jpatt,"%.","%%.")
                  for k,m in ipairs(maps) do
                    f = assert(io.open(dir .. "/" .. m,"rb"))
                    local mcontent = f:read("*all")
                    f:close()
                    local new_mcontent = (string.gsub(mcontent,
                      "(%<%[?)" .. jpatt .. 
                      "( %<%w+%.pfb \" fontinst%-autoenc[%w%-_]*)( ReEncodeFont)", 
                      "%1" .. targenc .. "%2-" .. tag .. "%3"
                    ))
                    if new_mcontent ~= mcontent then 
                      print("Writing adjusted map lines to ", m)
                      f = assert(io.open(dir .. "/" .. m,"w"))
                      -- remove the second value returned by string.gsub
                      f:write("%% Encodings renamed by fontscripts\n",
                      (string.gsub(new_mcontent,"\n",fnt.os_newline_cp)))
                      f:close()
                    else
                      print("Nothing to do for ", m, ".\n")
                    end
                  end
                else
                  print("FOUND NO MAPS??\n")
                end
              else
                fnt.gwall("Attempt to write ",targenc,1)
              end
            else
              fnt.gwall("Attempt to uniquify " .. j .. " as ",targenc,1)
            end
          end
        end
      end
    end
    return fnt.nifergwall
  end
  print("Something weird happened.\n")
  return 1
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- fontinst
-------------------------------------------------
-- finst {{{
---@param patt string
---@param dir string
---@param mode string
---@return 
---@see 
---@usage public
local function finst (patt,dir,mode)
  dir = dir or "."
  mode = mode or "nonstopmode"
  local cmd = "pdftex --interaction=" .. mode
  -- https://lunarmodules.github.io/luafilesystem/examples.html (expl)
  -- l3build-file-functions.lua (filelist fn)
  local targs = filelist(dir,patt)
  for i,j in ipairs(targs) do
    -- local errorlevel = tex(j,dir,cmd)
    local errorlevel = build_fnt(dir,cmd,j)
    fnt.gwall("Compilation of ", j, errorlevel)
  end
end
-- }}}
-------------------------------------------------
-- fontinst {{{
---@param dir string
---@param mode string
---@return 0 on success, error level otherwise
---@see 
---@usage public 
local function fontinst (dir,mode)
  -- dir = dir or unpackdir
  dir = dir or fnt.fntdir
  mode = mode or "errorstopmode --halt-on-error"
  fnt.standalone = false
  fnt.encodingtag = fnt.encodingtag or ""
  local errorlevel = 0
  buildinit ()
  local tfmfiles = filelist(dir,"*.tfm")
  for i,j in ipairs(tfmfiles) do
    local plname = string.gsub(j, "%.tfm$", ".pl")
    if fileexists(dir .. "/" .. plname) then
      print(plname,  "already exists!")
      return 1
    else
      local cmd = "tftopl " .. j .. " " .. plname
      -- safe or not?
      errorlevel = runcmd(cmd,dir)
      -- necessary or not?
      -- local errorlevel = build_fnt(cmd,dir)
      fnt.gwall("Conversion to pl from tfm ",j,errorlevel)
      -- remove tfm to reduce pollution of package later
      rm(dir,j)
      fnt.gwall("Deletion of tfm ", j, errorlevel)
    end
  end
  print("Creating families ...\n")
  for i,j in ipairs(fnt.familymakers) do
    errorlevel = finst(j,dir,mode)
    fnt.gwall("Compilation of driver ", j, errorlevel)
  end
  if fnt.nifergwall ~= 0 then return fnt.nifergwall end
  for i,j in ipairs(fnt.mapmakers) do
    errorlevel = finst (j,dir,mode)
    fnt.gwall("Compilation of map ", j, errorlevel)
  end
  if fnt.nifergwall ~= 0 then return fnt.nifergwall end
  errorlevel = build_tidy ()
  fnt.gwall("Tidying ",fnt.fntdir,errorlevel)
  -- print("Tidying up build directory ...\n")
  -- for _,i in ipairs(fnt.buildsuppfiles_sys) do
  --   local errorlevel = rm(dir,i) 
  --   fnt.gwall("Removal of ",dir .. "/" .. i,errorlevel)
  -- end
  for i,j in ipairs(fnt.binmakers) do
    local targs = filelist(dir,j)
    -- https://www.lua.org/pil/21.1.html
    for k,m in ipairs(targs) do
      targ = dir .. "/" .. m
      -- is this really the right way to do this?
      -- surely it is not at all safe?
      -- though presumably no worse than executing the script directly
      for line in io.lines(targ) do
        if string.match(line,"^pltotf [a-zA-Z0-9%-]+%.pl [a-zA-Z0-9%-]+%.tfm$") then
          -- local errorlevel = runcmd(line,dir)
          errorlevel = build_fnt(dir,line)
          fnt.gwall("Creation of TFM using " .. line .. " from ", j, errorlevel)
        else
          print("Ignoring unexpected line \"" .. line .. "\" in", j .. ".\n")
          fnt.nifergwall = fnt.nifergwall + 1
        end
      end
    end
  end
  if fnt.nifergwall ~= 0 then return fnt.nifergwall end
  local targs = filelist(dir,"*.vpl")
  for i,j in ipairs(targs) do
    -- local cmd = "vptovf " .. j
    -- local errorlevel = runcmd(cmd,dir)
    local cmd = "vptovf"
    errorlevel = build_fnt(dir,cmd,j)
    fnt.gwall("Creation of virtual font from ", j, errorlevel)
  end
  -- edit the .fd files if a scale factor is declared because fontinst 
  -- doesn't allow us to do this and the last message to the mailing list
  -- is from 2022 with no response from the maintainer
  local fdfiles = filelist(dir, "*.fd")
  for i,j in ipairs(fdfiles) do
    local f = assert(io.open(dir .. "/" .. j,"rb"))
    local content = f:read("*all")
    f:close()
    local new_content = content
    local csscaleaux = string.match(content, "%<%-%> *\\([%a%d][%a%d]*@@scale)") 
    if csscaleaux ~= nil then
      local csscale = string.gsub(csscaleaux, "@(@)", "%1")
      if csscale ~= nil then
        new_content = string.gsub(content, "(\\DeclareFontFamily{)", 
        "%% addaswyd o t1phv.fd (dyddiad y ffeil fd: 2020-03-25)\n\\expandafter\\ifx\\csname " 
        .. csscale .. "\\endcsname\\relax\n  \\let\\" .. csscaleaux 
        .. "\\@empty\n\\else\n  \\edef\\" .. csscaleaux 
        .. "{s*[\\csname " .. csscale .. "\\endcsname]}%%\n\\fi\n\n%1")
      end
    end
    csscaleaux = string.match(content, 
    "\\DeclareFontFamily{[^}]*}{[^}]*}{[^}]*\\hyphenchar *\\font *=[^}\n]*}") 
    if csscaleaux ~= nil then
      content = new_content
      new_content = string.gsub(content, 
      "(\\DeclareFontFamily{[^}]*}{[^}]*}{\\hyphenchar) *(\\font) *(=[^ }\n]*) *([^ }\n]* *})", 
      "%1%2%3%4")
    end
    if new_content ~= content then
      local f = assert(io.open(dir .. "/" .. j,"w"))
      -- this somehow removes the second value returned by string.gsub??
      f:write("%% Scaling added by fontscripts\n",(string.gsub(new_content,
        "\n",fnt.os_newline_cp)))
      f:close()
    end
  end
  errorlevel = uniquify(fnt.encodingtag)
  if errorlevel ~= 0 then
    fnt.gwall("Encodings not uniquified! Do not submit to CTAN! uniquify(" 
      .. fnt.encodingtag .. ")","",errorlevel)
  end
  errorlevel = fntsubsetter()
  if errorlevel ~= 0 then
    fnt.gwall("Encoding fnt.subset definitions not inserted! fntsubsetter() ","",errorlevel)
  end
  errorlevel = fntkeeper()
  if errorlevel ~= 0 then
    fnt.gwall(
      "FONT KEEPER FAILED! DO NOT MAKE STANDARD TARGETS WITHOUT RESOLVING!! fntkeeper() ", 
      dir, errorlevel)
  end
  return fnt.nifergwall
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- afm2tfm (simple symbol fonts only)
-------------------------------------------------
-- afm2tfm (dir) {{{
---@param dir string
---@return 0 on success, number of errors otherwise 
---@see 
---@usage public
local function afm2tfm (dir)
  dir = dir or fnt.fntdir
  local fntbasename = fntbasename or module
  local map = mapfile or fntbasename .. ".map"
  local fntencs = fnt.encs or {}
  fnt.standalone = false
  fnt.encodingtag = fnt.encodingtag or ""
  buildinit ()
  print("Running afm2tfm. Please be patient ...\n")
  local afms = filelist(dir,"*.afm")
  local content = ""
  for i,k in ipairs(afms) do
    j = string.gsub(k,"%.afm","")
    if fntencs[j] == nil then 
      local rtn = fileexists(dir .. "/" .. j .. ".enc")
      if not rtn then
        errorlevel = build_fnt(dir,"afm2tfm " .. k " >> " .. dir 
          .. "/" .. map .. ".tmp")
      else
        errorlevel = build_fnt(dir, "afm2tfm " .. k .. " -p " .. j 
          .. ".enc" .. " >> " .. dir .. "/" .. map .. ".tmp")
      end
    elseif not fileexists(dir .. "/" .. fntencs[j]) then
      fnt.gwall("Search for encoding specified for " .. j .. " ",dir,1)
    else
      errorlevel = build_fnt(dir, "afm2tfm " .. k .. " -p " .. fntencs[j] 
        .. " >> " .. dir .. "/" .. map .. ".tmp")
    end
    if errorlevel ~= 0 then 
      fnt.gwall("afm2tfm (" .. j ..") ",dir,errorlevel) 
    else
      local g = assert(io.open(dir .. "/" .. map .. ".tmp","rb"))
      local c = g:read("all")
      g:close()
      content = content .. string.gsub(c, "\n", " <" 
        .. string.gsub(k,"%.afm",".pfb") .. "\n")
      rm(dir, map .. ".tmp")
    end
  end
  -- need to do this as uniquify() isn't used
  -- otherwise the file ends up in localdir (and probably the package)
  -- catching this is the only benefit I can see in my inability to clean localdir
  -- if fileexists(dir .. "/pdftex.map") then
  --   local errorlevel = rm(dir,"pdftex.map") 
  --   fnt.gwall("Removing ","pdftex.map",errorlevel)
  -- end
  local f
  f = assert(io.open(dir .. "/" .. map, "w"))
  f:write((string.gsub(content,"\n",fnt.os_newline_cp)))
  f:close()
  errorlevel = fntkeeper()
  if errorlevel ~= 0 then
    fnt.gwall("FONT KEEPER FAILED! DO NOT MAKE STANDARD TARGETS WITHOUT RESOLVING!! ", 
      dir, errorlevel)
  end
  return fnt.nifergwall
end
-- }}}
-------------------------------------------------
-------------------------------------------------
-- exports {{{
fnt.build_fnt = build_fnt
fnt.build_tidy = build_tidy
fnt.buildinit = buildinit
fnt.buildinit_fontinst = buildinit_fontinst
fnt.buildinit_hook = buildinit_hook
fnt.finst = finst
fnt.fntkeeper = fntkeeper
fnt.fntsubsetter = fntsubsetter
fnt.afm2tfm = afm2tfm
fnt.fontinst = fontinst
fnt.uniquify = uniquify
-- }}}
-------------------------------------------------
-------------------------------------------------
-- vim: ts=2:sw=2:et:foldmethod=marker:
