luatex-fonts-def.lua /size: 3821 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['luatex-fonts-def'] = {
2    version   = 1.001,
3    comment   = "companion to luatex-*.tex",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9if context then
10    os.exit()
11end
12
13local fonts = fonts
14
15-- A bit of tuning for definitions.
16
17fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload
18
19-- tricky: we sort of bypass the parser and directly feed all into
20-- the sub parser
21
22function fonts.definers.getspecification(str)
23    return "", str, "", ":", str
24end
25
26-- the generic name parser (different from context!)
27
28local list = { } -- we could pass Carg but let's keep the old one
29
30local function issome ()    list.lookup = 'name'          end -- xetex mode prefers name (not in context!)
31local function isfile ()    list.lookup = 'file'          end
32local function isname ()    list.lookup = 'name'          end
33local function thename(s)   list.name   = s               end
34local function issub  (v)   list.sub    = v               end
35local function iscrap (s)   list.crap   = string.lower(s) end
36local function iskey  (k,v) list[k]     = v               end
37local function istrue (s)   list[s]     = true            end
38local function isfalse(s)   list[s]     = false           end
39
40local P, S, R, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs
41
42local spaces     = P(" ")^0
43local namespec   = Cs((P("{")/"") * (1-S("}"))^0 * (P("}")/"") + (1-S("/:("))^0)
44local crapspec   = spaces * P("/") * (((1-P(":"))^0)/iscrap) * spaces
45local filename_1 = P("file:")/isfile * (namespec/thename)
46local filename_2 = P("[") * P(true)/isfile * (((1-P("]"))^0)/thename) * P("]")
47local fontname_1 = P("name:")/isname * (namespec/thename)
48local fontname_2 = P(true)/issome * (namespec/thename)
49local sometext   = R("az","AZ","09")^1
50local somekey    = R("az","AZ","09")^1
51local somevalue  = (P("{")/"")*(1-P("}"))^0*(P("}")/"") + (1-S(";"))^1
52local truevalue  = P("+") * spaces * (sometext/istrue)
53local falsevalue = P("-") * spaces * (sometext/isfalse)
54local keyvalue   = (C(somekey) * spaces * P("=") * spaces * C(somevalue))/iskey
55local somevalue  = sometext/istrue
56local subvalue   = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim
57local option     = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces
58local options    = P(":") * spaces * (P(";")^0  * option)^0
59
60local pattern    = (filename_1 + filename_2 + fontname_1 + fontname_2)
61                 * subvalue^0 * crapspec^0 * options^0
62
63function fonts.definers.analyze(str,size)
64    local specification = fonts.definers.makespecification(str,nil,nil,nil,":",nil,size)
65    list = { }
66    lpeg.match(pattern,str)
67    list.crap = nil
68    if list.name then
69        specification.name = list.name
70        list.name = nil
71    end
72    if list.lookup then
73        specification.lookup = list.lookup
74        list.lookup = nil
75    end
76    if list.sub then
77        specification.sub = list.sub
78        list.sub = nil
79    end
80    specification.features.normal = fonts.handlers.otf.features.normalize(list)
81    list = nil
82    return specification
83end
84
85function fonts.definers.applypostprocessors(tfmdata)
86    local postprocessors = tfmdata.postprocessors
87    if postprocessors then
88        for i=1,#postprocessors do
89            local extrahash = postprocessors[i](tfmdata) -- after scaling etc
90            if type(extrahash) == "string" and extrahash ~= "" then
91                -- e.g. a reencoding needs this
92                extrahash = string.gsub(lower(extrahash),"[^a-z]","-")
93                tfmdata.properties.fullname = format("%s-%s",tfmdata.properties.fullname,extrahash)
94            end
95        end
96    end
97    return tfmdata
98end
99