require "asciidoctor" require "asciidoctor/nist" require "asciidoctor/standoc/converter" require "isodoc/nist/html_convert" require "isodoc/nist/word_convert" require_relative "front" require_relative "boilerplate" require_relative "validate" require_relative "cleanup" require "fileutils" module Asciidoctor module NIST class Converter < Standoc::Converter XML_ROOT_TAG = "nist-standard".freeze XML_NAMESPACE = "https://www.metanorma.org/ns/nist".freeze register_for "nist" def table(node) role = node.role || node.attr("style") return errata(node) if role == "errata" super end def errata1(node) cols = [] node.rows[:head][-1].each { |c| cols << c.text.downcase } table = [] node.rows[:body].each do |r| row = {} r.each_with_index { |c, i| row[cols[i]] = c.content.join("") } table << row end table end def errata_row(row, entry) row.date { |x| x << entry["date"] } row.type { |x| x << entry["type"] } row.change { |x| x << entry["change"] } row.pages { |x| x << entry["pages"] } end def errata(node) table = errata1(node) noko do |xml| xml.errata do |errata| table.each do |entry| errata.row do |row| errata_row(row, entry) end end end end end def dlist(node) role = node.role || node.attr("style") return glossary(node) if role == "glossary" super end def olist(node) id = Asciidoctor::Standoc::Utils::anchor_or_uuid(node) noko do |xml| xml.ol **attr_code(id: id, class: node.attr("class")) do |xml_ol| node.items.each { |item| li(xml_ol, item) } end end.join("\n") end def glossary(node) noko do |xml| xml.dl **{id: Asciidoctor::Standoc::Utils::anchor_or_uuid(node), type: "glossary"} do |xml_dl| node.items.each do |terms, dd| dt(terms, xml_dl) dd(dd, xml_dl) end end end.join("\n") end def makexml(node) @draft = node.attributes.has_key?("draft") super end def doctype(node) d = super || "standard" d = "standard" if d == "article" # article is Asciidoctor default d end def init(node) @callforpatentclaims = node.attr("call-for-patent-claims") @commitmenttolicence = node.attr("commitment-to-licence") @patentcontact = node.attr("patent-contact") @biblioasappendix = node.attr("biblio-as-appendix") @nistdivision = node.attr("nist-division") || "Computer Security Division, Information Technology Laboratory" @nistdivisionaddress = node.attr("nist-division-address") || "100 Bureau Drive (Mail Stop 8930) Gaithersburg, MD 20899-8930" @series = node.attr("series") super end def outputs(node, ret) File.open(@filename + ".xml", "w:UTF-8") { |f| f.write(ret) } presentation_xml_converter(node).convert(@filename + ".xml") html_converter(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}.html") doc_converter(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}.doc") pdf_converter(node)&.convert(@filename + ".presentation.xml", nil, false, "#{@filename}.pdf") end def clause_parse(attrs, xml, node) role = node.role || node.attr("style") attrs[:executivesummary] = true if role == "executive-summary" super end def acknowledgements_parse(attrs, xml, node) xml.acknowledgements **attr_code(attrs) do |xml_section| xml_section << node.content end end def audience_parse(attrs, xml, node) xml.audience **attr_code(attrs) do |xml_section| xml_section << node.content end end def conformancetesting_parse(attrs, xml, node) xml.conformancetesting **attr_code(attrs) do |xml_section| xml_section << node.content end end def style(n, t) return end def sectiontype_streamline(ret) case ret when "glossary", "terminology" "terms and definitions" when "introduction" "donotrecognise_introduction" when "normative references" "bibliography" else super end end def term_def_parse(attrs, xml, node, toplevel) if node.attr("style") == "appendix" && node.level == 1 terms_annex_parse(attrs, xml, node) else clause_parse(attrs, xml, node) end end def bibliography_parse(a, xml, node) @biblioasappendix and node.level == 1 and return bibliography_annex_parse(a, xml, node) super end def bibliography_annex_parse(attrs, xml, node) attrs1 = attrs.merge(id: "_" + UUIDTools::UUID.random_create) xml.annex **attr_code(attrs1) do |xml_section| xml_section.title { |t| t << node.title } @biblio = true xml.references **attr_code(attrs.merge(normative: true)) do |r| r << node.content end end @biblio = false end def terms_annex_parse(attrs, xml, node) attrs1 = attrs.merge(id: "_" + UUIDTools::UUID.random_create) xml.annex **attr_code(attrs1) do |xml_section| xml_section.title { |name| name << node.title } xml_section.terms **attr_code(attrs) do |terms| (s = node.attr("source")) && s.split(/,/).each do |s1| terms.termdocsource(nil, **attr_code(bibitemid: s1)) end terms << node.content end end end NIST_PREFIX_REFS = "SP|FIPS" def refitem(xml, item, node) item.sub!(Regexp.new("^(]+>)\\[(#{NIST_PREFIX_REFS}) "), "\\1[NIST \\2 ") super end def fetch_ref(xml, code, year, **opts) code.sub!(Regexp.new("^(#{NIST_PREFIX_REFS}) "), "NIST \\1 ") super end def presentation_xml_converter(node) IsoDoc::NIST::PresentationXMLConvert.new(html_extract_attributes(node)) end def html_converter(node) IsoDoc::NIST::HtmlConvert.new(html_extract_attributes(node)) end def doc_converter(node) IsoDoc::NIST::WordConvert.new(doc_extract_attributes(node)) end def pdf_converter(node) return nil if node.attr("no-pdf") IsoDoc::NIST::PdfConvert.new(html_extract_attributes(node)) end end end end