From 30f83b71d2110d38b99069e4c22d950f097a9315 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 22 Apr 2013 16:03:50 +0200 Subject: make main files recognize the new ``luaotfload-`` prefix --- fontdbutil.lua | 391 ++++++++++++++++++++++++++++++++++++++++++++++++ luaotfload-font-nms.lua | 4 +- luaotfload.dtx | 258 ++++++++++++++++++-------------- mkluatexfontdb.lua | 391 ------------------------------------------------ 4 files changed, 542 insertions(+), 502 deletions(-) create mode 100755 fontdbutil.lua delete mode 100755 mkluatexfontdb.lua diff --git a/fontdbutil.lua b/fontdbutil.lua new file mode 100755 index 0000000..a17dbe7 --- /dev/null +++ b/fontdbutil.lua @@ -0,0 +1,391 @@ +#!/usr/bin/env texlua +--[[ +This file was originally written by Elie Roux and Khaled Hosny and is under CC0 +license (see http://creativecommons.org/publicdomain/zero/1.0/legalcode). + +This file is a wrapper for the luaotfload's font names module. It is part of the +luaotfload bundle, please see the luaotfload documentation for more info. +--]] + +kpse.set_program_name"luatex" + +local stringformat = string.format +local texiowrite_nl = texio.write_nl +local stringfind = string.find +local stringlower = string.lower + +-- First we need to be able to load module (code copied from +-- luatexbase-loader.sty): +local loader_file = "luatexbase.loader.lua" +local loader_path = assert(kpse.find_file(loader_file, "lua"), + "File '"..loader_file.."' not found") + +--texiowrite_nl("("..loader_path..")") +dofile(loader_path) -- FIXME this pollutes stdout with filenames + +--[[doc-- +Depending on how the script is called we change its behavior. +For backwards compatibility, moving or symlinking the script to a +file name starting with \fileent{mkluatexfontdb} will cause it to +trigger a database update on every run. +Running as \fileent{fontdbutil} -- the new name -- will do this upon +request only. + +There are two naming conventions followed here: firstly that of +utilities such as \fileent{mktexpk}, \fileent{mktexlsr} and the likes, +and secondly that of \fileent{fmtutil}. +After support for querying the database was added, the latter appeared +to be the more appropriate. +--doc]]-- + +config = config or { } +local config = config +config.luaotfload = config.luaotfload or { } + +do -- we don’t have file.basename and the likes yet, so inline parser ftw + local C, P = lpeg.C, lpeg.P + local lpegmatch = lpeg.match + local slash = P"/" + local dot = P"." + local noslash = 1 - slash + local slashes = slash^1 + local path = slashes^-1 * (noslash^1 * slashes)^1 + local thename = (1 - slash - dot)^1 + local extension = dot * (1 - slash - dot)^1 + local p_basename = path^-1 * C(thename) * extension^-1 * P(-1) + + -- if stringfind(stringlower(arg[0]), "^fontdbutil") then + local self = lpegmatch(p_basename, stringlower(arg[0])) + if self == "fontdbutil" then + config.luaotfload.self = "fontdbutil" + else + config.luaotfload.self = "mkluatexfontdb" + end +end + +config.lualibs = config.lualibs or { } +config.lualibs.verbose = false +config.lualibs.prefer_merged = true +config.lualibs.load_extended = false + +require"lualibs" +require"luaotfload-basics-gen.lua" +require"luaotfload-luat-ovr.lua" --- this populates the logs.* namespace +require"luaotfload-font-nms" +require"alt_getopt" + +local version = "2.2" -- same version number as luaotfload +local names = fonts.names + +local db_src_out = names.path.dir.."/"..names.path.basename +local db_bin_out = file.replacesuffix(db_src_out, "luc") + +local help_messages = { + fontdbutil = [[ + +Usage: %s [OPTION]... + +Operations on the LuaTeX font database. + +This tool is part of the luaotfload package. Valid options are: + +------------------------------------------------------------------------------- + VERBOSITY AND LOGGING + + -q --quiet don't output anything + -v --verbose=LEVEL be more verbose (print the searched directories) + -vv print the loaded fonts + -vvv print all steps of directory searching + -V --version print version and exit + -h --help print this message + +------------------------------------------------------------------------------- + DATABASE + + -u --update update the database + -f --force force re-indexing all fonts + + --find="font name" query the database for a font name + -F --fuzzy look for approximate matches if --find fails + --limit=n limit display of fuzzy matches to + (default: n = 1) + -i --info display font metadata + + --log=stdout redirect log output to stdout + +The font database will be saved to + %s + %s + +]], + mkluatexfontdb = [[ + +Usage: %s [OPTION]... + +Rebuild the LuaTeX font database. + +Valid options: + -f --force force re-indexing all fonts + -q --quiet don't output anything + -v --verbose=LEVEL be more verbose (print the searched directories) + -vv print the loaded fonts + -vvv print all steps of directory searching + -V --version print version and exit + -h --help print this message + +The font database will be saved to + %s + %s + +]], +} + +local help_msg = function ( ) + local template = help_messages[config.luaotfload.self] + or help.messages.fontdbutil + texiowrite_nl(stringformat(template, config.luaotfload.self, db_src_out, db_bin_out)) +end + +local version_msg = function ( ) + texiowrite_nl(stringformat( + "%s version %s, database version %s.\n", + config.luaotfload.self, version, names.version)) +end + +local show_info_items = function (fontinfo) + local items = table.sortedkeys(fontinfo) + for n = 1, #items do + local item = items[n] + texiowrite_nl(stringformat( + [[ %11s: %s]], item, fontinfo[item])) + end +end + +local show_font_info = function (filename) + local fullname = resolvers.findfile(filename) + if fullname then + local fontinfo = fontloader.info(fullname) + local nfonts = #fontinfo + if nfonts > 0 then -- true type collection + logs.names_report(true, 0, "resolve", + [[%s is a font collection]], filename) + for n = 1, nfonts do + logs.names_report(true, 0, "resolve", + [[showing info for font no. %d]], n) + show_info_items(fontinfo[n]) + end + else + show_info_items(fontinfo) + end + else + logs.names_report(true, 0, "resolve", + "font %s not found", filename) + end +end + +--[[-- +Running the scripts triggers one or more actions that have to be +executed in the correct order. To avoid duplication we track them in a +set. +--]]-- + +local action_sequence = { + "loglevel", "help", "version", "generate", "query" +} +local action_pending = table.tohash(action_sequence, false) + +action_pending.loglevel = true --- always set the loglevel +action_pending.generate = false --- this is the default action + +local actions = { } --- (jobspec -> (bool * bool)) list + +actions.loglevel = function (job) + logs.set_loglevel(job.log_level) + logs.names_report("log", 2, "util", + "setting log level", "%d", job.log_level) + return true, true +end + +actions.version = function (job) + version_msg() + return true, false +end + +actions.help = function (job) + help_msg() + return true, false +end + +actions.generate = function (job) + local fontnames, savedname + fontnames = names.update(fontnames, job.force_reload) + logs.names_report("log", 0, "db", + "fonts in the database", "%i", #fontnames.mappings) + savedname = names.save(fontnames) + if savedname then --- FIXME have names.save return bool + return true, true + end + return false, false +end + +actions.query = function (job) + + local query = job.query + local tmpspec = { + name = query, + lookup = "name", + specification = "name:" .. query, + optsize = 0, + } + + local foundname, _whatever, success = + fonts.names.resolve(nil, nil, tmpspec) + + if success then + logs.names_report(false, 0, + "resolve", "Font “%s” found!", query) + logs.names_report(false, 0, + "resolve", "Resolved file name “%s”:", foundname) + if job.show_info then + show_font_info(foundname) + end + else + logs.names_report(false, 0, + "resolve", "Cannot find “%s”.", query) + if job.fuzzy == true then + logs.names_report(false, 2, + "resolve", "Looking for close matches, this may take a while ...") + local success = fonts.names.find_closest(query, job.fuzzy_limit) + end + end + return true, true +end + +--[[-- +Command-line processing. +mkluatexfontdb.lua relies on the script alt_getopt to process argv and +analyzes its output. + +TODO with extended lualibs we have the functionality from the +environment.* namespace that could eliminate the dependency on +alt_getopt. +--]]-- + +local process_cmdline = function ( ) -- unit -> jobspec + local result = { -- jobspec + force_reload = nil, + query = "", + log_level = 1, + } + + if config.luaotfload.self == "mkluatexfontdb" then + action_pending["generate"] = true + end + + local long_options = { + find = 1, + force = "f", + fuzzy = "F", + help = "h", + info = "i", + limit = 1, + log = 1, + quiet = "q", + update = "u", + verbose = 1 , + version = "V", + } + + local short_options = "fFiquvVh" + + local options, _, optarg = + alt_getopt.get_ordered_opts (arg, short_options, long_options) + + local nopts = #options + for n=1, nopts do + local v = options[n] + if v == "q" then + result.log_level = 0 + elseif v == "u" then + action_pending["generate"] = true + elseif v == "v" then + if result.log_level > 0 then + result.log_level = result.log_level + 1 + else + result.log_level = 2 + end + elseif v == "V" then + action_pending["version"] = true + elseif v == "h" then + action_pending["help"] = true + elseif v == "f" then + result.update = true + result.force_reload = 1 + elseif v == "verbose" then + local lvl = optarg[n] + if lvl then + result.log_level = tonumber(lvl) + end + elseif v == "log" then + local str = optarg[n] + if str then + logs.set_logout(str) + end + elseif v == "find" then + action_pending["query"] = true + result.query = optarg[n] + elseif v == "F" then + result.fuzzy = true + elseif v == "limit" then + local lim = optarg[n] + if lim then + result.fuzzy_limit = tonumber(lim) + end + elseif v == "i" then + result.show_info = true + end + end + return result +end + +local main = function ( ) -- unit -> int + local retval = 0 + local job = process_cmdline() + +-- inspect(action_pending) +-- inspect(job) + + for i=1, #action_sequence do + local actionname = action_sequence[i] + local exit = false + if action_pending[actionname] then + logs.names_report("log", 3, "util", "preparing for task", + "%s", actionname) + + local action = actions[actionname] + local success, continue = action(job) + + if not success then + logs.names_report(false, 0, "util", + "could not finish task", "%s", actionname) + retval = -1 + exit = true + elseif not continue then + logs.names_report(false, 3, "util", + "task completed, exiting", "%s", actionname) + exit = true + else + logs.names_report(false, 3, "util", + "task completed successfully", "%s", actionname) + end + end + if exit then break end + end + + texiowrite_nl"" + return retval +end + +return main() + +-- vim:tw=71:sw=4:ts=4:expandtab diff --git a/luaotfload-font-nms.lua b/luaotfload-font-nms.lua index cec2a54..54abf67 100644 --- a/luaotfload-font-nms.lua +++ b/luaotfload-font-nms.lua @@ -66,7 +66,7 @@ local names = fonts.names names.version = 2.2 names.data = nil names.path = { - basename = "otfl-names.lua", + basename = "luaotfload-names.lua", dir = "", path = "", } @@ -704,7 +704,7 @@ names.blacklist = { } local function read_blacklist() local files = { - kpselookup("otfl-blacklist.cnf", {all=true, format="tex"}) + kpselookup("luaotfload-blacklist.cnf", {all=true, format="tex"}) } local blacklist = names.blacklist local whitelist = { } diff --git a/luaotfload.dtx b/luaotfload.dtx index 3685083..efc53eb 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -315,7 +315,7 @@ and the derived files % The next example shows how to load the \emphasis{Porson} font digitized by % the Greek Font Society using \XETEX-style syntax and an absolute path from a % non-standard directory: -% +% % \begin{quote} % \begin{verbatim} % \font\gfsporson="[/tmp/GFSPorson.otf]" at 12pt @@ -486,7 +486,7 @@ and the derived files % Their arguments are names of \LUA tables that contain % values for the respective features.\footnote{% % For examples of the table layout please refer to the -% section of the file \fileent{otfl-fonts-ext.lua} where the +% section of the file \fileent{luaotfload-fonts-ext.lua} where the % default values are defined. % Alternatively and with loss of information, you can dump % those tables into your terminal by issuing @@ -701,7 +701,7 @@ and the derived files % approximate matching. % Suppose you cannot precisely remember if the variant of % \identifier{Iwona} you are looking for was “Bright” or “Light”. -% The query +% The query % % \begin{quote} % \begin{verbatim} @@ -724,7 +724,7 @@ and the derived files % \LUATEX reference manual.\footnote{% % In \TEX Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}. % } -% +% % \verb|fontdbutil --help| will list the available command line % switches, including some not discussed in detail here. % @@ -737,7 +737,7 @@ and the derived files % running \verb|fontdbutil -v| to increase verbosity. % Take a note of the \emphasis{filename} of the font that database % creation fails with and append it to the file -% \fileent{otfl-blacklist.cnf}. +% \fileent{luaotfload-blacklist.cnf}. % % A blacklist file is a list of font filenames, one per line. % Specifying the full path to where the file is located is optional, the @@ -754,8 +754,8 @@ and the derived files % } % or just leave it in the working directory of your document. % \identifier{luaotfload} reads all files named -% \fileent{otfl-blacklist.cnf} it finds, so the fonts in -% \fileent{./otfl-blacklist.cnf} extend the global blacklist. +% \fileent{luaotfload-blacklist.cnf} it finds, so the fonts in +% \fileent{./luaotfload-blacklist.cnf} extend the global blacklist. % % Furthermore, a filename prepended with a dash character (|-|) is % removed from the blacklist, causing it to be temporarily whitelisted @@ -814,10 +814,10 @@ and the derived files % \def\incitem#1{% % \normalitem{\fileent{#1}} % } -% \fileitem{luatex-fonts.lua}{otfl-fonts.lua} +% \fileitem{luatex-fonts.lua}{luaotfload-fonts.lua} % The wrapper that loads the font loader code. % -% \fileitem{luatex-fonts-merged.lua}{otfl-fonts-merged.lua} +% \fileitem{luatex-fonts-merged.lua}{luaotfload-fonts-merged.lua} % The font loader package. % It is generated by \fileent{mtx-package}, a \LUA % source code merging tool developed by Hans @@ -890,10 +890,10 @@ and the derived files % instead. % Their names remain the same as in \CONTEXT (without the % \verb|otfl|-prefix) since they are hard-coded in -% \fileent{otfl-fonts.lua}. +% \fileent{luaotfload-fonts.lua}. % Thus if you prefer running bleeding edge code from the % \CONTEXT beta, all you have to do is remove -% \fileent{otfl-fonts-merged.lua} from the search path. +% \fileent{luaotfload-fonts-merged.lua} from the search path. % % \end{itemize} % @@ -908,20 +908,20 @@ and the derived files % \normalitem{\fileent{#1}}% % \space--\hskip1em % } -% \ouritem {otfl-font-otc.lua} \fileent{font-otc} from \CONTEXT; +% \ouritem {luaotfload-font-otc.lua} \fileent{font-otc} from \CONTEXT; % font feature handling. -% \ouritem {otfl-lib-dir.lua} \fileent{l-dir} from \CONTEXT; +% \ouritem {luaotfload-lib-dir.lua} \fileent{l-dir} from \CONTEXT; % contains functionality required -% by \fileent{otfl-font-nms.lua}. -% \ouritem {otfl-luat-ovr.lua} overrides the \CONTEXT logging +% by \fileent{luaotfload-font-nms.lua}. +% \ouritem {luaotfload-luat-ovr.lua} overrides the \CONTEXT logging % functionality. -% \ouritem {otfl-font-pfb.lua} registers the \OpenType +% \ouritem {luaotfload-font-pfb.lua} registers the \OpenType % font reader as handler for % Postscript fonts. -% \ouritem {otfl-font-nms.lua} font database. -% \ouritem {otfl-font-clr.lua} color handling. -% \ouritem {otfl-font-ltx.lua} font feature handling. -% \ouritem {otfl-features.lua} definitions of the \verb|anum| and +% \ouritem {luaotfload-font-nms.lua} font database. +% \ouritem {luaotfload-font-clr.lua} color handling. +% \ouritem {luaotfload-font-ltx.lua} font feature handling. +% \ouritem {luaotfload-features.lua} definitions of the \verb|anum| and % \verb|tlig| features. % \end{itemize} % @@ -991,6 +991,7 @@ and the derived files % \fi % \begin{macrocode} luaotfload = luaotfload or {} +local luaotfload = luaotfload luaotfload.module = { name = "luaotfload", @@ -1008,6 +1009,7 @@ local type, next = type, next local stringfind = string.find local stringsub = string.sub local stringmatch = string.match +local stringformat = string.format local find_file = kpse.find_file local add_to_callback, create_callback = @@ -1019,6 +1021,7 @@ local dummy_function = function () end % \end{macrocode} % +% % No final decision has been made on how to handle font definition. At % the moment, there are three candidates: The \identifier{generic} % callback as hard-coded in the font loader, the \identifier{old} @@ -1026,6 +1029,7 @@ local dummy_function = function () end % that does nothing besides applying font patches. % % \begin{macrocode} + luaotfload.font_definer = "patch" --- | “generic” | “old” local error, warning, info, log = @@ -1033,6 +1037,7 @@ local error, warning, info, log = % \end{macrocode} % +% % This is a necessary initalization in order not to rebuild an existing % font. % Maybe 600 should be replaced by \texmacro{pdfpkresolution} %% (why?) @@ -1048,6 +1053,7 @@ kpse.init_prog("", 600, "/") % \end{macrocode} % +% % We set the minimum version requirement for \LUATEX to v0.74, as it was % the first version to include version 5.2 of the \LUA interpreter. % @@ -1063,27 +1069,34 @@ end % \end{macrocode} % +% % \subsection{Module loading} % % We load the files imported from \CONTEXT with this function. -% It automatically prepends the prefix \fileent{otfl-} to its argument, -% so we can refer to the files with their actual \CONTEXT name. +% It automatically prepends the prefix \fileent{luaotfload-} to its +% argument, so we can refer to the files with their actual \CONTEXT name. % % \begin{macrocode} -local fl_prefix = "otfl" -- “luatex” for luatex-plain +local fl_prefix = "luaotfload" -- “luatex” for luatex-plain local loadmodule = function (name) - require(fl_prefix .."-"..name) + local tofind = fl_prefix .."-"..name + local found = find_file(tofind,"tex") + if found then + log("loading file %s.", found) + dofile(found) + else + error("file %s not found.", tofind) + end end % \end{macrocode} % -% Before \TeX Live 2013 version, \LUATEX had a bug that made ofm fonts fail -% when called with their extension. There was a side-effect making ofm -% totally unloadable when luaotfload was present. The following lines are -% a patch for this bug. The utility of these lines is questionable as they -% are not necessary since \TeX Live 2013. They should be removed in the next -% version. +% +% Virtual fonts are resolved via a callback. +% \luafunction{find_vf_file} derives the name of the virtual font file +% from the filename. +% (NB: \CONTEXT handles this likewise in \fileent{font-vf.lua}.) % % \begin{macrocode} local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match @@ -1104,51 +1117,14 @@ local find_vf_file = function (name) return fullname end ---[[-- keep --]] ---- from Hans (all merged): - ---- file name modified include name ---- × basics-gen.lua t luat-basics-gen ---- × font-def -> fonts-def t luatex-font-def (there’s also the normal font-def!) ---- × fonts-enc f luatex-font-enc ---- × fonts-ext t luatex-fonts-ext ---- × fonts-lua f luatex-fonts-lua ---- fonts-tfm f luatex-fonts-tfm ---- × fonts-cbk f luatex-fonts-lua - ---- from Hans (unmerged): ---- font-otc.lua -> otfl-font-otc.lua - ---- from luaotfload: ---- otfl-luat-ovr.lua -- override some luat-dum functions ---- otfl-font-clr.lua ---- otfl-font-ltx.lua ---- otfl-font-nms.lua ---- otfl-font-pfb.lua -- ? - ---[[-- new --]] ---- basics-nod (merged as fonts-nod !) ---- fonts-demo-vf-1.lua ---- fonts-syn (merged) - ---[[-- merged, to be dropped --]] ---- otfl-data-con.lua ---- otfl-font-cid.lua ---- otfl-font-con.lua ---- otfl-font-ini.lua ---- otfl-font-ota.lua ---- otfl-font-otb.lua ---- otfl-font-otf.lua ---- otfl-font-oti.lua ---- otfl-font-otn.lua - % \end{macrocode} % % +% % \subsection{Preparing the Font Loader} % We treat the fontloader as a black box so behavior is consistent % between formats. -% The wrapper file is \fileent{otfl-fonts.lua} which we imported from +% The wrapper file is \fileent{luaotfload-fonts.lua} which we imported from % \href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}. % It has roughly two purposes: % @@ -1163,7 +1139,7 @@ end % How the first step is executed depends on the presence on the % \emphasis{merged font loader code}. % In \identifier{luaotfload} this is contained in the file -% \fileent{otfl-fonts-merged.lua}. +% \fileent{luaotfload-fonts-merged.lua}. % If this file cannot be found, the original libraries from \CONTEXT of % which the merged code was composed are loaded instead. % @@ -1187,16 +1163,63 @@ end % \identifier{luatexbase}-style callback handling here. % % \begin{macrocode} -generic_context = {no_callbacks_yet = true} -non_generic_context = { luatex_fonts = { - load_before = "otfl-fonts-merged.lua", - -- load_after = nil, --- TODO, this is meant for callbacks + +--- these are obsolescent due to our plan of removing luaotfload-fonts.lua +generic_context = generic_context or { } +non_generic_context = non_generic_context or { } + +generic_context.no_callbacks_yet = true + +non_generic_context.luatex_fonts = { + --- TODO we’ll kill luaotfload-fonts.lua soon, so + --- this is gonna vanish, and the file will become + --- luaotfload-merged.lua + load_before = "luaotfload-fonts-merged.lua", skip_loading = true, -}} +} + +% \end{macrocode} +% +% +% In its raw form, the font loader will write to the terminal quite +% liberally, not using the proper channels (loggers) even of \CONTEXT. +% To make it behave we temporarily replace two functions from the +% \luafunction{texio} library with wrappers that redirect output to the +% log. +% Just in case Hans decides to call \luafunction{texio.write*} with the +% optional target parameter (which he doesn’t at the moment), we catch the +% first argument and skip it where appropriate. +% The originals are backed up and restored after loading +% \fileent{luaotfload-fonts.lua}. +% +% Should we decide to do our own packaging (we’re capable of that +% anyways), this will most likely become unnecessary. +% +% \begin{macrocode} + +local normal_write, normal_write_nl = texio.write, texio.write_nl + +local log_template = "luaotfload: %s" +local fake_write = function (first, rest) + if first == "log" or first == "term" then -- ignore + normal_write("log", stringformat(log_template, rest)) + else + normal_write("log", stringformat(log_template, first)) + end +end +local fake_write_nl = function (first, rest) + if first == "log" or first == "term" then -- ignore + normal_write_nl("log", stringformat(log_template, rest)) + else + normal_write_nl("log", stringformat(log_template, first, rest)) + end +end +texio.write, texio.write_nl = fake_write, fake_write_nl % \end{macrocode} % +% % The imported font loader will call \luafunction{callback.register} once % while reading \fileent{font-def.lua}. % This is unavoidable unless we modify the imported files, but harmless @@ -1209,31 +1232,24 @@ callback.register = dummy_function % \end{macrocode} % -% In order to have an output with normal verbosity, we need to pre-override -% some \CONTEXT log function: +% +% Now that things are sorted out we can finally load the fontloader. % % \begin{macrocode} -local dummylogfunction=function() end -local dummylogreporter=function(c) return function(...) log(string.formatters(...)) end end - -logs={ - new=dummylogreporter, - reporter=dummylogreporter, - messenger=dummylogreporter, - report=dummylogfunction, -} +loadmodule"fonts.lua" % \end{macrocode} % -% Now that things are sorted out we can finally load the fontloader. +% +% Here we restore the original \luafunction{texio} functions. % % \begin{macrocode} - -loadmodule"fonts.lua" +texio.write, texio.write_nl = normal_write, normal_write_nl % \end{macrocode} % +% % By default, the fontloader requires a number of \emphasis{private % attributes} for internal use. % These must be kept consistent with the attribute handling methods as @@ -1241,22 +1257,22 @@ loadmodule"fonts.lua" % Our strategy is to override the function that allocates new attributes % before we initialize the font loader, making it a wrapper around % \luafunction{luatexbase.new_attribute}.\footnote{% -% Many thanks, again, to Hans Hagen for making this part -% configurable! +% Many thanks, again, to Hans Hagen for making this part +% configurable! % } -% The attribute identifiers are prefixed “\fileent{otfl@}” to +% The attribute identifiers are prefixed “\fileent{luaotfload@}” to % avoid name clashes. % % \begin{macrocode} do - local new_attribute = luatexbase.new_attribute - local the_attributes = luatexbase.attributes + local new_attribute = luatexbase.new_attribute + local the_attributes = luatexbase.attributes attributes = attributes or { } attributes.private = function (name) - local attr = "otfl@" .. name + local attr = "luaotfload@" .. name --- used to be: “otfl@” local number = the_attributes[attr] if not number then number = new_attribute(attr) @@ -1268,6 +1284,7 @@ end % \end{macrocode} % % +% % \subsection{Callbacks} % % After the fontloader is ready we can restore the callback trap from @@ -1279,6 +1296,7 @@ callback.register = trapped_register % \end{macrocode} % +% % We do our own callback handling with the means provided by luatexbase. % % Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} @@ -1297,26 +1315,44 @@ add_to_callback("hpack_filter", add_to_callback("find_vf_file", find_vf_file, "luaotfload.find_vf_file") -loadmodule"font-otc.lua" -- TODO check what we can drop from otfl-features +loadmodule"font-otc.lua" -- TODO check what we can drop from luaotfload-features loadmodule"lib-dir.lua" -- required by font-nms loadmodule"luat-ovr.lua" % \end{macrocode} % % -% \CONTEXT does not support ofm, these lines were added in order to make it -% work. However they do not seem necessary so they are commented for now. +% We aim at reducing the clutter on the terminal, so there is a range of +% logging thresholds. +% (See \fileent{luaotfload-luat-ovr.lua} for the implementation.) +% Each log/report is assigned an integer parameter determining the log +% level at or above which it will appear. +% The default is “1”, and though there is no fixed upper bound, +% meaningful values should not exceed five. % % \begin{macrocode} --- if fonts and fonts.readers.tfm then --- fonts.readers.ofm = fonts.readers.tfm --- fonts.handlers.ofm = fonts.handlers.tfm --- empty anyways --- fonts.formats.ofm = fonts.formats.tfm --- “type1” --- --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm" ---end +logs.set_loglevel(3) + +if fonts and fonts.readers.tfm then + -------------------------------------------------------------------- + --- OFM; read this first + -------------------------------------------------------------------- + --- I can’t quite make out whether this is still relevant + --- as those ofm fonts always fail, even in the 2011 version + --- (mktexpk: don't know how to create bitmap font for omarabb.ofm) + --- the font loader appears to read ofm like tfm so if this + --- hack was supposed achieve that, we should excise it anyways + fonts.readers.ofm = fonts.readers.tfm + fonts.handlers.ofm = fonts.handlers.tfm --- empty anyways + fonts.formats.ofm = fonts.formats.tfm --- “type1” + --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm" + -------------------------------------------------------------------- +end + % \end{macrocode} % % +% % Now we load the modules written for \identifier{luaotfload}. % % \begin{macrocode} @@ -1328,15 +1364,15 @@ loadmodule"font-ltx.lua" --- new in 2.0, added 2011 % \end{macrocode} % % -% This hack makes fonts called with file method found by fonts.names.resove +% This hack makes fonts called with file method found by fonts.names.resolve % instead of just trying to find them with kpse. It is necessary in case -% of fonts that are not accessible by kpse but present in the database, a +% of fonts that are not accessible by kpse but present in the database, a % quite common case under Linux. % % \begin{macrocode} -fonts.definers.resolvers.file = function (specification) - specification.name = fonts.names.resolve('', '', specification) +fonts.definers.resolvers.file = function (specification) + specification.name = fonts.names.resolve('', '', specification) end % \end{macrocode} @@ -1354,6 +1390,7 @@ create_callback("luaotfload.patch_font", "simple", dummy_function) % \end{macrocode} % % +% % This is a wrapper for the imported font loader. % As of 2013, everything it does appear to be redundand, so we won’t use % it unless somebody points out a cogent reason. @@ -1405,6 +1442,7 @@ end % \end{macrocode} % % +% % \subsection{\CONTEXT override} % % We provide a simplified version of the original font definition @@ -1418,6 +1456,7 @@ local patch_defined_font = function (...) if type(tfmdata) == "table" then call_callback("luaotfload.patch_font", tfmdata) end + -- inspect(table.keys(tfmdata)) return tfmdata end @@ -1427,6 +1466,7 @@ reset_callback("define_font") % \end{macrocode} % +% % Finally we register the callbacks % % \begin{macrocode} @@ -1646,7 +1686,7 @@ loadmodule"features.lua" % % \begin{enumerate} % -% \item +% \item % You must cause the modified files to carry prominent notices stating that % you changed the files and the date of any change. % diff --git a/mkluatexfontdb.lua b/mkluatexfontdb.lua deleted file mode 100755 index 776fbb3..0000000 --- a/mkluatexfontdb.lua +++ /dev/null @@ -1,391 +0,0 @@ -#!/usr/bin/env texlua ---[[ -This file was originally written by Elie Roux and Khaled Hosny and is under CC0 -license (see http://creativecommons.org/publicdomain/zero/1.0/legalcode). - -This file is a wrapper for the luaotfload's font names module. It is part of the -luaotfload bundle, please see the luaotfload documentation for more info. ---]] - -kpse.set_program_name"luatex" - -local stringformat = string.format -local texiowrite_nl = texio.write_nl -local stringfind = string.find -local stringlower = string.lower - --- First we need to be able to load module (code copied from --- luatexbase-loader.sty): -local loader_file = "luatexbase.loader.lua" -local loader_path = assert(kpse.find_file(loader_file, "lua"), - "File '"..loader_file.."' not found") - ---texiowrite_nl("("..loader_path..")") -dofile(loader_path) -- FIXME this pollutes stdout with filenames - ---[[doc-- -Depending on how the script is called we change its behavior. -For backwards compatibility, moving or symlinking the script to a -file name starting with \fileent{mkluatexfontdb} will cause it to -trigger a database update on every run. -Running as \fileent{fontdbutil} -- the new name -- will do this upon -request only. - -There are two naming conventions followed here: firstly that of -utilities such as \fileent{mktexpk}, \fileent{mktexlsr} and the likes, -and secondly that of \fileent{fmtutil}. -After support for querying the database was added, the latter appeared -to be the more appropriate. ---doc]]-- - -config = config or { } -local config = config -config.luaotfload = config.luaotfload or { } - -do -- we don’t have file.basename and the likes yet, so inline parser ftw - local C, P = lpeg.C, lpeg.P - local lpegmatch = lpeg.match - local slash = P"/" - local dot = P"." - local noslash = 1 - slash - local slashes = slash^1 - local path = slashes^-1 * (noslash^1 * slashes)^1 - local thename = (1 - slash - dot)^1 - local extension = dot * (1 - slash - dot)^1 - local p_basename = path^-1 * C(thename) * extension^-1 * P(-1) - - -- if stringfind(stringlower(arg[0]), "^fontdbutil") then - local self = lpegmatch(p_basename, stringlower(arg[0])) - if self == "fontdbutil" then - config.luaotfload.self = "fontdbutil" - else - config.luaotfload.self = "mkluatexfontdb" - end -end - -config.lualibs = config.lualibs or { } -config.lualibs.verbose = false -config.lualibs.prefer_merged = true -config.lualibs.load_extended = false - -require"lualibs" -require"otfl-basics-gen.lua" -require"otfl-luat-ovr.lua" --- this populates the logs.* namespace -require"otfl-font-nms" -require"alt_getopt" - -local version = "2.2" -- same version number as luaotfload -local names = fonts.names - -local db_src_out = names.path.dir.."/"..names.path.basename -local db_bin_out = file.replacesuffix(db_src_out, "luc") - -local help_messages = { - fontdbutil = [[ - -Usage: %s [OPTION]... - -Operations on the LuaTeX font database. - -This tool is part of the luaotfload package. Valid options are: - -------------------------------------------------------------------------------- - VERBOSITY AND LOGGING - - -q --quiet don't output anything - -v --verbose=LEVEL be more verbose (print the searched directories) - -vv print the loaded fonts - -vvv print all steps of directory searching - -V --version print version and exit - -h --help print this message - -------------------------------------------------------------------------------- - DATABASE - - -u --update update the database - -f --force force re-indexing all fonts - - --find="font name" query the database for a font name - -F --fuzzy look for approximate matches if --find fails - --limit=n limit display of fuzzy matches to - (default: n = 1) - -i --info display font metadata - - --log=stdout redirect log output to stdout - -The font database will be saved to - %s - %s - -]], - mkluatexfontdb = [[ - -Usage: %s [OPTION]... - -Rebuild the LuaTeX font database. - -Valid options: - -f --force force re-indexing all fonts - -q --quiet don't output anything - -v --verbose=LEVEL be more verbose (print the searched directories) - -vv print the loaded fonts - -vvv print all steps of directory searching - -V --version print version and exit - -h --help print this message - -The font database will be saved to - %s - %s - -]], -} - -local help_msg = function ( ) - local template = help_messages[config.luaotfload.self] - or help.messages.fontdbutil - texiowrite_nl(stringformat(template, config.luaotfload.self, db_src_out, db_bin_out)) -end - -local version_msg = function ( ) - texiowrite_nl(stringformat( - "%s version %s, database version %s.\n", - config.luaotfload.self, version, names.version)) -end - -local show_info_items = function (fontinfo) - local items = table.sortedkeys(fontinfo) - for n = 1, #items do - local item = items[n] - texiowrite_nl(stringformat( - [[ %11s: %s]], item, fontinfo[item])) - end -end - -local show_font_info = function (filename) - local fullname = resolvers.findfile(filename) - if fullname then - local fontinfo = fontloader.info(fullname) - local nfonts = #fontinfo - if nfonts > 0 then -- true type collection - logs.names_report(true, 0, "resolve", - [[%s is a font collection]], filename) - for n = 1, nfonts do - logs.names_report(true, 0, "resolve", - [[showing info for font no. %d]], n) - show_info_items(fontinfo[n]) - end - else - show_info_items(fontinfo) - end - else - logs.names_report(true, 0, "resolve", - "font %s not found", filename) - end -end - ---[[-- -Running the scripts triggers one or more actions that have to be -executed in the correct order. To avoid duplication we track them in a -set. ---]]-- - -local action_sequence = { - "loglevel", "help", "version", "generate", "query" -} -local action_pending = table.tohash(action_sequence, false) - -action_pending.loglevel = true --- always set the loglevel -action_pending.generate = false --- this is the default action - -local actions = { } --- (jobspec -> (bool * bool)) list - -actions.loglevel = function (job) - logs.set_loglevel(job.log_level) - logs.names_report("log", 2, "util", - "setting log level", "%d", job.log_level) - return true, true -end - -actions.version = function (job) - version_msg() - return true, false -end - -actions.help = function (job) - help_msg() - return true, false -end - -actions.generate = function (job) - local fontnames, savedname - fontnames = names.update(fontnames, job.force_reload) - logs.names_report("log", 0, "db", - "fonts in the database", "%i", #fontnames.mappings) - savedname = names.save(fontnames) - if savedname then --- FIXME have names.save return bool - return true, true - end - return false, false -end - -actions.query = function (job) - - local query = job.query - local tmpspec = { - name = query, - lookup = "name", - specification = "name:" .. query, - optsize = 0, - } - - local foundname, _whatever, success = - fonts.names.resolve(nil, nil, tmpspec) - - if success then - logs.names_report(false, 0, - "resolve", "Font “%s” found!", query) - logs.names_report(false, 0, - "resolve", "Resolved file name “%s”:", foundname) - if job.show_info then - show_font_info(foundname) - end - else - logs.names_report(false, 0, - "resolve", "Cannot find “%s”.", query) - if job.fuzzy == true then - logs.names_report(false, 2, - "resolve", "Looking for close matches, this may take a while ...") - local success = fonts.names.find_closest(query, job.fuzzy_limit) - end - end - return true, true -end - ---[[-- -Command-line processing. -mkluatexfontdb.lua relies on the script alt_getopt to process argv and -analyzes its output. - -TODO with extended lualibs we have the functionality from the -environment.* namespace that could eliminate the dependency on -alt_getopt. ---]]-- - -local process_cmdline = function ( ) -- unit -> jobspec - local result = { -- jobspec - force_reload = nil, - query = "", - log_level = 1, - } - - if config.luaotfload.self == "mkluatexfontdb" then - action_pending["generate"] = true - end - - local long_options = { - find = 1, - force = "f", - fuzzy = "F", - help = "h", - info = "i", - limit = 1, - log = 1, - quiet = "q", - update = "u", - verbose = 1 , - version = "V", - } - - local short_options = "fFiquvVh" - - local options, _, optarg = - alt_getopt.get_ordered_opts (arg, short_options, long_options) - - local nopts = #options - for n=1, nopts do - local v = options[n] - if v == "q" then - result.log_level = 0 - elseif v == "u" then - action_pending["generate"] = true - elseif v == "v" then - if result.log_level > 0 then - result.log_level = result.log_level + 1 - else - result.log_level = 2 - end - elseif v == "V" then - action_pending["version"] = true - elseif v == "h" then - action_pending["help"] = true - elseif v == "f" then - result.update = true - result.force_reload = 1 - elseif v == "verbose" then - local lvl = optarg[n] - if lvl then - result.log_level = tonumber(lvl) - end - elseif v == "log" then - local str = optarg[n] - if str then - logs.set_logout(str) - end - elseif v == "find" then - action_pending["query"] = true - result.query = optarg[n] - elseif v == "F" then - result.fuzzy = true - elseif v == "limit" then - local lim = optarg[n] - if lim then - result.fuzzy_limit = tonumber(lim) - end - elseif v == "i" then - result.show_info = true - end - end - return result -end - -local main = function ( ) -- unit -> int - local retval = 0 - local job = process_cmdline() - --- inspect(action_pending) --- inspect(job) - - for i=1, #action_sequence do - local actionname = action_sequence[i] - local exit = false - if action_pending[actionname] then - logs.names_report("log", 3, "util", "preparing for task", - "%s", actionname) - - local action = actions[actionname] - local success, continue = action(job) - - if not success then - logs.names_report(false, 0, "util", - "could not finish task", "%s", actionname) - retval = -1 - exit = true - elseif not continue then - logs.names_report(false, 3, "util", - "task completed, exiting", "%s", actionname) - exit = true - else - logs.names_report(false, 3, "util", - "task completed successfully", "%s", actionname) - end - end - if exit then break end - end - - texiowrite_nl"" - return retval -end - -return main() - --- vim:tw=71:sw=4:ts=4:expandtab -- cgit v1.2.3