将 ConTeXt 引用 `(context.currentstructurereference)` 传递给 lua 函数

将 ConTeXt 引用 `(context.currentstructurereference)` 传递给 lua 函数

我想将一些 ConTeXt 引用传递给 Lua 函数。就像下面的 MWE 一样,想法是通过 将表名传递给函数context.currentstructurereference。如果我取消注释调用 context.currentstructurereference 的行,MWE 将无法编译,如果我取消注释下一行 (),则返回引用。使用括号没有帮助。

\startluacode 
userdata = userdata or {}
   function userdata.Test (t)
      for key,value in table.sortedhash(t)
      do
         tex.print (value)
      end
   end

Paris = {
pays = "France",
région = "Ile-de-France",
megapole = "oui"
}

\stopluacode

\starttext

\startsection[title={Paris},reference={Paris}]

\startluacode
context(context.currentstructurereference)
context.par()
userdata.Test(Paris)
-- userdata.Test(context.currentstructurereference) --does not compile
-- userdata.Test(context.currentstructurereference()) --not the expected result
\stopluacode
\stopsection

\stoptext

userdata.Test(Paris)我应该怎么做才能获得与致电相同的结果context.currentstructurereference

答案1

您可以使类似这样的操作起作用,但是您的代码中存在两个概念错误。

首先,该函数userdata.Test(...)需要 Lua 表的名称作为参数。无论您做什么,context.currentstructurereference都不会指向 Lua 表。因此,您需要做的第一件事就是更改的参数userdata.Test(...)。更改它的最简单方法是让它需要一个字符串,这是存储相关数据的表中的键。一种选择如下:

\startluacode 
userdata = userdata or {}

local references = {
  ["Paris"] = {
                pays = "France",
                région = "Ile-de-France",
                megapole = "oui"
              },
}


function userdata.Test (ref)
  local tbl = references[ref]
  for key, value in table.sortedhash(tbl)
  do
     tex.print (value)
  end
end
\stopluacode

现在,如果我们能以某种方式将 (TeX 宏)的值context.currentstructurerefence作为字符串传递给 Lua,那就好了。您尝试使用userdata.Test(context.currentstructurereference)仍然不起作用。为什么?

命名空间context.使用了一个元编程技巧:当你调用时context.something,它大致相当于tex.print("\\something"),但具有一些奇特的功能:

  • context.something("arg")等于tex.print("\\something{arg}")
  • context.something({key=value}, "arg")等于tex.print("\\something[key=value]{arg}")

该宏执行的一项奇特功能context称为延迟处理(在 TeX 和 Lua 之间来回传递控制时需要此功能)。从高层次来看,

  • context.something(function ... end)等于output of function

您可以通过运行以下代码来检查这一点:

\startluacode
  context(function() context("Hello") end)
\stopluacode

因此,context.currentstructurereference()是一个函数,它有效地调用了tex.sprint("\\currentstructurereference{}")将的扩展值打印\currentstructurereference到 TeX 流中。因此,

\startluacode
  context(context.currentstructurereference)
\stopluacode

与简单调用 [^1] 大致相同context.currentstructurereference。当然,这不适用于该userdata.Test函数,因为:(i) 它需要一个 Lua 表(或我们上面修改后的版本中的 Lua 字符串);(ii)context.something等于tex.print("\\something"),因此它会写入 TeX 字符串,而 Lua 根本看不到该值。您可以做的非常简单:

\startluacode
   userdata.Test("\currentstructurereference")
\stopluacode

请注意,我使用的"\currentstructurereference"是 而不是"\\currentstructureference"。因此,会立即展开,因此您将在遇到 时\currentstructurereference获得 的值。这在您拥有的最小示例中有效,但如果您的实际用例更复杂,可能会失败。\currentstructurereference\startluacode

[^1]: 严格来说,这不是真的。有一个延迟调用的概念,但我不会在这里讨论它。有关详细信息,请参阅 CLD 手册。

相关内容