使用 Luatex 创建表

使用 Luatex 创建表

我想制作一个带参数的模板表。我找到了不同类型的解决方案,但当我尝试进行一些更改时,它不再起作用了。

我尝试了两种不同的方法:第一种方法

\documentclass{beamer}
\usepackage{luacode}
\usepackage{xparse}

\NewDocumentCommand{\awesomelist}{%
m
}{%

\directlua{
    tex.print([[\begin{tabular}{|c|c|}]])
    tex.print([[\hline]])
    for i,k in pairs(table.pack("#1"))
        do
        if i == 1 then
            tex.print(String.format([[\%s & \%s \\]],k))
        else
            tex.print(String.format([[ & \%s \\]],k))
        end
    end
    tex.print([[\hline\end{tabular}]])
}
}

\begin{document}

\awesomelist{Scope,Test A,Test B,Test C,Test D}

hello world

\end{document}

第二个想法是这样做:

 \documentclass{article}
 \usepackage{longtable}
 \usepackage{luacode}
 \usepackage{luatextra}

 \begin{luacode*}
 function semisplit(input)
  local lst = string.split(input,";")
  for i, x in ipairs(lst) do
        if i == 0 then
              tex.print(string.format([[%s]],x))
        else
              tex.print(string.format([[ &\multicolumn{4}{p{11cm}}{%s}\\]],x))
        end
  end
end
\end{luacode*}

\newcommand{\builder}[1]{\directlua{semisplit("#1")}}

\begin{longtable}{p{2.5cm}|p{2.5cm} p{2.5cm} p{3.5cm} p{2.5cm}}
\hline
First Column & \multicolumn{4}{l}{some text inside} \\ 
\hline
Scope&\multicolumn{4}{p{11cm}}{\builder{Test a}}\\[2pt]
\hline
\end{longtable}

我希望你们能有个想法。这是我第一次使用 lua,所以不要评判我。

答案1

我仍然不能 100% 确定您要做什么;从代码中我无法完全清楚地了解您的意图。

就使用 Lua 而言,我认为总的来说,最好设置一个执行每一行的命令,而不是尝试执行整个表的命令。这样你就需要设置表,但使用命令来格式化每一行。显然,可以扩展它来同时读取很多行,但除非您打算从文件中读取它们,否则我看不出这样做的好处。

我设置了语法,如果您喜欢不同的语法TITLE=line|line|line,您可以摆弄和string.findstring.match来更改它。我放入了largely,\cline这样人们就可以看到每个框的结束位置;如果没有,它会更容易。

但我的直觉是,你只是用错误的方式处理这件事。我思考如果你想,我认为,LaTeX 风格的惯用方法是使用描述列表。所以我也演示了这一点。

\documentclass{article}
\usepackage{luacode}
\usepackage{longtable}
\usepackage{enumitem}
\begin{luacode*}
  function doline(line)
    local splitpoint = string.find(line, "=")
    local title = line:sub(1, splitpoint-1)
    local description = line:sub(splitpoint + 1)
    tex.print(title)
    for token in string.gmatch(description, "[^|]+") do
      tex.print("&" .. token .. "\\\\")
    end
    tex.print("\\cline{1-2}")
  end
\end{luacode*}
\newcommand{\tabularline}[1]{%
  \directlua{
    doline("#1")
  }}
\begin{document}

\begin{longtable}{|p{3cm} | p{7cm} |}
  \cline{1-2}
  \tabularline{Title=Description| More Description| Third Line}
  \tabularline{Title 2=And plenty| More | Where that | Came From}
\end{longtable}

% And a more latex-y solution IMO
\begin{description}[leftmargin=3.2cm, labelwidth=3cm, labelsep=0.2cm]
\item[Title 1] And here.

  We have.

  Some text.

\item[Title 2 Like This] And here is a longer description.

  Which also has a paragraph in it.
\end{description}

\end{document}

输出图像显示两种解决方案

更新

在评论中,原贴作者问是否必须使用这个|字符,或者是否可以在换行符上进行拆分。我说可以,但原贴作者发现这行不通。没错。

问题不在于 lua 代码,而在于由于参数在\tabularline传递到 Lua 之前由 TeX “处理”,换行符已被空格替换。解决方案是找到在这里的答案中:我们需要先对该论点进行去标记化。

但是,这会导致格式化函数收到一个字符串,其中换行符被“\par”替换。由于我拆分的方式,这个问题并不容易解决。也许最好的方法是循环遍历字符串,使用 来string.find定位\par并在那里拆分。但它更短,虽然不太整洁,只是在拆分之前替换\par\n所以我们最终得到修改后的代码,如下所示:

\begin{luacode*}
  function doline(line)
    local splitpoint = string.find(line, "=")
    local title = line:sub(1, splitpoint-1)
    local description = string.gsub(line:sub(splitpoint + 1), "\\par", "\n")
    tex.print(title)
    for token in string.gmatch(description, "[^\n]+") do
      tex.print("&" .. token .. "\\\\")
    end
    tex.print("\\cline{1-2}")
  end
\end{luacode*}

\newcommand{\tabularline}[1]{%
  \directlua{
    doline("\luatexluaescapestring{\detokenize{#1}}")
  }}

就我而言,我更喜欢烟斗(或者更好的是描述列表),但这实际上只是一个品味问题。

相关内容