我需要在不使用longtable
包的情况下将表格拆分到下一页。因为longtable
包不直接支持float
。
我的 MWE 是:
\documentclass{article}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
local domobject = require "luaxml-domobject"
sample = [[
<?xml version="1.0" encoding="utf-8"?>
<art>
<title>Scattering of flexural waves an electric current</title>
<p>From these observations, another important result is that the individual masses of such observed black hole–black hole (BBHs) binaries can be much larger than what were expected previously both theoretically and observationally [14], and various scenarios have been proposed [<xref ref-type="bibr" rid="cqgab7bbabib2">2</xref>, <xref ref-type="bibr" rid="cqgab7bbabib26">26</xref>]. In particular, observations of the same signal in two different detectors provides an efficient independent way to cross check and validate the instruments, which is particularly valuable for a space-based detector behavior of these parameters is presented in the table <xref ref-type="table" rid="cqgab7bbat1">1</xref>.</p>
<table-wrap id="tab1" position="float" tab-row-break="5"><label>Table 1.</label><caption id="tab1"><p>The large <italic>x</italic> behavior for different <italic>w</italic>, where <italic>F</italic> means finite.</p></caption><table><colgroup><col align="left"/><col align="center"/><col align="center"/><col align="center"/><col align="center"/><col align="center"/><col align="center"/></colgroup><thead><tr><th>Parameters:</th><th>e<sup>2<italic>γ</italic></sup></th><th><italic>r</italic><sup>2</sup></th><th><italic>ρ</italic></th><th><italic>L</italic></th><th><italic>V</italic></th><th><italic>E</italic></th></tr></thead><tbody><tr><td>A1</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>B2</td><td>0</td><td>∞</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>C3</td><td>∞</td><td>0</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>D4</td><td>0</td><td>∞</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>E5</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>F6</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>G7</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>H8</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>I9</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>J10</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr></tbody></table></table-wrap>
</art>
]]
local dom = domobject.parse(sample)
\end{luacode*}
\end{document}
如果table
属性是具有tab-row-break='5'
,我需要从而tbody
不是在中计算表行thead
,并且需要给出关闭tabular
和打开新的tabular
像\end{tabular}\pagebreak\begin{tabular}{...}
。
如何实现这一点?
答案1
您可以使用库来转换 XML luaxml-transform
,但是由于需要根据属性将表拆分为两个浮点数,因此这项任务变得更加困难tab-row-break
。我们可以使用该luaxml-domobject
库来预处理 XML,拆分表,然后我们可以轻松使用转换库。
这是完整的代码,我将在下面进行描述:
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Linux Libertine O}
\usepackage{luacode}
% this is a modified version of \@makecaption from LaTeX classes
% it doesn't print : between table number and caption
\makeatletter
\newcommand\tablecaption[2]{%
\vskip\abovecaptionskip
\sbox\@tempboxa{\textbf{#1} #2}%
\ifdim \wd\@tempboxa >\hsize
\textbf{#1} #2\par
\else
\global \@minipagefalse
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
\fi
\vskip\belowcaptionskip
}
\makeatother
\begin{document}
\begin{luacode*}
local domobject = require "luaxml-domobject"
local transform = require "luaxml-transform"
sample = [[
<?xml version="1.0" encoding="utf-8"?>
<art>
<title>Scattering of flexural waves an electric current</title>
<p>From these observations, another important result is that the individual masses of such observed black hole–black hole (BBHs) binaries can be much larger than what were expected previously both theoretically and observationally [14], and various scenarios have been proposed [<xref ref-type="bibr" rid="cqgab7bbabib2">2</xref>, <xref ref-type="bibr" rid="cqgab7bbabib26">26</xref>]. In particular, observations of the same signal in two different detectors provides an efficient independent way to cross check and validate the instruments, which is particularly valuable for a space-based detector behavior of these parameters is presented in the table <xref ref-type="table" rid="cqgab7bbat1">1</xref>.</p>
<table-wrap id="tab1" position="float" tab-row-break="5"><label>Table 1.</label><caption id="tab1"><p>The large <italic>x</italic> behavior for different <italic>w</italic>, where <italic>F</italic> means finite.</p></caption><table><colgroup><col align="left"/><col align="center"/><col align="center"/><col align="center"/><col align="center"/><col align="center"/><col align="center"/></colgroup><thead><tr><th>Parameters:</th><th>e<sup>2<italic>γ</italic></sup></th><th><italic>r</italic><sup>2</sup></th><th><italic>ρ</italic></th><th><italic>L</italic></th><th><italic>V</italic></th><th><italic>E</italic></th></tr></thead><tbody><tr><td>A1</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>B2</td><td>0</td><td>∞</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>C3</td><td>∞</td><td>0</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>D4</td><td>0</td><td>∞</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>E5</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td><td><italic>F</italic></td><td><italic>F</italic></td></tr><tr><td>F6</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>G7</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>H8</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>I9</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr><tr><td>J10</td><td>∞</td><td>∞</td><td>0</td><td>∞</td><td>∞</td><td><italic>F</italic></td></tr></tbody></table></table-wrap>
</art>
]]
local dom = domobject.parse(sample)
-- prepare tables
for _, wrap in ipairs(dom:query_selector("table-wrap[tab-row-break]")) do
local row_break = wrap:get_attribute("tab-row-break")
local tables = wrap:query_selector("table") or {}
-- we assume that there is just one table as <table-wrap> children
local tbl = tables[1]
if tbl then
-- convert <col> elements to latex specification and save it as an attribute
local align = {}
local align_convert = {left = "l", right = "r", center = "c"}
for _, col in ipairs(tbl:query_selector("col")) do
local al = col:get_attribute("align") or "left"
align[#align+1] = align_convert[al]
end
tbl:set_attribute("align", table.concat(align, " "))
end
-- create floats
-- first save children
local children = wrap:get_children()
-- it will contain floats
wrap._children = {}
-- this is needed to fix a bug in LuaXML
local function fix_parents(el)
for k,v in ipairs(el._children or {}) do
if v:is_element() then
v._parent = el
fix_parents(v)
end
end
end
for i = 1, 2 do
local float = wrap:create_element("float")
wrap:add_child_node(float)
-- add saved children
for _, child in ipairs(children) do
-- save copy of the original child
float:add_child_node(child:copy_node())
end
fix_parents(float)
end
-- now split tables
local tbl = wrap:query_selector("table")
-- there should be two tables now
if #tbl == 2 then
local tbody = tbl[1]:query_selector("tbody tr")
-- remove spurious rows from the first table
for i = row_break + 1, #tbody do
tbody[i]:remove_node()
end
-- remove spurious lines from the second table
local tbody = tbl[2]:query_selector("tbody tr")
for i = 1, row_break do
tbody[i]:remove_node()
end
end
-- place (continued...) text to second caption
local captions = wrap:query_selector("caption")
local caption = captions[2]
if caption then
-- remove original text
caption._children = {}
local par = caption:create_element("p")
local text = par:create_text_node("(continued...)")
par:add_child_node(text)
caption:add_child_node(par)
end
end
transformer = transform.new()
transformer:add_action("title", "\\section{@<.>}")
transformer:add_action("p", "@<.>\n\n")
transformer:add_action("table-wrap float", "\\begin{table}\n@<.>\n\\end{table}\n")
-- you need to define this command in your TeX file
transformer:add_action("table-wrap label", "\\tablecaption{@<.>}")
-- this is a second argument to \tablecaption
transformer:add_action("table-wrap caption", "{@<.>}\n\n")
transformer:add_action("italic", "\\textit{@<.>}")
transformer:add_action("sub", "\\textsubscript{@<.>}")
transformer:add_action("sup", "\\textsuperscript{@<.>}")
transformer:add_action("table", "\\begin{tabular}{@{align}}\n@<.>\\end{tabular}\n")
transformer:add_action("tr", "@<.>\\\\\n")
transformer:add_action("th", "@<.> &")
transformer:add_action("th:last-of-type", "@<.>")
transformer:add_action("tbody td", "@<.> &")
transformer:add_action("tbody td:last-of-type", "@<.>")
local content = transformer:process_dom(dom)
-- print(content)
-- print the transformed XML to LaTeX
transform.print_tex(content)
-- print(dom:serialize())
\end{luacode*}
\end{document}
这是处理表格的部分:
local dom = domobject.parse(sample)
-- prepare tables
for _, wrap in ipairs(dom:query_selector("table-wrap[tab-row-break]")) do
local row_break = wrap:get_attribute("tab-row-break")
local tables = wrap:query_selector("table") or {}
-- we assume that there is just one table as <table-wrap> children
local tbl = tables[1]
if tbl then
-- convert <col> elements to latex specification and save it as an attribute
local align = {}
local align_convert = {left = "l", right = "r", center = "c"}
for _, col in ipairs(tbl:query_selector("col")) do
local al = col:get_attribute("align") or "left"
align[#align+1] = align_convert[al]
end
tbl:set_attribute("align", table.concat(align, " "))
end
-- create floats
-- first save children
local children = wrap:get_children()
-- it will contain floats
wrap._children = {}
-- this is needed to fix a bug in LuaXML
local function fix_parents(el)
for k,v in ipairs(el._children or {}) do
if v:is_element() then
v._parent = el
fix_parents(v)
end
end
end
for i = 1, 2 do
local float = wrap:create_element("float")
wrap:add_child_node(float)
-- add saved children
for _, child in ipairs(children) do
-- save copy of the original child
float:add_child_node(child:copy_node())
end
fix_parents(float)
end
-- now split tables
local tbl = wrap:query_selector("table")
-- there should be two tables now
if #tbl == 2 then
local tbody = tbl[1]:query_selector("tbody tr")
-- remove spurious rows from the first table
for i = row_break + 1, #tbody do
tbody[i]:remove_node()
end
-- remove spurious lines from the second table
local tbody = tbl[2]:query_selector("tbody tr")
for i = 1, row_break do
tbody[i]:remove_node()
end
end
-- place (continued...) text to second caption
local captions = wrap:query_selector("caption")
local caption = captions[2]
if caption then
-- remove original text
caption._children = {}
local par = caption:create_element("p")
local text = par:create_text_node("(continued...)")
par:add_child_node(text)
caption:add_child_node(par)
end
end
首先,它将列对齐信息转换为 LaTeX 表格规范,并将其保存为元素的属性<table>
。它使转换更容易。然后,它创建两个浮动元素,并将原始表格内容复制到它们。然后,我们从两个副本中删除虚假的表格行,并将其设置(continued...)
为第二个浮动元素的表格标题。
然后可以使用以下规则转换此 DOM 对象:
transformer = transform.new()
transformer:add_action("title", "\\section{@<.>}")
transformer:add_action("p", "@<.>\n\n")
transformer:add_action("table-wrap float", "\\begin{table}\n@<.>\n\\end{table}\n")
-- you need to define this command in your TeX file
transformer:add_action("table-wrap label", "\\tablecaption{@<.>}")
-- this is a second argument to \tablecaption
transformer:add_action("table-wrap caption", "{@<.>}\n\n")
transformer:add_action("italic", "\\textit{@<.>}")
transformer:add_action("sub", "\\textsubscript{@<.>}")
transformer:add_action("sup", "\\textsuperscript{@<.>}")
transformer:add_action("table", "\\begin{tabular}{@{align}}\n@<.>\\end{tabular}\n")
transformer:add_action("tr", "@<.>\\\\\n")
transformer:add_action("th", "@<.> &")
transformer:add_action("th:last-of-type", "@<.>")
transformer:add_action("tbody td", "@<.> &")
transformer:add_action("tbody td:last-of-type", "@<.>")
没什么特别的,只看到我们需要处理行中的最后一个项,以防止插入多余的&
字符,这会导致编译错误。 这是我们所需要的规则tbody td:last-of-type
。
还要注意,我们使用align
之前由 DOM 处理函数定义的属性来设置正确的表格声明。
我们还期望<label>
和<caption>
元素彼此相邻,因为它们产生命令\tablecaption
,并且如果它们不在预期的位置,它就会中断。
最后,请注意您需要使用支持所有特殊字符的字体,例如我示例中的 Linux Libertine。
结果如下: