require "iso-639" module Asciidoctor module NIST class Converter < Standoc::Converter def metadata_id(node, xml) did = node.attr("docidentifier") dn = node.attr("docnumber") @series == "nist-cswp" && !node.attr("docnumber") and dn = Iso690Render.MMMddyyyy(node.attr("issued-date")) metadata_id_compose(node, xml, dn, did) xml.docnumber node.attr("docnumber") || did&.sub(/^[^0-9]*/, "")&.sub(/[ -].*$/, "") end def unabbreviate(did) SERIES_ABBR.each { |k, v| did = did.sub(/^#{v} /, "#{k} ") } SERIES.each { |k, v| did = did.sub(/^#{k} /, "#{v} ") } did end def id_args(node, dn0) return nil unless dn0 { id: dn0, series: node.attr("series"), edition: node.attr("edition"), version: node.attr("version"), revision: node.attr("revision"), update: node.attr("update"), year: (node.attr("copyright-year") || node.attr("updated-date") || node.attr("revdate") || node.attr("circulated-date") || Date.today.year.to_s).sub(/^(....).*$/, "\\1"), vol: node.attr("volume"), part: node.attr("part") || node.attr("part-number"), section: node.attr("section") || node.attr("section-number"), supplement: node.attr("supplement") || node.attr("supplement-number"), index: node.attr("index") || node.attr("index-number"), stage: node.attr("status") || node.attr("docstage"), iter: node.attr("iteration"), language: node.attr("language") || "en", date: /^draft/.match(node.attr("status") || node.attr("docstage")) ? (node.attr("circulated-date") || node.attr("revdate")) : node.attr("updated-date") } end def metadata_id_compose(node, xml, dn0, did) if did xml.docidentifier did, **attr_code(type: "NIST") xml.docidentifier unabbreviate(did), **attr_code(type: "nist-long") else args = id_args(node, dn0) || return xml.docidentifier add_id_parts(args, false), **attr_code(type: "NIST") xml.docidentifier add_id_parts(args, true), **attr_code(type: "nist-long") xml.docidentifier add_id_parts_mr(args), **attr_code(type: "nist-mr") end end def MMMddyyyy(isodate) return nil if isodate.nil? Date.parse(isodate).strftime("%B %d, %Y") end def status_abbr(stage, iter) IsoDoc::NIST::Metadata.new(nil, nil, @i18n).status_abbr(stage, iter) end def add_id_parts(args, long) args[:series] and series_name = long ? SERIES.dig(args[:series].to_sym) : SERIES_ABBR.dig(args[:series].to_sym) dn = (series_name || "NIST #{args[:series]}") + " " + args[:id] dn += " Volume #{args[:vol]}" if args[:vol] dn += "," if args[:vol] && args[:revision] dn += " Revision #{args[:revision]}" if args[:revision] dn += "/Upd #{args[:update]}:#{args[:year]}" if args[:update] stage = status_abbr(args[:stage], args[:iter]) and dn += " (#{stage})" dn += " (#{MMMddyyyy(args[:date])})" if args[:date] dn end def id_parts_mr(args) part = [] part << "v-#{args[:vol]}" if args[:vol] part << "pt-#{args[:part]}" if args[:part] part << "sec-#{args[:section]}" if args[:section] part << "sup-#{args[:supplement]}" if args[:supplement] part << "indx-#{args[:index]}" if args[:index] part end def id_editions_mr(args) part = [] part << "e-#{args[:edition]}" if args[:edition] part << "r-#{args[:revision]}" if args[:revision] part << "ver-#{args[:version]}" if args[:version] part end def id_lang_mr(args) ret = args[:language].split(/,\s*/).map do |l| ISO_639.find(l).alpha3 end.join(",") end def add_id_parts_mr(args) ret = ["NIST"] args[:series] and ret << SERIES_ABBR&.dig(args[:series].to_sym)&.sub(/^NIST /, "") stage = status_abbr(args[:stage], nil) || "" stage += "[-#{args[:iter]}]" if args[:iter] ret << stage unless stage.empty? ret << args[:id] ret += id_parts_mr(args) ret += id_editions_mr(args) ret << id_lang_mr(args) args[:update] and ret << "upd-#{args[:update]}:#{args[:year]}" ret.join(".") end end end end