8

On a fresh install of TL 2018, on Linux, no tikz graph drawing libraries can be found.

The files, e.g. texlive/2018/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex are there.

\documentclass{scrartcl}


\usepackage{tikz}
\usetikzlibrary{graphdrawing}
\usegdlibrary{trees}



\begin{document}

Hello World

\end{document}

Compiling with lualatex yields ! Package pgf Error: Graph drawing library 'trees' not found.

MaxNoe
  • 6,136
  • 2
    See https://github.com/u-fischer/luaotfload/issues/6 – Ulrike Fischer Sep 29 '18 at 20:59
  • Do read this right, that pgf uses an internal function from luaotfload and that internal function got its API changed? – MaxNoe Sep 29 '18 at 21:02
  • Hell, dependency management in TeX is even worse than javascript, in javascript there it at least exists. – MaxNoe Sep 29 '18 at 21:03
  • @MaxNoe This is Lua code, not TeX, and the API concerned isn't one for font loading ... – Joseph Wright Sep 29 '18 at 21:11
  • @MaxNoe Also, as the change is a propagation from ConTeXt, and as the function concerned is almost certainly there specifically for ConTeXt support, I don't think one can really blame luaotfload. – Joseph Wright Sep 29 '18 at 21:14
  • Does not change the fact, that this lua code is a dependency of TeX code, right? – MaxNoe Sep 29 '18 at 21:15
  • I don't blame luaotfload. PGF probably should have never used an internal function from luaotfload – MaxNoe Sep 29 '18 at 21:16
  • I'm not sure that they meant to use a luaotfload function, the code is probably meant for the use as a context library. The problem is that the generic fontloader used by luaotfload has such a function too, and this has changed. I asked on the context list, if there is a better solution then asking pgf to change its code. – Ulrike Fischer Sep 29 '18 at 21:41

1 Answers1

19

As detailed in the https://github.com/u-fischer/luaotfload/issues/6, pgf_lookup_and_require wrongly uses resolvers.findfile to find the graph drawing libraries when used with ConTeXt. This bug surfaced when luaotfload was upgraded which now also the resolvers.findfile function.

The problem is clearly with PGF here, because resolvers.findfile is to find fonts and not arbitrary files in the TeX tree. Until this is fixed, you can override the pgf_lookup_and_require function with your own variant which does the correct thing.

\documentclass{article}

\usepackage{luacode}
\usepackage{tikz}
\usetikzlibrary{graphdrawing}

\begin{luacode*}
function pgf_lookup_and_require(name)
    local sep = package.config:sub(1,1)
    local function lookup(name)
        local sub = name:gsub('%.',sep)  
        if kpse.find_file(sub, 'lua') then
            require(name)
        elseif kpse.find_file(sub, 'clua') then
            collectgarbage('stop') 
            require(name)
            collectgarbage('restart')
        else
            return false
        end
        return true
    end
    return
        lookup('pgf.gd.' .. name .. '.library') or
        lookup('pgf.gd.' .. name) or
        lookup(name .. '.library') or
        lookup(name) 
end
\end{luacode*}

\usegdlibrary{trees}

\begin{document}

Hello World

\end{document}

It seems to me that the Lua code in PGF is not so well thought through as this simple function already exhibits some Lua antipatterns, such as polluting the global environment by require instead of returning a table and stopping and restarting the garbage collector, which forces a collection cycle. Also this clumsy way of determining the path separator instead of using package.config should really be avoided.

Henri Menke
  • 109,596
  • For determining path separator, what's wrong with os.type (as it's either windows or 'something else')? I've looked at package.config and felt that this approach is much less clear. – Joseph Wright Sep 30 '18 at 08:24
  • @JosephWright The package.config way is the documented way and hence preferred. I guess os.type would also be okay, but that is not what PGF is doing. PGF checks whether the entries in the PATH environment variable are delimited by ; (which is the case on Windows). Furthermore local sep = package.config:sub(1,1) takes only a single line. – Henri Menke Sep 30 '18 at 08:33
  • Sure: I'm thinking for l3build where we have quite a lot of things to do. I'd not looked at the pgf code: that sounds scary! – Joseph Wright Sep 30 '18 at 08:35
  • resolvers.findfile was already in luaotfload before, it only handled the lua type differently. – Ulrike Fischer Sep 30 '18 at 13:40
  • For anyone not willing to click through the issue, the bug was fixed in pgf. – Keith Prussing Feb 06 '19 at 03:02