奇怪的 ConTeXt 无法加载 pgf.gd.control

奇怪的 ConTeXt 无法加载 pgf.gd.control

我正在使用 PGF(算法)图形绘制,它内部依赖于 Lua。我使用 LaTeX 没有问题,但 ConTeXt 无法加载包。对于简单文档:

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

我得到:

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}

为了简单起见,本文档也导致错误:

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

奇怪的是,其他所有 Lua 包都正确加载了(例如pgf.gd.interface)。此外,当我复制目录controlcontrol.lua/opt/texlive/2017/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd到放置文档源的目录(pgf/gd/当然是),一切都运行正常。对于更复杂的文档,也可以在 Lua 中正确计算布局并绘制图形。

control.lua文件很简单,一般来说:

require "pgf"
require "pgf.gd"


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


-- Done

return pgf.gd.control

这是 ConTeXt+Lua magic 中的一些奇怪错误吗?或者是 TikZ?

我的系统是当前的 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.

更新

在深入研究了 ConTeXt Lua 库之后,我发现l-package.lua和已被修改。正如我所料,它用于扩展 4 个规范定义的 Lua 加载器,其中包含更多与 TeX 相关的内容。设置data-lua.luapackage.loaders

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

记录了大量有关这些加载器的内部工作原理以及 ConTeXt 的沙盒内容的信息。例如,加载pgf.gd.interfacespits:

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'

失败pgf.gd.control始于:

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'

注意最后一行的区别。在软件包失败的情况下,下一个解析器会继续搜索,尽管找到了软件包!原因似乎是Control.lua上一行中的文件名中的大写字母: !

不幸的是,这对于我的理解来说太深奥了,但是 ConTeXt 黑魔法的某些部分错误地将包名称大写。

答案1

我的问题已得到部分解答由我和部分作者:汉斯·哈根在 NTG 上下文邮件列表上。

问题在于 ConTeXt 不区分大小写。通过查看其树缓存可以看出这一点,它主要包含(在 中["content"]["files"]

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

以及(在["content"]["remap"]

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

其行为大致如下:

  1. (在 ConTeXt 初始化时:添加了一些自定义函数package.searchers
  2. require 'pgf.gd.control'叫做
  3. Lua 扫描package.searchers
  4. 直到使用 ConTeXt 搜索器时才找到任何内容
  5. 解析器查看上述缓存,找到control.lua其包含的目录的映射;其中一个目录具有与包名称前缀相同的后缀(即pgf/gd),并选择
  6. (这就是错误)remap树缓存中的条目更改control.luaControl.lua
  7. 搜索器无法加载文件(大小写错误...)并且 Lua 继续下一个搜索器
  8. Lua 找不到包

真正的问题是,我看不出有什么干净的办法可以解决这个问题。ConTeXt 不区分大小写,而且不会改变。更改pgf/gd/force/Control.lua为小写会影响 TeX 之外的 PGF Lua 用户。解决方法是将 Lua 包放在 TeX 树之外(例如,与文档位于同一文件夹中)。

上述场景还表明了更严重的问题,即一个“流氓”包可能会破坏另一个包的工作。假设 CTAN 包my-library有文件mylibrary/functions.lua。在系统中安装另一个rogue带有文件 的包后rogue/FuNcTiOnS.lua,ConTeXt 开始在 上失败require 'mylibrary.functions,因为它现在在树缓存中被错误地重新映射到不存在的文件路径mylibrary/FuNcTiOnS.lua

相关内容