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
- #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 |
#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 |
# 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 @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)
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/metanorma/converter/ref_queue.rb', line 232 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 |