Class: Asciidoctor::Ogc::Converter

Inherits:
Standoc::Converter
  • Object
show all
Defined in:
lib/asciidoctor/ogc/front.rb,
lib/asciidoctor/ogc/converter.rb

Overview

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

Constant Summary collapse

STANDARDTYPE =
%w{standard standard-with-suite abstract-specification
community-standard profile}.freeze
SEQ =

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

[
    {
      msg: "Prefatory material must be followed by (clause) Scope",
      val: [{ tag: "clause", title: "Scope" }],
    },
    {
      msg: "Scope must be followed by Conformance",
      val: [{ tag: "clause", title: "Conformance" }],
    },
    {
      msg: "Normative References must be followed by "\
      "Terms and Definitions",
      val: [
        { tag: "terms", title: "Terms and definitions" },
        { tag: "clause", title: "Terms and definitions" },
        {
          tag: "terms",
          title: "Terms, definitions, symbols and abbreviated terms",
        },
        {
          tag: "clause",
          title: "Terms, definitions, symbols and abbreviated terms",
        },
      ],
    },
].freeze

Instance Method Summary collapse

Instance Method Details

#bibliography_parse(attrs, xml, node) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/asciidoctor/ogc/converter.rb', line 161

def bibliography_parse(attrs, xml, node)
  clausetype = node&.attr("heading")&.downcase || node.title.downcase
  if clausetype == "references" then norm_ref_parse(attrs, xml, node) 
  else
    super
  end
end

#clause_parse(attrs, xml, node) ⇒ Object



153
154
155
156
157
158
159
# File 'lib/asciidoctor/ogc/converter.rb', line 153

def clause_parse(attrs, xml, node)
  clausetype = node&.attr("heading")&.downcase || node.title.downcase
  if clausetype == "submitters" then submitters_parse(attrs, xml, node)
  else
    super
  end
end

#cleanup(xmldoc) ⇒ Object



193
194
195
196
197
198
# File 'lib/asciidoctor/ogc/converter.rb', line 193

def cleanup(xmldoc)
  recommendation_cleanup(xmldoc)
  requirement_cleanup(xmldoc)
  permission_cleanup(xmldoc)
  super
end

#corporate_author(node, xml) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/asciidoctor/ogc/front.rb', line 18

def corporate_author(node, xml)
  return unless node.attr("submitting-organizations")
  node.attr("submitting-organizations").split(/;[ ]*/).each do |org|
    xml.contributor do |c|
      c.role **{ type: "author" }
      c.organization do |a|
        a.name org
      end
    end
  end
end

#doctype(node) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/asciidoctor/ogc/converter.rb', line 37

def doctype(node)
  d = node.attr("doctype")
  unless %w{standard standard-with-suite abstract-specification
  community-standard profile best-practice 
  engineering-report discussion-paper reference-model user-guide
  policy guide amendment technical-corrigendum administrative}.include? d
    warn "#{d} is not a legal document type: reverting to 'standard'"
    d = "standard"
  end
  d
end

#document(node) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/asciidoctor/ogc/converter.rb', line 49

def document(node)
  init(node)
  ret1 = makexml(node)
  ret = ret1.to_xml(indent: 2)
  unless node.attr("nodoc") || !node.attr("docfile")
    filename = node.attr("docfile").gsub(/\.adoc/, ".xml").
      gsub(%r{^.*/}, "")
    File.open(filename, "w") { |f| f.write(ret) }
    html_converter(node).convert filename unless node.attr("nodoc")
    word_converter(node).convert filename unless node.attr("nodoc")
    pdf_converter(node).convert filename unless node.attr("nodoc")
  end
  @files_to_delete.each { |f| FileUtils.rm f }
  ret
end

#example(node) ⇒ Object



175
176
177
178
179
180
181
182
183
# File 'lib/asciidoctor/ogc/converter.rb', line 175

def example(node)
  return term_example(node) if in_terms?
  noko do |xml|
    xml.example **id_attr(node) do |ex|
      figure_title(node, ex)
      wrap_in_para(node, ex)
    end
  end.join("\n")
end

#externalurl(node) ⇒ Object



110
111
112
113
114
115
116
# File 'lib/asciidoctor/ogc/front.rb', line 110

def externalurl(node)
  if node.attr("doctype") == "engineering-report"
    "http://www.opengis.net/doc/PER/t14-#{node.attr('referenceurlid')}"
  else
    node.attr('referenceurlid')
  end
end

#html_converter(node) ⇒ Object



240
241
242
# File 'lib/asciidoctor/ogc/converter.rb', line 240

def html_converter(node)
  IsoDoc::Ogc::HtmlConvert.new(html_extract_attributes(node))
end

#make_preface(x, s) ⇒ Object



144
145
146
147
148
149
150
151
# File 'lib/asciidoctor/ogc/converter.rb', line 144

def make_preface(x, s)
  super
  if x.at("//submitters")
    preface = s.at("//preface") || s.add_previous_sibling("<preface/>").first
    submitters = x.at("//submitters").remove
    preface.add_child submitters.remove
  end
end

#makexml(node) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/asciidoctor/ogc/converter.rb', line 24

def makexml(node)
  result = ["<?xml version='1.0' encoding='UTF-8'?>\n<ogc-standard>"]
  @draft = node.attributes.has_key?("draft")
  result << noko { |ixml| front node, ixml }
  result << noko { |ixml| middle node, ixml }
  result << "</ogc-standard>"
  result = textcleanup(result.flatten * "\n")
  ret1 = cleanup(Nokogiri::XML(result))
  validate(ret1)
  ret1.root.add_namespace(nil, Metanorma::Ogc::DOCUMENT_NAMESPACE)
  ret1
end

#metadata(node, xml) ⇒ Object



157
158
159
160
# File 'lib/asciidoctor/ogc/front.rb', line 157

def (node, xml)
  super
  (node, xml)
end

#metadata_author(node, xml) ⇒ Object



13
14
15
16
# File 'lib/asciidoctor/ogc/front.rb', line 13

def (node, xml)
  corporate_author(node, xml)
  personal_author(node, xml)
end

#metadata_committee(node, xml) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/asciidoctor/ogc/front.rb', line 79

def (node, xml)
  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


123
124
125
126
127
128
129
130
131
132
133
# File 'lib/asciidoctor/ogc/front.rb', line 123

def (node, xml)
  from = node.attr("copyright-year") || node.attr("copyrightyear") || Date.today.year
  xml.copyright do |c|
    c.from from
    c.owner do |owner|
      owner.organization do |o|
        o.name Metanorma::Ogc::ORGANIZATION_NAME_SHORT
      end
    end
  end
end

#metadata_date(node, xml) ⇒ Object



142
143
144
145
146
147
# File 'lib/asciidoctor/ogc/front.rb', line 142

def (node, xml)
  super
  ogc_date(node, xml, "submissiondate", "received" )
  ogc_date(node, xml, "publicationdate", "published" )
  ogc_date(node, xml, "approvaldate", "issued" )
end

#metadata_id(node, xml) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/asciidoctor/ogc/front.rb', line 98

def (node, xml)
  node.attr("external-id") and
    xml.docidentifier node.attr("external-id"), **{ 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_keywords(node, xml) ⇒ Object



135
136
137
138
139
140
# File 'lib/asciidoctor/ogc/front.rb', line 135

def (node, xml)
  return unless node.attr("keywords")
  node.attr("keywords").split(/,[ ]*/).each do |kw|
    xml.keyword kw
  end
end

#metadata_publisher(node, xml) ⇒ Object



70
71
72
73
74
75
76
77
# File 'lib/asciidoctor/ogc/front.rb', line 70

def (node, xml)
  xml.contributor do |c|
    c.role **{ type: "publisher" }
    c.organization do |a|
      a.name Metanorma::Ogc::ORGANIZATION_NAME_SHORT
    end
  end
end

#metadata_source(node, xml) ⇒ Object



118
119
120
121
# File 'lib/asciidoctor/ogc/front.rb', line 118

def (node, xml)
  super
  node.attr("previous-uri") && xml.source(node.attr("previous-uri"), type: "previous")
end

#metadata_status(node, xml) ⇒ Object



93
94
95
96
# File 'lib/asciidoctor/ogc/front.rb', line 93

def (node, xml)
  status = node.attr("status") || "published"
  xml.status(**{ format: "plain" }) { |s| s << status }
end

#ogc_date(node, xml, ogcname, metanormaname) ⇒ Object



149
150
151
152
153
154
155
# File 'lib/asciidoctor/ogc/front.rb', line 149

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) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/asciidoctor/ogc/front.rb', line 42

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

#pdf_converter(node) ⇒ Object



244
245
246
# File 'lib/asciidoctor/ogc/converter.rb', line 244

def pdf_converter(node)
  IsoDoc::Ogc::PdfConvert.new(html_extract_attributes(node))
end

#permission_cleanup(xmldoc) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/asciidoctor/ogc/converter.rb', line 226

def permission_cleanup(xmldoc)
  xmldoc.xpath("//table").each do |t|
    td = t&.at("./tbody/tr/td[1]")&.text
    /^\s*(Permission( \d+)?)\s*/.match td or next
    body = t&.at("./tbody/tr/td[2]") or next
    t.name = "permission"
    t.children = body&.children
    label = t&.at("./p")&.remove or next
    label.name = "name"
    t.prepend_child label
  end
end

#personal_author(node, xml) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/asciidoctor/ogc/front.rb', line 30

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) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/asciidoctor/ogc/front.rb', line 54

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

#recommendation_cleanup(xmldoc) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/asciidoctor/ogc/converter.rb', line 200

def recommendation_cleanup(xmldoc)
  xmldoc.xpath("//table").each do |t|
    td = t&.at("./tbody/tr/td[1]")&.text
    /^\s*(Recommendation( \d+)?)\s*$/.match td or next
    body = t&.at("./tbody/tr/td[2]") or next
    t.name = "recommendation"
    t.children = body&.children
    label = t&.at("./p")&.remove or next
    label.name = "name"
    t.prepend_child label
  end
end

#requirement_cleanup(xmldoc) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/asciidoctor/ogc/converter.rb', line 213

def requirement_cleanup(xmldoc)
  xmldoc.xpath("//table").each do |t|
    td = t&.at("./tbody/tr/td[1]")&.text
    /^\s*(Requirement( \d+)?)\s*$/.match td or next
    body = t&.at("./tbody/tr/td[2]") or next
    t.name = "requirement"
    t.children = body&.children
    label = t&.at("./p")&.remove or next
    label.name = "name"
    t.prepend_child label
  end
end

#section_validate(doc) ⇒ Object



71
72
73
# File 'lib/asciidoctor/ogc/converter.rb', line 71

def section_validate(doc)
  sections_sequence_validate(doc.root)
end

#sections_cleanup(x) ⇒ Object



137
138
139
140
141
142
# File 'lib/asciidoctor/ogc/converter.rb', line 137

def sections_cleanup(x)
  super
  x.xpath("//*[@inline-header]").each do |h|
    h.delete("inline-header")
  end
end

#sections_sequence_validate(root) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/asciidoctor/ogc/converter.rb', line 117

def sections_sequence_validate(root)
  return unless STANDARDTYPE.include? root&.at("//bibdata/@type")&.text
  f = root.at("//sections").elements
  names = f.map { |s| { tag: s.name, title: s&.at("./title")&.text } }
  names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val]) || return
  names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val]) || return
  names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val]) || return
  n = names.shift
  if n == { tag: "definitions", title: nil }
    n = names.shift
  end
  unless n
    warn "OGC style: Document must contain at least one clause"
    return
  end
  root.at("//references | //clause[descendant::references][not(parent::clause)]") or
    seqcheck([{tag: "clause"}], 
             "Normative References are mandatory", [{tag: "references"}])
end

#seqcheck(names, msg, accepted) ⇒ Object



108
109
110
111
112
113
114
115
# File 'lib/asciidoctor/ogc/converter.rb', line 108

def seqcheck(names, msg, accepted)
  n = names.shift
  unless accepted.include? n
    warn "OGC style: #{msg}"
    names = []
  end
  names
end

#style(n, t) ⇒ Object



185
186
187
# File 'lib/asciidoctor/ogc/converter.rb', line 185

def style(n, t)
  return
end

#submitters_parse(attrs, xml, node) ⇒ Object



169
170
171
172
173
# File 'lib/asciidoctor/ogc/converter.rb', line 169

def submitters_parse(attrs, xml, node)
  xml.submitters **attr_code(attrs) do |xml_section|
    xml_section << node.content
  end
end

#termdef_boilerplate_cleanup(xmldoc) ⇒ Object



189
190
191
# File 'lib/asciidoctor/ogc/converter.rb', line 189

def termdef_boilerplate_cleanup(xmldoc)
  return
end

#title_validate(root) ⇒ Object



20
21
22
# File 'lib/asciidoctor/ogc/converter.rb', line 20

def title_validate(root)
  nil
end

#toc(value) ⇒ Object

ignore, we generate ToC outside of asciidoctor



17
18
# File 'lib/asciidoctor/ogc/converter.rb', line 17

def toc(value)
end

#validate(doc) ⇒ Object



65
66
67
68
69
# File 'lib/asciidoctor/ogc/converter.rb', line 65

def validate(doc)
  content_validate(doc)
  schema_validate(formattedstr_strip(doc.dup),
                  File.join(File.dirname(__FILE__), "ogc.rng"))
end

#word_converter(node) ⇒ Object



248
249
250
# File 'lib/asciidoctor/ogc/converter.rb', line 248

def word_converter(node)
  IsoDoc::Ogc::WordConvert.new(doc_extract_attributes(node))
end