Module: Metanorma::Standoc::Bibitem
- Includes:
- Attachment
- Included in:
- Cleanup
- Defined in:
- lib/metanorma/cleanup/bibitem.rb
Constant Summary
collapse
- BIBITEM_ELEM_ORDER =
canonical element order of BibliographicItem per biblio.rnc
%w(fetched formattedref title uri docidentifier docnumber date
contributor edition version note language locale script abstract
status copyright relation series medium place price extent size
accesslocation license classification keyword validity depiction)
.freeze
Instance Method Summary
collapse
-
#bibitem_cleanup(xmldoc) ⇒ Object
-
#bibitem_i18n(xmldoc) ⇒ Object
-
#bibitem_i18n_insert(bib) ⇒ Object
-
#bibitem_id_docid_hash(xmldoc) ⇒ Object
-
#bibitem_nested_id(xmldoc) ⇒ Object
-
#bibitem_reorder_elems(bib) ⇒ Object
the spans-derived fragment is appended after any elements already on the bibitem (e.g. formattedref, docnumber, date), which violates the ordered relaton content model; restore grammar order, stably.
-
#bibitem_title_to_id(bibitem) ⇒ Object
-
#biblio_hidden_inherit(xmldoc) ⇒ Object
-
#biblio_no_ext(xmldoc) ⇒ Object
-
#empty_docid_to_title(xmldoc) ⇒ Object
-
#empty_docid_to_title?(bibitem) ⇒ Boolean
normative references only, biblio uses ordinal code instead.
-
#extract_notes_from_biblio(refs) ⇒ Object
-
#fetch_local_bibitem(xmldoc) ⇒ Object
if citation uri points to local file, get bibitem from it.
-
#fetch_termbase(_termbase, _id) ⇒ Object
-
#fold_notes_into_biblio(refs) ⇒ Object
-
#format_ref(ref, type) ⇒ Object
-
#formattedref_spans(xmldoc) ⇒ Object
-
#idtype2cit(ref) ⇒ Object
-
#merge_bibitem_from_formattedref_span_attrs(bib, new) ⇒ Object
-
#merge_bibitem_from_formattedref_spans(bib, new) ⇒ Object
-
#new_bibitem_from_formattedref_spans(bib) ⇒ Object
-
#read_local_bibitem(uri) ⇒ Object
-
#read_local_bibitem_file(uri) ⇒ Object
-
#reference_names(xmldoc) ⇒ Object
-
#remove_dup_bibtem_id(xmldoc) ⇒ Object
remove dupes if both same ID and same docid, in case dupes introduced through termbases.
-
#remove_empty_docid(xmldoc) ⇒ Object
-
#select_docid(ref, type = nil) ⇒ Object
Methods included from Attachment
#attachment_cleanup, #attachment_location, #attachment_uri, #datauri_attachment, #init_attachments, #save_attachment, #valid_attachment?
Instance Method Details
#bibitem_cleanup(xmldoc) ⇒ Object
245
246
247
248
249
250
251
252
253
254
255
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 245
def bibitem_cleanup(xmldoc)
bibitem_nested_id(xmldoc) ref_dl_cleanup(xmldoc)
formattedref_spans(xmldoc)
fetch_local_bibitem(xmldoc)
remove_empty_docid(xmldoc)
empty_docid_to_title(xmldoc)
remove_dup_bibtem_id(xmldoc)
bibitem_i18n(xmldoc)
attachment_cleanup(xmldoc)
end
|
#bibitem_i18n(xmldoc) ⇒ Object
226
227
228
229
230
231
232
233
234
235
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 226
def bibitem_i18n(xmldoc)
xmldoc.xpath("//references/bibitem").each do |b|
s = b.at("./script")
l = b.at("./language")
s && l and next
ins = bibitem_i18n_insert(b)
s or ins.next = "<script>#{@script}</script>"
l or ins.next = "<language>#{@lang}</language>"
end
end
|
#bibitem_i18n_insert(bib) ⇒ Object
237
238
239
240
241
242
243
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 237
def bibitem_i18n_insert(bib)
bib.at("./note[last()]") || bib.at("./version[last()]") ||
bib.at("./edition[last()]") || bib.at("./contributor[last()]") ||
bib.at("./date[last()]") || bib.at("./docnumber[last()]") ||
bib.at("./docidentifier[last()]") || bib.at("./source[last()]") ||
bib.at("./title[last()]") || bib.children.first
end
|
#bibitem_id_docid_hash(xmldoc) ⇒ Object
189
190
191
192
193
194
195
196
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 189
def bibitem_id_docid_hash(xmldoc)
xmldoc.xpath("//bibitem[@anchor]").each_with_object({}) do |b, m|
m[b["anchor"]] ||= {}
docid = b.at("./docidentifier")&.text || "NO ID"
m[b["anchor"]][docid] ||= []
m[b["anchor"]][docid] << b
end
end
|
#bibitem_nested_id(xmldoc) ⇒ Object
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 168
def bibitem_nested_id(xmldoc)
xmldoc.xpath("//bibitem//bibitem").each do |b|
b.delete("id")
b.delete("anchor")
end
xmldoc.xpath("//bibdata//bibitem").each do |b|
b.delete("id")
b.delete("anchor")
end
end
|
#bibitem_reorder_elems(bib) ⇒ Object
the spans-derived fragment is appended after any elements already on
the bibitem (e.g. formattedref, docnumber, date), which violates the
ordered relaton content model; restore grammar order, stably
51
52
53
54
55
56
57
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 51
def bibitem_reorder_elems(bib)
bib.element_children
.sort_by
.with_index do |e, i|
[BIBITEM_ELEM_ORDER.index(e.name) || BIBITEM_ELEM_ORDER.size, i]
end.each { |e| bib << e }
end
|
#bibitem_title_to_id(bibitem) ⇒ Object
216
217
218
219
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 216
def bibitem_title_to_id(bibitem)
t = bibitem.at("./title") || bibitem.at("./formattedref") or return
t.text
end
|
#biblio_hidden_inherit(xmldoc) ⇒ Object
83
84
85
86
87
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 83
def biblio_hidden_inherit(xmldoc)
xmldoc.xpath("//references[@hidden = 'true']").each do |r|
r.xpath("./bibitem").each { |b| b["hidden"] = true }
end
end
|
#biblio_no_ext(xmldoc) ⇒ Object
89
90
91
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 89
def biblio_no_ext(xmldoc)
xmldoc.xpath("//bibitem/ext").each(&:remove)
end
|
#empty_docid_to_title(xmldoc) ⇒ Object
203
204
205
206
207
208
209
210
211
212
213
214
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 203
def empty_docid_to_title(xmldoc)
xmldoc.xpath("//references/bibitem").each do |b|
b.at("./docidentifier[not(@type = 'metanorma' or @type = 'DOI' or " \
"@type = 'metanorma-ordinal')]") and next
empty_docid_to_title?(b) or next
ins = b.at("./title[last()]") || b.at("./formattedref")
id = bibitem_title_to_id(b) or return
ins.next = <<~XML
<docidentifier type='title' primary='true'>#{id}</docidentifier>
XML
end
end
|
#empty_docid_to_title?(bibitem) ⇒ Boolean
normative references only, biblio uses ordinal code instead
222
223
224
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 222
def empty_docid_to_title?(bibitem)
bibitem.parent["normative"] == "true"
end
|
74
75
76
77
78
79
80
81
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 74
def (refs)
refs.xpath("./bibitem").each do |r|
r.xpath("./note[@appended]").reverse_each do |n|
n.delete("appended")
r.next = n
end
end
end
|
#fetch_local_bibitem(xmldoc) ⇒ Object
if citation uri points to local file, get bibitem from it
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 157
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"]
bibitem["anchor"] = b["anchor"]
b.replace(bibitem)
end
end
|
#fetch_termbase(_termbase, _id) ⇒ Object
132
133
134
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 132
def fetch_termbase(_termbase, _id)
""
end
|
#fold_notes_into_biblio(refs) ⇒ Object
65
66
67
68
69
70
71
72
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 65
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
|
93
94
95
96
97
98
99
100
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 93
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
|
8
9
10
11
12
13
14
15
16
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 8
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
xmldoc.xpath("//bibitem[@amend]").each do |b|
b.delete("amend")
end
end
|
#idtype2cit(ref) ⇒ Object
113
114
115
116
117
118
119
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 113
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
|
59
60
61
62
63
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 59
def merge_bibitem_from_formattedref_span_attrs(bib, new)
%w(type).each do |k|
new[k] and bib[k] = new[k]
end
end
|
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 27
def merge_bibitem_from_formattedref_spans(bib, new)
merge_bibitem_from_formattedref_span_attrs(bib, new)
if bib.at("./title") && bib["amend"]
bib.children = Metanorma::Standoc::Cleanup::MergeBibitems
.new(bib.to_xml, new.to_xml).merge.to_noko.children
elsif bib.at("./title") bib.children = new.children.to_xml
else bib << new.children.to_xml
end
bibitem_reorder_elems(bib)
end
|
18
19
20
21
22
23
24
25
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 18
def new_bibitem_from_formattedref_spans(bib)
ret = Metanorma::Standoc::Cleanup::SpansToBibitem.new(bib).convert
ret.err.each do |e|
@log.add(e[:fatal] ? "STANDOC_52" : "STANDOC_53",
bib, params: [e[:msg]])
end
ret.out
end
|
#read_local_bibitem(uri) ⇒ Object
136
137
138
139
140
141
142
143
144
145
146
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 136
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
|
#read_local_bibitem_file(uri) ⇒ Object
148
149
150
151
152
153
154
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 148
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
|
#reference_names(xmldoc) ⇒ Object
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 102
def reference_names(xmldoc)
xmldoc.xpath("//bibitem[not(ancestor::bibitem)]").each do |ref|
@anchors[ref["anchor"]] =
if docid = select_docid(ref)
reference = format_ref(docid.children.to_xml, docid["type"])
{ xref: reference, id: idtype2cit(ref) }
else { xref: ref["anchor"], id: { "" => ref["anchor"] } }
end
end
end
|
#remove_dup_bibtem_id(xmldoc) ⇒ Object
remove dupes if both same ID and same docid, in case dupes introduced
through termbases
181
182
183
184
185
186
187
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 181
def remove_dup_bibtem_id(xmldoc)
bibitem_id_docid_hash(xmldoc).each_value do |v|
v.each_value do |v1|
v1[1..].each(&:remove)
end
end
end
|
#remove_empty_docid(xmldoc) ⇒ Object
198
199
200
201
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 198
def remove_empty_docid(xmldoc)
xmldoc.xpath("//bibitem/docidentifier[normalize-space(.)='']")
.each(&:remove)
end
|
#select_docid(ref, type = nil) ⇒ Object
121
122
123
124
125
126
127
128
129
130
|
# File 'lib/metanorma/cleanup/bibitem.rb', line 121
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
|