diff options
| author | Philipp Gesang <phg42.2a@gmail.com> | 2013-04-27 12:26:55 +0200 | 
|---|---|---|
| committer | Philipp Gesang <phg42.2a@gmail.com> | 2013-04-27 12:26:55 +0200 | 
| commit | a82850e3121af3f0c2412a9a2d8b442cf44cbac2 (patch) | |
| tree | 6e0d4cd59d3f503483c7f4d821d6ff34a244ce75 | |
| parent | 8331000eb1d76381fe5f03fa6c090ae936a110b6 (diff) | |
| download | luaotfload-a82850e3121af3f0c2412a9a2d8b442cf44cbac2.tar.gz | |
Revert to old fonts.conf scanner because of ``io.popen`` restrictions
Apparently ``fc-cat`` would have to be whitelisted in TeX Live if we
want to rebuild the database during document compilation. Thanks Élie,
FOR POINTing that out to me.
| -rw-r--r-- | luaotfload-database.lua | 140 | 
1 files changed, 95 insertions, 45 deletions
| diff --git a/luaotfload-database.lua b/luaotfload-database.lua index e23902a..4980766 100644 --- a/luaotfload-database.lua +++ b/luaotfload-database.lua @@ -21,7 +21,6 @@ local tonumber                = tonumber  local fontloaderinfo          = fontloader.info  local iolines                 = io.lines  local ioopen                  = io.open -local iopopen                 = io.popen  local kpseexpand_path         = kpse.expand_path  local kpseexpand_var          = kpse.expand_var  local kpselookup              = kpse.lookup @@ -235,6 +234,7 @@ local find_closest  local flush_cache  local font_fullinfo  local load_names +local read_fonts_conf  local reload_db  local resolve  local save_names @@ -1141,29 +1141,6 @@ local function scan_texmf_fonts(fontnames, newfontnames)      return n_scanned, n_new  end ---- fc-cat outputs every directory it finds fonts in, ---- so we have to remove all subdirectories from the ---- list. - ---- dir list -> dir list -local collapse_paths = function (dir_lst) -    tablesort(dir_lst) -    local last  = dir_lst[1] -    local res   = { last } -    local ndirs = #dir_lst -    if ndirs > 1 then -        for i=2, ndirs do -            local dir = dir_lst[i] -            if stringsub(dir, 1, #last) ~= last then -                --- new prefix -                res[#res+1] = dir -                last = dir -            end -        end -    end -    return res -end -  --[[    For the OS fonts, there are several options:     - if OSFONTDIR is set (which is the case under windows by default but @@ -1171,32 +1148,99 @@ end       in the scan_texmf_fonts.     - if not:       - under Windows and Mac OSX, we take a look at some hardcoded directories -     - under Unix, we parse the output of “fc-cat -v” +     - under Unix, we read /etc/fonts/fonts.conf and read the directories in it    This means that if you have fonts in fancy directories, you need to set them    in OSFONTDIR.  ]] ---[[doc-- -Instead of processing the fontconfig configuration files with a -haphazarad XML parser, we scan the output of fc-cache for search paths -and use these. This way we don’t need to resolve possible included -files. ---doc]]-- -local get_fontconfig_paths = function ( ) -    local fc_cat_cmd = "fc-cat -v 2> /dev/null" -    local res = { } -    local chan = assert(iopopen(fc_cat_cmd, "r"), -                        "cannot read from pipe") -    local nlines = 0 -    for line in chan:lines() do -        nlines = nlines + 1 -        if stringsub(line, 1, 11) == "Directory: " then -            res[#res+1] = string.explode(line, " ")[2] .. "/" +--- (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. + +    TODO    fonts.conf are some kind of XML so in theory the following +            is totally inappropriate. Maybe a future version of the +            lualibs will include the lxml-* files from Context so we +            can write something presentable instead. +    ]] +    local fh = ioopen(path) +    passed_paths[#passed_paths+1] = path +    passed_paths_set = tabletohash(passed_paths, true) +    if not fh then +        report("log", 2, "db", "cannot open file %s", path) +        return results +    end +    local incomments = false +    for line in fh:lines() do +        while line and line ~= "" do +            -- spaghetti code... hmmm... +            if incomments then +                local tmp = stringfind(line, '-->') --- wtf? +                if tmp then +                    incomments = false +                    line = stringsub(line, tmp+3) +                else +                    line = nil +                end +            else +                local tmp = stringfind(line, '<!--') +                local newline = line +                if tmp then +                    -- for the analysis, we take everything that is before the +                    -- comment sign +                    newline = stringsub(line, 1, tmp-1) +                    -- and we loop again with the comment +                    incomments = true +                    line = stringsub(line, tmp+4) +                else +                    -- if there is no comment start, the block after that will +                    -- end the analysis, we exit the while loop +                    line = nil +                end +                for dir in stringgmatch(newline, '<dir>([^<]+)</dir>') do +                    -- now we need to replace ~ by kpse.expand_path('~') +                    if stringsub(dir, 1, 1) == '~' then +                        dir = filejoin(kpseexpand_path('~'), stringsub(dir, 2)) +                    end +                    -- we exclude paths with texmf in them, as they should be +                    -- found anyway +                    if not stringfind(dir, 'texmf') then +                        results[#results+1] = dir +                    end +                end +                for include in stringgmatch(newline, '<include[^<]*>([^<]+)</include>') do +                    -- include here can be four things: a directory or a file, +                    -- in absolute or relative path. +                    if stringsub(include, 1, 1) == '~' then +                        include = filejoin(kpseexpand_path('~'),stringsub(include, 2)) +                        -- First if the path is relative, we make it absolute: +                    elseif not lfs.isfile(include) and not lfs.isdir(include) then +                        include = filejoin(file.dirname(path), include) +                    end +                    if      lfs.isfile(include) +                    and     kpsereadable_file(include) +                    and not passed_paths_set[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, passed_paths) +                    elseif lfs.isdir(include) then +                        for _,f in next, dirglob(filejoin(include, "*.conf")) do +                            if not passed_paths_set[f] then +                                read_fonts_conf(f, results, passed_paths) +                            end +                        end +                    end +                end +            end          end      end -    chan:close() -    return collapse_paths(res) +    fh:close() +    return results  end  -- for testing purpose @@ -1215,7 +1259,13 @@ local function get_os_dirs()          local windir = os.getenv("WINDIR")          return { filejoin(windir, 'Fonts') }      else  -        local os_dirs = get_fontconfig_paths() +        local passed_paths = {} +        local os_dirs = {} +        for _,p in next, {"/usr/local/etc/fonts/fonts.conf", "/etc/fonts/fonts.conf"} do +            if lfs.isfile(p) then +                read_fonts_conf(p, os_dirs, passed_paths) +            end +        end          return os_dirs      end      return {} @@ -1225,7 +1275,7 @@ local function scan_os_fonts(fontnames, newfontnames)      local n_scanned, n_new = 0, 0      --[[      This function scans the OS fonts through -      - fontcache for Unix (runs fc-cat -v and scans the directories) +      - fontcache for Unix (reads the fonts.conf file and scans the directories)        - a static set of directories for Windows and MacOSX      ]]      report("info", 2, "db", "Scanning OS fonts...") | 
