require "isodoc" require "twitter_cldr" require_relative "./metadata_id.rb" module IsoDoc module NIST class Metadata < IsoDoc::Metadata def initialize(lang, script, labels) super here = File.dirname(__FILE__) set(:logo_nist, File.expand_path(File.join(here, "html", "logo.png"))) set(:logo_cswp, File.expand_path(File.join(here, "html", "logo_cswp.png"))) set(:logo_commerce, File.expand_path(File.join(here, "html", "commerce-logo-color.png"))) set(:logo_commerce_word, File.expand_path(File.join(here, "html", "deptofcommerce.png"))) end def title(ixml, out) main = ixml&.at(ns("//bibdata/title[@type = 'main']"))&.text set(:doctitle, main) short = ixml&.at(ns("//bibdata/title[@type = 'short-title']"))&.text set(:doctitle_short, short || main) end def subtitle(ixml, _out) main = ixml&.at(ns("//bibdata/title[@type = 'subtitle']"))&.text set(:docsubtitle, main) if main short = ixml&.at(ns("//bibdata/title[@type = 'short-subtitle']"))&.text set(:docsubtitle_short, short || main) if (short || main) main = ixml&.at(ns("//bibdata/title[@type = 'document-class']"))&.text set(:docclasstitle, main) if main end def author(ixml, _out) tc = ixml.at(ns("//bibdata/ext/editorialgroup/committee")) set(:tc, tc.text.upcase) if tc subdiv = ixml.at(ns("//bibdata/contributor[role/@type = 'publisher']/"\ "organization/subdivision")) and set(:nist_subdiv, subdiv.text) super end def version(ixml, _out) super rev = ixml&.at(ns("//bibdata/edition"))&.text&.sub(/^Revision /, "") set(:revision, rev) if rev revdate = get[:revdate] set(:revdate_monthyear, monthyr(revdate)) set(:revdate_MMMddyyyy, MMMddyyyy(revdate)) end def bibdate(ixml, _out) super ixml.xpath(ns("//bibdata/date")).each do |d| val = Common::date_range(d) next if val == "XXX" set("#{d['type']}date_monthyear".to_sym, daterange_proc(val, :monthyr)) set("#{d['type']}date_mmddyyyy".to_sym, daterange_proc(val, :mmddyyyy)) set("#{d['type']}date_MMMddyyyy".to_sym, daterange_proc(val, :MMMddyyyy)) end withdrawal_pending(ixml) most_recent_date(ixml) end def most_recent_date(ixml) date = most_recent_date1(ixml) || return val = Common::date_range(date) return if val == "XXX" set(:most_recent_date_monthyear, daterange_proc(val, :monthyr)) set(:most_recent_date_mmddyyyy, daterange_proc(val, :mmddyyyy)) set(:most_recent_date_MMMddyyyy, daterange_proc(val, :MMMddyyyy)) end def most_recent_date1(ixml) docstatus = ixml.at(ns("//bibdata/status/stage"))&.text /^draft/.match(docstatus) ? (ixml.at(ns("//bibdata/date[@type = 'circulated']")) || ixml.at(ns("//version/revision-date"))) : ( ixml.at(ns("//bibdata/date[@type = 'issued']"))) end def withdrawal_pending(ixml) d = ixml&.at(ns("//bibdata/date[@type = 'obsoleted']"))&.text&.strip or return d += "-01" if /^\d\d\d\d-\d\d$/.match(d) date = Date.parse(d) or return set(:withdrawal_pending, true) if date > Date.today end def daterange_proc(val, fn) m = /^(?[^&]+)(?\–)?(?.*)$/.match val val_monthyear = self.send(fn, m[:date1]) val_monthyear += "–" if m[:ndash] val_monthyear += self.send(fn, m[:date2]) unless m[:date2].empty? val_monthyear end def series(ixml, _out) series = ixml.at(ns("//bibdata/series[@type = 'main']/title"))&.text and set(:series, series) seriesabbr = ixml.at(ns("//bibdata/series[@type = 'main']/abbreviation"))&.text set(:seriesabbr, seriesabbr) if seriesabbr subs = ixml.at(ns("//bibdata/series[@type = 'secondary']/"\ "title"))&.text and set(:subseries, subs) end def mmddyyyy(isodate) return nil if isodate.nil? isodate += "-01" if /^\d\d\d\d-\d\d$/.match(isodate) Date.parse(isodate).strftime("%m-%d-%Y") end def commentperiod(ixml, _out) from = ixml.at(ns("//bibdata/ext/commentperiod/from"))&.text to = ixml.at(ns("//bibdata/ext/commentperiod/to"))&.text extended = ixml.at(ns("//bibdata/ext/commentperiod/extended"))&.text set(:comment_from, from) if from set(:comment_to, to) if to set(:comment_extended, extended) if extended end def url(xml, _out) super a = xml.at(ns("//bibdata/uri[@type = 'email']")) and set(:email, a.text) a = xml.at(ns("//bibdata/uri[@type = 'doi']")) and set(:doi, a.text) a = xml.at(ns("//bibdata/uri[@type = 'uri' or not(@type)]")) and set(:url, a.text) end def relations1(ixml, type) ret = [] ixml.xpath(ns("//bibdata/relation[@type = '#{type}'][not(xmlns:description)] | "\ "//bibdata/relation[description = '#{type}']")).each do |x| id = x&.at(ns(".//docidentifier"))&.text and ret << id end ret end def relations(ixml, _out) ret = relations1(ixml, "obsoletes") set(:obsoletes, ret) unless ret.empty? ret = relations1(ixml, "obsoletedBy") set(:obsoletedby, ret) unless ret.empty? ret = relations1(ixml, "supersedes") set(:supersedes, ret) unless ret.empty? ret = relations1(ixml, "supersededBy") set(:supersededby, ret) unless ret.empty? superseding_doc(ixml) end def superseding_doc(ixml) d = ixml.at(ns("//bibdata/relation[@type = 'obsoletedBy']/bibitem")) return unless d set(:superseding_status, status_print(d.at(ns("./status/stage"))&.text || "final")) superseding_iteration(d) docid = d.at(ns("./docidentifier[@type = 'NIST']"))&.text and set(:superseding_docidentifier, docid) docid_long = d.at(ns("./docidentifier[@type = 'nist-long']"))&.text and set(:superseding_docidentifier_long, docid_long) superseding_dates(d) doi = d.at(ns("./uri[@type = 'doi']"))&.text and set(:superseding_doi, doi) uri = d.at(ns("./uri[@type = 'uri']"))&.text and set(:superseding_uri, uri) superseding_titles(ixml, d) authors = d.xpath(ns("./contributor[role/@type = 'author']/person")) authors.empty? and authors = ixml.xpath(ns("//bibdata/contributor[role/@type = 'author']/person")) set(:superseding_authors, extract_person_names(authors)) end def superseding_titles(ixml, d) if title = d.at(ns("./title[@type = 'main']"))&.text set(:superseding_title, d.at(ns("./title[@type = 'main']"))&.text) set(:superseding_subtitle, d.at(ns("./title[@type = 'subtitle']"))&.text) else set(:superseding_title, ixml.at(ns("//bibdata/title[@type = 'main']"))&.text) set(:superseding_subtitle, ixml.at(ns("//bibdata/title[@type = 'subtitle']"))&.text) end end def superseding_iteration(d) return unless d.at(ns("./status/stage"))&.text == "draft-public" iter = d.at(ns("./status/iteration"))&.text || "1" case iter.downcase when "1" set(:superseding_iteration_ordinal, "Initial") set(:superseding_iteration_code, "IPD") when "final" set(:superseding_iteration_ordinal, "Final") set(:superseding_iteration_code, "FPD") else set(:superseding_iteration_ordinal, iter.to_i.localize.to_rbnf_s("SpelloutRules", "spellout-ordinal")) set(:superseding_iteration_code, "#{iter}PD") end end def superseding_dates(d) if cdate = d.at(ns("./date[@type = 'circulated']/on"))&.text set(:superseding_circulated_date, cdate) set(:superseding_circulated_date_monthyear, monthyr(cdate)) end if cdate = d.at(ns("./date[@type = 'issued']/on"))&.text set(:superseding_issued_date, cdate) set(:superseding_issued_date_monthyear, monthyr(cdate)) end if cdate = d.at(ns("./date[@type = 'updated']/on"))&.text set(:superseding_updated_date, cdate) set(:superseding_updated_date_monthyear, monthyr(cdate)) set(:superseding_updated_date_MMMddyyyy, MMMddyyyy(cdate)) end end def note(xml, _out) note = xml.at(ns("//bibdata/note[@type = 'additional-note']"))&.text and set(:additional_note, note) note = xml.at(ns("//bibdata/note[@type = 'withdrawal-note']"))&.text and set(:withdrawal_note, note) note = xml.at(ns("//bibdata/note[@type = "\ "'withdrawal-announcement-link']"))&.text and set(:withdrawal_announcement_link, note) end end end end