5

I'm playing with PGF's (algorithmic) graph drawing, which relies on Lua internally. I have no problems with LaTeX, but ConTeXt fails to load the package. For the simple document:

\usemodule[tikz]
\usetikzlibrary[graphdrawing]
\starttext
\stoptext

I get:

open source     > level 4, order 67, name '/opt/texlive/2017/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex'

lua error       > lua error on line 1127 in file /opt/texlive/2017/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex:

...live/2017/texmf-dist/tex/context/base/mkiv/l-sandbox.lua:180: module 'pgf.gd.control' not found:
        no field package.preload['pgf.gd.control']
        no file '/usr/local/share/lua/5.2/pgf/gd/control.lua'
        no file '/usr/local/share/lua/5.2/pgf/gd/control/init.lua'
        no file '/usr/local/lib/lua/5.2/pgf/gd/control.lua'
        no file '/usr/local/lib/lua/5.2/pgf/gd/control/init.lua'
        no file './pgf/gd/control.lua'
        no file '/usr/local/lib/lua/5.2/pgf/gd/control.so'
        no file '/usr/local/lib/lua/5.2/loadall.so'
        no file './pgf/gd/control.so'
        no file '/usr/local/lib/lua/5.2/pgf.so'
        no file '/usr/local/lib/lua/5.2/loadall.so'
        no file './pgf.so'
stack traceback:
        [C]: in function 'requiem'
        ...live/2017/texmf-dist/tex/context/base/mkiv/l-sandbox.lua:180: in function <...live/2017/texmf-dist/tex/context/base/mkiv/l-sandbox.lua:165>
        (...tail calls...)
        ...neric/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua:41: in main chunk
        [C]: in function 'requiem'
        ...live/2017/texmf-dist/tex/context/base/mkiv/l-sandbox.lua:180: in function <...live/2017/texmf-dist/tex/context/base/mkiv/l-sandbox.lua:165>
        (...tail calls...)
        ...graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua:45: in main chunk
        [C]: in function 'requiem'
        ...live/2017/texmf-dist/tex/context/base/mkiv/l-sandbox.lua:180: in function <...live/2017/texmf-dist/tex/context/base/mkiv/l-sandbox.lua:165>
        (...tail calls...)
        [ctxlua]:1: in main chunk

1117     }
1118     }
1119     
1120     
1121     %
1122     % Ok, fire up the system by creating the binding!
1123     %
1124     \directlua{
1125       require 'pgf.gd.interface.InterfaceToDisplay' 
1126       pgf.gd.interface.InterfaceToDisplay.bind(require 'pgf.gd.bindings.BindingToPGF')
1127 >>  } 
1128     
1129     
1130     
1131     %
1132     % Special setup for keys that are declared by the above libraries, but
1133     % that have a special meaning on the display layer.
1134     %
1135     
1136     \pgfkeys{/graph drawing/nodes behind edges/.append code=\csname pgf@gd@nodes@behind@edges#1\endcsname}
1137     \pgfkeys{/graph drawing/nodes behind edges/.default=true}

For the sake of simplicity, also this document leads to the error:

\usemodule[tikz]
\directlua{require 'pgf.gd.control'}
\starttext
\stoptext

What is strange, all other Lua packages are loaded correctly (e.g. pgf.gd.interface). Moreover, when I copy the control directory and control.lua from /opt/texlive/2017/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd to the directory where the document source is placed (into pgf/gd/, of course), everything works perfectly. Also for more complicated documents, the layout is correctly computed in Lua and graphs are drawn.

The control.lua file is a no-brainer, generally:

require "pgf"
require "pgf.gd"


-- Declare namespace
pgf.gd.control = {}


-- Done

return pgf.gd.control

It this some strange bug in ConTeXt+Lua magic? Or TikZ maybe?

My system is current TeXLive 2017.

$ context --version

mtx-context     | ConTeXt Process Management 1.01
mtx-context     |
mtx-context     | main context file: /opt/texlive/2017/texmf-dist/tex/context/base/mkiv/context.mkiv
mtx-context     | current version: 2017.05.15 21:48

$ luatex --version
This is LuaTeX, Version 1.0.4 (TeX Live 2017)

Execute  'luatex --credits'  for credits and version details.

There is NO warranty. Redistribution of this software is covered by
the terms of the GNU General Public License, version 2 or (at your option)
any later version. For more information about these matters, see the file
named COPYING and the LuaTeX source.

LuaTeX is Copyright 2017 Taco Hoekwater and the LuaTeX Team.

UPDATE:

After diving deep into ConTeXt Lua libs I found l-package.lua and data-lua.lua, in which package.loaders are modified. As I suspected, it is used to extend 4 specification-defined Lua loaders with more TeX related. Setting:

\directlua{sandbox.settrace(true)}
\directlua{package.helpers.trace = true}

logs a lot about inner workings of those loaders, as well as ConTeXt's sandbox stuff. For example, loading pgf.gd.interface spits:

sandbox         > requiring: pgf.gd.interface
resolvers       > libraries > locating, level '1', method 'already loaded', name 'pgf.gd.interface'
resolvers       > libraries > locating, level '1', method 'preload table', name 'pgf.gd.interface'
resolvers       > libraries > locating, level '1', method 'lua variable format', name 'pgf.gd.interface'
resolvers       > libraries > lua format, checking 33 paths
resolvers       > libraries > lua format, identifying 'pgf/gd/interface.lua' using format 'tex'
resolvers       > libraries > lua format, 'pgf/gd/interface.lua' found on '/opt/texlive/2017/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua'
resolvers       > libraries > found, level '1', method 'lua variable format', name 'pgf.gd.interface'

and failing pgf.gd.control starts with:

sandbox         > requiring: pgf.gd.control
resolvers       > libraries > locating, level '1', method 'already loaded', name 'pgf.gd.control'
resolvers       > libraries > locating, level '1', method 'preload table', name 'pgf.gd.control'
resolvers       > libraries > locating, level '1', method 'lua variable format', name 'pgf.gd.control'
resolvers       > libraries > lua format, checking 33 paths
resolvers       > libraries > lua format, identifying 'pgf/gd/control.lua' using format 'tex'
resolvers       > libraries > lua format, 'pgf/gd/control.lua' found on '/opt/texlive/2017/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/Control.lua'
resolvers       > libraries > locating, level '1', method 'lib variable format', name 'pgf.gd.control'

Notice the difference in the last line. In the case of the failing package, next resolvers continue to search despite finding the package! The reason seems to be the uppercase in the filename: Control.lua, in the previous line!

Unfortunately, this is far too deep for my understanding, but some part of ConTeXt black magic uppercased the package name incorrectly.

  • Can't reproduce your error. Works with TL2017 context standalone (2018.02.06 18:11). You could use tlmgr to check and/or reinstall context – DG' Feb 7 '18 at 20:07
  • 1
    @DG' Are you on Windows or on Linux? On Windows the error will not be relevant, as filenames are case insensitive. It's not the case with my installation, the same error occurs in docker container using camilstaps/texlive image. – pwes Feb 7 '18 at 21:38
  • osx, which is not case sensitive either. Maybe you should ask the context mailing list. – DG' Feb 7 '18 at 21:44
  • I'll do, especially as I just found that there is Control.lua file, but in different folder: there is pgf/gd/control.lua and pgf/gd/force/Control.lua. Looks like either TeXLive or ConTeXt messes up. – pwes Feb 7 '18 at 21:56
  • 2
    @cfr it's a mess, maybe the new file system (apfs) will improve things... – DG' Feb 8 '18 at 6:06
3

My question was answered partially by me and partially by Hans Hagen on NTG-context mailing list.

The problem is that ConTeXt is case insensitive. One can see this by looking at its tree cache, which mainly contains (in ["content"]["files"])

["control.lua"]={ "tex/generic/pgf/graphdrawing/lua/pgf/gd", "tex/generic/pgf/graphdrawing/lua/pgf/gd/force" }

as well as (in ["content"]["remap"])

["control.lua"]="Control.lua"

and the behavior is (roughly) as follows:

  1. (on ConTeXt init: some custom functions are added to package.searchers)
  2. require 'pgf.gd.control' is called
  3. Lua scans package.searchers
  4. Nothing is found until ConTeXt searcher is hit
  5. The resolver looks into the aformentioned cache and finds the mapping of control.lua to directories it contains; one of the directories has the same suffix as the package name prefix (i.e. pgf/gd) and is chosen
  6. (and this is the bug) The remap entry in the tree cache changes control.lua to Control.lua
  7. The searcher cannot load the file (the case is wrong...) and Lua continue with next searcher
  8. Lua fails to find the package

The real problem is that I see no clean way to fix it. ConTeXt is case insensitive and it will not change. Changing pgf/gd/force/Control.lua to lower case will influence PGF Lua users outside TeX. The workaround is to put the Lua packages out of TeX tree (e.g. same folder as the document is).

The above scenario also suggests more serious problems, where one "rogue" package can destroy working of another one. Imagine that CTAN package my-library has file mylibrary/functions.lua. After installing in the system another package rogue with file rogue/FuNcTiOnS.lua, ConTeXt starts failing on require 'mylibrary.functions, as it is now incorrectly remapped in the tree cache to non-existing filepath mylibrary/FuNcTiOnS.lua.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.