I have successfully loaded XML
in LuaLaTeX with help of Michal.h21
. Now I would like to store all the customized defined Lua Script
in a separate LaTeX Style file, like bibr.sty
, so that I will call just \usepackage{bibr}
in the LaTeX file.
In the bibr.sty
file all the customized defined lua script
need to be defined.
My BIBR Cross-Links XML file is below:
\documentclass{article}
\usepackage{luacode}
\usepackage{natbib}
\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>
<para>The first <xref ref-type="section" rid="Sec1">Section 1</xref> description and correlation between gait impairment and hydrocephalus were made in 1965 by Hakim and Adam (<xref ref-type="bibr" rid="B1">1</xref>). The etiology of idiopathic normal pressure hydrocephalus (iNPH) has not yet been entirely understood (<xref ref-type="bibr" rid="B2">2</xref>–<xref ref-type="bibr" rid="B5">5</xref>). In elderly patients, other conditions such as spinal canal stenosis, Parkinson's disease, and polyneuropathy may influence the gait negatively.</para>
</art>]]
local dom = domobject.parse(sample)
local function process_instructions(el)
-- try to find <xref> followed by dash and another <xref>
-- we then expand rid attributes
for _, xref in ipairs(dom:query_selector("xref[ref-type='bibr']")) do
local first = xref:get_sibling_node(1)
local second = xref:get_sibling_node(2)
if first and second and
first:is_text() and first:get_text() == "–" and -- next node must be "–" text
second:is_element() and second:get_element_name() == "xref" -- second element must be <xref>
then
local rid1 = xref:get_attribute("rid") or ""
local rid2 = second:get_attribute("rid") or ""
local prefix1, number1 = rid1:match("(%a+)(%d+)")
local prefix2, number2 = rid2:match("(%a+)(%d+)")
-- expand only if prefixes match each other
if prefix1 and prefix2 and prefix1 == prefix2 then
-- expand numbers
local t = {}
for i = number1, number2 do
t[#t+1] = prefix1 .. math.floor(i)
end
-- save expanded numbers
xref:set_attribute("rid", table.concat(t, ","))
-- remove unnecessary elements
first:remove_node()
second:remove_node()
end
end
end
end
process_instructions(dom:root_node())
local transformer = transform.new()
transformer:add_action("title", "\\section{@<.>}")
transformer:add_action("para", "@<.>\\par")
transformer:add_action("xref[ref-type='bibr']", "\\citep{@{rid}}")
-- handle the processing instruction
transformer:add_custom_action("lualatex-instruction",
function(el)
return el:get_attribute("text")
end)
local result = transformer:process_dom(dom)
-- Print Output Result in Command-Prompt/Terminal
print(result)
-- Print Output Result in PDF uncomment below
--transform.print_tex(result)
\end{luacode*}
\end{document}
How to achieve this?
Best Answer
As David suggested, it is a good idea to move the Lua code to a standalone file, to prevent some interaction issues between TeX and Lua. It could look like this,
bibr.lua
:I've moved the code that was originally in the main body of the
luacode
environment to a functionM.process
. TheM
table is returned from this library, so it will enable you to use this code in this way:I've also made another function,
M.process_file
, which will transform XML file, so you don't need to pass the XML code to your document.You then need a LaTeX package that will provide commands that can be used in your documents. It can look like this,
bibr.sty
:It provides
processbibr
environment and\processbibrfile
command. The environment can be used if you want to put the XML code in the document, the command for including external XML files.It can be used like this:
In general, I think it is better to use
\processbibrfile
, as you shouldn't run into strange errors that can happen when you include the XML file directly to your TeX file.This is the result: