将 ConTeXt' \documentvariable 放入 LuaTex

将 ConTeXt' \documentvariable 放入 LuaTex

我一直在尝试使用 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”......

相关内容