变量处理,lualatex 还是 expl3,还是别的?

变量处理,lualatex 还是 expl3,还是别的?

我经常发现自己面临着同样的任务:简化我编写的类的复杂数据输入。我总是使用相同的前端。数据被输入并存储在变量中,然后处理命令使用这些变量中的信息来生成复杂格式的输出。

举一个简单的例子

\name{The name goes here}

\descr{The description goes here}

\tablecontents{column a}{column b}{column c}{column d}

\note{The note goes here}

\makeentry

调用时,\makeentry将使用输入到“变量”中的任何数据。

多年来,我制作了多个后端,一个是基本 latex,一个是 expl3,最近又制作了一个 lua。每个后端都有自己的问题。我很快就从基本 latex 转到了 expl3,因为处理任何形式的逻辑都是一场噩梦,做同样的事情需要大约 3 倍的代码。

我对 expl3 有意见,因为其中有很多错误的内容。而且看旧代码看起来就像是某种密码。处理所有奇怪的数据结构(查看标记列表和序列)非常繁琐。处理所有 :Nn 让我想死。

下面是 expl3 中变量存储命令的一个示例

\tl_new:N \name %delcares the variable \name

\NewDocumentCommand{\name}{s+m} {%set command for names
    \tl_set:Nn \itemname {#2}
}

Lualatex 似乎提供了一个黄金解决方案,一种“真正的”编程语言。上面的相同代码可以用它处理。

function myluafile.setname(alpha)
    name = alpha
end

function myluafile.getname()
    tex.print(name)
end

然后你的 .tex 中的相邻代码将是

\directlua{myluafile = require("myluafile")}%this links the .lua

\newcommand{\name}[1]{\directlua{myluafile("#1")}}

但进一步深入研究后,我发现自己想要在 latex 中构建格式(因为,你知道,这就是它的用途),这实际上需要将变量传递到 lua,解析它们,将它们传递回 latex,将它们存储在 expl3 变量中,然后格式化它们。我通过在 lua 中对它们进行 psudo 处理并吐出巨大的打印序列来解决这个问题,然后 latex 可以正确读取,就像这样

local function buildnamedtable()
    tex.print("\\setlength{\\tabcolsep}{0pt}")
    tex.print("\\renewcommand{\\arraystretch}{1.2}")
    --Table settings for un-named entrys, D D D T
    tex.print("\\newcolumntype{N}{>{\\hsize=0.4\\linewidth \\raggedright\\arraybackslash}X}%")
    tex.print("\\newcolumntype{C}{>{\\hsize=0.15\\linewidth \\centering\\arraybackslash}X}%")
    tex.print("\\newcolumntype{T}{>{\\hsize=0.3\\linewidth \\raggedright\\arraybackslash}X}%")
    tex.print("\\begin{center}\\begin{tabularx}{0.98\\linewidth}{ N C C C T }")
    tex.print("& \\textbf{b} & \\textbf{c}& \\textbf{d}& \\textbf{e}\\\\")
    tex.print("\\hline")
    for k=0, (count - 1), 1 do
        if tocolorline[k] then
            tex.print("\\rowcolor{mycellcolor}")
        end
        tex.print(a[k] .. "&" .. b[k] .. "&" .. c[k] .. "&" .. d[k] .. "&" .. e[0] .. "\\\\")
    end
    tex.print("\\end{tabularx}\\end{center}")
end

不用说,这感觉很不对劲,但它确实有效。我想说这比处理 expl3 要好,但它并不完美,lua 和 latex 之间的连接命令似乎有问题。特别是我在存储命令的 latex 方面遇到了麻烦\newcommand{\name}[1]{\directlua{myluafile("#1")}}。似乎如果你试图传递复杂的字符串,比如那些带有反斜杠\引号"单引号'或百分号的字符串,%它就会死掉。错误处理也很糟糕。

有没有更好的方法来完成我正在尝试做的事情?我正在寻找关于其他人如何处理这种情况的意见,因为我肯定不是唯一一个。我明白这些回应可能非常主观,但这正是我正在寻找的意见。我觉得到目前为止我的解决方案都存在这样或那样的缺陷。

编辑:我已对我提到的有关复杂字符串的具体问题进行了澄清。并添加了相应的getname函数。

答案1

使用luacode打包你想要的任何东西都是可能的。基本上\luastringN避免了任何扩展,所以它发生在 TeX 端。你现在可以传递复杂的参数。

%!TEX program = lualatex
\documentclass[A5]{article}
\usepackage{luacode}
\begin{luacode*}
function setname(str)
    name = str
end
\end{luacode*}
\newcommand{\name}[1]{\luadirect{setname(\luastringN{#1})}}
\newcommand{\getname}{\directlua{tex.print(name)}}
\begin{document}
\name{\textbf{text}}\getname

\name{$x^2+1$}\getname

\name{"Jerky" comes from Quechua \emph{charqui}}\getname
\end{document}

在此处输入图片描述

答案2

现在你有了另一个选择:functional包。该包提供了 LaTeX2 接口expl3。但复合函数的求值是从内到外的,与语言相同Lua。也可以将每个函数组成一个组,这样函数结束后局部变量的值会被重置。

\documentclass[A5]{article}

\usepackage{functional}

\PrgNewFunction \name {m} {%
  \TlSet \lNameTl {#1}%
}

\PrgNewFunction \getname {} {%
  \TlUse \lNameTl
}

\begin{document}

\name{\textbf{text}}\getname

\name{$x^2+1$}\getname

\name{"Jerky" comes from Quechua \emph{charqui}}\getname

\end{document}

在此处输入图片描述

相关内容