我已XML
在 的帮助下成功加载了 LuaLaTeX Michal.h21
。现在我想将所有自定义定义存储Lua Script
在单独的 LaTeX 样式文件中,例如bibr.sty
,以便我只\usepackage{bibr}
在 LaTeX 文件中调用。
该文件中bibr.sty
所有自定义的定义都lua script
需要进行定义。
我的 BIBR 交叉链接 XML 文件如下:
\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}
如何实现这一点?
答案1
正如 David 所建议的,将 Lua 代码移至独立文件是一个好主意,以防止 TeX 和 Lua 之间的一些交互问题。它可能看起来像这样bibr.lua
:
local M = {}
local domobject = require "luaxml-domobject"
local transform = require "luaxml-transform"
local function process_instructions(el)
for _, child in ipairs(el:get_children()) do
local ntype = child:get_node_type()
if ntype == "PI" and child._name=="LuaLaTeX" then
local text = child._attr[ "_text" ]
local newel = el:create_element("lualatex-instruction", {text = text})
child:replace_node(newel)
end
if child:is_element() then
process_instructions(child)
end
end
end
function M.process(sample)
local dom = domobject.parse(sample)
-- 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
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(result)
transform.print_tex(result)
end
function M.process_file(filename)
local f = io.open(filename, "r")
if not f then return nil, "Cannot open file: " .. filename end
local content = f:read("*all")
f:close()
M.process(content)
end
return M
我已将环境主体中原来的代码移至luacode
函数中M.process
。该M
表从此库返回,因此您可以按以下方式使用此代码:
local bibr = require "bibr"
bibr.process("xml code...")
我还制作了另一个函数,M.process_file
它将转换 XML 文件,因此您不需要将 XML 代码传递给您的文档。
然后,您需要一个 LaTeX 包,它将提供可以在您的文档中使用的命令。它看起来像这样bibr.sty
:
\ProvidesPackage{bibr}
\NewDocumentEnvironment{processbibr}{+b}{%
\directlua{
local bibr = require "bibr"
bibr.process([[\unexpanded{#1}]])
}
}{}
\NewDocumentCommand\processbibrfile{m}{%
\directlua{%
local bibr = require "bibr"
bibr.process_file("#1")
}
}
\endinput
它提供processbibr
环境和\processbibrfile
命令。如果要将 XML 代码放入文档中,可以使用环境;如果要包含外部 XML 文件,可以使用命令。
它可以像这样使用:
\documentclass{article}
\usepackage{natbib}
\usepackage{bibr}
\begin{document}
\begin{processbibr}
<?xml version="1.0" encoding="utf-8"?>
<art>
<title>Scattering of flexural waves an electric current</title>
<para>Smart testing structures are $a+b$ components Reduce acoustic noise used in engineering applications that are capable of sensing or reacting to their environment change <?LuaLaTeX Sample XXX1?> their mechanical properties. in a predictable and desired manner. In addition to carrying mechanical loads, <?LuaLaTeX \hspace*{12pt}Abc?> alleviate vibration, reduce acoustic noise, change their mechanical properties as required or monitor their own condition.</para>
<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>
\end{processbibr}
\processbibrfile{test.xml}
\end{document}
总的来说,我认为最好使用\processbibrfile
,因为当您将 XML 文件直接包含到 TeX 文件中时,您不会遇到可能发生的奇怪错误。
结果如下:
答案2
你把这个
\ProvidesPackage{bibr}
\RequirePackage{luacode}
\begin{luacode*}
% HERE YOUR CODE, exactly as it is in your example
\end{luacode*}
在文件中,并将其以.sty
扩展名保存在与您的.tex
.