From 24b1bdad120fcb18d0aebd66a52f3b2f19677e42 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 9 Apr 2013 14:53:07 +0200 Subject: fix function names --- otfl-font-nms.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 094ebec..3934919 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -30,13 +30,14 @@ else end end -local splitpath, expandpath = file.split_path, kpse.expand_path -local glob, basename = dir.glob, file.basename -local extname = file.extname -local upper, lower, format = string.upper, string.lower, string.format -local gsub, match, rpadd = string.gsub, string.match, string.rpadd -local gmatch, sub, find = string.gmatch, string.sub, string.find -local utfgsub = unicode.utf8.gsub +local splitpath, collapsepath = file.splitpath, file.collapsepath +local expandpath = kpse.expand_path +local glob, basename = dir.glob, file.basename +local extname = file.extname +local upper, lower, format = string.upper, string.lower, string.format +local gsub, match, rpadd = string.gsub, string.match, string.rpadd +local gmatch, sub, find = string.gmatch, string.sub, string.find +local utfgsub = unicode.utf8.gsub local trace_short = false --tracing adapted to rebuilding of the database inside a document local trace_search = false --trackers.register("names.search", function(v) trace_search = v end) @@ -430,7 +431,7 @@ local function path_normalize(path) end end end - path = file.collapse_path(path) + path = collapsepath(path) return path end -- cgit v1.2.3 From 6fbac590374db31f6dd03cafc363657efc6f4a44 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 10 Apr 2013 22:57:21 +0200 Subject: =?UTF-8?q?make=20loglevel=20=E2=80=9C-q=E2=80=9D=20effective?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- otfl-font-nms.lua | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 3934919..a0d81ae 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -39,9 +39,10 @@ local gsub, match, rpadd = string.gsub, string.match, string.rpadd local gmatch, sub, find = string.gmatch, string.sub, string.find local utfgsub = unicode.utf8.gsub -local trace_short = false --tracing adapted to rebuilding of the database inside a document -local trace_search = false --trackers.register("names.search", function(v) trace_search = v end) -local trace_loading = false --trackers.register("names.loading", function(v) trace_loading = v end) +local suppress_output = false +local trace_short = false --tracing adapted to rebuilding of the database inside a document +local trace_search = false --trackers.register("names.search", function(v) trace_search = v end) +local trace_loading = false --trackers.register("names.loading", function(v) trace_loading = v end) local function sanitize(str) if str then @@ -244,7 +245,9 @@ end names.resolvespec = names.resolve function names.set_log_level(level) - if level == 2 then + if level == 0 then + suppress_output = true + elseif level == 2 then trace_loading = true elseif level >= 3 then trace_loading = true @@ -252,30 +255,29 @@ function names.set_log_level(level) end end -local lastislog = 0 - -local function log(category, fmt, ...) - lastislog = 1 - if fmt then - texio.write_nl(format("luaotfload | %s: %s", category, format(fmt, ...))) - elseif category then - texio.write_nl(format("luaotfload | %s", category)) - else - texio.write_nl(format("luaotfload |")) +local function log (category, fmt, ...) + if not suppress_output then + if fmt then + texio.write_nl(format("luaotfload | %s: %s", category, format(fmt, ...))) + elseif category then + texio.write_nl(format("luaotfload | %s", category)) + else + texio.write_nl(format("luaotfload |")) + end + io.flush() end - io.flush() end logs = logs or { } logs.report = logs.report or log -logs.info = logs.info or log +logs.info = logs.info or log local function font_fullinfo(filename, subfont, texmf) local t = { } local f = fontloader.open(filename, subfont) if not f then if trace_loading then - logs.report("error", "failed to open %s", filename) + logs.report("error", "failed to open %s", filename) end return end @@ -769,3 +771,4 @@ names.save = save_names function fonts.names.getfilename(askedname,suffix) -- only supported in mkiv return "" end +-- vim:tw=71:sw=4:ts=4:expandtab -- cgit v1.2.3 From b85a3646ea13a26b2d8506531d2bdf072db81837 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Thu, 11 Apr 2013 00:18:13 +0200 Subject: enable overrides for Context loggers --- otfl-font-nms.lua | 4 ---- 1 file changed, 4 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index a0d81ae..856046c 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -268,10 +268,6 @@ local function log (category, fmt, ...) end end -logs = logs or { } -logs.report = logs.report or log -logs.info = logs.info or log - local function font_fullinfo(filename, subfont, texmf) local t = { } local f = fontloader.open(filename, subfont) -- cgit v1.2.3 From 25444ac8cd48cd5ad7ed32bfcc9a0a1314e2223a Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 15 Apr 2013 00:14:23 +0200 Subject: rewrite filename logger --- otfl-font-nms.lua | 95 +++++++++++++++++-------------------------------------- 1 file changed, 29 insertions(+), 66 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 856046c..b2b5390 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -42,7 +42,6 @@ local utfgsub = unicode.utf8.gsub local suppress_output = false local trace_short = false --tracing adapted to rebuilding of the database inside a document local trace_search = false --trackers.register("names.search", function(v) trace_search = v end) -local trace_loading = false --trackers.register("names.loading", function(v) trace_loading = v end) local function sanitize(str) if str then @@ -244,37 +243,11 @@ end names.resolvespec = names.resolve -function names.set_log_level(level) - if level == 0 then - suppress_output = true - elseif level == 2 then - trace_loading = true - elseif level >= 3 then - trace_loading = true - trace_search = true - end -end - -local function log (category, fmt, ...) - if not suppress_output then - if fmt then - texio.write_nl(format("luaotfload | %s: %s", category, format(fmt, ...))) - elseif category then - texio.write_nl(format("luaotfload | %s", category)) - else - texio.write_nl(format("luaotfload |")) - end - io.flush() - end -end - local function font_fullinfo(filename, subfont, texmf) local t = { } local f = fontloader.open(filename, subfont) if not f then - if trace_loading then - logs.report("error", "failed to open %s", filename) - end + logs.names_loading("error", "failed to open %s", filename) return end local m = fontloader.to_table(f) @@ -304,9 +277,7 @@ local function font_fullinfo(filename, subfont, texmf) end else -- no names table, propably a broken font - if trace_loading then - logs.report("broken font rejected", "%s", basefile) - end + logs.names_loading("broken font rejected", "%s", basefile) return end t.fontname = m.fontname @@ -359,9 +330,7 @@ local function load_font(filename, fontnames, newfontnames, texmf) newmappings[#newmappings+1] = mappings[v] newstatus[basefile].index[index+1] = #newmappings end - if trace_loading then - logs.report("font already indexed", "%s", basefile) - end + logs.names_loading("font already indexed", "%s", basefile) return end local info = fontloader.info(filename) @@ -396,9 +365,7 @@ local function load_font(filename, fontnames, newfontnames, texmf) newstatus[basefile].index[1] = index end else - if trace_loading then - logs.report("failed to load", "%s", basefile) - end + logs.names_loading("failed to load", "%s", basefile) end end end @@ -479,33 +446,31 @@ end local installed_fonts_scanned = false local function scan_installed_fonts(fontnames, newfontnames) - -- Try to query and add font list from operating system. - -- This uses the lualatex-platform module. - logs.info("Scanning fonts known to operating system...") - local fonts = get_installed_fonts() - if fonts and #fonts > 0 then - installed_fonts_scanned = true - if trace_search then - logs.report("operating system fonts found", "%d", #fonts) - end - for key, value in next, fonts do - local file = value.path - if file then - local ext = extname(file) - if ext and font_extensions_set[ext] then - file = path_normalize(file) - if trace_loading then - logs.report("loading font", "%s", file) - end - load_font(file, fontnames, newfontnames, false) + -- Try to query and add font list from operating system. + -- This uses the lualatex-platform module. + logs.info("Scanning fonts known to operating system...") + local fonts = get_installed_fonts() + if fonts and #fonts > 0 then + installed_fonts_scanned = true + if trace_search then + logs.report("operating system fonts found", "%d", #fonts) + end + for key, value in next, fonts do + local file = value.path + if file then + local ext = extname(file) + if ext and font_extensions_set[ext] then + file = path_normalize(file) + logs.names_loading("loading font", "%s", file) + load_font(file, fontnames, newfontnames, false) + end end - end - end - else - if trace_search then - logs.report("Could not retrieve list of installed fonts") - end - end + end + else + if trace_search then + logs.report("Could not retrieve list of installed fonts") + end + end end local function scan_dir(dirname, fontnames, newfontnames, texmf) @@ -539,9 +504,7 @@ local function scan_dir(dirname, fontnames, newfontnames, texmf) for _,file in next, list do file = path_normalize(file) - if trace_loading then - logs.report("loading font", "%s", file) - end + logs.names_loading("loading font", "%s", file) load_font(file, fontnames, newfontnames, texmf) end end -- cgit v1.2.3 From 5a8c4657de6b599e1897d8ac4e685264e0ac0587 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 15 Apr 2013 00:57:10 +0200 Subject: unify logging --- otfl-font-nms.lua | 93 ++++++++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 56 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index b2b5390..0942eda 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -39,9 +39,7 @@ local gsub, match, rpadd = string.gsub, string.match, string.rpadd local gmatch, sub, find = string.gmatch, string.sub, string.find local utfgsub = unicode.utf8.gsub -local suppress_output = false -local trace_short = false --tracing adapted to rebuilding of the database inside a document -local trace_search = false --trackers.register("names.search", function(v) trace_search = v end) +local report = logs.names_report local function sanitize(str) if str then @@ -76,9 +74,10 @@ local function load_names() foundname = luaname end if data then - logs.info("Font names database loaded", "%s", foundname) + report("info", 0, "Font names database loaded", "%s", foundname) else - logs.info([[Font names database not found, generating new one. + report("info", 0, + [[Font names database not found, generating new one. This can take several minutes; please be patient.]]) data = names.update(fontnames_init()) names.save(data) @@ -187,9 +186,10 @@ function names.resolve(_,_,specification) -- the 1st two parameters are used by end if #found == 1 then if kpse.lookup(found[1].filename[1]) then - logs.report("load font", - "font family='%s', subfamily='%s' found: %s", - name, style, found[1].filename[1]) + report("log", 0, "load font", + "font family='%s', subfamily='%s' found: %s", + name, style, found[1].filename[1] + ) return found[1].filename[1], found[1].filename[2] end elseif #found > 1 then @@ -207,9 +207,10 @@ function names.resolve(_,_,specification) -- the 1st two parameters are used by end end if kpse.lookup(closest.filename[1]) then - logs.report("load font", - "font family='%s', subfamily='%s' found: %s", - name, style, closest.filename[1]) + report("log", 0, "load font", + "font family='%s', subfamily='%s' found: %s", + name, style, closest.filename[1] + ) return closest.filename[1], closest.filename[2] end elseif found.fallback then @@ -247,7 +248,7 @@ local function font_fullinfo(filename, subfont, texmf) local t = { } local f = fontloader.open(filename, subfont) if not f then - logs.names_loading("error", "failed to open %s", filename) + report("log", 1, "error", "failed to open %s", filename) return end local m = fontloader.to_table(f) @@ -277,7 +278,7 @@ local function font_fullinfo(filename, subfont, texmf) end else -- no names table, propably a broken font - logs.names_loading("broken font rejected", "%s", basefile) + report("log", 1, "broken font rejected", "%s", basefile) return end t.fontname = m.fontname @@ -305,9 +306,7 @@ local function load_font(filename, fontnames, newfontnames, texmf) if filename then if names.blacklist[filename] or names.blacklist[basename(filename)] then - if trace_search then - logs.report("ignoring font", "%s", filename) - end + report("log", 2, "ignoring font", "%s", filename) return end local timestamp, db_timestamp @@ -330,7 +329,7 @@ local function load_font(filename, fontnames, newfontnames, texmf) newmappings[#newmappings+1] = mappings[v] newstatus[basefile].index[index+1] = #newmappings end - logs.names_loading("font already indexed", "%s", basefile) + report("log", 1, "font already indexed", "%s", basefile) return end local info = fontloader.info(filename) @@ -365,7 +364,7 @@ local function load_font(filename, fontnames, newfontnames, texmf) newstatus[basefile].index[1] = index end else - logs.names_loading("failed to load", "%s", basefile) + report("log", 1, "failed to load", "%s", basefile) end end end @@ -423,10 +422,8 @@ local function read_blacklist() if string.sub(line,1,1) == "-" then whitelist[string.sub(line,2,-1)] = true else - if trace_search then - logs.report("blacklisted file", "%s", line) - end - blacklist[line] = true + report("log", 2, "blacklisted file", "%s", line) + blacklist[line] = true end end end @@ -448,28 +445,24 @@ local installed_fonts_scanned = false local function scan_installed_fonts(fontnames, newfontnames) -- Try to query and add font list from operating system. -- This uses the lualatex-platform module. - logs.info("Scanning fonts known to operating system...") + report("info", 0, "Scanning fonts known to operating system...") local fonts = get_installed_fonts() if fonts and #fonts > 0 then installed_fonts_scanned = true - if trace_search then - logs.report("operating system fonts found", "%d", #fonts) - end + report("log", 2, "operating system fonts found", "%d", #fonts) for key, value in next, fonts do local file = value.path if file then local ext = extname(file) if ext and font_extensions_set[ext] then file = path_normalize(file) - logs.names_loading("loading font", "%s", file) + report("log", 1, "loading font", "%s", file) load_font(file, fontnames, newfontnames, false) end end end else - if trace_search then - logs.report("Could not retrieve list of installed fonts") - end + report("log", 2, "Could not retrieve list of installed fonts") end end @@ -483,28 +476,22 @@ local function scan_dir(dirname, fontnames, newfontnames, texmf) ]] local list, found = { }, { } local nbfound = 0 - if trace_search then - logs.report("scanning", "%s", dirname) - end + report("log", 2, "scanning", "%s", dirname) for _,i in next, font_extensions do for _,ext in next, { i, upper(i) } do found = glob(format("%s/**.%s$", dirname, ext)) -- note that glob fails silently on broken symlinks, which happens -- sometimes in TeX Live. - if trace_search then - logs.report("fonts found", "%s '%s' fonts found", #found, ext) - end + report("log", 2, "fonts found", "%s '%s' fonts found", #found, ext) nbfound = nbfound + #found table.append(list, found) end end - if trace_search then - logs.report("fonts found", "%d fonts found in '%s'", nbfound, dirname) - end + report("log", 2, "fonts found", "%d fonts found in '%s'", nbfound, dirname) for _,file in next, list do file = path_normalize(file) - logs.names_loading("loading font", "%s", file) + report("log", 1, "loading font", "%s", file) load_font(file, fontnames, newfontnames, texmf) end end @@ -515,9 +502,9 @@ local function scan_texmf_fonts(fontnames, newfontnames) variables OPENTYPEFONTS and TTFONTS of texmf.cnf ]] if expandpath("$OSFONTDIR"):is_empty() then - logs.info("Scanning TEXMF fonts...") + report("info", 0, "Scanning TEXMF fonts...") else - logs.info("Scanning TEXMF and OS fonts...") + report("info", 0, "Scanning TEXMF and OS fonts...") end local fontdirs = expandpath("$OPENTYPEFONTS"):gsub("^%.", "") fontdirs = fontdirs .. expandpath("$TTFONTS"):gsub("^%.", "") @@ -548,9 +535,7 @@ local function read_fonts_conf(path, results) ]] local f = io.open(path) if not f then - if trace_search then - logs.report("cannot open file", "%s", path) - end + report("log", 2, "cannot open file", "%s", path) return results end local incomments = false @@ -648,10 +633,8 @@ local function scan_os_fonts(fontnames, newfontnames) - fontcache for Unix (reads the fonts.conf file and scans the directories) - a static set of directories for Windows and MacOSX ]] - logs.info("Scanning OS fonts...") - if trace_search then - logs.info("Searching in static system directories...") - end + report("info", 0, "Scanning OS fonts...") + report("info", 2, "Searching in static system directories...") for _,d in next, get_os_dirs() do scan_dir(d, fontnames, newfontnames, false) end @@ -663,7 +646,7 @@ local function update_names(fontnames, force) - fontnames is the final table to return - force is whether we rebuild it from scratch or not ]] - logs.info("Updating the font names database") + report("info", 0, "Updating the font names database") if force then fontnames = fontnames_init() @@ -673,10 +656,8 @@ local function update_names(fontnames, force) end if fontnames.version ~= names.version then fontnames = fontnames_init() - if trace_search then - logs.report("No font names database or old one found; " - .."generating new one") - end + report("log", 0, "No font names database or old one found; " + .."generating new one") end end local newfontnames = fontnames_init() @@ -700,10 +681,10 @@ local function save_names(fontnames) local luaname, lucname = make_name(path) table.tofile(luaname, fontnames, true) caches.compile(fontnames,luaname,lucname) - logs.info("Font names database saved") + report("info", 0, "Font names database saved") return path else - logs.info("Failed to save names database") + report("info", 0, "Failed to save names database") return nil end end -- cgit v1.2.3 From cf7d6eceb827fc8d7c0c0afc2255155552f030af Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 16 Apr 2013 12:13:46 +0200 Subject: =?UTF-8?q?add=20fixes=20courtesy=20of=20=C3=89lie=20Roux=20to=20t?= =?UTF-8?q?he=20database=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- otfl-font-nms.lua | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 0942eda..8869bef 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -88,9 +88,16 @@ end local synonyms = { regular = { "normal", "roman", "plain", "book", "medium" }, - bold = { "boldregular", "demi", "demibold" }, + --- TODO note from Élie Roux + --- boldregular was for old versions of Linux Libertine, is it still useful? + --- semibold is in new versions of Linux Libertine, but there is also a bold, + --- not sure it's useful here... + bold = { "demi", "demibold", "semibold", "boldregular" }, italic = { "regularitalic", "normalitalic", "oblique", "slanted" }, - bolditalic = { "boldoblique", "boldslanted", "demiitalic", "demioblique", "demislanted", "demibolditalic" }, + bolditalic = { + "boldoblique", "boldslanted", "demiitalic", "demioblique", + "demislanted", "demibolditalic", "semibolditalic" + }, } local loaded = false @@ -585,7 +592,7 @@ local function read_fonts_conf(path, results) elseif not lfs.isfile(include) and not lfs.isdir(include) then include = file.join(file.dirname(path), include) end - if lfs.isfile(include) then + if lfs.isfile(include) and kpse.readable_file(include) then -- maybe we should prevent loops here? -- we exclude path with texmf in them, as they should -- be found otherwise -- cgit v1.2.3 From 0909225c254332ac9cfa587f3d7212bd4141c83e Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 16 Apr 2013 20:27:43 +0200 Subject: make fonts.names.resolve() a local --- otfl-font-nms.lua | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 8869bef..095ecbd 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -11,7 +11,7 @@ fonts.names = fonts.names or { } local names = fonts.names local names_dir = "luatex-cache/generic/names" -names.version = 2.010 -- not the same as in context +names.version = 2.2 -- not the same as in context names.data = nil names.path = { basename = "otfl-names.lua", @@ -103,7 +103,18 @@ local synonyms = { local loaded = false local reloaded = false -function names.resolve(_,_,specification) -- the 1st two parameters are used by ConTeXt +--[[doc-- + +Luatex-fonts, the font-loader package luaotfload imports, comes with +basic file location facilities (see luatex-fonts-syn.lua). +However, the builtin functionality is too limited to be of more than +basic use, which is why we supply our own resolver that accesses the +font database created by the mkluatexfontdb script. + +--doc]]-- + +local resolve resolve = function (_,_,specification) -- the 1st two parameters are used by ConTeXt + inspect(specification) local name = sanitize(specification.name) local style = sanitize(specification.style) or "regular" @@ -229,7 +240,7 @@ function names.resolve(_,_,specification) -- the 1st two parameters are used by names.data = names.update(names.data) names.save(names.data) reloaded = true - return names.resolve(_,_,specification) + return resolve(_,_,specification) else -- else, fallback to filename -- XXX: specification.name is empty with absolute paths, looks @@ -242,14 +253,15 @@ function names.resolve(_,_,specification) -- the 1st two parameters are used by names.data = names.update() names.save(names.data) reloaded = true - return names.resolve(_,_,specification) + return resolve(_,_,specification) else return specification.name, false end end end -names.resolvespec = names.resolve +names.resolve = resolve --- replace the resolver from luatex-fonts +names.resolvespec = resolve local function font_fullinfo(filename, subfont, texmf) local t = { } -- cgit v1.2.3 From 5a8500f312740eeca9dd7bc8a507d6e88d7653f7 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Tue, 16 Apr 2013 18:47:44 +0200 Subject: Preventing loop-references in fontconfig files I just had this case on a recent Ubuntu... Conflicts: otfl-font-nms.lua --- otfl-font-nms.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 095ecbd..8e89ea5 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -38,6 +38,7 @@ local upper, lower, format = string.upper, string.lower, string.format local gsub, match, rpadd = string.gsub, string.match, string.rpadd local gmatch, sub, find = string.gmatch, string.sub, string.find local utfgsub = unicode.utf8.gsub +local tableinsert = table.insert local report = logs.names_report @@ -547,12 +548,13 @@ end in OSFONTDIR. ]] -local function read_fonts_conf(path, results) +local read_fonts_conf read_fonts_conf = function (path, results, passed_paths) --[[ This function parses /etc/fonts/fonts.conf and returns all the dir it finds. The code is minimal, please report any error it may generate. ]] local f = io.open(path) + tableinsert(passed_paths, path) if not f then report("log", 2, "cannot open file", "%s", path) return results @@ -604,14 +606,14 @@ local function read_fonts_conf(path, results) elseif not lfs.isfile(include) and not lfs.isdir(include) then include = file.join(file.dirname(path), include) end - if lfs.isfile(include) and kpse.readable_file(include) then + if lfs.isfile(include) and kpse.readable_file(include) and not table.contains(passed_paths, include) then -- maybe we should prevent loops here? -- we exclude path with texmf in them, as they should -- be found otherwise - read_fonts_conf(include, results) + read_fonts_conf(include, results, passed_paths) elseif lfs.isdir(include) then for _,f in next, glob(file.join(include, "*.conf")) do - read_fonts_conf(f, results) + read_fonts_conf(f, results, passed_paths) end end end @@ -639,7 +641,7 @@ local function get_os_dirs() else for _,p in next, {"/usr/local/etc/fonts/fonts.conf", "/etc/fonts/fonts.conf"} do if lfs.isfile(p) then - return read_fonts_conf("/etc/fonts/fonts.conf", {}) + return read_fonts_conf("/etc/fonts/fonts.conf", {}, {}) end end end -- cgit v1.2.3 From 6a552fe231117c66188afc45503a884507e13e97 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 16 Apr 2013 22:18:21 +0200 Subject: organize font-nms --- otfl-font-nms.lua | 307 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 195 insertions(+), 112 deletions(-) (limited to 'otfl-font-nms.lua') diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 8e89ea5..13921a2 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -6,6 +6,43 @@ if not modules then modules = { } end modules ['font-nms'] = { license = "GNU GPL v2" } +--- Luatex builtins +local dofile = dofile +local load = load +local next = next +local pcall = pcall +local require = require +local tonumber = tonumber + +local iolines = io.lines +local ioopen = io.open +local kpseexpand_path = kpse.expand_path +local mathabs = math.abs +local stringfind = string.find +local stringformat = string.format +local stringgmatch = string.gmatch +local stringgsub = string.gsub +local stringlower = string.lower +local stringsub = string.sub +local stringupper = string.upper +local tableinsert = table.insert +local texiowrite_nl = texio.write_nl +local utf8gsub = unicode.utf8.gsub +local utf8lower = unicode.utf8.lower + +--- these come from Lualibs/Context +local dirglob = dir.glob +local filebasename = file.basename +local filecollapsepath = file.collapsepath +local fileextname = file.extname +local filejoin = file.join +local filereplacesuffix = file.replacesuffix +local filesplitpath = file.splitpath +local stringis_empty = string.is_empty +local stringsplit = string.split +local stringstrip = string.strip + +--- the font loader namespace is “fonts”, same as in Context fonts = fonts or { } fonts.names = fonts.names or { } @@ -15,12 +52,13 @@ names.version = 2.2 -- not the same as in context names.data = nil names.path = { basename = "otfl-names.lua", - dir = file.join(kpse.expand_var("$TEXMFVAR"), names_dir), + dir = filejoin(kpse.expand_var("$TEXMFVAR"), names_dir), } local success = pcall(require, "luatexbase.modutils") if success then - success = pcall(luatexbase.require_module, "lualatex-platform", "2011/03/30") + success = pcall(luatexbase.require_module, + "lualatex-platform", "2011/03/30") end local get_installed_fonts if success then @@ -30,27 +68,21 @@ else end end -local splitpath, collapsepath = file.splitpath, file.collapsepath -local expandpath = kpse.expand_path -local glob, basename = dir.glob, file.basename -local extname = file.extname -local upper, lower, format = string.upper, string.lower, string.format -local gsub, match, rpadd = string.gsub, string.match, string.rpadd -local gmatch, sub, find = string.gmatch, string.sub, string.find -local utfgsub = unicode.utf8.gsub -local tableinsert = table.insert +--[[doc-- +Auxiliary functions +--doc]]-- + local report = logs.names_report -local function sanitize(str) - if str then - return utfgsub(lower(str), "[^%a%d]", "") - else - return str -- nil +local sanitize_string = function (str) + if str ~= nil then + return utf8gsub(utf8lower(str), "[^%a%d]", "") end + return nil end -local function fontnames_init() +local fontnames_init = function ( ) return { mappings = { }, status = { }, @@ -58,22 +90,61 @@ local function fontnames_init() } end -local function make_name(path) - return file.replacesuffix(path, "lua"), file.replacesuffix(path, "luc") +local make_name = function (path) + return filereplacesuffix(path, "lua"), filereplacesuffix(path, "luc") end -local function load_names() - local path = file.join(names.path.dir, names.path.basename) - local luaname, lucname = make_name(path) - local foundname - local data - if file.isreadable(lucname) then - data = dofile(lucname) - foundname = lucname - elseif file.isreadable(luaname) then - data = dofile(luaname) - foundname = luaname +--- When loading a lua file we try its binary complement first, which +--- is assumed to be located at an identical path, carrying the suffix +--- .luc. +--- Furthermore, we memoize loaded files along the way to avoid +--- duplication. + +local code_cache = { } + +--- string -> (string * table) +local load_lua_file = function (path) + local code = code_cache[path] + if code then return path, code() end + + local foundname = filereplacesuffix(path, "luc") + + local fh = ioopen(foundname, "rb") -- try bin first + if fh then + local chunk = fh:read"*all" + fh:close() + code = load(chunk, "b") end + + if not code then --- fall back to text file + foundname = filereplacesuffix(path, "lua") + fh = ioopen(foundname, "rb") + if fh then + local chunk = fh:read"*all" + fh:close() + code = load(chunk, "t") + end + end + + if not code then return nil, nil end + + code_cache[path] = code --- insert into memo + return foundname, code() +end + +--- define locals in scope +local load_names +local save_names +local scan_external_dir +local update_names +local read_fonts_conf +local resolve + + +load_names = function ( ) + local path = filejoin(names.path.dir, names.path.basename) + local foundname, data = load_lua_file(path) + if data then report("info", 0, "Font names database loaded", "%s", foundname) else @@ -83,22 +154,27 @@ local function load_names() data = names.update(fontnames_init()) names.save(data) end - texio.write_nl("") + texiowrite_nl("") return data end local synonyms = { - regular = { "normal", "roman", "plain", "book", "medium" }, + regular = { "normal", "roman", + "plain", "book", + "medium" }, --- TODO note from Élie Roux --- boldregular was for old versions of Linux Libertine, is it still useful? --- semibold is in new versions of Linux Libertine, but there is also a bold, --- not sure it's useful here... - bold = { "demi", "demibold", "semibold", "boldregular" }, - italic = { "regularitalic", "normalitalic", "oblique", "slanted" }, + bold = { "demi", "demibold", + "semibold", "boldregular", }, + italic = { "regularitalic", "normalitalic", + "oblique", "slanted", }, bolditalic = { - "boldoblique", "boldslanted", "demiitalic", "demioblique", - "demislanted", "demibolditalic", "semibolditalic" - }, + "boldoblique", "boldslanted", + "demiitalic", "demioblique", + "demislanted", "demibolditalic", + "semibolditalic", }, } local loaded = false @@ -114,10 +190,9 @@ font database created by the mkluatexfontdb script. --doc]]-- -local resolve resolve = function (_,_,specification) -- the 1st two parameters are used by ConTeXt - inspect(specification) - local name = sanitize(specification.name) - local style = sanitize(specification.style) or "regular" +resolve = function (_,_,specification) -- the 1st two parameters are used by ConTeXt + local name = sanitize_string(specification.name) + local style = sanitize_string(specification.style) or "regular" local size if specification.optsize then @@ -128,7 +203,7 @@ local resolve resolve = function (_,_,specification) -- the 1st two parameters a if not loaded then - names.data = names.load() + names.data = load_names() loaded = true end @@ -137,12 +212,12 @@ local resolve resolve = function (_,_,specification) -- the 1st two parameters a if data.mappings then local found = { } for _,face in next, data.mappings do - local family = sanitize(face.names and face.names.family) - local subfamily = sanitize(face.names and face.names.subfamily) - local fullname = sanitize(face.names and face.names.fullname) - local psname = sanitize(face.names and face.names.psname) - local fontname = sanitize(face.fontname) - local pfullname = sanitize(face.fullname) + local family = sanitize_string(face.names and face.names.family) + local subfamily = sanitize_string(face.names and face.names.subfamily) + local fullname = sanitize_string(face.names and face.names.fullname) + local psname = sanitize_string(face.names and face.names.psname) + local fontname = sanitize_string(face.fontname) + local pfullname = sanitize_string(face.fullname) local optsize, dsnsize, maxsize, minsize if #face.size > 0 then optsize = face.size @@ -219,7 +294,7 @@ local resolve resolve = function (_,_,specification) -- the 1st two parameters a local least = math.huge -- initial value is infinity for i,face in next, found do local dsnsize = face.size[1]/10 - local difference = math.abs(dsnsize-size) + local difference = mathabs(dsnsize-size) if difference < least then closest = face least = difference @@ -261,9 +336,6 @@ local resolve resolve = function (_,_,specification) -- the 1st two parameters a end end -names.resolve = resolve --- replace the resolver from luatex-fonts -names.resolvespec = resolve - local function font_fullinfo(filename, subfont, texmf) local t = { } local f = fontloader.open(filename, subfont) @@ -304,7 +376,7 @@ local function font_fullinfo(filename, subfont, texmf) t.fontname = m.fontname t.fullname = m.fullname t.familyname = m.familyname - t.filename = { texmf and basename(filename) or filename, subfont } + t.filename = { texmf and filebasename(filename) or filename, subfont } t.weight = m.pfminfo.weight t.width = m.pfminfo.width t.slant = m.italicangle @@ -322,10 +394,11 @@ local function load_font(filename, fontnames, newfontnames, texmf) local newstatus = newfontnames.status local mappings = fontnames.mappings local status = fontnames.status - local basefile = texmf and basename(filename) or filename + local basename = filebasename(filename) + local basefile = texmf and basename or filename if filename then if names.blacklist[filename] or - names.blacklist[basename(filename)] then + names.blacklist[basename] then report("log", 2, "ignoring font", "%s", filename) return end @@ -333,7 +406,7 @@ local function load_font(filename, fontnames, newfontnames, texmf) db_timestamp = status[basefile] and status[basefile].timestamp timestamp = lfs.attributes(filename, "modification") - local index_status = newstatus[basefile] or (not texmf and newstatus[basename(filename)]) + local index_status = newstatus[basefile] or (not texmf and newstatus[basename]) if index_status and index_status.timestamp == timestamp then -- already indexed this run return @@ -399,23 +472,23 @@ local function path_normalize(path) - using kpse.readable_file on Win32 ]] if os.type == "windows" or os.type == "msdos" or os.name == "cygwin" then - path = path:gsub('\\', '/') - path = path:lower() - path = path:gsub('^/cygdrive/(%a)/', '%1:/') + path = stringgsub(path, '\\', '/') + path = stringlower(path) + path = stringgsub(path, '^/cygdrive/(%a)/', '%1:/') end if os.type ~= "windows" and os.type ~= "msdos" then local dest = lfs.readlink(path) if dest then if kpse.readable_file(dest) then path = dest - elseif kpse.readable_file(file.join(file.dirname(path), dest)) then - path = file.join(file.dirname(path), dest) + elseif kpse.readable_file(filejoin(file.dirname(path), dest)) then + path = filejoin(file.dirname(path), dest) else -- broken symlink? end end end - path = collapsepath(path) + path = filecollapsepath(path) return path end @@ -432,15 +505,16 @@ local function read_blacklist() if files and type(files) == "table" then for _,v in next, files do - for line in io.lines(v) do - line = line:strip() -- to get rid of lines like " % foo" - if line:find("^%%") or line:is_empty() then + for line in iolines(v) do + line = stringstrip(line) -- to get rid of lines like " % foo" + local first_chr = stringsub(line, 1, 1) --- faster than find + if first_chr == "%" or stringis_empty(line) then -- comment or empty line else - line = line:split("%")[1] - line = line:strip() - if string.sub(line,1,1) == "-" then - whitelist[string.sub(line,2,-1)] = true + line = stringsplit(line, "%")[1] + line = stringstrip(line) + if stringsub(line, 1, 1) == "-" then + whitelist[stringsub(line, 2, -1)] = true else report("log", 2, "blacklisted file", "%s", line) blacklist[line] = true @@ -473,7 +547,7 @@ local function scan_installed_fonts(fontnames, newfontnames) for key, value in next, fonts do local file = value.path if file then - local ext = extname(file) + local ext = fileextname(file) if ext and font_extensions_set[ext] then file = path_normalize(file) report("log", 1, "loading font", "%s", file) @@ -498,8 +572,8 @@ local function scan_dir(dirname, fontnames, newfontnames, texmf) local nbfound = 0 report("log", 2, "scanning", "%s", dirname) for _,i in next, font_extensions do - for _,ext in next, { i, upper(i) } do - found = glob(format("%s/**.%s$", dirname, ext)) + for _,ext in next, { i, stringupper(i) } do + found = dirglob(stringformat("%s/**.%s$", dirname, ext)) -- note that glob fails silently on broken symlinks, which happens -- sometimes in TeX Live. report("log", 2, "fonts found", "%s '%s' fonts found", #found, ext) @@ -521,15 +595,15 @@ local function scan_texmf_fonts(fontnames, newfontnames) This function scans all fonts in the texmf tree, through kpathsea variables OPENTYPEFONTS and TTFONTS of texmf.cnf ]] - if expandpath("$OSFONTDIR"):is_empty() then + if stringis_empty(kpseexpand_path("$OSFONTDIR")) then report("info", 0, "Scanning TEXMF fonts...") else report("info", 0, "Scanning TEXMF and OS fonts...") end - local fontdirs = expandpath("$OPENTYPEFONTS"):gsub("^%.", "") - fontdirs = fontdirs .. expandpath("$TTFONTS"):gsub("^%.", "") - if not fontdirs:is_empty() then - for _,d in next, splitpath(fontdirs) do + local fontdirs = stringgsub(kpseexpand_path("$OPENTYPEFONTS"), "^%.", "") + fontdirs = fontdirs .. stringgsub(kpseexpand_path("$TTFONTS"), "^%.", "") + if not stringis_empty(fontdirs) then + for _,d in next, filesplitpath(fontdirs) do scan_dir(d, fontnames, newfontnames, true) end end @@ -548,71 +622,76 @@ end in OSFONTDIR. ]] -local read_fonts_conf read_fonts_conf = function (path, results, passed_paths) +--- (string -> tab -> tab -> tab) +read_fonts_conf = function (path, results, passed_paths) --[[ - This function parses /etc/fonts/fonts.conf and returns all the dir it finds. - The code is minimal, please report any error it may generate. + This function parses /etc/fonts/fonts.conf and returns all the dir + it finds. The code is minimal, please report any error it may + generate. ]] - local f = io.open(path) + local fh = ioopen(path) tableinsert(passed_paths, path) - if not f then + if not fh then report("log", 2, "cannot open file", "%s", path) return results end local incomments = false - for line in f:lines() do + for line in fh:lines() do while line and line ~= "" do -- spaghetti code... hmmm... if incomments then - local tmp = find(line, '-->') + local tmp = stringfind(line, '-->') --- wtf? if tmp then incomments = false - line = sub(line, tmp+3) + line = stringsub(line, tmp+3) else line = nil end else - local tmp = find(line, '