Skip to content

Commit

Permalink
reference clause with both bibitems and reference subclauses: metanor…
Browse files Browse the repository at this point in the history
  • Loading branch information
opoudjis committed Nov 30, 2023
1 parent f217d91 commit 1a3bcd3
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 310 deletions.
145 changes: 145 additions & 0 deletions lib/metanorma/standoc/cleanup_bibitem.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
module Metanorma
module Standoc
module Cleanup
def formattedref_spans(xmldoc)
xmldoc.xpath("//bibitem[formattedref//span]").each do |b|
ret = new_bibitem_from_formattedref_spans(b)
merge_bibitem_from_formattedref_spans(b, ret)
end
end

def new_bibitem_from_formattedref_spans(bib)
ret = SpansToBibitem.new(bib).convert
ret.err.each do |e|
@log.add("Bibliography", bib, e[:msg])
e[:fatal] and @fatalerror << e[:msg]
end
ret.out
end

def merge_bibitem_from_formattedref_spans(bib, new)
new["type"] and bib["type"] = new["type"]
if bib.at("./title") # there already is a fetched record here: merge
bib.children = MergeBibitems
.new(bib.to_xml, new.to_xml).merge.to_noko.children
else bib << new.children.to_xml
end
end

def fold_notes_into_biblio(refs)
refs.xpath("./bibitem").each do |r|
while r&.next_element&.name == "note"
r.next_element["appended"] = true
r << r.next_element.remove
end
end
end

def extract_notes_from_biblio(refs)
refs.xpath("./bibitem").each do |r|
r.xpath("./note[@appended]").reverse.each do |n|
n.delete("appended")
r.next = n
end
end
end

def biblio_hidden_inherit(xmldoc)
xmldoc.xpath("//references[@hidden = 'true']").each do |r|
r.xpath("./bibitem").each { |b| b["hidden"] = true }
end
end

def biblio_no_ext(xmldoc)
xmldoc.xpath("//bibitem/ext").each(&:remove)
end

def format_ref(ref, type)
ret = Nokogiri::XML.fragment(ref)
ret.traverse { |x| x.remove if x.name == "fn" }
ref = to_xml(ret)
type != "metanorma" and return @isodoc.docid_prefix(type, ref)
/^\d+$/.match(ref) && !/^\[.*\]$/.match(ref) and return "[#{ref}]"
ref
end

def reference_names(xmldoc)
xmldoc.xpath("//bibitem[not(ancestor::bibitem)]").each do |ref|
@anchors[ref["id"]] =
if docid = select_docid(ref)
reference = format_ref(docid.children.to_xml, docid["type"])
{ xref: reference, id: idtype2cit(ref) }
else { xref: ref["id"], id: { "" => ref["id"] } }
end
end
end

def idtype2cit(ref)
ref.xpath("./docidentifier/@type").each_with_object({}) do |t, m|
m[t.text] and next
docid = select_docid(ref, t.text) or next
m[t.text] = format_ref(docid.children.to_xml, docid["type"])
end
end

def select_docid(ref, type = nil)
type and t = "[@type = '#{type}']"
ref.at("./docidentifier[@type = 'metanorma']#{t}") ||
ref.at("./docidentifier[@primary = 'true'][@language = '#{@lang}']#{t}") ||
ref.at("./docidentifier[@primary = 'true'][not(@language)]#{t}") ||
ref.at("./docidentifier[@primary = 'true']#{t}") ||
ref.at("./docidentifier[not(@type = 'DOI')][@language = '#{@lang}']#{t}") ||
ref.at("./docidentifier[not(@type = 'DOI')][not(@language)]#{t}") ||
ref.at("./docidentifier[not(@type = 'DOI')]#{t}")
end

def fetch_termbase(_termbase, _id)
""
end

def read_local_bibitem(uri)
xml = read_local_bibitem_file(uri) or return nil
ret = xml.at("//*[local-name() = 'bibdata']") or return nil
ret = Nokogiri::XML(ret.to_xml
.sub(%r{(<bibdata[^>]*?) xmlns=("[^"]+"|'[^']+')}, "\\1")).root
ret.name = "bibitem"
ins = ret.at("./*[local-name() = 'docidentifier']") or return nil
ins.previous = %{<uri type="citation">#{uri}</uri>}
ret&.at("./*[local-name() = 'ext']")&.remove
ret
end

def read_local_bibitem_file(uri)
%r{^https?://}.match?(uri) and return nil
file = "#{@localdir}#{uri}.rxl"
File.file?(file) or file = "#{@localdir}#{uri}.xml"
File.file?(file) or return nil
Nokogiri::XML(File.read(file, encoding: "utf-8"))
end

# if citation uri points to local file, get bibitem from it
def fetch_local_bibitem(xmldoc)
xmldoc.xpath("//bibitem[formattedref][uri[@type = 'citation']]")
.each do |b|
uri = b&.at("./uri[@type = 'citation']")&.text
bibitem = read_local_bibitem(uri) or next
bibitem["id"] = b["id"]
b.replace(bibitem)
end
end

def bibitem_nested_id(xmldoc)
xmldoc.xpath("//bibitem//bibitem").each do |b|
b.delete("id")
end
end

def bibitem_cleanup(xmldoc)
bibitem_nested_id(xmldoc)
ref_dl_cleanup(xmldoc)
formattedref_spans(xmldoc)
fetch_local_bibitem(xmldoc)
end
end
end
end
160 changes: 18 additions & 142 deletions lib/metanorma/standoc/cleanup_ref.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,11 @@
require "relaton_bib"
require_relative "merge_bibitems"
require_relative "spans_to_bibitem"
require_relative "cleanup_bibitem"

module Metanorma
module Standoc
module Cleanup
def formattedref_spans(xmldoc)
xmldoc.xpath("//bibitem[formattedref//span]").each do |b|
ret = new_bibitem_from_formattedref_spans(b)
merge_bibitem_from_formattedref_spans(b, ret)
end
end

def new_bibitem_from_formattedref_spans(bib)
ret = SpansToBibitem.new(bib).convert
ret.err.each do |e|
@log.add("Bibliography", bib, e[:msg])
e[:fatal] and @fatalerror << e[:msg]
end
ret.out
end

def merge_bibitem_from_formattedref_spans(bib, new)
new["type"] and bib["type"] = new["type"]
if bib.at("./title") # there already is a fetched record here: merge
bib.children = MergeBibitems
.new(bib.to_xml, new.to_xml).merge.to_noko.children
else bib << new.children.to_xml
end
end

def biblio_reorder(xmldoc)
xmldoc.xpath("//references[@normative = 'false']").each do |r|
biblio_reorder1(r)
Expand All @@ -40,7 +16,7 @@ def biblio_reorder(xmldoc)
def biblio_reorder1(refs)
fold_notes_into_biblio(refs)
bib = sort_biblio(refs.xpath("./bibitem"))
insert = refs&.at("./bibitem")&.previous_element
insert = refs.at("./bibitem")&.previous_element
refs.xpath("./bibitem").each(&:remove)
bib.reverse.each do |b|
(insert and insert.next = b.to_xml) or
Expand All @@ -50,24 +26,6 @@ def biblio_reorder1(refs)
refs.xpath("./references").each { |r| biblio_reorder1(r) }
end

def fold_notes_into_biblio(refs)
refs.xpath("./bibitem").each do |r|
while r&.next_element&.name == "note"
r.next_element["appended"] = true
r << r.next_element.remove
end
end
end

def extract_notes_from_biblio(refs)
refs.xpath("./bibitem").each do |r|
r.xpath("./note[@appended]").reverse.each do |n|
n.delete("appended")
r.next = n
end
end
end

def sort_biblio(bib)
bib
end
Expand Down Expand Up @@ -114,12 +72,6 @@ def biblio_cleanup(xmldoc)
biblio_no_ext(xmldoc)
end

def biblio_hidden_inherit(xmldoc)
xmldoc.xpath("//references[@hidden = 'true']").each do |r|
r.xpath("./bibitem").each { |b| b["hidden"] = true }
end
end

def biblio_linkonly(xmldoc)
xmldoc.at("//xref[@hidden]") or return
ins = xmldoc.at("//bibliography")
Expand All @@ -139,10 +91,6 @@ def insert_hidden_bibitems(bib)
reference_populate(refs)
end

def biblio_no_ext(xmldoc)
xmldoc.xpath("//bibitem/ext").each(&:remove)
end

def biblio_annex(xmldoc)
xmldoc.xpath("//annex[references/references]").each do |t|
t.xpath("./clause | ./references | ./terms").size == 1 or next
Expand All @@ -153,101 +101,29 @@ def biblio_annex(xmldoc)
end

def biblio_nested(xmldoc)
xmldoc.xpath("//references[references]").each do |t|
t.name = "clause"
t.xpath("./references").each { |r| r["normative"] = t["normative"] }
t.delete("normative")
end
end

def format_ref(ref, type)
ret = Nokogiri::XML.fragment(ref)
ret.traverse { |x| x.remove if x.name == "fn" }
ref = to_xml(ret)
return @isodoc.docid_prefix(type, ref) if type != "metanorma"
return "[#{ref}]" if /^\d+$/.match(ref) && !/^\[.*\]$/.match(ref)

ref
end

def reference_names(xmldoc)
xmldoc.xpath("//bibitem[not(ancestor::bibitem)]").each do |ref|
@anchors[ref["id"]] = if docid = select_docid(ref)
reference = format_ref(docid.children.to_xml,
docid["type"])
{ xref: reference, id: idtype2cit(ref) }
else
{ xref: ref["id"], id: { "" => ref["id"] } }
end
end
end

def idtype2cit(ref)
ref.xpath("./docidentifier/@type").each_with_object({}) do |t, m|
m[t.text] and next
docid = select_docid(ref, t.text) or next
m[t.text] = format_ref(docid.children.to_xml, docid["type"])
end
end

def select_docid(ref, type = nil)
type and t = "[@type = '#{type}']"
ref.at("./docidentifier[@type = 'metanorma']#{t}") ||
ref.at("./docidentifier[@primary = 'true'][@language = '#{@lang}']#{t}") ||
ref.at("./docidentifier[@primary = 'true'][not(@language)]#{t}") ||
ref.at("./docidentifier[@primary = 'true']#{t}") ||
ref.at("./docidentifier[not(@type = 'DOI')][@language = '#{@lang}']#{t}") ||
ref.at("./docidentifier[not(@type = 'DOI')][not(@language)]#{t}") ||
ref.at("./docidentifier[not(@type = 'DOI')]#{t}")
end

def fetch_termbase(_termbase, _id)
""
end

def read_local_bibitem(uri)
xml = read_local_bibitem_file(uri) or return nil
ret = xml.at("//*[local-name() = 'bibdata']") or return nil
ret = Nokogiri::XML(ret.to_xml
.sub(%r{(<bibdata[^>]*?) xmlns=("[^"]+"|'[^']+')}, "\\1")).root
ret.name = "bibitem"
ins = ret.at("./*[local-name() = 'docidentifier']") or return nil
ins.previous = %{<uri type="citation">#{uri}</uri>}
ret&.at("./*[local-name() = 'ext']")&.remove
ret
biblio_nested_initial_items(xmldoc)
biblio_nested_sections(xmldoc)
end

def read_local_bibitem_file(uri)
%r{^https?://}.match?(uri) and return nil
file = "#{@localdir}#{uri}.rxl"
File.file?(file) or file = "#{@localdir}#{uri}.xml"
File.file?(file) or return nil
Nokogiri::XML(File.read(file, encoding: "utf-8"))
end

# if citation uri points to local file, get bibitem from it
def fetch_local_bibitem(xmldoc)
xmldoc.xpath("//bibitem[formattedref][uri[@type = 'citation']]")
.each do |b|
uri = b&.at("./uri[@type = 'citation']")&.text
bibitem = read_local_bibitem(uri) or next
bibitem["id"] = b["id"]
b.replace(bibitem)
def biblio_nested_initial_items(xmldoc)
xmldoc.xpath("//references[references][bibitem]").each do |t|
r = t.at("./references")
ref = t.at("./bibitem")
.before("<references unnumbered='true'></references>").previous
(ref.xpath("./following-sibling::*") &
r.xpath("./preceding-sibling::*")).each do |x|
ref << x
end
end
end

def bibitem_nested_id(xmldoc)
xmldoc.xpath("//bibitem//bibitem").each do |b|
b.delete("id")
def biblio_nested_sections(xmldoc)
xmldoc.xpath("//references[references]").each do |t|
t.name = "clause"
t.xpath("./references").each { |r| r["normative"] = t["normative"] }
t.delete("normative")
end
end

def bibitem_cleanup(xmldoc)
bibitem_nested_id(xmldoc)
ref_dl_cleanup(xmldoc)
formattedref_spans(xmldoc)
fetch_local_bibitem(xmldoc)
end
end
end
end
8 changes: 3 additions & 5 deletions lib/metanorma/standoc/front.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ def metadata_getrelation1(doc, xml, type, desc)
end

def metadata_keywords(node, xml)
return unless node.attr("keywords")

node.attr("keywords") or return
node.attr("keywords").split(/,\s*/).each do |kw|
xml.keyword kw
end
Expand Down Expand Up @@ -225,9 +224,8 @@ def title_english(node, xml)

def title_otherlangs(node, xml)
node.attributes.each do |k, v|
next unless /^title-(?<titlelang>.+)$/ =~ k
next if titlelang == "en"

/^title-(?<titlelang>.+)$/ =~ k or next
titlelang == "en" and next
xml.title v, { language: titlelang, format: "text/plain" }
end
end
Expand Down
Loading

0 comments on commit 1a3bcd3

Please sign in to comment.