module Metanorma module Ogc class Converter < Standoc::Converter def boilerplate_file(_xmldoc) File.join(@libdir, "boilerplate.adoc") end def sections_cleanup(xml) super xml.xpath("//*[@inline-header]").each do |h| h.delete("inline-header") end end def make_preface(xml, sect) super insert_execsummary(xml, sect) insert_security(xml, sect) insert_submitters(xml, sect) end def add_id %(id="_#{UUIDTools::UUID.random_create}") end def insert_execsummary(xml, sect) summ = xml&.at("//clause[@type = 'executivesummary']")&.remove or return preface = sect.at("//preface") || sect.add_previous_sibling("").first preface.add_child summ end def insert_security(xml, sect) description = "document" description = "standard" if %w(standard community-standard) .include?(@doctype) @doctype == "engineering-report" and return remove_security(xml) preface = sect.at("//preface") || sect.add_previous_sibling("").first sect = xml.at("//clause[@type = 'security']")&.remove || create_security_clause(xml) preface.add_child sect end def remove_security(xml) a = xml.at("//clause[@type = 'security']") and a.delete("type") end def create_security_clause(xml) doctype = xml.at("//bibdata/ext/doctype")&.text description = "document" description = "standard" if %w(standard community-standard) .include?(doctype) <<~CLAUSE Security considerations

#{@i18n.security_empty.sub('%', description)}

CLAUSE end def insert_submitters(xml, sect) if xml.at("//submitters") preface = sect.at("//preface") || sect.add_previous_sibling("").first submitters = xml.at("//submitters").remove submitters.xpath(".//table").each do |t| t["unnumbered"] = true end preface.add_child submitters.remove end end def termdef_boilerplate_cleanup(xmldoc); end def bibdata_cleanup(xmldoc) super a = xmldoc.at("//bibdata/status/stage") a.text == "published" and a.children = "approved" if @doctype == "technical-paper" doctype = xmldoc.at("//bibdata/ext/doctype") doctype.children = "white-paper" @doctype = "white-paper" end end def section_names_terms_cleanup(xml) replace_title(xml, "//definitions[@type = 'symbols']", @i18n&.symbols) replace_title(xml, "//definitions[@type = 'abbreviated_terms']", @i18n&.abbrev) replace_title(xml, "//definitions[not(@type)]", @i18n&.symbolsabbrev) replace_title(xml, "//sections//terms#{SYMnoABBR} | " \ "//sections//clause[.//terms]#{SYMnoABBR}", @i18n&.termsdefsymbols, true) replace_title(xml, "//sections//terms#{ABBRnoSYM} | " \ "//sections//clause[.//terms]#{ABBRnoSYM}", @i18n&.termsdefabbrev, true) replace_title(xml, "//sections//terms#{SYMABBR} | " \ "//sections//clause[.//terms]#{SYMABBR}", @i18n&.termsdefsymbolsabbrev, true) replace_title(xml, "//sections//terms#{NO_SYMABBR} | " \ "//sections//clause[.//terms]#{NO_SYMABBR}", @i18n&.termsdefsymbolsabbrev, true) replace_title(xml, "//sections//terms[not(.//definitions)] | " \ "//sections//clause[.//terms][not(.//definitions)]", @i18n&.termsdef, true) end def termdef_cleanup(xmldoc) super termdef_subclause_cleanup(xmldoc) end # skip annex/terms/terms, which is empty node def termdef_subclause_cleanup(xmldoc) xmldoc.xpath("//annex//clause[terms]").each do |t| next unless t.xpath("./clause | ./terms | ./definitions").size == 1 t.children.each { |n| n.parent = t.parent } t.remove end end def normref_cleanup(xmldoc) r1 = xmldoc.at("//references[title[translate(text(), 'R', 'r') = " \ "'Normative references']]") r2 = xmldoc.at("//references[title[text() = 'References']]") if r1 && r2 r2["normative"] = false end super end def obligations_cleanup_inherit(xml) xml.xpath("//annex").each do |r| r["obligation"] = "informative" unless r["obligation"] end xml.xpath("//clause[not(ancestor::boilerplate)]").each do |r| r["obligation"] = "normative" unless r["obligation"] end xml.xpath(::Metanorma::Standoc::Utils::SUBCLAUSE_XPATH).each do |r| o = r.at("./ancestor::*/@obligation")&.text and r["obligation"] = o end end def sections_order_cleanup(xml) super sort_annexes(xml) end def sort_annexes(xml) last = xml.at("//annex[last()]") or return last.next = "" and last = last.next_element gl = xml.at("//annex[.//term]") and last.previous = gl.remove rev = xml.at("//annex[title[normalize-space(.) = 'Revision history']]") || xml.at("//annex[title[normalize-space(.) = 'Revision History']]") and last.previous = rev.remove last.remove end def sort_biblio(bib) bib.sort do |a, b| sort_biblio_key(a) <=> sort_biblio_key(b) end end PUBLISHER = "./contributor[role/@type = 'publisher']/organization".freeze def pub_class(bib) return 1 if bib.at("#{PUBLISHER}[abbreviation = 'OGC']") return 1 if bib.at("#{PUBLISHER}[name = 'Open Geospatial " \ "Consortium']") return 2 if bib.at("./docidentifier[@type][not(#{skip_docid} or " \ "@type = 'metanorma')]") 3 end # sort by: doc class (OGC, other standard (not DOI &c), other # then standard class (docid class other than DOI &c) # then if OGC, doc title else if other, authors # then docnumber if present, numeric sort # else alphanumeric metanorma id (abbreviation) # then doc part number if present, numeric sort # then doc id (not DOI &c) # then title def sort_biblio_key(bib) pubclass = pub_class(bib) ids = sort_biblio_ids_key(bib) title = title_key(bib) sortkey3 = author_title_key(pubclass, title, bib) num = if ids[:num].nil? then ids[:abbrid] else sprintf("%09d", ids[:num].to_i) end "#{pubclass} :: #{ids[:type]} :: #{sortkey3} :: #{num} :: " \ "#{sprintf('%09d', ids[:partid])} :: #{ids[:id]} :: #{title}" end def author_title_key(pubclass, title, bib) case pubclass when 1, 2 then title when 3 cite = ::Relaton::Render::General.new .render_all("#{bib.to_xml}") cite[:author] end end def title_key(bib) title = bib.at("./title[@type = 'main']") || bib.at("./title") || bib.at("./formattedref") title&.text&.sub!(/^(OGC|Open Geospatial Consortium)\b/, "") end def sort_biblio_ids_key(bib) id = bib.at("./docidentifier[@primary]") || bib.at("./docidentifier[not(#{skip_docid} or @type = 'metanorma')]") metaid = bib.at("./docidentifier[@type = 'metanorma']")&.text /\d-(?\d+)/ =~ id&.text { id: id&.text, num: bib.at("./docnumber")&.text, abbrid: /^\[\d+\]$/.match?(metaid) ? metaid : nil, partid: partid&.to_i || 0, type: id ? id["type"] : nil } end end end end