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