2

I have successfully loaded XML in LuaLaTeX but how to load XML-Tables?

\documentclass{book}
\usepackage{luacode}

\begin{document}

\begin{luacode*} local domobject = require "luaxml-domobject" sample = [[ <datas> <arttitle>Quantum vacuum under mixed boundary conditions: the case for curved spacetime</arttitle> <table-wrap id="tab1" position="float"> <label>Table 1ABC.</label> <caption id="t1"><p>The large <italic>x</italic> behavior for different <italic>w</italic>.</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> </table> <thead> <tr> <th>A1</th> <th>A2</th> </tr> </thead> <tbody> <tr> <td>B1</td> <td>B2</td> </tr> </tbody> </table-wrap> </datas>]] local dom = domobject.parse(sample) tex.sprint(dom:query_selector("arttitle")[1]:get_text())

\end{luacode*} \end{document}

It's printing article-title in PDF. How to do number of columns in XML and create in PDF?

Balaji
  • 2,282

1 Answers1

1

Edit:

Here is how this XML file can be transformed to LaTeX and printed in the document. We can utilize the new luaxml-transform library which is present in the development version of LuaXML.

Here is the updated TeX file:

% https://tex.stackexchange.com/a/574004/2891
\documentclass{book}
\usepackage{luacode}

\begin{document}

\begin{luacode*} local domobject = require "luaxml-domobject" local transform = require "luaxml-transform" sample = [[ <datas> <arttitle>Quantum vacuum under mixed boundary conditions: the case for curved spacetime</arttitle> <table-wrap id="tab1" position="float"> <label>Table 1ABC.</label> <caption id="t1"><p>The large <italic>x</italic> behavior for different <italic>w</italic>.</p></caption> <table> <colgroup> <col align="left"/> <col align="center"/> <col align="center"/> <col align="center"/> <col align="center"/> <col align="center"/> <col align="char" char="."/> </colgroup> <thead> <tr> <th>A1</th> <th>A2</th> <th>A3</th> <th>A4</th> <th>A5</th> <th>A6</th> </tr> </thead> <tbody> <tr> <td>B1</td> <td>B2</td> <td>B3</td> <td>B4</td> <td>B5</td> <td>B6</td> </tr> </tbody> </table> </table-wrap> </datas>]] local dom = domobject.parse(sample) local alignments = {left="l", center="c", right="r"}

-- rules for conversion transform.add_action("p", "%s\n\n") transform.add_action("italic", "\textit{%s}") transform.add_action("arttitle", "\noindent{\large\bfseries %s\par\noindent}") transform.add_action("table-wrap", [[ \begin{table} %s \end{table} ]])

transform.add_action("label", "\label{%s}") transform.add_action("caption", "\caption{%s}") transform.add_action("table", [[ \begin{tabular}{@{data-columns}} %s \end{tabular} ]])

transform.add_action("tr", "%s \\") transform.add_action("td", "& %s ") transform.add_action("td:first-child", "%s ") transform.add_action("th", "& %s ") transform.add_action("th:first-child", "%s ")

-- get table columns local function get_columns(tbl) local columns = {} for _, column in ipairs(tbl:query_selector("col")) do -- save column alignment. left is default local align = column:get_attribute("align") or "left" table.insert(columns, alignments[align]) end return table.concat(columns, " ") end

for i, tbl in ipairs(dom:query_selector("table")) do -- save table columns in table attribute, so it is available in transformation rules local columns = get_columns(tbl) tbl:set_attribute("data-columns", columns) end

local converted = transform.process_dom(dom) print(converted) transform.print_tex(converted)

\end{luacode*} \end{document}

In this case, we use the following code to set the tabular columns before the transformation:

-- get table columns
local function get_columns(tbl)
  local columns = {}
  for _, column in ipairs(tbl:query_selector("col")) do
    -- save column alignment. left is default
    local align = column:get_attribute("align") or "left"
    table.insert(columns, alignments[align])
  end
  return table.concat(columns, " ")
end

for i, tbl in ipairs(dom:query_selector("table")) do -- save table columns in table attribute, so it is available in transformation rules local columns = get_columns(tbl) tbl:set_attribute("data-columns", columns) end

It sets the custom attribute, data-columns, with a value needed for the tabular environment based on the align attribute, like l c c c c c in this case.

The transformation rules are declared like this:

transform.add_action("label", "\\label{%s}")

The first argument is CSS selector that should be transformed. In the easiest case, it is just element name. The second argument is a template that will be used. %s is replaced with the element contents.

transform.add_action("table", [[
\begin{tabular}{@{data-columns}}
%s
\end{tabular}
]])

This more complicated transformation configures the table. @{data-columns} selects the data-columns attribute that we set earlier in the DOM processing function.

transform.add_action("td", "& %s ")
transform.add_action("td:first-child", "%s ")

This is an example of a more specific CSS rule. & characters are appended before table cells, except the first cell in each row.

This is the resulting PDF:

enter image description here

Another edit:

You can use this code as a standalone script to convert XML to LaTeX from the command line, bxmltolatex.lua:

kpse.set_program_name "luatex"
local domobject = require "luaxml-domobject"
local transform = require "luaxml-transform"

-- read input from stdio local sample = io.read("*all")

local dom = domobject.parse(sample)

-- rules for conversion transform.add_action("p", "%s\n\n") transform.add_action("italic", "\textit{%s}") transform.add_action("arttitle", "\noindent{\large\bfseries %s\par\noindent}") transform.add_action("table-wrap", [[ \begin{table} %s \end{table} ]])

transform.add_action("label", "\label{%s}") transform.add_action("caption", "\caption{%s}") transform.add_action("table", [[ \begin{tabular}{@{data-columns}} %s \end{tabular} ]])

transform.add_action("tr", "%s \\") transform.add_action("td", "& %s ") transform.add_action("td:first-child", "%s ") transform.add_action("th", "& %s ") transform.add_action("th:first-child", "%s ")

-- ignore colgroup transform.add_action("colgroup", "")

-- get table columns local alignments = {left="l", center="c", right="r"}

local function get_columns(tbl) local columns = {} for _, column in ipairs(tbl:query_selector("col")) do -- save column alignment. left is default local align = column:get_attribute("align") or "left" table.insert(columns, alignments[align]) end return table.concat(columns, " ") end

for i, tbl in ipairs(dom:query_selector("table")) do -- save table columns in table attribute, so it is available in transformation rules local columns = get_columns(tbl) tbl:set_attribute("data-columns", columns) end

local converted = transform.process_dom(dom) print(converted)

file.xml is:

<datas>
  <arttitle>Quantum vacuum under mixed boundary conditions: the case for curved spacetime</arttitle>
  <table-wrap id="tab1" position="float">
  <label>Table 1ABC.</label>
  <caption id="t1"><p>The large <italic>x</italic> behavior for different <italic>w</italic>.</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>A1</th>
  <th>A2</th>
  <th>A3</th>
  <th>A4</th>
  <th>A5</th>
  <th>A6</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>B1</td>
  <td>B2</td>
  <td>B3</td>
  <td>B4</td>
  <td>B5</td>
  <td>B6</td>
  </tr>
  </tbody>
  </table>
  </table-wrap>
</datas>

Use it as:

texlua bxmltolatex.lua < file.xml > TransformedLatex.tex

Original answer:

You can use the query_selector on particular elements:

\documentclass{book}
\usepackage{luacode}

\begin{document}

\begin{luacode*} local domobject = require "luaxml-domobject" sample = [[ <datas> <arttitle>Quantum vacuum under mixed boundary conditions: the case for curved spacetime</arttitle> <table-wrap id="tab1" position="float"> <label>Table 1ABC.</label> <caption id="t1"><p>The large <italic>x</italic> behavior for different <italic>w</italic>.</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> </table> <thead> <tr> <th>A1</th> <th>A2</th> </tr> </thead> <tbody> <tr> <td>B1</td> <td>B2</td> </tr> </tbody> </table-wrap> </datas>]] local dom = domobject.parse(sample)

tex.sprint(dom:query_selector("arttitle")[1]:get_text())

tex.sprint("\par")

local function get_columns(tbl) return #tbl:query_selector("col") end for i, tbl in ipairs(dom:query_selector("table")) do tex.sprint("Table: " .. i .. " has " .. get_columns(tbl) .. " columns") end

\end{luacode*} \end{document}

The important part is this:

local function get_columns(tbl)
  return #tbl:query_selector("col")
end
for i, tbl in ipairs(dom:query_selector("table")) do
  tex.sprint("Table: " .. i .. " has " .. get_columns(tbl) .. " columns")
end

It processes all tables in your document and it prints the column count calculated by #tbl:query_selector("col") for every table.

This is the result:

enter image description here

Balaji
  • 2,282
michal.h21
  • 50,697