我一直在尝试使用 ConTeXt 来进入 LuaTeX。
我有一个文档,其中包含一些自定义变量\startdocument
变量(你得到的变量\documentvariable
)。例如说\startdocument[myvar=15]
。
当然,我可以通过 LuaTeX 用 来排版它context.documentvariable('myvar')
,但我不能用 Lua 来操作它——比如,像在这个例子中,从中获取这个数字并将其[myvar]
与 Lua 中的数值相加:
\startluacode
userdata['test'] = {}
ut = userdata.test
function ut.add(addto)
local number = context.documentvariable('myvar') -- This throws an "attempt to perform arithmetic on a nil value (local 'number')" error
local number = tokens.getters.macro(tokens.getters.macro('??documentvariables') .. 'myvar') -- and this throws an "attempt to concatenate a nil value" error
local number = tokens.getters.macro(tokens.getters.macro('??documentvariable') .. 'myvar') -- same thing
context(number + addto)
end
\stopluacode
\startdocument[myvar=15]
\ctxlua{userdata.test.add(20)}
\stopdocument
所以正如你所看到的,我尝试了一些胡言乱语,试图遵循惯例CLD 传递变量但无法使其工作 - 不确定是否\documentvariable
有特殊的 LuaTeX 命名空间或类似的东西,以便我可以挂接它并让那些变量与 Lua 一起工作。
编辑1
正在做local number = tonumber(context.documentvariable('myvar'))
来。而且感觉有点脏
编辑2
我发现有一个“documentdata”的命名空间. 我以菜鸟的身份深入研究了一下源代码,在 mult-ini.lmt 中发现了一些对我来说像是线索的东西:
if documentdata then
local prefix, getmacro
function documentdata.variable(name)
if not prefix then
prefix = usednamespaces.variables .. ">document:"
end
if not getmacro then
getmacro = tokens.getters.macro
end
return getmacro(prefix..name)
end
end
因此我认为可以使用该documentdata.variable()
函数从文档命名空间中获取一个变量,但是当local rate
使用该函数进行设置时,它也会失败,并出现“尝试对零值(本地‘数字’)执行算术运算” -documentdata.variable('number')
打印“nil”。
答案1
据我所知,没有干净的解决方案。
一种选择是直接访问存储变量内容的 TeX 宏:
\setuppagenumbering[state=stop]
\setuppapersize[A10, landscape]
\startluacode
function userdata.getvariable(namespace, name)
local namespace = tokens.getters.macro("??" .. namespace)
local value = tokens.getters.macro(namespace .. ":" .. name)
return value
end
\stopluacode
\startdocument[
title={Test Title},
author={First Last},
number={12},
]
\cldcontext{userdata.getvariable("document", "title")}
\cldcontext{userdata.getvariable("document", "author"):upper()}
\cldcontext{tonumber(userdata.getvariable("document", "number")) ^ 3}
\stopdocument
作为一个更通用(但不太强大)的选项,您可以用它publications.prerollcmdstring
来获取任意宏的排版结果(而无需实际将其排版到页面上):
\setuppagenumbering[state=stop]
\setuppapersize[A10, landscape]
\startluacode
function userdata.documentvariable(name)
return publications.prerollcmdstring(
string.format("\\documentvariable{%s}", name)
)
end
\stopluacode
\startdocument[
title={Test Title},
author={First Last},
number={12},
]
\cldcontext{userdata.documentvariable("title")}
\cldcontext{userdata.documentvariable("author"):upper()}
\cldcontext{tonumber(userdata.documentvariable("number")) ^ 3}
\stopdocument
两个选项都提供相同的输出:
答案2
在阅读完怎么做\command{arg1}{arg2}
钩子插入 Lua*(并且真的很困惑CLD 传递变量)我发现我可以在 userdata 命名空间中创建一个新变量,并在其中分配以下值\documentvariable[myvar]
:
\def\setaddto#1{\ctxlua{userdata.test.addto = [==[#1]==]}}
然后它将是关于如何在执行任何操作之前调用这一部分,我这样做了\setupdocument
:
\setupdocument[before={\setaddto{\documentvariable{myvar}}}]
这样,整个事情看起来就像这样,并且似乎与我所做的完全非科学的测试一起工作 - 在这种情况下,它打印 137:
\startluacode
userdata['test'] = {}
ut = userdata.test
function ut.add(number)
context(number + ut.addto)
end
\stopluacode
\def\setaddto#1{\ctxlua{userdata.test.addto = [==[#1]==]}}
\setupdocument[before={\setaddto{\documentvariable{myvar}}}]
\startdocument[myvar=15]
\ctxlua{userdata.test.add(122)}
\stopdocument
*附录
它的标题应该是“将 \command{arg} 钩入 Lua”......