module RelatonIeee class IeeeBibliography class << self # @param text [String] # @return [RelatonIeee::HitCollection] def search(text) HitCollection.new text rescue Faraday::ConnectionFailed raise RelatonBib::RequestError, "Could not access #{HitCollection::DOMAIN}" end # @param code [String] the IEEE standard Code to look up (e..g "528-2019") # @param year [String] the year the standard was published (optional) # @param opts [Hash] options # # @return [Hash, NilClass] returns { ret: RelatonBib::BibliographicItem } # if document is found else returns NilClass def get(code, year = nil, _opts = {}) warn "[relaton-ieee] (\"#{code}\") fetching..." result = search(code) || (return nil) year ||= code.match(/(?<=-)\d{4}/)&.to_s ret = bib_results_filter(result, code, year) if ret[:ret] item = ret[:ret].fetch warn "[relaton-ieee] (\"#{code}\") found #{item.docidentifier.first.id}" item else fetch_ref_err(code, year, ret[:years]) end end private # Sort through the results from RelatonIeee, fetching them three at a time, # and return the first result that matches the code, # matches the year (if provided), and which # has a title (amendments do not). # Only expects the first page of results to be populated. # Does not match corrigenda etc (e.g. ISO 3166-1:2006/Cor 1:2007) # If no match, returns any years which caused mismatch, for error reporting # # @param result [RelatonIeee::HitCollection] # @param opts [Hash] options # # @return [Hash] def bib_results_filter(result, ref, year) rp1 = ref_parts ref missed_years = [] result.each do |hit| rp2 = ref_parts hit.hit["recordTitle"] next if rp1[:code] != rp2[:code] || rp1[:corr] != rp2[:corr] return { ret: hit } if !year return { ret: hit } if year.to_i == hit.hit[:year] missed_years << hit.hit[:year] end { years: missed_years.uniq } end def ref_parts(ref) %r{ ^(?:IEEE\s(?:Std\s)?)? (?<code>[^-/]+) (?:-(?<year>\d{4}))? (?:/(?<corr>\w+\s\d+-\d{4}))? }x.match ref end # @param code [Strig] # @param year [String] # @param missed_years [Array<Strig>] def fetch_ref_err(code, year, missed_years) id = year ? "#{code} year #{year}" : code warn "[relaton-ieee] WARNING: no match found online for #{id}. "\ "The code must be exactly like it is on the standards website." unless missed_years.empty? warn "[relaton-ieee] (There was no match for #{year}, though there were matches "\ "found for #{missed_years.join(', ')}.)" end nil end end end end