将 conText 命令移入 luacode 环境

将 conText 命令移入 luacode 环境

我正在尝试弄清楚如何在 Lua 环境中移动一些上下文命令。(我正在尝试创建一个文档,其中大部分内容都是从外部源提取的数据动态创建的)

我已经在正常情况下创建了这个非常简单的 MWE,它可以按预期工作。

\defineexternalfigure
    [svgframe][method=svg, conversion=mp, width=10cm, height=10cm]
\defineoverlay
    [boxframe][{\externalfigure[frame.svg][svgframe][width=10cm,height=10cm]}]
    
\defineframed
    [CARDFRAME][height=10cm, width=10cm, frame=off, align=inner, background=boxframe]
\starttext
\CARDFRAME{\blank\blank Hello World!}
\stoptext

我正在为 MWE 使用任意 CC0 svg 框架从这里

在尝试转换普通的 conText 代码时。我创建了这个:


\startluacode

context.defineexternalfigure({ "svgframe" }, {method = "svg", conversion = "mp", width = "10cm" , height = "10cm" })
context.defineoverlay({ "boxframe" }, context.externalfigure( { "frame.svg" }, { "svgframe" } ) )
context.defineframed({ "CARDFRAME" }, {height = "10cm", width = "10cm", frame = "off", align = "inner", background = boxframe})
context.starttext()

context.CARDFRAME( context("Hello World") )

context.stoptext()
\stopluacode

这段代码至少有两个问题我无法弄清楚。

  1. 正如所写,我收到错误:tex error > tex error on line 1 in file : You can't use '\end' in internal vertical mode在编译期间
  2. 如果我删除context.CARDFRAME(和匹配的右括号,那么编译会成功,但是图像似乎是在 defineoverlay 时排版的。

第 29 页ConTEXt Lua 文档讨论了我认为类似的情况,并采用那里给出的解决方案,我想我会将 defineoverlay 命令写为:

context.defineoverlay({ "boxframe" }, function() context.externalfigure( { "frame.svg" }, { "svgframe" } ) end )

但即使我这样做了,图像似乎仍然是在 defineoverlay 命令时排版的。

有人能给我指出解决这些问题的正确方向吗?

谢谢

答案1

  1. 正如所写,我收到错误:
    tex error > tex error on line 1 in file : You can't use '\end' in internal vertical mode
    
    在编译期间

context.stoptext()结束整个编译运行,但此时luacode环境仍然打开,因此这不起作用。

一个选项是将\starttext/放在/\stoptext周围:\startluacode\stopluacode

% test.tex
\starttext
\startluacode
    context("Hello World")
\stopluacode
\stoptext

但更好的选择是放置内容/放入一个文件中,ConTeXt 将直接将其作为 Lua 进行处理\startluacode\stopluacode.cld

-- test.tex
context.starttext()
context("Hello World")
context.stoptext()
  1. 如果我删除context.CARDFRAME(和匹配的右括号,那么编译会成功,但是图像似乎是在 时排版的\defineoverlay

    在 ConTEXt Lua Documents 的第 29 页上讨论了一种我认为类似的情况,并且根据那里给出的解决方案,我想我会将 defineoverlay 命令写成:

    context.defineoverlay({ "boxframe" }, function() context.externalfigure( { "frame.svg" }, { "svgframe" } ) end )
    

    但即使我这样做了,图像似乎仍然是在命令执行时排版的defineoverlay

您正在编写context.defineoverlay({"first"}, "second"),它被序列化为\defineoverlay[first]{second},ConTeXt 最终将其处理为\defineoverlay[first](带有一个参数的命令),然后是second(原始文本)。

为了使其工作,您需要将函数括在{括号中}

context.defineexternalfigure(
    { "svgframe" },
    {
        method = "svg",
        conversion = "mp",
        width =
        "10cm",
        height = "10cm",
    }
)

context.defineoverlay(
    { "boxframe" },
    { -- Braces needed here since it's `\defineoverlay[...][...]`, not `\defineoverlay[...]{...}`.
        function ()  -- Wrap with a function here as you suggested
            context.externalfigure({ "frame.svg" }, { "svgframe" })
            return true  -- We need to return `true` here for weird caching reasons that only apply to this specific macro (and a few other rare cases that you probably won't run into).
        end
    }
)

context.defineframed(
    { "CARDFRAME" },
    {
        height = "10cm",
        width = "10cm",
        frame = "off",
        align = "inner",
        background = "boxframe", -- Quotes needed here since `boxframe` refers to the Lua variable which is undefined and therefore `nil`.
    }
)
context.startTEXpage()
context.CARDFRAME(function() -- Use a function so we can add the `\blank`s from the original example.
    context.blank()
    context.blank()
    context("Hello World")
end)
context.stopTEXpage()

示例输出

相关内容