module Iso690Render

Public Class Methods

MMMddyyyy(isodate) click to toggle source
# File lib/isodoc/nist/render_dates.rb, line 29
def self.MMMddyyyy(isodate)
  return nil if isodate.nil?
  return isodate if isodate == "--"
  arr = isodate.split("-")
  if arr.size == 1 and (/^\d+$/.match isodate)
    Date.new(*arr.map(&:to_i)).strftime("%Y")
  elsif arr.size == 2
    Date.new(*arr.map(&:to_i)).strftime("%B %Y")
  else
    Date.parse(isodate).strftime("%B %d, %Y")
  end
end
accessLocation(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 109
def self.accessLocation(doc)
  s = doc.at("./accessLocation") or return ""
  s.text
end
blank?(x) click to toggle source
# File lib/isodoc/nist/render.rb, line 21
def self.blank?(x)
  x.nil? || x.empty?
end
commajoin(a, b) click to toggle source
# File lib/isodoc/nist/render_contributors.rb, line 29
def self.commajoin(a, b)
  return a unless b
  return b unless a
  #"#{a}, #{b}"
  "#{a} #{b}"
end
contributorRole(contributors) click to toggle source
# File lib/isodoc/nist/render_contributors.rb, line 56
  def self.contributorRole(contributors)
  return "" unless contributors.length > 0
  if contributors[0]&.at("role/@type")&.text == "editor"
    return contributors.length > 1 ? " (Eds.)" : "(Ed.)"
  end
  ""
end
creatornames(doc) click to toggle source
# File lib/isodoc/nist/render_contributors.rb, line 64
def self.creatornames(doc)
  cr = doc.xpath("./contributor[role/@type = 'author']")
  cr.empty? and cr = doc.xpath("./contributor[role/@type = 'performer']")
  cr.empty? and cr = doc.xpath("./contributor[role/@type = 'adapter']")
  cr.empty? and cr = doc.xpath("./contributor[role/@type = 'translator']")
  cr.empty? and cr = doc.xpath("./contributor[role/@type = 'editor']")
  cr.empty? and cr = doc.xpath("./contributor[role/@type = 'publisher']")
  cr.empty? and cr = doc.xpath("./contributor[role/@type = 'distributor']")
  cr.empty? and cr = doc.xpath("./contributor")
  cr.empty? and return ""
  ret = []
  cr.each do |x|
    ret << extractname(x)
  end
  multiplenames(ret) + contributorRole(cr)
end
date(doc) click to toggle source
# File lib/isodoc/nist/render_dates.rb, line 12
def self.date(doc)
  updated = date1(doc&.at("./date[@type = 'updated']"))
  pub = date1(doc&.at("./date[@type = 'issued']"))
  if pub
    ret = pub
    ret += " (updated #{updated})" if updated
    return ret
  end
  pub = date1(doc&.at("./date[@type = 'circulated']")) and return pub
  date1(doc&.at("./date"))
end
date1(date) click to toggle source
# File lib/isodoc/nist/render_dates.rb, line 2
def self.date1(date)
  return nil if date.nil?
  on = date&.at("./on")&.text
  from = date&.at("./from")&.text
  to = date&.at("./to")&.text
  return MMMddyyyy(on) if on
  return "#{MMMddyyyy(from)}&ndash;#{MMMddyyyy(to)}" if from
  nil
end
draft(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 165
def self.draft(doc)
  return nil unless is_nist(doc)
  dr = doc&.at("./status/stage")&.text
  iter = doc&.at("./status/iteration")&.text
  return nil unless /^draft/.match(dr)
  iterord = iter_ordinal(doc)
  status = status_print(dr)
  status = "#{iterord} #{status}" if iterord
  status
end
extent(localities) click to toggle source
# File lib/isodoc/nist/render.rb, line 149
def self.extent(localities)
  ret = []
  ret1 = ""
  localities.each do |l|
    if %w(localityStack).include? l.name
      ret << ret1
      ret1 = ""
      ret << extent1(l.children)
    else
      ret1 += extent1([l])
    end
  end
  ret << ret1
  ret.reject { |c| c.empty? }.join("; ")
end
extent1(localities) click to toggle source
# File lib/isodoc/nist/render.rb, line 141
def self.extent1(localities)
  ret = []
  localities.each do |l|
    ret << extent2(l["type"] || "page", l.at("./referenceFrom"), l.at("./referenceTo"))
  end
  ret.join(", ")
end
extent2(type, from, to) click to toggle source
# File lib/isodoc/nist/render.rb, line 129
def self.extent2(type, from, to)
  ret = ""
  case type 
  when "page" then type = to ? "pp." : "p."
  when "volume" then type = to ? "Vols." : "Vol."
  end
  ret += "#{type} "
  ret += from.text if from
  ret += "&ndash;#{to.text}" if to
  ret
end
extract_orgname(org) click to toggle source
# File lib/isodoc/nist/render_contributors.rb, line 15
def self.extract_orgname(org)
  name = org.at("./name")
  name&.text || "--"
end
extract_personname(person) click to toggle source
# File lib/isodoc/nist/render_contributors.rb, line 36
def self.extract_personname(person)
  completename = person.at("./name/completename")
  return completename.text if completename
  surname = person.at("./name/surname")
  initials = person.xpath("./name/initial")
  forenames = person.xpath("./name/forename")
  #given = []
  #forenames.each { |x| given << x.text }
  #given.empty? && initials.each { |x| given << x.text }
  commajoin(surname&.text, frontname(forenames, initials))
end
extractname(contributor) click to toggle source
# File lib/isodoc/nist/render_contributors.rb, line 48
def self.extractname(contributor)
  org = contributor.at("./organization")
  person = contributor.at("./person")
  return extract_orgname(org) if org
  return extract_personname(person) if person
  "--"
end
frontname(given, initials) click to toggle source
# File lib/isodoc/nist/render_contributors.rb, line 20
def self.frontname(given, initials)
  if given.empty? && initials.empty? then ""
  elsif initials.empty?
    given.map{ |m| m.text[0] }.join("")
  else
    initials.map{ |m| m.text[0] }.join("")
  end
end
included(type) click to toggle source
# File lib/isodoc/nist/render.rb, line 114
def self.included(type)
  ["article", "inbook", "incollection", "inproceedings"].include? type
end
is_nist(doc) click to toggle source

def self.edition(doc)

x = doc.at("./edition")
return "" unless x
return x.text unless /^\d+$/.match x.text
x.text.to_i.localize.to_rbnf_s("SpelloutRules", "spellout-ordinal")

end

# File lib/isodoc/nist/render.rb, line 34
def self.is_nist(doc)
  publisher = doc&.at("./contributor[role/@type = 'publisher']/organization/name")&.text
  abbr = doc&.at("./contributor[role/@type = 'publisher']/organization/abbreviation")&.text
  publisher == "NIST" || abbr == "NIST" ||
    publisher == "National Institute of Standards and Technology"
end
iter_ordinal(isoxml) click to toggle source
# File lib/isodoc/nist/render.rb, line 176
def self.iter_ordinal(isoxml)
  docstatus = isoxml.at(("./status/stage"))&.text
  return nil unless docstatus == "draft-public"
  iter = isoxml.at(("./status/iteration"))&.text || "1"
  return "Initial" if iter == "1"
  return "Final" if iter.downcase == "final"
  iter.to_i.localize.to_rbnf_s("SpelloutRules", "spellout-ordinal").capitalize
end
medium(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 17
def self.medium(doc)
  doc&.at("./medium")&.text
end
multiplenames(names) click to toggle source

def self.multiplenames_and(names)

return "" if names.length == 0
return names[0] if names.length == 1
return "#{names[0]} and #{names[1]}" if names.length == 2
names[0..-2].join(", ") + " and #{names[-1]}"

end

# File lib/isodoc/nist/render_contributors.rb, line 11
def self.multiplenames(names)
  names.join(", ")
end
parse(doc, embedded = false) click to toggle source

converting bibitem to <formattedref> + <docidentifier>

# File lib/isodoc/nist/render.rb, line 198
def self.parse(doc, embedded = false)
  f = doc.at("./formattedref") and 
    return embedded ? f.children.to_xml : doc.to_xml

  ret = ""
  type = type(doc)
  container = doc.at("./relation[@type='includedIn']")
  if container && !date(doc) && date(container&.at("./bibitem"))
    doc << ( container&.at("./bibitem/date[@type = 'issued' or @type = 'published' or "\
                    "@type = 'circulated']")&.remove )
  end
  dr = draft(doc)
  cr = creatornames(doc)
  # NIST has seen fit to completely change rendering based on the type of publication.
  if series_title(doc) == "NIST Federal Information Processing Standards"
    cr = "National Institute of Standards and Technology"
  end
  pub = placepub(doc)

  ret += wrap(cr, "", "")
  if dr
    mdy = MMMddyyyy(date(doc)) and ret += wrap(mdy, " (", ")")
  else
    yr = year(date(doc)) and ret += wrap(yr, " (", ")")
  end
  ret += included(type) ? wrap(title(doc), " ", "") : wrap(title(doc), " <em>", "</em>")
  ret += wrap(medium(doc), " [", "]")
  #ret += wrap(edition(doc), "", " edition.")
  if cr != pub
    ret += wrap(pub, " (", ")")
  end
  if cr != pub && pub && !pub.empty? && (dr || !blank?(series(doc, type)))
    ret += ","
  end
  if dr
    ret += " Draft (#{dr})"
  end
  ret += wrap(series(doc, type), " ", "")
  ret += wrap(date(doc), ", ", "")
  ret += wrap(standardidentifier(doc), ". ", "") unless is_nist(doc)
  ret += wrap(uri(doc), ". ", "")
  ret += wrap(accessLocation(doc), ". At: ", "")
  if container 
    ret += wrap(parse(container.at("./bibitem"), true), ". In: ", "")
    locality = doc.xpath("./extent")
    ret += wrap(extent(locality), ", " , "")
  else
    ret += wrap(extent(doc.xpath("./extent")), ", ", "")
  end
  if !embedded
    ret += "."
  end

  embedded ? ret : "<formattedref>#{ret}</formattedref>#{doc.xpath('./docidentifier').to_xml}"
end
placepub(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 41
def self.placepub(doc)
  place = doc&.at("./place")&.text
  publisher = doc&.at("./contributor[role/@type = 'publisher']/organization/name")&.text
  abbr = doc&.at("./contributor[role/@type = 'publisher']/organization/abbreviation")&.text
  series = series_title(doc)
  series == "NIST Federal Information Processing Standards" and
    return "U.S. Department of Commerce, Washington, D.C."
  is_nist(doc) and
    return "National Institute of Standards and Technology, Gaithersburg, MD"
  ret = ""
  ret += place if place
  ret += ": " if place && publisher
  ret += publisher if publisher
  ret
end
render(bib, embedded = false) click to toggle source
# File lib/isodoc/nist/render.rb, line 7
def self.render(bib, embedded = false)
  docxml = Nokogiri::XML(bib)
  docxml.remove_namespaces!
  parse(docxml.root, embedded)
end
series(doc, type) click to toggle source
# File lib/isodoc/nist/render.rb, line 62
def self.series(doc, type)
  s = doc.at("./series[@type = 'main']") || doc.at("./series[not(@type)]") || doc.at("./series")
  return "" unless s
  f = s.at("./formattedref") and return f.text
  t = s.at("./title")
  a = s.at("./abbreviation")
  n = s.at("./number")
  p = s.at("./partnumber")
  dn = doc.at("./docnumber")
  rev = doc&.at(".//edition")&.text&.sub(/^Revision /, "")
  ret = ""
  if t
    title = included(type) ? wrap(t.text, " <em>", "</em>") : wrap(t.text, " ", "")
    ret += title
    ret += " (#{a.text.sub(/^NIST /, "")})" if a
  end
  if n || p
    ret += " #{n.text}" if n
    ret += ".#{p.text}" if p
  elsif dn && is_nist(doc)
    ret += " #{dn.text}"
    ret += " Rev. #{rev}" if rev
  end
  ret
end
series_title(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 57
def self.series_title(doc)
  s = doc.at("./series[@type = 'main']") || doc.at("./series[not(@type)]") || doc.at("./series")
  s&.at("./title")&.text
end
standardidentifier(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 88
def self.standardidentifier(doc)
  ret = []
  doc.xpath("./docidentifier").each do |id|
    next if %w(nist-mr nist-long metanorma rfc-anchor).include? id["type"]
    ret << standardidentifier1(id)
  end
  ret.join(". ")
end
standardidentifier1(id) click to toggle source
# File lib/isodoc/nist/render.rb, line 97
def self.standardidentifier1(id)
  r = ""
  r += "#{id['type']} " if id["type"] and !%w(ISO IEC NIST).include? id["type"]
  r += id.text
  r
end
status_print(status) click to toggle source
# File lib/isodoc/nist/render.rb, line 185
def self.status_print(status)
  case status
  when "draft-internal" then "Internal Draft"
  when "draft-wip" then "Work-in-Progress Draft"
  when "draft-prelim" then "Preliminary Draft"
  when "draft-public" then "Public Draft"
  when "draft-approval" then "Approval Draft"
  when "final" then "Final"
  when "final-review" then "Under Review"
  end
end
title(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 13
def self.title(doc)
  doc&.at("./title")&.text
end
type(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 123
def self.type(doc)
  type = doc.at("./@type") and return type&.text
  doc.at("./includedIn") and return "inbook"
  "book"
end
uri(doc) click to toggle source
# File lib/isodoc/nist/render.rb, line 104
def self.uri(doc)
  uri = doc.at("./uri[@type = 'doi']") || doc.at("./uri[@type = 'uri']") || doc.at("./uri")
  uri&.text
end
wrap(text, startdelim = " ", enddelim = ".") click to toggle source
# File lib/isodoc/nist/render.rb, line 118
def self.wrap(text, startdelim = " ", enddelim = ".")
  return "" if blank?(text)
  "#{startdelim}#{text}#{enddelim}"
end
year(date) click to toggle source
# File lib/isodoc/nist/render_dates.rb, line 24
def self.year(date)
  return nil if date.nil?
  date.sub(/^(\d\d\d\d).*$/, "\\1")
end