metanorma-ogc 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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