diff options
| author | Philipp Gesang <phg42.2a@gmail.com> | 2013-11-03 09:48:57 -0800 | 
|---|---|---|
| committer | Philipp Gesang <phg42.2a@gmail.com> | 2013-11-03 09:48:57 -0800 | 
| commit | a67eed2364954d8f7e12a9c2a6d873884c5320fb (patch) | |
| tree | 56e8942504f67338f7fe39662fdfe1e99302f114 | |
| parent | 483aef134dc38b89bcc2196b868c5ba3a7595967 (diff) | |
| parent | 3220fd09a4f97680849047211dab5588c8b33e97 (diff) | |
| download | luaotfload-a67eed2364954d8f7e12a9c2a6d873884c5320fb.tar.gz | |
Merge pull request #143 from phi-gamma/master
add single-line status messages
| -rw-r--r-- | luaotfload-database.lua | 63 | ||||
| -rw-r--r-- | luaotfload-override.lua | 125 | ||||
| -rwxr-xr-x | luaotfload-tool.lua | 2 | 
3 files changed, 151 insertions, 39 deletions
| diff --git a/luaotfload-database.lua b/luaotfload-database.lua index 755ad52..1b20a84 100644 --- a/luaotfload-database.lua +++ b/luaotfload-database.lua @@ -82,14 +82,15 @@ local tablefastcopy           = table.fastcopy  local tabletofile             = table.tofile  local tabletohash             = table.tohash +local runasscript             = caches == nil +  --- the font loader namespace is “fonts”, same as in Context  --- we need to put some fallbacks into place for when running  --- as a script -fonts                = fonts          or { } -fonts.names          = fonts.names    or { } -fonts.definers       = fonts.definers or { } - -local names          = fonts.names +fonts                          = fonts          or { } +fonts.names                    = fonts.names    or { } +fonts.definers                 = fonts.definers or { } +local names                    = fonts.names --- font index namespace  config                         = config or { }  config.luaotfload              = config.luaotfload or { } @@ -121,7 +122,10 @@ local make_luanames = function (path)             filereplacesuffix(path, "luc")  end -local report = logs.names_report +local report                = logs.names_report +local report_status         = logs.names_status +local report_status_start   = logs.names_status_start +local report_status_stop    = logs.names_status_stop  names.patterns          = { }  local patterns          = names.patterns @@ -148,7 +152,7 @@ patterns.splitcomma     = splitcomma      created by different user.  --doc]]-- -if caches then +if not runasscript then      local globals   = names.path.globals      local names_dir = globals.names_dir @@ -389,7 +393,7 @@ load_names = function (dry_run)      local foundname, data = load_lua_file (names.path.index.lua)      if data then -        report ("both", 2, "db", +        report ("both", 1, "db",                  "Font names database loaded", "%s", foundname)          report ("info", 3, "db", "Loading took %0.f ms",                  1000*(os.gettimeofday()-starttime)) @@ -709,10 +713,6 @@ resolve_cached = function (_, _, specification)      local entry = { filename, subfont }      report("both", 4, "cache", "New entry: %s", request)      names.lookups[request] = entry - -    --- obviously, the updated cache needs to be stored. -    --- TODO this should trigger a save only once the -    ---      document is compiled (finish_pdffile callback?)      report("both", 5, "cache", "Saving updated cache")      local success = save_lookups()      if not success then --- sad, but not critical @@ -1542,7 +1542,7 @@ local create_blacklist = function (blacklist, whitelist)      local result = { }      local dirs   = { } -    report("info", 2, "db", "Blacklisting %q files and directories", +    report("info", 1, "db", "Blacklisting %q files and directories",             #blacklist)      for i=1, #blacklist do          local entry = blacklist[i] @@ -1553,7 +1553,7 @@ local create_blacklist = function (blacklist, whitelist)          end      end -    report("info", 2, "db", "Whitelisting %q files", #whitelist) +    report("info", 1, "db", "Whitelisting %q files", #whitelist)      for i=1, #whitelist do          result[whitelist[i]] = nil      end @@ -1812,11 +1812,10 @@ local scan_dir = function (dirname, fontnames, newfontnames,          fullname = path_normalize(fullname)          local new          if dry_run == true then -            report ("both", 1, "db", -                    "Would have been loading %q", fullname) +            report_status ("both", "db", +                           "Would have been loading %q", fullname)          else -            report ("both", 4, "db", -                    "Loading font %q", fullname) +            report_status ("both", "db", "Loading font %q", fullname)              local new = load_font (fullname, fontnames,                                     newfontnames, texmf)              if new == true then @@ -1824,8 +1823,8 @@ local scan_dir = function (dirname, fontnames, newfontnames,              end          end      end - -    report("both", 4, "db", "%d fonts found in '%s'", n_found, dirname) +    report ("both", 4, "db", "Done. %d fonts indexed in %q", +            n_found, dirname)      return n_found, n_new  end @@ -1860,9 +1859,9 @@ local scan_texmf_fonts = function (fontnames, newfontnames, dry_run)      local osfontdir = kpseexpand_path "$OSFONTDIR"      if stringis_empty (osfontdir) then -        report ("info", 2, "db", "Scanning TEXMF fonts...") +        report ("info", 1, "db", "Scanning TEXMF fonts...")      else -        report ("info", 2, "db", "Scanning TEXMF and OS fonts...") +        report ("info", 1, "db", "Scanning TEXMF and OS fonts...")          if logs.get_loglevel () > 3 then              local osdirs = filesplitpath (osfontdir)              report ("info", 0, "db", @@ -1881,12 +1880,14 @@ local scan_texmf_fonts = function (fontnames, newfontnames, dry_run)          local tasks = filter_out_pwd (filesplitpath (fontdirs))          report ("info", 3, "db",                  "Initiating scan of %d directories.", #tasks) +        report_status_start (2, 4)          for _, d in next, tasks do              local found, new = scan_dir (d, fontnames, newfontnames,                                           dry_run, true)              n_scanned = n_scanned + found              n_new     = n_new     + new          end +        report_status_stop ("term", "db", "Scanned %d files, %d new.", n_scanned, n_new)      end      return n_scanned, n_new @@ -2162,16 +2163,18 @@ local scan_os_fonts = function (fontnames, newfontnames,                                  dry_run)      local n_scanned, n_new = 0, 0 -    report ("info", 2, "db", "Scanning OS fonts...") +    report ("info", 1, "db", "Scanning OS fonts...")      report ("info", 3, "db",              "Searching in static system directories...") +    report_status_start (2, 4)      for _, d in next, get_os_dirs () do          local found, new = scan_dir (d, fontnames,                                       newfontnames, dry_run)          n_scanned = n_scanned + found          n_new     = n_new     + new      end +    report_status_stop ("term", "db", "Scanned %d files, %d new.", n_scanned, n_new)      return n_scanned, n_new  end @@ -2186,7 +2189,7 @@ end  --- dbobj -> dbobj  local gen_fast_lookups = function (fontnames) -    report("both", 2, "db", "Creating filename map") +    report("both", 1, "db", "Creating filename map")      local mappings   = fontnames.mappings      local nmappings  = #mappings      --- this is needlessly complicated due to texmf priorization @@ -2245,7 +2248,7 @@ local gen_fast_lookups = function (fontnames)      end      if config.luaotfload.prioritize == "texmf" then -        report("both", 2, "db", "Preferring texmf fonts") +        report("both", 1, "db", "Preferring texmf fonts")          addmap(sys)          addmap(texmf)      else --- sys @@ -2266,7 +2269,7 @@ end  update_names = function (fontnames, force, dry_run)      if config.luaotfload.update_live == false then -        report("info", 2, "db", +        report("info", 1, "db",                 "Skipping database update")          --- skip all db updates          return fontnames or names.data @@ -2280,7 +2283,7 @@ update_names = function (fontnames, force, dry_run)      - “newfontnames” is the final table to return      - force is whether we rebuild it from scratch or not      ]] -    report("both", 2, "db", "Updating the font names database" +    report("both", 1, "db", "Updating the font names database"                           .. (force and " forcefully" or ""))      if force then @@ -2416,9 +2419,9 @@ end  --- string -> string -> string list -> bool -> bool  local purge_from_cache = function (category, path, list, all) -    report("info", 2, "cache", "Luaotfload cache: %s %s", +    report("info", 1, "cache", "Luaotfload cache: %s %s",          (all and "erase" or "purge"), category) -    report("info", 2, "cache", "location: %s",path) +    report("info", 1, "cache", "location: %s",path)      local n = 0      for i=1,#list do          local filename = list[i] @@ -2441,7 +2444,7 @@ local purge_from_cache = function (category, path, list, all)              end          end      end -    report("info", 2, "cache", "Removed lua files : %i", n) +    report("info", 1, "cache", "Removed lua files : %i", n)      return true  end diff --git a/luaotfload-override.lua b/luaotfload-override.lua index 1326182..889bea5 100644 --- a/luaotfload-override.lua +++ b/luaotfload-override.lua @@ -32,6 +32,8 @@ local texio_write       = texio.write  local texiowrite        = texio.write  local type              = type +local dummyfunction     = function () end +  local texjob = false  if tex and (tex.jobname or tex.formatname) then      --- TeX @@ -52,7 +54,7 @@ We recreate the verbosity levels previously implemented in font-nms:  --doc]]-- -local loglevel = 1 --- default +local loglevel = 0 --- default  local logout   = "log"  --- int -> bool @@ -74,7 +76,9 @@ logs.getloglevel    = get_loglevel  logs.get_loglevel   = get_loglevel  logs.get_log_level  = get_loglevel -local writeln --- scope so we can change it +local writeln  --- pointer to terminal/log writer +local statusln --- terminal writer that reuses the current line +local first_status = true --- indicate the begin of a status region  local log_msg = [[  logging output redirected to %s @@ -126,6 +130,7 @@ local set_logout = function (s, finalizers)          texiowrite    = writefile          texiowrite_nl = writefile_nl          writeln       = writefile_nl +        statusln      = dummyfunction          finalizers[#finalizers+1] = function ()              chan:write (stringformat ("\nlogging finished at %s\n", @@ -162,18 +167,34 @@ end  io.stdout:setvbuf "no"  io.stderr:setvbuf "no" +local kill_line = "\r\x1b[K" +  if texjob == true then +    --- We imitate the texio.* functions so the output is consistent.      writeln = function (str) -        texiowrite_nl ("term", str) +        iowrite "\n" +        iowrite(str) +    end +    statusln = function (str) +        if first_status == false then +            iowrite (kill_line) +        end +        iowrite (str)      end  else      writeln = function (str)          iowrite(str)          iowrite "\n"      end +    statusln = function (str) +        if first_status == false then +            iowrite (kill_line) +        end +        iowrite (str) +    end  end -stdout = function (category, ...) +stdout = function (writer, category, ...)      local res = { module_name, "|", category, ":" }      local nargs = select("#", ...)      if nargs == 0 then @@ -184,7 +205,7 @@ stdout = function (category, ...)      else          res[#res+1] = stringformat(...)      end -    writeln(tableconcat(res, " ")) +    writer (tableconcat(res, " "))  end  --- at default (zero), we aim to be quiet @@ -227,9 +248,9 @@ local names_report = function (mode, lvl, ...)              log (...)          elseif mode == "both" and logout ~= "redirect" then              log (...) -            stdout (...) +            stdout (writeln, ...)          else -            stdout (...) +            stdout (writeln, ...)          end      end  end @@ -238,6 +259,95 @@ logs.names_report = names_report  --[[doc-- +    status_logger -- Overwrites the most recently printed line of the +    terminal. Its purpose is to provide feedback without spamming +    stdout with irrelevant messages, i.e. when building the database. + +    Status logging must be initialized by calling status_start() and +    properly reset via status_stop(). + +    The arguments low and high indicate the loglevel threshold at which +    linewise and full logging is triggered, respectively. E.g. + +            names_status (1, 4, "term", "Hello, world!") + +    will print nothing if the loglevel is less than one, reuse the +    current line if the loglevel ranges from one to three inclusively, +    and output the message on a separate line otherwise. + +--doc]]-- + +local status_logger = function (mode, ...) +    if mode == "log" then +        log (...) +    else +        if mode == "both" and logout ~= "redirect" then +            log (...) +            stdout (statusln, ...) +        else +            stdout (statusln, ...) +        end +        first_status = false +    end +end + +--[[doc-- + +    status_start -- Initialize status logging. This installs the status +        logger if the loglevel is in the specified range, and the normal +        logger otherwise.  It also resets the first line state which +        causing the next line printed using the status logger to not kill +        the current line. + +--doc]]-- + +local status_writer +local status_low  = 99 +local status_high = 99 + +local status_start = function (low, high) +    first_status = true +    status_low   = low +    status_high  = high + +    if os.type == "windows" --- Assume broken terminal. +    or os.getenv "TERM" == "dumb" +    then +        status_writer = function (mode, ...) +            names_report (mode, high, ...) +        end +        return +    end + +    if low <= loglevel and loglevel < high then +        status_writer = status_logger +    else +        status_writer = function (mode, ...) +            names_report (mode, high, ...) +        end +    end +end + +--[[doc-- + +    status_stop -- Finalize a status region by outputting a newline and +    printing a message. + +--doc]]-- + +local status_stop = function (...) +    if first_status == false then +        status_writer(...) +        writeln "" +    end +end + +logs.names_status = function (...) status_writer (...) end +logs.names_status_start = status_start +logs.names_status_stop  = status_stop + +--[[doc-- +      The fontloader comes with the Context logging mechanisms      inaccessible. Instead, it provides dumb fallbacks based      on the functions in texio.write*() that can be overridden @@ -274,7 +384,6 @@ texio.reporter = texioreporter  if fonts then --- need to be running TeX      if next(fonts.encodings.agl) then -        print(next, fonts.encodings.agl)          --- unnecessary because the file shouldn’t be loaded at this time          --- but we’re just making sure          fonts.encodings.agl = nil diff --git a/luaotfload-tool.lua b/luaotfload-tool.lua index c4670e8..eace7f6 100755 --- a/luaotfload-tool.lua +++ b/luaotfload-tool.lua @@ -1102,7 +1102,7 @@ local process_cmdline = function ( ) -- unit -> jobspec              if result.log_level > 0 then                  result.log_level = result.log_level + 1              else -                result.log_level = 2 +                result.log_level = 1              end          elseif v == "V" then              action_pending["version"] = true | 
