Module: Metanorma::Standoc::Refs
- Includes:
- Regex
- Included in:
- Converter
- Defined in:
- lib/metanorma/converter/ref.rb,
lib/metanorma/converter/ref_queue.rb,
lib/metanorma/converter/ref_utility.rb
Constant Summary collapse
- JOINT_REFS =
%i(merge dual).freeze
Constants included from Regex
Metanorma::Standoc::Regex::CONN_REGEX_STR, Metanorma::Standoc::Regex::ISO_REF, Metanorma::Standoc::Regex::ISO_REF_ALL_PARTS, Metanorma::Standoc::Regex::ISO_REF_NO_YEAR, Metanorma::Standoc::Regex::LOCALITIES, Metanorma::Standoc::Regex::LOCALITY_REGEX_STR, Metanorma::Standoc::Regex::LOCALITY_REGEX_STR_TRIPLEDASH, Metanorma::Standoc::Regex::LOCALITY_REGEX_VALUE_ONLY_STR, Metanorma::Standoc::Regex::NON_ISO_REF, Metanorma::Standoc::Regex::NON_ISO_REF1, Metanorma::Standoc::Regex::NUMERIC_REGEX, Metanorma::Standoc::Regex::TERM_REFERENCE_RE, Metanorma::Standoc::Regex::TERM_REFERENCE_RE_STR
Instance Method Summary collapse
- #analyse_ref_code(code) ⇒ Object
- #analyse_ref_code_csv(ret) ⇒ Object
- #analyse_ref_code_csv_breakup(line) ⇒ Object
- #analyse_ref_code_csv_map(source) ⇒ Object
- #analyse_ref_code_nested(ret) ⇒ Object
- #analyse_ref_numeric(ret) ⇒ Object
- #analyse_ref_repo_path(ret) ⇒ Object
- #conditional_date(bib, match, noyr) ⇒ Object
- #docid(bib, code, codetype = nil) ⇒ Object
- #docid_untyped?(code, codetype) ⇒ Boolean
- #docnumber(bib, code) ⇒ Object
- #docrelation_insert(base) ⇒ Object
- #dual_entries(base, add) ⇒ Object
- #fetch_ref(xml, code, year, **opts) ⇒ Object
- #fetch_ref1(code, year, opts) ⇒ Object
- #fetch_ref_async(ref, idx, res) ⇒ Object
- #fetch_ref_async1(ref, idx, res) ⇒ Object
- #fetch_ref_async_dual(ref, orig, idx, res) ⇒ Object
-
#flush_bib_caches_force(node) ⇒ Object
‘:flush-caches:` must clear stale cache state regardless of whether `:no-isobib-cache:` disables caching for this compile.
- #global_ievcache_name ⇒ Object
- #id_and_year(id, year) ⇒ Object
- #init_bib_caches(node) ⇒ Object
-
#init_iev_caches(node) ⇒ Object
Treat empty strings as falsy (they’re set by Asciidoctor for some attributes).
- #iso_publisher(bib, code) ⇒ Object
- #isorefmatches2_1(xml, match, code) ⇒ Object
- #isorefmatches2code(match, _item) ⇒ Object
- #isorefmatches2out(item, xml) ⇒ Object
- #isorefmatches3_1(xml, match, code, year, _hasyr, _ref) ⇒ Object
- #isorefmatches3code(match, _item) ⇒ Object
- #isorefmatches3out(item, xml) ⇒ Object
- #isorefmatchescode(match, _item) ⇒ Object
- #isorefmatchesout(item, xml) ⇒ Object
- #isorefrender1(bib, match, code, year, allp = "") ⇒ Object
- #joint_entries(out, joint_prep) ⇒ Object
- #joint_entries_prep(out) ⇒ Object
- #local_ievcache_name(cachename) ⇒ Object
- #merge_docids(base, add) ⇒ Object
-
#merge_entries(base, add) ⇒ Object
append publishers docids of add to base.
- #merge_publishers(base, add) ⇒ Object
- #merge_urls(base, add) ⇒ Object
- #mn_code(code) ⇒ Object
-
#no_year_generic_ref(code) ⇒ Object
if no year is supplied, interpret as no_year reference.
- #norm_year(year) ⇒ Object
-
#parse_ref_code_nested(ret, ident) ⇒ Object
ref id = (usrlbl)codeyear code = [? number ]? | ident | nofetch(code) | hidden(code) | dropid(code) | amend(code) | (repo|path|attachment):(key,code) | local-file(source,? key) | merge(code, code) | dual(code, code).
- #plaintxt ⇒ Object
- #ref_attributes(match) ⇒ Object
- #ref_fn(match, xml) ⇒ Object
- #ref_normalise(ref) ⇒ Object
- #ref_normalise_no_format(ref) ⇒ Object
- #reference(node) ⇒ Object
- #reference1_matches(item) ⇒ Object
- #reference1code(item, node) ⇒ Object
- #reference1out(item, xml) ⇒ Object
- #reference_normalise(refs) ⇒ Object
- #reference_populate(refs) ⇒ Object
- #reference_queue(results, size) ⇒ Object
- #references2xml(ret) ⇒ Object
- #references_fetch(refs) ⇒ Object
- #refitem1code(_item, match) ⇒ Object
- #refitem1yr(code) ⇒ Object
- #refitem_render(xml, match, code) ⇒ Object
- #refitem_render1(match, code, bib) ⇒ Object
- #refitem_render_attrs(match, code) ⇒ Object
- #refitem_render_formattedref(bibitem, title) ⇒ Object
- #refitem_uri(code, bib) ⇒ Object
-
#refitemcode(item, node) ⇒ Object
TODO: alternative where only title is available.
- #refitemout(item, xml) ⇒ Object
- #set_date_range(date, text) ⇒ Object
- #skip_docid ⇒ Object
- #smart_render_xml(xml, code, opts) ⇒ Object
- #supply_ref_prefix(ret) ⇒ Object
- #unfetchable_ref_code?(ref) ⇒ Boolean
- #use_my_anchor(ref, id, opt) ⇒ Object
- #use_retrieved_relaton(item, xml) ⇒ Object
Methods included from Regex
Instance Method Details
#analyse_ref_code(code) ⇒ Object
96 97 98 99 100 101 |
# File 'lib/metanorma/converter/ref_utility.rb', line 96 def analyse_ref_code(code) ret = { id: code } code.nil? || code.empty? and return ret analyse_ref_code_csv(ret) || analyse_ref_code_nested(ret) end |
#analyse_ref_code_csv(ret) ⇒ Object
103 104 105 106 107 108 109 110 |
# File 'lib/metanorma/converter/ref_utility.rb', line 103 def analyse_ref_code_csv(ret) ret[:id].include?("=") or return nil line = CSV.parse_line(ret[:id], liberal_parsing: true) or return nil a = analyse_ref_code_csv_breakup(line) analyse_ref_code_csv_map(a) rescue StandardError nil end |
#analyse_ref_code_csv_breakup(line) ⇒ Object
112 113 114 115 116 117 118 119 |
# File 'lib/metanorma/converter/ref_utility.rb', line 112 def analyse_ref_code_csv_breakup(line) line.each_with_object({}) do |x, m| kv = x.split("=", 2) kv.size == 1 and kv = ["code", kv.first] m[kv[0].to_sym] = kv[1].delete_prefix('"').delete_suffix('"') .delete_prefix("'").delete_suffix("'") end end |
#analyse_ref_code_csv_map(source) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/metanorma/converter/ref_utility.rb', line 121 def analyse_ref_code_csv_map(source) source.each_with_object({}) do |(k, v), ret| case k when :dropid, :hidden, :nofetch ret[k] = v == "true" when :repo, :path, :attachment ret[:type] = k.to_s ret[:key] = v ret[:nofetch] = true source[:code] or ret[:id] = v == :attachment ? nil : v.sub(%r{^[^/]+/}, "") when :"local-file" ret[:localfile] = v when :number if source[:code] then ret[:usrlabel] = "(#{v})" else ret[:numeric] = true end when :usrlabel ret[:usrlabel] = "(#{v})" when :code then ret[:id] = v end end end |
#analyse_ref_code_nested(ret) ⇒ Object
145 146 147 148 149 150 151 152 |
# File 'lib/metanorma/converter/ref_utility.rb', line 145 def analyse_ref_code_nested(ret) opts, id = parse_ref_code_nested({}, ret[:id]) ret[:id] = id ret.merge!(opts) analyse_ref_numeric(ret) analyse_ref_repo_path(ret) ret end |
#analyse_ref_numeric(ret) ⇒ Object
91 92 93 94 |
# File 'lib/metanorma/converter/ref_utility.rb', line 91 def analyse_ref_numeric(ret) /^\d+$/.match?(ret[:id]) or return ret ret.merge(numeric: true) end |
#analyse_ref_repo_path(ret) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/metanorma/converter/ref_utility.rb', line 77 def analyse_ref_repo_path(ret) %i(repo path attachment).each do |type| ret[type] or next id = if ret[:id].empty? if type == :attachment then "(#{ret[type]})" else ret[type].sub(%r{^[^/]+/}, "") end else ret[:id] end ret.merge!(id: id, type: type.to_s, key: ret[type], nofetch: true) end ret end |
#conditional_date(bib, match, noyr) ⇒ Object
26 27 28 29 30 31 32 |
# File 'lib/metanorma/converter/ref_utility.rb', line 26 def conditional_date(bib, match, noyr) if match.names.include?("year") && !match[:year].nil? bib.date(type: "published") do |d| (noyr and d.on "--") or set_date_range(d, norm_year(match[:year])) end end end |
#docid(bib, code, codetype = nil) ⇒ Object
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/metanorma/converter/ref_utility.rb', line 44 def docid(bib, code, codetype = nil) type, code1 = if /^\[\d+\]$|^\(.+\).*$/.match?(code) ["metanorma", mn_code(code)] elsif docid_untyped?(code, codetype) [nil, code] else @bibdb&.docid_type(code) || [nil, code] end code1.sub!(/^nofetch\((.+)\)$/, "\\1") add_noko_elem(bib, "docidentifier", code1, type: type) end |
#docid_untyped?(code, codetype) ⇒ Boolean
55 56 57 58 |
# File 'lib/metanorma/converter/ref_utility.rb', line 55 def docid_untyped?(code, codetype) %w(attachment repo path).include?(codetype) || code.strip.empty? || /^\d+$/.match?(code) end |
#docnumber(bib, code) ⇒ Object
60 61 62 63 |
# File 'lib/metanorma/converter/ref_utility.rb', line 60 def docnumber(bib, code) code or return add_noko_elem(bib, "docnumber", @c.decode(code).sub(/^[^\d]*/, "")) end |
#docrelation_insert(base) ⇒ Object
106 107 108 109 110 111 |
# File 'lib/metanorma/converter/ref_queue.rb', line 106 def docrelation_insert(base) %w(relation copyright status abstract locale language note version edition contributor date docnumber docidentifier).each do |v| r = base.at("//#{v}[last()]") and return r end end |
#dual_entries(base, add) ⇒ Object
101 102 103 104 |
# File 'lib/metanorma/converter/ref_queue.rb', line 101 def dual_entries(base, add) ins = docrelation_insert(base) ins.next = "<relation type='hasReproduction'>#{to_xml(add)}</relation>" end |
#fetch_ref(xml, code, year, **opts) ⇒ Object
137 138 139 140 141 142 143 144 145 146 |
# File 'lib/metanorma/converter/ref_queue.rb', line 137 def fetch_ref(xml, code, year, **opts) opts[:no_year] and return nil _, code = extract_balanced_parentheses(code) hit = fetch_ref1(code, year, opts) or return nil xml.parent.add_child(smart_render_xml(hit, code, opts)) xml rescue Relaton::RequestError @log.add("STANDOC_40", nil, params: [code]) nil end |
#fetch_ref1(code, year, opts) ⇒ Object
152 153 154 155 156 157 158 |
# File 'lib/metanorma/converter/ref_queue.rb', line 152 def fetch_ref1(code, year, opts) code = supply_ref_prefix(code) if opts[:localfile] @local_bibdb.get(code, opts[:localfile]) else @bibdb&.fetch(code, year, opts) end end |
#fetch_ref_async(ref, idx, res) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/metanorma/converter/ref_queue.rb', line 166 def fetch_ref_async(ref, idx, res) ref[:code] &&= supply_ref_prefix(ref[:code]) if unfetchable_ref_code?(ref) res << [ref, idx, nil] idx += 1 elsif ref[:localfile] res << [ref, idx, @local_bibdb.get(ref[:code], ref[:localfile])] idx += 1 else idx = fetch_ref_async1(ref, idx, res) end idx end |
#fetch_ref_async1(ref, idx, res) ⇒ Object
179 180 181 182 183 184 |
# File 'lib/metanorma/converter/ref_queue.rb', line 179 def fetch_ref_async1(ref, idx, res) @bibdb.fetch_async(ref[:code], ref[:year], ref) do |doc| res << [ref, idx, doc] end fetch_ref_async_dual(ref, idx, idx + 1, res) end |
#fetch_ref_async_dual(ref, orig, idx, res) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/metanorma/converter/ref_queue.rb', line 186 def fetch_ref_async_dual(ref, orig, idx, res) JOINT_REFS.each do |m| ref.dig(:analyse_code, m)&.each_with_index do |code, i| @bibdb.fetch_async(code, nil, ref.merge(ord: idx)) do |doc| res << [ref.merge("#{m}_into": orig, merge_order: i, ord: idx), idx, doc] end idx += 1 end end idx end |
#flush_bib_caches_force(node) ⇒ Object
‘:flush-caches:` must clear stale cache state regardless of whether `:no-isobib-cache:` disables caching for this compile. When both are set, the `Relaton::Db.init_bib_caches` path no-ops on the flush (because it has no cache paths to flush), leaving any previously cached entries on disk for the next compile that DOES have caching enabled to pick up. Force-flush the conventional cache locations here so the flag does what its name says. Source issue: github.com/relaton/relaton-iso/issues/181
241 242 243 244 245 246 247 248 |
# File 'lib/metanorma/converter/ref_queue.rb', line 241 def flush_bib_caches_force(node) FileUtils.rm_rf "#{Dir.home}/.relaton/cache" lcache_name = node.attr("local-cache") || node.attr("local-cache-only") if lcache_name base = lcache_name.to_s.empty? ? "relaton" : lcache_name FileUtils.rm_rf "#{base}/cache" end end |
#global_ievcache_name ⇒ Object
126 127 128 |
# File 'lib/metanorma/converter/ref_queue.rb', line 126 def global_ievcache_name "#{Dir.home}/.iev/cache" end |
#id_and_year(id, year) ⇒ Object
16 17 18 |
# File 'lib/metanorma/converter/ref_utility.rb', line 16 def id_and_year(id, year) year ? "#{id}:#{year}" : id end |
#init_bib_caches(node) ⇒ Object
219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/metanorma/converter/ref_queue.rb', line 219 def init_bib_caches(node) @no_isobib and return global = !@no_isobib_cache && !node.attr("local-cache-only") local = node.attr("local-cache") || node.attr("local-cache-only") local = nil if @no_isobib_cache flush_bib_caches_force(node) if node.attr("flush-caches") && @no_isobib_cache @bibdb = Relaton::Db.init_bib_caches( local_cache: local, flush_caches: node.attr("flush-caches"), global_cache: global, ) end |
#init_iev_caches(node) ⇒ Object
Treat empty strings as falsy (they’re set by Asciidoctor for some attributes)
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/metanorma/converter/ref_queue.rb', line 251 def init_iev_caches(node) no_cache = @no_isobib_cache && !@no_isobib_cache.empty? no_bib = @no_isobib && !@no_isobib.empty? unless no_cache || no_bib node.attr("local-cache-only") or @iev_globalname = global_ievcache_name @iev_localname = local_ievcache_name(node.attr("local-cache") || node.attr("local-cache-only")) if @flush_caches FileUtils.rm_f @iev_globalname unless @iev_globalname.nil? FileUtils.rm_f @iev_localname unless @iev_localname.nil? end end # @iev = Iev::Db.new(globalname, localname) unless @no_isobib end |
#iso_publisher(bib, code) ⇒ Object
7 8 9 10 11 12 13 14 15 16 |
# File 'lib/metanorma/converter/ref.rb', line 7 def iso_publisher(bib, code) code.sub(/(?<! ) .*$/, "").split("/").each do |abbrev| bib.contributor do |c| c.role type: "publisher" c.organization do |org| organization(org, abbrev, nil, true) end end end end |
#isorefmatches2_1(xml, match, code) ⇒ Object
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/metanorma/converter/ref.rb', line 68 def isorefmatches2_1(xml, match, code) xml.bibitem **attr_code(ref_attributes(match)) do |t| isorefrender1(t, match, code, "--") t.date type: "published" do |d| d.on "--" end iso_publisher(t, match[:code]) ref_fn(match, t) end end |
#isorefmatches2code(match, _item) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/metanorma/converter/ref.rb', line 47 def isorefmatches2code(match, _item) code = analyse_ref_code(match[:code]) { code: match[:code], no_year: true, lang: @lang || :all, note: match[:fn], year: nil, match:, analyse_code: code, title: match[:text], usrlbl: match[:usrlbl] || code[:usrlabel] } end |
#isorefmatches2out(item, xml) ⇒ Object
54 55 56 57 58 59 |
# File 'lib/metanorma/converter/ref.rb', line 54 def isorefmatches2out(item, xml) if item[:doc] then use_retrieved_relaton(item, xml) else isorefmatches2_1(xml, item[:ref][:match], item[:ref][:analyse_code]) end end |
#isorefmatches3_1(xml, match, code, year, _hasyr, _ref) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/metanorma/converter/ref.rb', line 98 def isorefmatches3_1(xml, match, code, year, _hasyr, _ref) xml.bibitem(**attr_code(ref_attributes(match))) do |t| isorefrender1(t, match, code, year, " (all parts)") conditional_date(t, match, year == "--") iso_publisher(t, match[:code]) ref_fn(match, t) t.extent type: "part" do |e| e.referenceFrom "all" end end end |
#isorefmatches3code(match, _item) ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/metanorma/converter/ref.rb', line 79 def isorefmatches3code(match, _item) code = analyse_ref_code(match[:code]) yr = norm_year(match[:year]) hasyr = !yr.nil? && yr != "--" { code: match[:code], match:, yr:, hasyr:, year: hasyr ? yr : nil, lang: @lang || :all, all_parts: true, no_year: yr == "--", title: match[:text], usrlbl: match[:usrlbl] || code[:usrlabel] } end |
#isorefmatches3out(item, xml) ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/metanorma/converter/ref.rb', line 89 def isorefmatches3out(item, xml) if item[:doc] then use_retrieved_relaton(item, xml) else isorefmatches3_1( xml, item[:ref][:match], item[:ref][:analyse_code], item[:ref][:yr], item[:ref][:hasyr], item[:doc] ) end end |
#isorefmatchescode(match, _item) ⇒ Object
27 28 29 30 31 32 33 |
# File 'lib/metanorma/converter/ref.rb', line 27 def isorefmatchescode(match, _item) code = analyse_ref_code(match[:code]) yr = norm_year(match[:year]) { code: match[:code], year: yr, match:, fn: match[:fn], title: match[:text], usrlbl: match[:usrlbl] || code[:usrlabel], analyse_code: code, lang: @lang || :all } end |
#isorefmatchesout(item, xml) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/metanorma/converter/ref.rb', line 35 def isorefmatchesout(item, xml) item[:doc] and return use_retrieved_relaton(item, xml) r = item[:ref] xml.bibitem **attr_code(ref_attributes(r[:match])) do |t| isorefrender1(t, r[:match], r[:analyse_code], r[:year]) y = r[:year] and t.date type: "published" do |d| set_date_range(d, y) end iso_publisher(t, r[:match][:code]) end end |
#isorefrender1(bib, match, code, year, allp = "") ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/metanorma/converter/ref.rb', line 18 def isorefrender1(bib, match, code, year, allp = "") bib.title(**plaintxt) { |i| i << ref_normalise(match[:text]) } # refitem_render_formattedref(bib, match[:text]) docid(bib, match[:usrlbl]) if match[:usrlbl] docid(bib, code[:usrlabel]) if code && code[:usrlabel] docid(bib, id_and_year(match[:code], year) + allp) docnumber(bib, match[:code]) end |
#joint_entries(out, joint_prep) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/metanorma/converter/ref_queue.rb', line 57 def joint_entries(out, joint_prep) joint_prep.each do |k, v| v[:merge]&.each do |i| merge_entries(out[k], out[i]) and out[i] = nil end v[:dual]&.each do |i| dual_entries(out[k], out[i]) and out[i] = nil end end out end |
#joint_entries_prep(out) ⇒ Object
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/metanorma/converter/ref_queue.rb', line 115 def joint_entries_prep(out) out.each_with_object({}) do |r, m| JOINT_REFS.each do |v| if i = r&.dig(:ref, :"#{v}_into") m[i] ||= { "#{v}": [] } m[i][v][r[:ref][:merge_order]] = r[:ref][:ord] end end end end |
#local_ievcache_name(cachename) ⇒ Object
130 131 132 133 134 135 |
# File 'lib/metanorma/converter/ref_queue.rb', line 130 def local_ievcache_name(cachename) cachename.nil? and return nil cachename += "_iev" unless cachename.empty? cachename = "iev" if cachename.empty? "#{cachename}/cache" end |
#merge_docids(base, add) ⇒ Object
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/metanorma/converter/ref_queue.rb', line 83 def merge_docids(base, add) ins = base.at("//docidentifier[last()]") [ins, add].each do |v| v.at("//docidentifier[@primary = 'true']") or v.at("//docidentifier")["primary"] = true end add.xpath("//docidentifier").reverse_each do |p| ins.next = p end end |
#merge_entries(base, add) ⇒ Object
append publishers docids of add to base
70 71 72 73 74 |
# File 'lib/metanorma/converter/ref_queue.rb', line 70 def merge_entries(base, add) merge_publishers(base, add) merge_docids(base, add) merge_urls(base, add) end |
#merge_publishers(base, add) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/metanorma/converter/ref_queue.rb', line 76 def merge_publishers(base, add) ins = base.at("//contributor[last()]") || base.children[-1] add.xpath("//contributor[role/@type = 'publisher']").reverse_each do |p| ins.next = p end end |
#merge_urls(base, add) ⇒ Object
94 95 96 97 98 99 |
# File 'lib/metanorma/converter/ref_queue.rb', line 94 def merge_urls(base, add) ins = base.at("./uri[last()]") || base.at("./title[last()]") add.xpath("./uri").reverse_each do |p| ins.next = p end end |
#mn_code(code) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/metanorma/converter/ref_utility.rb', line 65 def mn_code(code) # Handle balanced parentheses at the start of the string balance, remainder = extract_balanced_parentheses(code) balance and return "[#{balance}]" remainder .sub(/^dropid\((.+)\)$/, "\\1") .sub(/^hidden\((.+)\)$/, "\\1") .sub(/^nofetch\((.+)\)$/, "\\1") .sub(/^local-file\((.+)\)$/, "\\1") .sub(/^amend\((.+)\)$/, "\\1") end |
#no_year_generic_ref(code) ⇒ Object
if no year is supplied, interpret as no_year reference
191 192 193 |
# File 'lib/metanorma/converter/ref_utility.rb', line 191 def no_year_generic_ref(code) /^(BSI|BS)\b/.match?(code) end |
#norm_year(year) ⇒ Object
20 21 22 23 24 |
# File 'lib/metanorma/converter/ref_utility.rb', line 20 def norm_year(year) /^&\#821[12];$/.match(year) and return "--" /^\d\d\d\d-\d\d\d\d$/.match(year) and return year year&.sub(/^([0-9]+)-.*$/, "\\1") end |
#parse_ref_code_nested(ret, ident) ⇒ Object
ref id = (usrlbl)codeyear code = [? number ]? | ident | nofetch(code) | hidden(code) | dropid(code) | amend(code) | (repo|path|attachment):(key,code) | local-file(source,? key) | merge(code, code) | dual(code, code)
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/metanorma/converter/ref_utility.rb', line 159 def parse_ref_code_nested(ret, ident) keys = %w(nofetch hidden dropid local-file repo path attachment merge dual amend) if (m = /^(?<key>[a-z-]+):?\((?<val>.*)\)$/.match(ident)) && keys.include?(m[:key]) case m[:key] when "nofetch", "hidden", "dropid", "amend" ret[m[:key].to_sym] = true parse_ref_code_nested(ret, m[:val]) when "repo", "path", "attachment" kv = m[:val].split(",", 2).map(&:strip) ret[m[:key].to_sym] = kv[0] parse_ref_code_nested(ret, kv.size == 1 ? "" : kv[1]) when "local-file" kv = m[:val].split(",", 2).map(&:strip) source = kv.size == 1 ? "default" : kv[0] ret[:localfile] = source parse_ref_code_nested(ret, kv[-1]) when "merge", "dual" line = CSV.parse_line(m[:val], liberal_parsing: true) or return [ret, ident] line.size > 1 or return [ret, ident] ret[:id] = line.first ret[m[:key].to_sym] = line[1..].map(&:strip) [ret, ret[:id]] end else [ret, ident] end end |
#plaintxt ⇒ Object
195 196 197 |
# File 'lib/metanorma/converter/ref_utility.rb', line 195 def plaintxt { format: "text/plain" } end |
#ref_attributes(match) ⇒ Object
199 200 201 202 203 204 |
# File 'lib/metanorma/converter/ref_utility.rb', line 199 def ref_attributes(match) code = analyse_ref_code(match[:code]) { anchor: match[:anchor], id: "_#{UUIDTools::UUID.random_create}", type: "standard", suppress_identifier: code[:dropid] || nil } end |
#ref_fn(match, xml) ⇒ Object
61 62 63 64 65 66 |
# File 'lib/metanorma/converter/ref.rb', line 61 def ref_fn(match, xml) if match.names.include?("fn") && match[:fn] add_noko_elem(xml, "note", match[:fn].to_s, **plaintxt.merge(type: "Unpublished-Status")) end end |
#ref_normalise(ref) ⇒ Object
206 207 208 |
# File 'lib/metanorma/converter/ref_utility.rb', line 206 def ref_normalise(ref) ref.gsub("&amp;", "&").gsub(%r{^<em>(.*)</em>}, "\\1") end |
#ref_normalise_no_format(ref) ⇒ Object
210 211 212 213 |
# File 'lib/metanorma/converter/ref_utility.rb', line 210 def ref_normalise_no_format(ref) ref.gsub("&amp;", "&") .gsub(">\n", "> \n") end |
#reference(node) ⇒ Object
4 5 6 7 8 9 |
# File 'lib/metanorma/converter/ref_queue.rb', line 4 def reference(node) refs = node.items.each_with_object([]) do |b, m| m << reference1code(b.text, node) end reference_populate(reference_normalise(refs)) end |
#reference1_matches(item) ⇒ Object
190 191 192 193 194 195 |
# File 'lib/metanorma/converter/ref.rb', line 190 def reference1_matches(item) matched = ISO_REF.match item matched2 = ISO_REF_NO_YEAR.match item matched3 = ISO_REF_ALL_PARTS.match item [matched, matched2, matched3] end |
#reference1code(item, node) ⇒ Object
197 198 199 200 201 202 203 204 |
# File 'lib/metanorma/converter/ref.rb', line 197 def reference1code(item, node) m, m2, m3 = reference1_matches(item) m3.nil? && m2.nil? && m.nil? and return refitemcode(item, node).merge(process: 0) !m.nil? and return isorefmatchescode(m, item).merge(process: 1) !m2.nil? and return isorefmatches2code(m2, item).merge(process: 2) !m3.nil? and return isorefmatches3code(m3, item).merge(process: 3) end |
#reference1out(item, xml) ⇒ Object
206 207 208 209 210 211 212 213 214 |
# File 'lib/metanorma/converter/ref.rb', line 206 def reference1out(item, xml) item[:ref][:analyse_code] ||= analyse_ref_code(item[:ref][:code]) case item[:ref][:process] when 0 then refitemout(item, xml) when 1 then isorefmatchesout(item, xml) when 2 then isorefmatches2out(item, xml) when 3 then isorefmatches3out(item, xml) end end |
#reference_normalise(refs) ⇒ Object
11 12 13 14 15 16 |
# File 'lib/metanorma/converter/ref_queue.rb', line 11 def reference_normalise(refs) refs.each do |r| r[:code] = @c.decode(r[:code]) .gsub("\u2009\u2014\u2009", " -- ").strip end end |
#reference_populate(refs) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/metanorma/converter/ref_queue.rb', line 18 def reference_populate(refs) @biblio_cutoff and refs.each { |r| r[:publication_date_before] = @biblio_cutoff } ret = reference_queue(*references_fetch(refs)) joint_prep = joint_entries_prep(ret) out = references2xml(ret) joint_entries(out, joint_prep).compact.map { |x| to_xml(x) }.join end |
#reference_queue(results, size) ⇒ Object
46 47 48 49 50 51 52 53 54 55 |
# File 'lib/metanorma/converter/ref_queue.rb', line 46 def reference_queue(results, size) (1..size).each.with_object([]) do |_, m| ref, i, doc = results.pop m[i.to_i] = { ref: } if doc.is_a?(Relaton::RequestError) @log.add("STANDOC_40", nil, params: [ref[:code]]) else m[i.to_i][:doc] = doc end end end |
#references2xml(ret) ⇒ Object
27 28 29 30 31 32 |
# File 'lib/metanorma/converter/ref_queue.rb', line 27 def references2xml(ret) out = ret.map do |b| b.nil? ? nil : noko { |xml| reference1out(b, xml) } end out.map { |x| x.nil? ? nil : Nokogiri::XML(x).root } end |
#references_fetch(refs) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/metanorma/converter/ref_queue.rb', line 34 def references_fetch(refs) i = 0 seen = {} ret = refs.each_with_object(Queue.new) do |ref, res| idx = ref[:code] + (ref[:match] ? ref[:match][:anchor] : "") seen[idx] and next i = fetch_ref_async(ref.merge(ord: i), i, res) /[A-Za-z]/.match?(idx) and seen[idx] = true end [ret, i] end |
#refitem1code(_item, match) ⇒ Object
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/metanorma/converter/ref.rb', line 165 def refitem1code(_item, match) code = analyse_ref_code(match[:code]) ((code[:id] && code[:numeric]) || code[:nofetch]) and return { code: nil, match:, analyse_code: code, fn: match[:fn], hidden: code[:hidden] } { code: code[:id], analyse_code: code, localfile: code[:localfile], year: (m = refitem1yr(code[:id])) ? m[:year] : nil, title: match[:text], match:, hidden: code[:hidden], fn: match[:fn], usrlbl: match[:usrlbl] || code[:usrlabel], lang: @lang || :all } end |
#refitem1yr(code) ⇒ Object
176 177 178 179 180 181 |
# File 'lib/metanorma/converter/ref.rb', line 176 def refitem1yr(code) yr_match = /[:-](?<year>(?:19|20)[0-9][0-9])$/.match(code) /[:-](?:19|20)[0-9][0-9].*?[:-](?:19|20)[0-9][0-9]$/.match(code) and yr_match = nil yr_match end |
#refitem_render(xml, match, code) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/metanorma/converter/ref.rb', line 133 def refitem_render(xml, match, code) xml.bibitem(**refitem_render_attrs(match, code)) do |t| refitem_render_formattedref(t, match[:text]) yr_match = refitem1yr(code[:id]) refitem_render1(match, code, t) /^\d+$|^\(.+\)$/.match?(code[:id]) or docnumber(t, code[:id]&.sub(/[:-](19|20)[0-9][0-9]$/, "")) conditional_date(t, yr_match || match, false) ref_fn(match, t) end end |
#refitem_render1(match, code, bib) ⇒ Object
110 111 112 113 114 115 116 117 118 |
# File 'lib/metanorma/converter/ref.rb', line 110 def refitem_render1(match, code, bib) refitem_uri(code, bib) match[:usrlbl] and docid(bib, match[:usrlbl]) code[:usrlabel] and docid(bib, code[:usrlabel]) i = code[:id] and docid(bib, /^\d+$/.match?(i) ? "[#{i}]" : i, code[:type]) code[:type] == "repo" and add_noko_elem(bib, "docidentifier", code[:key], type: "repository") end |
#refitem_render_attrs(match, code) ⇒ Object
145 146 147 148 149 |
# File 'lib/metanorma/converter/ref.rb', line 145 def refitem_render_attrs(match, code) attr_code(anchor: match[:anchor], suppress_identifier: code[:dropid], amend: code[:amend], hidden: code[:hidden], id: "_#{UUIDTools::UUID.random_create}") end |
#refitem_render_formattedref(bibitem, title) ⇒ Object
151 152 153 154 155 |
# File 'lib/metanorma/converter/ref.rb', line 151 def refitem_render_formattedref(bibitem, title) (title.nil? || title.empty?) and title = @i18n.no_information_available add_noko_elem(bibitem, "formattedref", ref_normalise_no_format(title), format: "application/x-isodoc+xml") end |
#refitem_uri(code, bib) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/metanorma/converter/ref.rb', line 120 def refitem_uri(code, bib) if code[:type] == "path" add_noko_elem(bib, "uri", code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), type: "URI") add_noko_elem(bib, "uri", code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), type: "citation") end if code[:type] == "attachment" add_noko_elem(bib, "uri", code[:key], type: "attachment") add_noko_elem(bib, "uri", code[:key], type: "citation") end end |
#refitemcode(item, node) ⇒ Object
TODO: alternative where only title is available
158 159 160 161 162 163 |
# File 'lib/metanorma/converter/ref.rb', line 158 def refitemcode(item, node) m = NON_ISO_REF.match(item) and return refitem1code(item, m).compact m = NON_ISO_REF1.match(item) and return refitem1code(item, m).compact @log.add("STANDOC_43", node, params: [item]) {} end |
#refitemout(item, xml) ⇒ Object
183 184 185 186 187 188 |
# File 'lib/metanorma/converter/ref.rb', line 183 def refitemout(item, xml) item[:ref][:match].nil? and return nil item[:doc] or return refitem_render(xml, item[:ref][:match], item[:ref][:analyse_code]) use_retrieved_relaton(item, xml) end |
#set_date_range(date, text) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 |
# File 'lib/metanorma/converter/ref_utility.rb', line 4 def set_date_range(date, text) matched = /^(?<from>[0-9]+)(?:-+(?<to>[0-9]+))?$/.match text return unless matched[:from] if matched[:to] date.from matched[:from] date.to matched[:to] else date.on matched[:from] end end |
#skip_docid ⇒ Object
215 216 217 218 219 |
# File 'lib/metanorma/converter/ref_utility.rb', line 215 def skip_docid <<~XPATH.strip.freeze @type = 'DOI' or @type = 'doi' or @type = 'ISSN' or @type = 'issn' or @type = 'ISBN' or @type = 'isbn' or starts-with(@type, 'ISSN.') or starts-with(@type, 'ISBN.') or starts-with(@type, 'issn.') or starts-with(@type, 'isbn.') XPATH end |
#smart_render_xml(xml, code, opts) ⇒ Object
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/metanorma/converter/ref_queue.rb', line 199 def smart_render_xml(xml, code, opts) xml.respond_to? :to_xml or return nil xml = Nokogiri::XML(xml.to_xml(lang: opts[:lang])) emend_biblio(xml, code, opts) xml.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) } xml.traverse do |n| n.text? and n.replace(Metanorma::Utils::smartformat(n.text)) end xml.to_xml.sub(/<\?[^>]+>/, "") end |
#supply_ref_prefix(ret) ⇒ Object
148 149 150 |
# File 'lib/metanorma/converter/ref_queue.rb', line 148 def supply_ref_prefix(ret) ret end |
#unfetchable_ref_code?(ref) ⇒ Boolean
160 161 162 163 164 |
# File 'lib/metanorma/converter/ref_queue.rb', line 160 def unfetchable_ref_code?(ref) ref[:code].nil? || ref[:code].empty? || ref[:no_year] || /^\(.+\)$/.match?(ref[:code]) || (@bibdb.nil? && !ref[:localfile]) end |
#use_my_anchor(ref, id, opt) ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/metanorma/converter/ref_utility.rb', line 34 def use_my_anchor(ref, id, opt) elem = ref.parent.elements.last elem["anchor"] = id add_id(elem) a = opt[:hidden] and elem["hidden"] = a a = opt[:amend] and elem["amend"] = a a = opt[:dropid] and elem["suppress_identifier"] = a ref end |
#use_retrieved_relaton(item, xml) ⇒ Object
210 211 212 213 214 215 216 217 |
# File 'lib/metanorma/converter/ref_queue.rb', line 210 def use_retrieved_relaton(item, xml) xml.parent.add_child(smart_render_xml(item[:doc], item[:ref][:code], item[:ref])) use_my_anchor(xml, item[:ref][:match][:anchor], amend: item.dig(:ref, :analyse_code, :amend), hidden: item.dig(:ref, :analyse_code, :hidden), dropid: item.dig(:ref, :analyse_code, :dropid)) end |