使用 LuaLaTeX 根据输入 XML 扩展 BIBR

使用 LuaLaTeX 根据输入 XML 扩展 BIBR

在 XML 文件中cross-links不会像2–5最终的乳胶应该是\citep{B2,B3,B4,B5}

如果cross-linksXML 编码为11–18它应该转换为\citep{B11,B12,B13,B14,B15,B16,B17,B18}(从头到尾)。如何使用获得预期结果LuaLaTeX

我的 XML 是:

\documentclass{article}
\usepackage{luacode}

\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>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>&#x02013;<xref ref-type="bibr" rid="B5">5</xref>). In elderly patients, other conditions such as spinal canal stenosis, Parkinson&#x00027;s disease, and polyneuropathy may influence the gait negatively.</para>
</art>]]

local dom = domobject.parse(sample)
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

process_instructions(dom:root_node())

local transformer = transform.new()
transformer:add_action("title", "\\section{@<.>}")
transformer:add_action("para", "@<.>\\par")
-- handle the processing instruction
transformer:add_custom_action("lualatex-instruction",
    function(el)
        return el:get_attribute("text")
    end)
transform.print_tex(transformer:process_dom(dom))
\end{luacode*}
\end{document}

我预期的输出 LaTeX 文件是:

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 Sample XXX1 their mechanical properties. in a predictable
and desired manner. In addition to carrying mechanical loads,
Abc alleviate
vibration, reduce acoustic noise, change their mechanical properties as required
or monitor their own condition.

The first Section 1 description and correlation between gait impairment and
hydrocephalus were made in 1965 by Hakim and Adam (**\citep{B1}**). The etiology of idio-
pathic normal pressure hydrocephalus (iNPH) has not yet been entirely under-
stood (**\citep{B2,B3,B4,B5}**). In elderly patients, other conditions such as spinal canal stenosis,
Parkinson’s disease, and polyneuropathy may influence the gait negatively.

答案1

因此,如果我理解正确的话,您没有将想要扩展的数字明确地表示为元素的属性xref,而是将其编码为两个单独的xref元素:

<xref ref-type="bibr" rid="B2">2</xref>&#x02013;<xref ref-type="bibr" rid="B5">5</xref>

我认为这不是一个好主意,但我们还是可以尝试一下。在这种情况下,您需要对 DOM 进行一些预处理,以检测这些情况并将它们转换为可以在 tranformer 库中使用的东西。此代码应该这样做:

-- 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

它检测<xref>后跟 dash 和 another 的元素<xref>,将扩展的 id 设置为rid属性,并删除不必要的 dash 和 second <xref>。然后,您可以声明此转换规则以将<xref>ofref-type转换bibr\citep

transformer:add_action("xref[ref-type='bibr']", "\\citep{@{rid}}")

@{rid}操作将打印属性的值rid

这是翻译后的 TeX 结果:

\section{Scattering of flexural waves an electric current}
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  Sample XXX1 their mechanical properties. 
in a predictable and desired manner. In addition to carrying mechanical loads,  \hspace*{12pt}Abc alleviate vibration, reduce acoustic noise, change their mechanical properties as required or monitor their own condition.\par
The first Section 1 description and correlation between gait impairment and hydrocephalus were made in 1965 by Hakim and Adam (\citep{B1}). 
The etiology of idiopathic normal pressure hydrocephalus (iNPH) has not yet been entirely understood (\citep{B2,B3,B4,B5}). 
In elderly patients, other conditions such as spinal canal stenosis, Parkinson's disease, and polyneuropathy may influence the gait negatively.\par

这是完整的代码:

\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>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>&#x02013;<xref ref-type="bibr" rid="B5">5</xref>). In elderly patients, other conditions such as spinal canal stenosis, Parkinson&#x00027;s disease, and polyneuropathy may influence the gait negatively.</para>
</art>]]

local dom = domobject.parse(sample)
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

-- 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{luacode*}
\end{document}

相关内容