metanorma-ogc 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.hound.yml +3 -0
  4. data/.rubocop.yml +10 -0
  5. data/.travis.yml +16 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +25 -0
  9. data/README.adoc +323 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/rspec +17 -0
  13. data/bin/setup +8 -0
  14. data/lib/asciidoctor/ogc.rb +7 -0
  15. data/lib/asciidoctor/ogc/biblio.rng +890 -0
  16. data/lib/asciidoctor/ogc/converter.rb +253 -0
  17. data/lib/asciidoctor/ogc/front.rb +163 -0
  18. data/lib/asciidoctor/ogc/isodoc.rng +1091 -0
  19. data/lib/asciidoctor/ogc/isostandard.rng +1068 -0
  20. data/lib/asciidoctor/ogc/ogc.rng +210 -0
  21. data/lib/isodoc/ogc.rb +10 -0
  22. data/lib/isodoc/ogc/html/header.html +181 -0
  23. data/lib/isodoc/ogc/html/html_ogc_intro.html +85 -0
  24. data/lib/isodoc/ogc/html/html_ogc_titlepage.html +172 -0
  25. data/lib/isodoc/ogc/html/htmlstyle.scss +1054 -0
  26. data/lib/isodoc/ogc/html/ogc.scss +644 -0
  27. data/lib/isodoc/ogc/html/scripts.html +82 -0
  28. data/lib/isodoc/ogc/html/scripts.pdf.html +70 -0
  29. data/lib/isodoc/ogc/html/word_ogc_intro.html +92 -0
  30. data/lib/isodoc/ogc/html/word_ogc_titlepage.html +194 -0
  31. data/lib/isodoc/ogc/html/wordstyle.scss +1104 -0
  32. data/lib/isodoc/ogc/html_convert.rb +355 -0
  33. data/lib/isodoc/ogc/i18n-en.yaml +1 -0
  34. data/lib/isodoc/ogc/metadata.rb +102 -0
  35. data/lib/isodoc/ogc/pdf_convert.rb +357 -0
  36. data/lib/isodoc/ogc/word_convert.rb +345 -0
  37. data/lib/metanorma-ogc.rb +8 -0
  38. data/lib/metanorma/ogc.rb +11 -0
  39. data/lib/metanorma/ogc/processor.rb +43 -0
  40. data/lib/metanorma/ogc/version.rb +5 -0
  41. data/metanorma-ogc.gemspec +45 -0
  42. metadata +338 -0
@@ -0,0 +1,355 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+ require "fileutils"
4
+
5
+ module IsoDoc
6
+ module Ogc
7
+
8
+ # A {Converter} implementation that generates HTML output, and a document
9
+ # schema encapsulation of the document for validation
10
+ #
11
+ class HtmlConvert < IsoDoc::HtmlConvert
12
+ def initialize(options)
13
+ @libdir = File.dirname(__FILE__)
14
+ super
15
+ #FileUtils.cp html_doc_path('logo.jpg'), "logo.jpg"
16
+ #@files_to_delete << "logo.jpg"
17
+ end
18
+
19
+ def default_fonts(options)
20
+ {
21
+ bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Overpass",sans-serif'),
22
+ headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Overpass",sans-serif'),
23
+ monospacefont: '"Space Mono",monospace'
24
+ }
25
+ end
26
+
27
+ def default_file_locations(_options)
28
+ {
29
+ htmlstylesheet: html_doc_path("htmlstyle.scss"),
30
+ htmlcoverpage: html_doc_path("html_ogc_titlepage.html"),
31
+ htmlintropage: html_doc_path("html_ogc_intro.html"),
32
+ scripts: html_doc_path("scripts.html"),
33
+ }
34
+ end
35
+
36
+ def metadata_init(lang, script, labels)
37
+ @meta = Metadata.new(lang, script, labels)
38
+ end
39
+
40
+ def html_head
41
+ <<~HEAD.freeze
42
+ <title>{{ doctitle }}</title>
43
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
44
+
45
+ <!--TOC script import-->
46
+ <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
47
+
48
+ <!--Google fonts-->
49
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i|Space+Mono:400,700" rel="stylesheet">
50
+ <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
51
+ <!--Font awesome import for the link icon-->
52
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/solid.css" integrity="sha384-rdyFrfAIC05c5ph7BKz3l5NG5yEottvO/DQ0dCrwD8gzeQDjYBHNr1ucUpQuljos" crossorigin="anonymous">
53
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/fontawesome.css" integrity="sha384-u5J7JghGz0qUrmEsWzBQkfvc8nK3fUT7DCaQzNQ+q4oEXhGSx+P2OqjWsfIRB8QT" crossorigin="anonymous">
54
+ <style class="anchorjs"></style>
55
+ HEAD
56
+ end
57
+
58
+ def make_body(xml, docxml)
59
+ body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72", "xml:lang": "EN-US", class: "container" }
60
+ xml.body **body_attr do |body|
61
+ make_body1(body, docxml)
62
+ make_body2(body, docxml)
63
+ make_body3(body, docxml)
64
+ end
65
+ end
66
+
67
+ def html_toc(docxml)
68
+ docxml
69
+ end
70
+
71
+ def annex_name(annex, name, div)
72
+ div.h1 **{ class: "Annex" } do |t|
73
+ t << "#{get_anchors[annex['id']][:label]}"
74
+ t.br
75
+ t.b do |b|
76
+ name&.children&.each { |c2| parse(c2, b) }
77
+ end
78
+ end
79
+ end
80
+
81
+ def term_defs_boilerplate(div, source, term, preface)
82
+ if source.empty? && term.nil?
83
+ div << @no_terms_boilerplate
84
+ else
85
+ div << term_defs_boilerplate_cont(source, term)
86
+ end
87
+ end
88
+
89
+ def fileloc(loc)
90
+ File.join(File.dirname(__FILE__), loc)
91
+ end
92
+
93
+ def cleanup(docxml)
94
+ super
95
+ term_cleanup(docxml)
96
+ end
97
+
98
+ def term_cleanup(docxml)
99
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
100
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
101
+ h2.add_child("&nbsp;")
102
+ h2.add_child(d.remove)
103
+ end
104
+ docxml
105
+ end
106
+
107
+ def info(isoxml, out)
108
+ @meta.keywords isoxml, out
109
+ super
110
+ end
111
+
112
+ def load_yaml(lang, script)
113
+ y = if @i18nyaml then YAML.load_file(@i18nyaml)
114
+ elsif lang == "en"
115
+ YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
116
+ else
117
+ YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
118
+ end
119
+ super.merge(y)
120
+ end
121
+
122
+ def keywords(_docxml, out)
123
+ kw = @meta.get[:keywords]
124
+ kw.empty? and return
125
+ @prefacenum += 1
126
+ out.div **{ class: "Section3" } do |div|
127
+ clause_name(RomanNumerals.to_roman(@prefacenum).downcase, "Keywords", div, class: "IntroTitle")
128
+ div.p "The following are keywords to be used by search engines and document catalogues."
129
+ div.p kw.join(", ")
130
+ end
131
+ end
132
+
133
+ SUBMITTINGORGS =
134
+ "//bibdata/contributor[role/@type = 'author']/organization/name".freeze
135
+
136
+ def submittingorgs(docxml, out)
137
+ orgs = []
138
+ docxml.xpath(ns(SUBMITTINGORGS)).each { |org| orgs << org.text }
139
+ return if orgs.empty?
140
+ @prefacenum += 1
141
+ out.div **{ class: "Section3" } do |div|
142
+ clause_name(RomanNumerals.to_roman(@prefacenum).downcase, "Submitting Organizations", div, class: "IntroTitle")
143
+ div.p "The following organizations submitted this Document to the Open Geospatial Consortium (OGC):"
144
+ div.ul do |ul|
145
+ orgs.each do |org|
146
+ ul.li org
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ def submitters(docxml, out)
153
+ f = docxml.at(ns("//submitters")) || return
154
+ out.div **{ class: "Section3" } do |div|
155
+ clause_name(get_anchors[f['id']][:label], "Submitters", div, class: "IntroTitle")
156
+ f.elements.each { |e| parse(e, div) unless e.name == "title" }
157
+ end
158
+ end
159
+
160
+ def make_body3(body, docxml)
161
+ body.div **{ class: "main-section" } do |div3|
162
+ @prefacenum = 0
163
+ abstract docxml, div3
164
+ keywords docxml, div3
165
+ foreword docxml, div3
166
+ submittingorgs docxml, div3
167
+ submitters docxml, div3
168
+ middle docxml, div3
169
+ footnotes div3
170
+ comments div3
171
+ end
172
+ end
173
+
174
+ def preface_names(clause)
175
+ return if clause.nil?
176
+ @prefacenum += 1
177
+ @anchors[clause["id"]] =
178
+ { label: RomanNumerals.to_roman(@prefacenum).downcase,
179
+ level: 1, xref: preface_clause_name(clause), type: "clause" }
180
+ clause.xpath(ns("./clause | ./terms | ./term | ./definitions")).each_with_index do |c, i|
181
+ section_names1(c, "#{@prefacenum}.#{i + 1}", 2)
182
+ end
183
+ end
184
+
185
+ def abstract(isoxml, out)
186
+ f = isoxml.at(ns("//preface/abstract")) || return
187
+ @prefacenum += 1
188
+ page_break(out)
189
+ out.div **attr_code(id: f["id"]) do |s|
190
+ clause_name(get_anchors[f["id"]][:label], @abstract_lbl, s, class: "AbstractTitle")
191
+ f.elements.each { |e| parse(e, s) unless e.name == "title" }
192
+ end
193
+ end
194
+
195
+ def foreword(isoxml, out)
196
+ f = isoxml.at(ns("//foreword")) || return
197
+ @prefacenum += 1
198
+ page_break(out)
199
+ out.div **attr_code(id: f["id"]) do |s|
200
+ clause_name(get_anchors[f["id"]][:label], @foreword_lbl, s, class: "ForewordTitle")
201
+ f.elements.each { |e| parse(e, s) unless e.name == "title" }
202
+ end
203
+ end
204
+
205
+ def example_parse(node, out)
206
+ name = node.at(ns("./name"))
207
+ sourcecode_name_parse(node, out, name) if name
208
+ out.table **example_table_attr(node) do |t|
209
+ t.tr do |tr|
210
+ tr.td **EXAMPLE_TBL_ATTR do |td|
211
+ td << example_label(node)
212
+ end
213
+ tr.td **{ valign: "top", class: "example" } do |td|
214
+ node.children.each { |n| parse(n, td) unless n.name == "name" }
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ def error_parse(node, out)
221
+ case node.name
222
+ when "recommendation" then recommendation_parse(node, out)
223
+ when "requirement" then requirement_parse(node, out)
224
+ when "permission" then permission_parse(node, out)
225
+ else
226
+ super
227
+ end
228
+ end
229
+
230
+ def anchor_names(docxml)
231
+ super
232
+ recommendation_anchor_names(docxml)
233
+ requirement_anchor_names(docxml)
234
+ permission_anchor_names(docxml)
235
+ end
236
+
237
+ def recommendation_anchor_names(docxml)
238
+ docxml.xpath(ns("//recommendation")).each_with_index do |x, i|
239
+ @anchors[x["id"]] = anchor_struct(i+1, nil, "Recommendation", "recommendation")
240
+ end
241
+ end
242
+
243
+ def requirement_anchor_names(docxml)
244
+ docxml.xpath(ns("//requirement")).each_with_index do |x, i|
245
+ @anchors[x["id"]] = anchor_struct(i+1, nil, "Requirement", "requirement")
246
+ end
247
+ end
248
+
249
+ def permission_anchor_names(docxml)
250
+ docxml.xpath(ns("//permission")).each_with_index do |x, i|
251
+ @anchors[x["id"]] = anchor_struct(i+1, nil, "Permission", "permission")
252
+ end
253
+ end
254
+
255
+ def recommend_table_attr(node)
256
+ attr_code(id: node["id"], class: "recommend",
257
+ cellspacing: 0, cellpadding: 0,
258
+ style: "border-collapse:collapse" )
259
+ end
260
+
261
+ REQ_TBL_ATTR =
262
+ { valign: "top", class: "example_label",
263
+ style: "width:100.0pt;padding:0 0 0 1em;margin-left:0pt" }.freeze
264
+
265
+ def recommend_name_parse(node, div)
266
+ name = node&.at(ns("./name"))&.text or return
267
+ div.p do |p|
268
+ p.b name
269
+ end
270
+ end
271
+
272
+ def recommendation_parse(node, out)
273
+ out.table **recommend_table_attr(node) do |t|
274
+ t.tr do |tr|
275
+ tr.td **REQ_TBL_ATTR do |td|
276
+ td << recommendation_label(node)
277
+ end
278
+ tr.td **{ valign: "top", class: "recommend" } do |td|
279
+ recommend_name_parse(node, td)
280
+ node.children.each { |n| parse(n, td) unless n.name == "name" }
281
+ end
282
+ end
283
+ end
284
+ end
285
+
286
+ def recommendation_label(node)
287
+ n = get_anchors[node["id"]]
288
+ return "Recommendation" if n.nil? || n[:label].empty?
289
+ l10n("#{"Recommendation"} #{n[:label]}")
290
+ end
291
+
292
+ def requirement_parse(node, out)
293
+ out.table **recommend_table_attr(node) do |t|
294
+ t.tr do |tr|
295
+ tr.td **REQ_TBL_ATTR do |td|
296
+ td << requirement_label(node)
297
+ end
298
+ tr.td **{ valign: "top", class: "recommend" } do |td|
299
+ recommend_name_parse(node, td)
300
+ node.children.each { |n| parse(n, td) unless n.name == "name" }
301
+ end
302
+ end
303
+ end
304
+ end
305
+
306
+ def requirement_label(node)
307
+ n = get_anchors[node["id"]]
308
+ return "Requirement" if n.nil? || n[:label].empty?
309
+ l10n("#{"Requirement"} #{n[:label]}")
310
+ end
311
+
312
+ def permission_parse(node, out)
313
+ out.table **recommend_table_attr(node) do |t|
314
+ t.tr do |tr|
315
+ tr.td **REQ_TBL_ATTR do |td|
316
+ td << permission_label(node)
317
+ end
318
+ tr.td **{ valign: "top", class: "recommend" } do |td|
319
+ recommend_name_parse(node, td)
320
+ node.children.each { |n| parse(n, td) unless n.name == "name" }
321
+ end
322
+ end
323
+ end
324
+ end
325
+
326
+ def permission_label(node)
327
+ n = get_anchors[node["id"]]
328
+ return "Permission" if n.nil? || n[:label].empty?
329
+ l10n("#{"Permission"} #{n[:label]}")
330
+ end
331
+
332
+ def initial_anchor_names(d)
333
+ @prefacenum = 0
334
+ preface_names(d.at(ns("//preface/abstract")))
335
+ @prefacenum += 1 if d.at(ns("//keyword"))
336
+ preface_names(d.at(ns("//foreword")))
337
+ #preface_names(d.at(ns("//introduction")))
338
+ @prefacenum += 1 if d.at(ns(SUBMITTINGORGS))
339
+ preface_names(d.at(ns("//submitters")))
340
+ sequential_asset_names(d.xpath(ns("//preface/abstract | //foreword | //introduction | //submitters")))
341
+ n = section_names(d.at(ns("//clause[title = 'Scope']")), 0, 1)
342
+ n = section_names(d.at(ns("//clause[title = 'Conformance']")), n, 1)
343
+ n = section_names(d.at(ns(
344
+ "//references[title = 'Normative References' or title = 'Normative references']")), n, 1)
345
+ n = section_names(d.at(ns("//sections/terms | "\
346
+ "//sections/clause[descendant::terms]")), n, 1)
347
+ n = section_names(d.at(ns("//sections/definitions")), n, 1)
348
+ middle_section_asset_names(d)
349
+ clause_names(d, n)
350
+ termnote_anchor_names(d)
351
+ termexample_anchor_names(d)
352
+ end
353
+ end
354
+ end
355
+ end
@@ -0,0 +1 @@
1
+ foreword: Preface
@@ -0,0 +1,102 @@
1
+ require "isodoc"
2
+ require "iso-639"
3
+
4
+ module IsoDoc
5
+ module Ogc
6
+
7
+ class Metadata < IsoDoc::Metadata
8
+ def initialize(lang, script, labels)
9
+ super
10
+ set(:status, "XXX")
11
+ end
12
+
13
+ def title(isoxml, _out)
14
+ main = isoxml&.at(ns("//bibdata/title[@language='en']"))&.text
15
+ set(:doctitle, main)
16
+ end
17
+
18
+ def subtitle(_isoxml, _out)
19
+ nil
20
+ end
21
+
22
+ def author(isoxml, _out)
23
+ tc = isoxml.at(ns("//bibdata/editorialgroup/committee"))
24
+ set(:tc, tc.text) if tc
25
+ authors = isoxml.xpath(ns("//bibdata/contributor[role/@type = 'author']/person/name"))
26
+ set(:authors, extract_person_names(authors))
27
+ editors = isoxml.xpath(ns("//bibdata/contributor[role/@type = 'editor']/person/name"))
28
+ set(:editors, extract_person_names(editors))
29
+ end
30
+
31
+ def extract_person_names(authors)
32
+ ret = []
33
+ authors.each do |a|
34
+ if a.at(ns("./completename"))
35
+ ret << a.at(ns("./completename")).text
36
+ else
37
+ fn = []
38
+ forenames = a.xpath(ns("./forename"))
39
+ forenames.each { |f| fn << f.text }
40
+ surname = a&.at(ns("./surname"))&.text
41
+ ret << fn.join(" ") + " " + surname
42
+ end
43
+ end
44
+ ret
45
+ end
46
+
47
+ def docid(isoxml, _out)
48
+ set(:docnumber, isoxml&.at(ns("//bibdata/docidentifier[@type = 'ogc-internal']"))&.text)
49
+ set(:externalid, isoxml&.at(ns("//bibdata/docidentifier[@type = 'ogc-external']"))&.text)
50
+ end
51
+
52
+ def status_print(status)
53
+ status.split(/-/).map{ |w| w.capitalize }.join(" ")
54
+ end
55
+
56
+ def status_abbr(status)
57
+ end
58
+
59
+ def keywords(isoxml, _out)
60
+ keywords = []
61
+ isoxml.xpath(ns("//bibdata/keyword")).each do |kw|
62
+ keywords << kw.text
63
+ end
64
+ set(:keywords, keywords)
65
+ end
66
+
67
+ def version(isoxml, _out)
68
+ super
69
+ revdate = get[:revdate]
70
+ set(:revdate_monthyear, monthyr(revdate))
71
+ set(:edition, isoxml&.at(ns("//version/edition"))&.text)
72
+ set(:language, ISO_639.find_by_code(isoxml&.at(ns("//bibdata/language"))&.text))
73
+ end
74
+
75
+ MONTHS = {
76
+ "01": "January",
77
+ "02": "February",
78
+ "03": "March",
79
+ "04": "April",
80
+ "05": "May",
81
+ "06": "June",
82
+ "07": "July",
83
+ "08": "August",
84
+ "09": "September",
85
+ "10": "October",
86
+ "11": "November",
87
+ "12": "December",
88
+ }.freeze
89
+
90
+ def monthyr(isodate)
91
+ m = /(?<yr>\d\d\d\d)-(?<mo>\d\d)/.match isodate
92
+ return isodate unless m && m[:yr] && m[:mo]
93
+ return "#{MONTHS[m[:mo].to_sym]} #{m[:yr]}"
94
+ end
95
+
96
+ def url(xml, _out)
97
+ super
98
+ a = xml.at(ns("//bibdata/source[@type = 'previous']")) and set(:previousuri, a.text)
99
+ end
100
+ end
101
+ end
102
+ end