Module: Metanorma::Standoc::Ref
- Included in:
- Cleanup
- Defined in:
- lib/metanorma/cleanup/ref.rb
Constant Summary collapse
- BIBLIO_PUBLISHER_ORG =
"./contributor[role/@type = 'publisher']/organization".freeze
Instance Method Summary collapse
- #biblio_annex(xmldoc) ⇒ Object
- #biblio_cleanup(xmldoc) ⇒ Object
- #biblio_linkonly(xmldoc) ⇒ Object
- #biblio_nested(xmldoc) ⇒ Object
- #biblio_nested_initial_items(xmldoc) ⇒ Object
- #biblio_nested_sections(xmldoc) ⇒ Object
-
#biblio_renumber(xmldoc) ⇒ Object
default presuppose that all citations in biblio numbered consecutively, but that standards codes are preserved as is: only numeric references are renumbered.
- #biblio_reorder(xmldoc) ⇒ Object
- #biblio_reorder1(refs) ⇒ Object
-
#biblio_standards_ref?(bib) ⇒ Boolean
Whether a bibitem is a standards reference (sorts after the ranked publishers, before non-standard references).
- #insert_hidden_bibitems(bib) ⇒ Object
- #insert_sorted_bibitems(refs, bib) ⇒ Object
- #normref_cleanup(xmldoc) ⇒ Object
-
#publisher_org_match?(org, entry) ⇒ Boolean
A table entry matches a publisher organization on its abbreviation (case-insensitive, since AsciiDoc lowercases attribute-derived abbrevs) or on any of its names (
namemay be a single string or an array; the latter lets a flavour list, e.g., a Japanese and an English publisher name for the same rank). -
#publisher_sort_match(bib, table) ⇒ Object
lowest-ranked table entry whose publisher appears on the bibitem.
-
#publisher_sort_rank(bib, table) ⇒ Object
Configurable publisher sort ranking, shared by every flavour's bibliography sort.
-
#publisher_sort_second(bib, table) ⇒ Object
Secondary sort token: the co-publisher(s) other than the matched primary.
- #publisher_sort_table(default_table) ⇒ Object
-
#ref_cleanup(xmldoc) ⇒ Object
move ref before p.
- #sort_biblio(bib) ⇒ Object
Instance Method Details
#biblio_annex(xmldoc) ⇒ Object
170 171 172 173 174 175 176 177 |
# File 'lib/metanorma/cleanup/ref.rb', line 170 def biblio_annex(xmldoc) xmldoc.xpath("//annex[references/references]").each do |t| t.xpath("./clause | ./references | ./terms").size == 1 or next r = t.at("./references") r.xpath("./references").each { |b| b["normative"] = r["normative"] } r.replace(r.elements) end end |
#biblio_cleanup(xmldoc) ⇒ Object
140 141 142 143 144 145 146 147 148 |
# File 'lib/metanorma/cleanup/ref.rb', line 140 def biblio_cleanup(xmldoc) biblio_reorder(xmldoc) biblio_annex(xmldoc) biblio_nested(xmldoc) biblio_renumber(xmldoc) biblio_linkonly(xmldoc) biblio_hidden_inherit(xmldoc) biblio_no_ext(xmldoc) end |
#biblio_linkonly(xmldoc) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/metanorma/cleanup/ref.rb', line 150 def biblio_linkonly(xmldoc) xmldoc.at("//xref[@hidden]") or return ins = xmldoc.at("//bibliography") .add_child("<references hidden='true' normative='true'/>").first refs = xmldoc.xpath("//xref[@hidden]").each_with_object([]) do |x, m| @refids << x["target"] m << { id: x["target"], ref: x["hidden"] } x.delete("hidden") end ins << insert_hidden_bibitems(refs) end |
#biblio_nested(xmldoc) ⇒ Object
179 180 181 182 |
# File 'lib/metanorma/cleanup/ref.rb', line 179 def biblio_nested(xmldoc) biblio_nested_initial_items(xmldoc) biblio_nested_sections(xmldoc) end |
#biblio_nested_initial_items(xmldoc) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/metanorma/cleanup/ref.rb', line 184 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 |
#biblio_nested_sections(xmldoc) ⇒ Object
196 197 198 199 200 201 202 |
# File 'lib/metanorma/cleanup/ref.rb', line 196 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 |
#biblio_renumber(xmldoc) ⇒ Object
default presuppose that all citations in biblio numbered consecutively, but that standards codes are preserved as is: only numeric references are renumbered
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/metanorma/cleanup/ref.rb', line 111 def biblio_renumber(xmldoc) i = 0 xmldoc.xpath("//references[not(@normative = 'true')]" \ "[not(@hidden = 'true')]").each do |r| r.xpath("./bibitem[not(@hidden = 'true')]").each do |b| i += 1 docid = b.at("./docidentifier[@type = 'metanorma']") or next /^\[\d+\]$/.match?(docid.text) or next docid.children = "[#{i}]" end end end |
#biblio_reorder(xmldoc) ⇒ Object
9 10 11 12 13 |
# File 'lib/metanorma/cleanup/ref.rb', line 9 def biblio_reorder(xmldoc) xmldoc.xpath("//references[@normative = 'false']").each do |r| biblio_reorder1(r) end end |
#biblio_reorder1(refs) ⇒ Object
15 16 17 18 19 20 21 22 |
# File 'lib/metanorma/cleanup/ref.rb', line 15 def biblio_reorder1(refs) fold_notes_into_biblio(refs) bib = refs.xpath("./bibitem") @sort_biblio and bib = sort_biblio(bib) insert_sorted_bibitems(refs, bib) extract_notes_from_biblio(refs) refs.xpath("./references").each { |r| biblio_reorder1(r) } end |
#biblio_standards_ref?(bib) ⇒ Boolean
Whether a bibitem is a standards reference (sorts after the ranked publishers, before non-standard references). Base definition: it has a typed, non-DOI/ISSN/ISBN docidentifier. Flavours may widen this (ISO also treats an untyped docidentifier as a standards reference).
103 104 105 106 |
# File 'lib/metanorma/cleanup/ref.rb', line 103 def biblio_standards_ref?(bib) !!bib.at("./docidentifier[@type][not(#{@conv.skip_docid} or " \ "@type = 'metanorma')]") end |
#insert_hidden_bibitems(bib) ⇒ Object
162 163 164 165 166 167 168 |
# File 'lib/metanorma/cleanup/ref.rb', line 162 def insert_hidden_bibitems(bib) refs = bib.each_with_object([]) do |b, m| m << @conv .reference1code(%(<ref id="#{b[:id]}">[#{b[:ref]}]</ref>), nil) end @conv.reference_populate(refs) end |
#insert_sorted_bibitems(refs, bib) ⇒ Object
24 25 26 27 28 29 30 31 |
# File 'lib/metanorma/cleanup/ref.rb', line 24 def insert_sorted_bibitems(refs, bib) insert = refs.at("./bibitem")&.previous_element refs.xpath("./bibitem").each(&:remove) bib.reverse_each do |b| (insert and insert.next = b.to_xml) or refs.children.first.add_previous_sibling b.to_xml end end |
#normref_cleanup(xmldoc) ⇒ Object
132 133 134 135 136 137 138 |
# File 'lib/metanorma/cleanup/ref.rb', line 132 def normref_cleanup(xmldoc) r = xmldoc.at(self.class::NORM_REF) || return preface = ((r.xpath("./title/following-sibling::*") & # intersection r.xpath("./bibitem[1]/preceding-sibling::*")) - r.xpath("./note[@type = 'boilerplate']/descendant-or-self::*")) preface.each(&:remove) end |
#publisher_org_match?(org, entry) ⇒ Boolean
A table entry matches a publisher organization on its abbreviation
(case-insensitive, since AsciiDoc lowercases attribute-derived abbrevs)
or on any of its names (name may be a single string or an array; the
latter lets a flavour list, e.g., a Japanese and an English publisher
name for the same rank).
91 92 93 94 95 96 97 |
# File 'lib/metanorma/cleanup/ref.rb', line 91 def publisher_org_match?(org, entry) abbr = org.at("./abbreviation")&.text&.strip name = org.at("./name")&.text&.strip names = Array(entry[:name]).map { |n| n.to_s.strip }.reject(&:empty?) (!entry[:abbrev].to_s.empty? && abbr&.casecmp?(entry[:abbrev])) || (!name.to_s.empty? && names.include?(name)) end |
#publisher_sort_match(bib, table) ⇒ Object
lowest-ranked table entry whose publisher appears on the bibitem
79 80 81 82 83 84 |
# File 'lib/metanorma/cleanup/ref.rb', line 79 def publisher_sort_match(bib, table) orgs = bib.xpath(BIBLIO_PUBLISHER_ORG) table.sort_by { |e| e[:rank] }.find do |e| orgs.any? { |o| publisher_org_match?(o, e) } end end |
#publisher_sort_rank(bib, table) ⇒ Object
Configurable publisher sort ranking, shared by every flavour's
bibliography sort. table is the flavour's default ordering, an array
of { abbrev:, name:, rank: }. A per-document / metanorma-taste override
(:sort-biblio-
A matched publisher gets its configured rank; an unmatched standards reference sorts immediately after the ranked publishers, and a non-standard reference last. With no override and the flavour's own default table, this reproduces the flavour's historical hardcoded ranks.
50 51 52 53 54 55 56 57 58 |
# File 'lib/metanorma/cleanup/ref.rb', line 50 def publisher_sort_rank(bib, table) table = publisher_sort_table(table) if (entry = publisher_sort_match(bib, table)) return entry[:rank] end maxrank = table.map { |e| e[:rank] }.max || 0 biblio_standards_ref?(bib) ? maxrank + 1 : maxrank + 2 end |
#publisher_sort_second(bib, table) ⇒ Object
Secondary sort token: the co-publisher(s) other than the matched primary. Deterministic when several co-publishers exist (returns the smallest token), which reproduces e.g. JIS's "JIS+IEC before JIS+ISO, JIS+IEC+ISO alongside JIS+IEC" ordering.
64 65 66 67 68 69 70 71 |
# File 'lib/metanorma/cleanup/ref.rb', line 64 def publisher_sort_second(bib, table) entry = publisher_sort_match(bib, publisher_sort_table(table)) entry or return "" bib.xpath(BIBLIO_PUBLISHER_ORG) .reject { |o| publisher_org_match?(o, entry) } .map { |o| (o.at("./abbreviation") || o.at("./name"))&.text&.strip } .compact.reject(&:empty?).min || "" end |
#publisher_sort_table(default_table) ⇒ Object
73 74 75 76 |
# File 'lib/metanorma/cleanup/ref.rb', line 73 def publisher_sort_table(default_table) cfg = @publisher_sort_config cfg && !cfg.empty? ? cfg : default_table end |
#ref_cleanup(xmldoc) ⇒ Object
move ref before p
125 126 127 128 129 130 |
# File 'lib/metanorma/cleanup/ref.rb', line 125 def ref_cleanup(xmldoc) xmldoc.xpath("//p/ref").each do |r| parent = r.parent parent.previous = r.remove end end |
#sort_biblio(bib) ⇒ Object
33 34 35 |
# File 'lib/metanorma/cleanup/ref.rb', line 33 def sort_biblio(bib) bib end |