local readfile = require'luametalatex-readfile' local purenumber = lpeg.R'09'^1 local optoperator = lpeg.C(lpeg.S'+-='^-1)*lpeg.C(lpeg.P(1)^0) local commentchar = lpeg.S' %*;#'+-1 local wordpatt = (lpeg.C('"') * lpeg.C((1-lpeg.P'"')^0) * lpeg.P'"'^-1 + lpeg.C(('<' * lpeg.S'<['^-1)^-1) * lpeg.S' \t'^0 * lpeg.C((1-lpeg.S' \t')^0)) * lpeg.S' \t'^0 * lpeg.Cp() local fontmap = {} local function mapline(line, operator) if not operator then operator, line = optoperator:match(line) end if commentchar:match(line) then return end local pos = 1 local tfmname, psname, flags, special, enc, font, subset local kind, word while pos ~= #line+1 do kind, word, pos = wordpatt:match(line, pos) if kind == "" then if not tfmname then tfmname = word elseif not psname and not purenumber:match(word) then psname = word elseif purenumber:match(word) then flags = tonumber(word) else error[[Invalid map file line, excessive simple words]] end elseif kind == '"' then special = word else if kind == "<[" or (kind ~= "<<" and word:sub(-4) == ".enc") then enc = word else font = word subset = kind ~= "<<" end end end fontmap[tfmname] = {psname or tfmname, flags or (font and 4 or 0x22), font, enc, special, subset} end local function mapfile(filename, operator) if not operator then operator, filename = optoperator:match(filename) end local file = readfile('map', filename) for line in file:lines() do mapline(line, operator) end end local function reset() for k in next, fontmap do fontmap[k] = nil end end return { reset = reset, mapline = mapline, mapfile = mapfile, fontmap = fontmap }