class Asciidoctor::Ogc::Converter

A {Converter} implementation that generates RSD output, and a document schema encapsulation of the document for validation

Constants

SEQ

spec of permissible section sequence we skip normative references, it goes to end of list

STANDARDTYPE
XML_NAMESPACE
XML_ROOT_TAG

Public Instance Methods

add_id() click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 17
def add_id
  %(id="_#{UUIDTools::UUID.random_create}")
end
bibdata_cleanup(xmldoc) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/cleanup.rb, line 48
def bibdata_cleanup(xmldoc)
  super
  a = xmldoc.at("//bibdata/status/stage")
  a.text == "published" and a.children = "approved"
end
bibdata_validate(doc) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 19
def bibdata_validate(doc)
  stage_validate(doc)
  version_validate(doc)
end
clause_parse(attrs, xml, node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/converter.rb, line 74
def clause_parse(attrs, xml, node)
  case node&.attr("heading")&.downcase || node.title.downcase
  when "submitters" then return submitters_parse(attrs, xml, node)
  when "conformance" then attrs = attrs.merge(type: "conformance")
  when "security considerations" then attrs =
                                        attrs.merge(type: "security")
  end
  super
end
content_validate(doc) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/validate.rb, line 14
def content_validate(doc)
  super
  bibdata_validate(doc.root)
end
corporate_author(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 13
def corporate_author(node, xml)
  return unless node.attr("submitting-organizations")

  csv_split(HTMLEntities.new
    .decode(node.attr("submitting-organizations")), ";")&.each do |org|
    xml.contributor do |c|
      c.role **{ type: "author" }
      c.organization do |a|
        a.name org
      end
    end
  end
end
default_publisher() click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 68
def default_publisher
  "Open Geospatial Consortium"
end
doc_converter(node) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 139
def doc_converter(node)
  IsoDoc::Ogc::WordConvert.new(doc_extract_attributes(node))
end
doctype(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/converter.rb, line 27
def doctype(node)
  d = super
  d1 = ::IsoDoc::Ogc::DOCTYPE_ABBR.invert[d] and d = d1
  unless %w{abstract-specification-topic best-practice other policy
            change-request-supporting-document community-practice
            community-standard discussion-paper engineering-report
            reference-model release-notes standard user-guide white-paper
            test-suite}.include? d
    @warned_doctype or
      @log.add("Document Attributes", nil,
               "'#{d}' is not a legal document type: reverting to 'standard'")
    @warned_doctype = true
    d = "standard"
  end
  d
end
externalid(node) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 88
def externalid(node)
  return node.attr("external-id") if node.attr("external-id")

  d = doctype(node)
  a = node.attr("abbrev")
  return unless d && a

  url = "http://www.opengis.net/doc/#{IsoDoc::Ogc::DOCTYPE_ABBR[d]}/#{a}"
  v = (node.attr("edition") || node.attr("version")) and url += "/#{v}"
  url
end
externalurl(node) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 111
def externalurl(node)
  if doctype(node) == "engineering-report"
    "http://www.opengis.net/doc/PER/t14-#{node.attr('referenceurlid')}"
  else
    node.attr("referenceurlid")
  end
end
highlight_parse(text, xml) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 121
def highlight_parse(text, xml)
  xml.hi { |s| s << text }
end
html_converter(node) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 129
def html_converter(node)
  IsoDoc::Ogc::HtmlConvert.new(html_extract_attributes(node))
end
insert_security(xml, sect) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 21
def insert_security(xml, sect)
  description = "document"
  description = "standard" if %w(standard community-standard)
    .include?(sect&.at("//bibdata/ext/doctype")&.text)
  preface = sect.at("//preface") ||
    sect.add_previous_sibling("<preface/>").first
  sect = xml&.at("//clause[@type = 'security']")&.remove ||
    "<clause type='security' #{add_id}>"\
    "<title>Security considerations</title>"\
    "<p>#{@i18n.security_empty.sub(/%/, description)}</p></clause>"
  preface.add_child sect
end
insert_submitters(xml, sect) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 34
def insert_submitters(xml, sect)
  if xml.at("//submitters")
    preface = sect.at("//preface") ||
      sect.add_previous_sibling("<preface/>").first
    submitters = xml.at("//submitters").remove
    submitters.xpath(".//table").each do |t|
      t["unnumbered"] = true
    end
    preface.add_child submitters.remove
  end
end
make_preface(xml, sect) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/cleanup.rb, line 11
def make_preface(xml, sect)
  super
  insert_security(xml, sect)
  insert_submitters(xml, sect)
end
makexml(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/converter.rb, line 22
def makexml(node)
  @draft = node.attributes.has_key?("draft")
  super
end
metadata_author(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 8
def metadata_author(node, xml)
  corporate_author(node, xml)
  personal_author(node, xml)
end
metadata_committee(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 72
def metadata_committee(node, xml)
  return unless node.attr("committee")

  xml.editorialgroup do |a|
    a.committee(node.attr("committee") || "technical")
    node.attr("subcommittee") and
      a.subcommittee(node.attr("subcommittee"),
                     **attr_code(type: node.attr("subcommittee-type"),
                                 number: node.attr("subcommittee-number")))
    (node.attr("workgroup") || node.attr("workinggroup")) and
      a.workgroup(node.attr("workgroup") || node.attr("workinggroup"),
                  **attr_code(type: node.attr("workgroup-type"),
                              number: node.attr("workgroup-number")))
  end
end
metadata_date(node, xml) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/front.rb, line 131
def metadata_date(node, xml)
  super
  ogc_date(node, xml, "submissiondate", "received")
  ogc_date(node, xml, "publicationdate", "published")
  ogc_date(node, xml, "approvaldate", "issued")
end
metadata_ext(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 184
def metadata_ext(node, xml)
  metadata_doctype(node, xml)
  metadata_subdoctype(node, xml)
  metadata_committee(node, xml)
end
metadata_id(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 100
def metadata_id(node, xml)
  e = externalid(node) and xml.docidentifier e, **{ type: "ogc-external" }
  node.attr("referenceurlid") and
    xml.docidentifier externalurl(node), **{ type: "ogc-external" }
  docnumber = node.attr("docnumber") || node.attr("docreference")
  if docnumber
    xml.docidentifier docnumber, **{ type: "ogc-internal" }
    xml.docnumber docnumber
  end
end
metadata_source(node, xml) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/front.rb, line 119
def metadata_source(node, xml)
  super
  node.attr("previous-uri") && xml.uri(node.attr("previous-uri"),
                                       type: "previous")
end
metadata_subdoctype(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 152
def metadata_subdoctype(node, xml)
  s = node.attr("docsubtype")
  s1 = ::IsoDoc::Ogc::DOCSUBTYPE_ABBR.invert[s] and s = s1
  case doctype(node)
  when "standard"
    unless %w{conceptual-model conceptual-model-and-encoding
              conceptual-model-and-implementation encoding extension
              implementation profile profile-with-extension}.include? s
      @log.add("Document Attributes", nil,
               "'#{s}' is not a permitted subtype of Standard: "\
               "reverting to 'implementation'")
      s = "implementation"
    end
  when "best-practice"
    unless %w{general encoding extension profile
              profile-with-extension}.include? s
      @log.add("Document Attributes", nil,
               "'#{s}' is not a permitted subtype of Standard: "\
               "reverting to 'implementation'")
      s = "general"
    end
  end
  s and xml.subdoctype s
end
metadata_version(node, xml) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/front.rb, line 146
def metadata_version(node, xml)
  node.attr("version") and
    node.set_attr("edition", node.attr("version"), false)
  super
end
ogc_date(node, xml, ogcname, metanormaname) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 138
def ogc_date(node, xml, ogcname, metanormaname)
  if node.attr(ogcname)
    xml.date **{ type: metanormaname } do |d|
      d.on node.attr(ogcname)
    end
  end
end
ogc_editor(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 39
def ogc_editor(node, xml)
  return unless node.attr("editor")

  xml.contributor do |c|
    c.role **{ type: "editor" }
    c.person do |p|
      p.name do |n|
        n.completename node.attr("editor")
      end
    end
  end
end
outputs(node, ret) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 63
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
pdf_converter(node) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 133
def pdf_converter(node)
  return nil if node.attr("no-pdf")

  IsoDoc::Ogc::PdfConvert.new(html_extract_attributes(node))
end
personal_author(node, xml) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 27
def personal_author(node, xml)
  ogc_editor(node, xml)
  if node.attr("fullname") || node.attr("surname")
    personal_author1(node, xml, "")
  end
  i = 2
  while node.attr("fullname_#{i}") || node.attr("surname_#{i}")
    personal_author1(node, xml, "_#{i}")
    i += 1
  end
end
personal_author1(node, xml, suffix) click to toggle source
# File lib/asciidoctor/ogc/front.rb, line 52
def personal_author1(node, xml, suffix)
  xml.contributor do |c|
    c.role **{ type: node&.attr("role#{suffix}")&.downcase || "editor" }
    c.person do |p|
      p.name do |n|
        if node.attr("fullname#{suffix}")
          n.completename node.attr("fullname#{suffix}")
        else
          n.forename node.attr("givenname#{suffix}")
          n.surname node.attr("surname#{suffix}")
        end
      end
    end
  end
end
preface_sequence_validate(root) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 108
def preface_sequence_validate(root)
  root.at("//preface/abstract") or @log.add("Style", nil,
                                            "Abstract is missing!")
  root.at("//bibdata/keyword | //bibdata/ext/keyword") or
    @log.add("Style", nil, "Keywords are missing!")
  root.at("//foreword") or @log.add("Style", nil,
                                    "Preface is missing!")
  root.at("//bibdata/contributor[role/@type = 'author']/organization/"\
          "name") or
    @log.add("Style", nil, "Submitting Organizations is missing!")
  root.at("//submitters") or @log.add("Style", nil,
                                      "Submitters is missing!")
end
presentation_xml_converter(node) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 125
def presentation_xml_converter(node)
  IsoDoc::Ogc::PresentationXMLConvert.new(html_extract_attributes(node))
end
requirement_metadata(xmldoc) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/cleanup.rb, line 102
def requirement_metadata(xmldoc)
  super
  xmldoc.xpath(REQRECPER).each do |r|
    requirement_metadata_to_component(r)
    requirement_metadata_to_requirement(r)
    requirement_subparts_to_blocks(r)
  end
end
requirement_metadata1(reqt, dlist) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/cleanup.rb, line 81
def requirement_metadata1(reqt, dlist)
  ins = super
  dlist.xpath("./dt").each do |e|
    next unless requirement_metadata_component_tags.include? e.text

    ins.next = requirement_metadata1_component(e)
    ins = ins.next
  end
end
requirement_metadata1_component(term) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 91
def requirement_metadata1_component(term)
  val = term.at("./following::dd")
  val.name = term.text
  if %w(requirement permission
        recommendation).include?(term.text) && !val.text.empty?
    val["label"] = val.text.strip
    val.children.remove
  end
  val
end
requirement_metadata_component_tags() click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 76
def requirement_metadata_component_tags
  %w(test-purpose test-method conditions part description reference
     requirement permission recommendation)
end
requirement_metadata_to_component(reqt) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 111
def requirement_metadata_to_component(reqt)
  reqt.xpath("./test-method | ./test-purpose | ./conditions | ./part | "\
             "./reference")
    .each do |c|
    c["class"] = c.name
    c.name = "component"
  end
end
requirement_metadata_to_requirement(reqt) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 120
def requirement_metadata_to_requirement(reqt)
  reqt.xpath("./requirement | ./permission | ./recommendation")
    .each do |c|
    c["id"] = Metanorma::Utils::anchor_or_uuid
  end
end
requirement_subparts_to_blocks(reqt) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 127
def requirement_subparts_to_blocks(reqt)
  reqt.xpath("./component | ./description").each do |c|
    %w(p ol ul dl table).include?(c&.elements&.first&.name) and next
    c.children = "<p>#{c.children.to_xml}</p>"
  end
end
section_names_terms_cleanup(xml) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 54
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
section_validate(doc) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/validate.rb, line 46
def section_validate(doc)
  preface_sequence_validate(doc.root)
  sections_sequence_validate(doc.root)
  super
end
sections_cleanup(xml) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/cleanup.rb, line 4
def sections_cleanup(xml)
  super
  xml.xpath("//*[@inline-header]").each do |h|
    h.delete("inline-header")
  end
end
sections_sequence_validate(root) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 85
def sections_sequence_validate(root)
  return unless STANDARDTYPE.include?(
    root&.at("//bibdata/ext/doctype")&.text,
  )

  names = root.xpath("//sections/* | //bibliography/*")
  names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val])
  names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val])
  names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val])
  n = names.shift
  if n&.at("./self::definitions")
    n = names.shift
  end
  if n.nil? || n.name != "clause"
    @log.add("Style", nil,
             "Document must contain at least one clause")
    return
  end
  root.at("//references | //clause[descendant::references]"\
          "[not(parent::clause)]") or
    @log.add("Style", nil, "Normative References are mandatory")
end
sectiontype(node, level = true) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/converter.rb, line 44
def sectiontype(node, level = true)
  ret = sectiontype_streamline(sectiontype1(node))
  return ret if ret == "terms and definitions" &&
    node.attr("style") == "appendix" && node.level == 1

  super
end
sectiontype_streamline(ret) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/converter.rb, line 52
def sectiontype_streamline(ret)
  case ret
  when "preface" then "foreword"
  when "foreword", "introduction" then "donotrecognise-foreword"
  when "references" then "normative references"
  when "glossary" then "terms and definitions"
  else
    super
  end
end
seqcheck(names, msg, accepted) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 74
def seqcheck(names, msg, accepted)
  n = names.shift
  return [] if n.nil?

  test = accepted.map { |a| n.at(a) }
  if test.all?(&:nil?)
    @log.add("Style", nil, msg)
  end
  names
end
stage_validate(xmldoc) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 24
def stage_validate(xmldoc)
  stage = xmldoc&.at("//bibdata/status/stage")&.text
  %w(swg-draft oab-review public-rfc tc-vote
     approved deprecated retired).include? stage or
    @log.add("Document Attributes", nil,
             "#{stage} is not a recognised status")
end
style(_node, _text) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 91
def style(_node, _text)
  nil
end
submitters_parse(attrs, xml, node) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 84
def submitters_parse(attrs, xml, node)
  xml.submitters **attr_code(attrs) do |xml_section|
    xml_section.title @i18n.submitters
    xml_section << node.content
  end
end
table_cell(node, xml_tr, tblsec) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/converter.rb, line 103
def table_cell(node, xml_tr, tblsec)
  node.set_attr("valign", "middle")
  super
end
term_def_parse(attrs, xml, node, _toplevel) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/converter.rb, line 95
def term_def_parse(attrs, xml, node, _toplevel)
  if node.attr("style") == "appendix" && node.level == 1
    terms_annex_parse(attrs, xml, node)
  else
    super
  end
end
termdef_boilerplate_cleanup(xmldoc) click to toggle source
# File lib/asciidoctor/ogc/cleanup.rb, line 46
def termdef_boilerplate_cleanup(xmldoc); end
termdef_subclause_cleanup(xmldoc) click to toggle source

skip annex/terms/terms, which is empty node

# File lib/asciidoctor/ogc/cleanup.rb, line 135
def termdef_subclause_cleanup(xmldoc)
  xmldoc.xpath("//annex//terms[terms]").each do |t|
    next if t.parent.name == "terms"

    t.children.each { |n| n.parent = t.parent }
    t.remove
  end
end
terms_annex_parse(attrs, xml, node) click to toggle source
# File lib/asciidoctor/ogc/converter.rb, line 108
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
title(node, xml) click to toggle source
Calls superclass method
# File lib/asciidoctor/ogc/front.rb, line 177
def title(node, xml)
  super
  at = { format: "text/plain", type: "abbrev" }
  a = node.attr("abbrev") and
    xml.title a, **attr_code(at)
end
title_validate(_root) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 10
def title_validate(_root)
  nil
end
toc(value) click to toggle source

ignore, we generate ToC outside of asciidoctor

# File lib/asciidoctor/ogc/converter.rb, line 20
def toc(value); end
validate(doc) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 4
def validate(doc)
  content_validate(doc)
  schema_validate(formattedstr_strip(doc.dup),
                  File.join(File.dirname(__FILE__), "ogc.rng"))
end
version_validate(xmldoc) click to toggle source
# File lib/asciidoctor/ogc/validate.rb, line 32
def version_validate(xmldoc)
  version = xmldoc&.at("//bibdata/edition")&.text
  doctype = xmldoc&.at("//bibdata/ext/doctype")&.text
  if %w(engineering-report discussion-paper).include? doctype
    version.nil? or
      @log.add("Document Attributes", nil,
               "Version not permitted for #{doctype}")
  else
    version.nil? and
      @log.add("Document Attributes", nil,
               "Version required for #{doctype}")
  end
end