metanorma-nist 0.0.7 → 0.0.8

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.
@@ -9,7 +9,7 @@
9
9
 
10
10
  <authority2>
11
11
  <p align="center">National Institute of Standards and Technology {{ docidentifier_long | remove: "NIST " }} <br/>
12
- Natl. Inst. Stand. Technol. {{ docidentifier | remove: "NIST " }}, ({{ revdate_monthyear }}) <br/>
12
+ Natl. Inst. Stand. Technol. {{ docidentifier | remove: "NIST " | replace: " Volume ", " Vol. " }}, ({{ revdate_monthyear }}) <br/>
13
13
  CODEN: NSPUE2</p>
14
14
 
15
15
  {% if doi %}
@@ -46,9 +46,11 @@ CODEN: NSPUE2</p>
46
46
  <p align="center"><strong>Comments on this publication may be submitted to:</strong></p>
47
47
 
48
48
  <p align="center">National Institute of Standards and Technology <br/>
49
- Attn: Computer Security Division, Information Technology Laboratory <br/>
50
- 100 Bureau Drive (Mail Stop 8930) Gaithersburg, MD 20899-8930 <br/>
51
- Email: <link target="mailto:{{ email }}"/></p>
49
+ Attn: {{ nist_division }} <br/>
50
+ {{ nist_division_address }} <br/>
51
+ {% if email %}
52
+ Email: <link target="mailto:{{ email }}"/>
53
+ {% endif %}</p>
52
54
 
53
55
  <p align="center">All comments are subject to release under the Freedom of Information Act (FOIA).</p>
54
56
  </authority5>
@@ -0,0 +1,434 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+ require "fileutils"
4
+
5
+ module IsoDoc
6
+ module NIST
7
+ module BaseConvert
8
+ def abstract(isoxml, out)
9
+ f = isoxml.at(ns("//preface/abstract")) || return
10
+ #page_break(out)
11
+ out.div **attr_code(id: f["id"]) do |s|
12
+ clause_name(nil, @abstract_lbl, s, class: "AbstractTitle")
13
+ f.elements.each { |e| parse(e, s) unless e.name == "title" }
14
+ end
15
+ end
16
+
17
+ def keywords(_docxml, out)
18
+ kw = @meta.get[:keywords]
19
+ kw.empty? and return
20
+ out.div **{ class: "Section3" } do |div|
21
+ clause_name(nil, "Keywords", div, class: "IntroTitle")
22
+ div.p kw.sort.join("; ")
23
+ end
24
+ end
25
+
26
+ FRONT_CLAUSE = "//*[parent::preface][not(local-name() = 'abstract')]".freeze
27
+
28
+ # All "[preface]" sections should have class "IntroTitle" to prevent
29
+ # page breaks
30
+ # But for the Exec Summary
31
+ def preface(isoxml, out)
32
+ isoxml.xpath(ns(FRONT_CLAUSE)).each do |c|
33
+ foreword(isoxml, out) and next if c.name == "foreword"
34
+ authority_parse(c, out) and next if c.name == "authority"
35
+ next if skip_render(c, isoxml)
36
+ title = c&.at(ns("./title"))
37
+ patent = ["Call for Patent Claims", "Patent Disclosure Notice"].include? title&.text
38
+ out.div **attr_code(id: c["id"]) do |s|
39
+ page_break(s) if patent
40
+ clause_name(get_anchors[c['id']][:label], title&.content, s,
41
+ class: (c.name == "executivesummary") ? "NormalTitle" :
42
+ "IntroTitle")
43
+ c.elements.reject { |c1| c1.name == "title" }.each do |c1|
44
+ parse(c1, s)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def skip_render(c, isoxml)
51
+ return false unless c.name == "reviewernote"
52
+ status = isoxml&.at(ns("//bibdata/status/stage"))&.text
53
+ return true if status.nil?
54
+ /^final/.match status
55
+ end
56
+
57
+ def term_defs_boilerplate(div, source, term, preface)
58
+ if source.empty? && term.nil?
59
+ div << @no_terms_boilerplate
60
+ else
61
+ div << term_defs_boilerplate_cont(source, term)
62
+ end
63
+ end
64
+
65
+ def i18n_init(lang, script)
66
+ super
67
+ end
68
+
69
+ def fileloc(loc)
70
+ File.join(File.dirname(__FILE__), loc)
71
+ end
72
+
73
+ def requirement_cleanup(docxml)
74
+ docxml.xpath("//div[@class = 'recommend' or @class = 'require' "\
75
+ "or @class = 'permission'][title]").each do |d|
76
+ title = d.at("./title")
77
+ title.name = "b"
78
+ n = title.next_element
79
+ n&.children&.first&.add_previous_sibling(" ")
80
+ n&.children&.first&.add_previous_sibling(title.remove)
81
+ end
82
+ docxml
83
+ end
84
+
85
+ def figure_parse(node, out)
86
+ return pseudocode_parse(node, out) if node["type"] == "pseudocode"
87
+ super
88
+ end
89
+
90
+ def dl_parse(node, out)
91
+ return glossary_parse(node, out) if node["type"] == "glossary"
92
+ super
93
+ end
94
+
95
+ def glossary_parse(node, out)
96
+ out.dl **attr_code(id: node["id"], class: "glossary") do |v|
97
+ node.elements.select { |n| dt_dd? n }.each_slice(2) do |dt, dd|
98
+ v.dt **attr_code(id: dt["id"]) do |term|
99
+ dt_parse(dt, term)
100
+ end
101
+ v.dd **attr_code(id: dd["id"]) do |listitem|
102
+ dd.children.each { |n| parse(n, listitem) }
103
+ end
104
+ end
105
+ end
106
+ node.elements.reject { |n| dt_dd? n }.each { |n| parse(n, out) }
107
+ end
108
+
109
+ def error_parse(node, out)
110
+ case node.name
111
+ when "nistvariable" then nistvariable_parse(node, out)
112
+ when "recommendation" then recommendation_parse(node, out)
113
+ when "requirement" then requirement_parse(node, out)
114
+ when "permission" then permission_parse(node, out)
115
+ when "errata" then errata_parse(node, out)
116
+ when "authority" then authority_parse(node, out)
117
+ when "authority1" then authority1_parse(node, out, "authority1")
118
+ when "authority2" then authority1_parse(node, out, "authority2")
119
+ when "authority3" then authority1_parse(node, out, "authority3")
120
+ when "authority4" then authority1_parse(node, out, "authority4")
121
+ when "authority5" then authority1_parse(node, out, "authority5")
122
+ else
123
+ super
124
+ end
125
+ end
126
+
127
+ def authority_parse(node, out)
128
+ out.div **{class: "authority"} do |s|
129
+ node.children.each do |n|
130
+ if n.name == "title"
131
+ s.h1 do |h|
132
+ n.children.each { |nn| parse(nn, h) }
133
+ end
134
+ else
135
+ parse(n, s)
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ def authority1_parse(node, out, classname)
142
+ out.div **{class: classname} do |s|
143
+ node.children.each do |n|
144
+ if n.name == "title"
145
+ s.h2 do |h|
146
+ n.children.each { |nn| parse(nn, h) }
147
+ end
148
+ else
149
+ parse(n, s)
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ def nistvariable_parse(node, out)
156
+ out.span **{class: "nistvariable"} do |s|
157
+ node.children.each { |n| parse(n, s) }
158
+ end
159
+ end
160
+
161
+ def recommendation_parse(node, out)
162
+ name = node["type"]
163
+ out.div **{ class: "recommend" } do |t|
164
+ t.title { |b| b << "Recommendation #{get_anchors[node['id']][:label]}:" }
165
+ node.children.each do |n|
166
+ parse(n, t)
167
+ end
168
+ end
169
+ end
170
+
171
+ def requirement_parse(node, out)
172
+ name = node["type"]
173
+ out.div **{ class: "require" } do |t|
174
+ t.title { |b| b << "Requirement #{get_anchors[node['id']][:label]}:" }
175
+ node.children.each do |n|
176
+ parse(n, t)
177
+ end
178
+ end
179
+ end
180
+
181
+ def permission_parse(node, out)
182
+ name = node["type"]
183
+ out.div **{ class: "permission" } do |t|
184
+ t.title { |b| b << "Permission #{get_anchors[node['id']][:label]}:" }
185
+ node.children.each do |n|
186
+ parse(n, t)
187
+ end
188
+ end
189
+ end
190
+
191
+ def errata_parse(node, out)
192
+ out.a **{ name: "errata_XYZZY" }
193
+ out.table **make_table_attr(node) do |t|
194
+ t.thead do |h|
195
+ h.tr do |tr|
196
+ %w(Date Type Change Pages).each do |hdr|
197
+ tr.th hdr
198
+ end
199
+ end
200
+ end
201
+ t.tbody do |b|
202
+ node.xpath(ns("./row")).each do |row|
203
+ b.tr do |tr|
204
+ tr.td do |td|
205
+ row&.at(ns("./date"))&.children.each do |n|
206
+ parse(n, td)
207
+ end
208
+ end
209
+ tr.td do |td|
210
+ row&.at(ns("./type"))&.children.each do |n|
211
+ parse(n, td)
212
+ end
213
+ end
214
+ tr.td do |td|
215
+ row&.at(ns("./change"))&.children.each do |n|
216
+ parse(n, td)
217
+ end
218
+ end
219
+ tr.td do |td|
220
+ row&.at(ns("./pages"))&.children.each do |n|
221
+ parse(n, td)
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ MIDDLE_CLAUSE = "//clause[parent::sections] | "\
231
+ "//terms[parent::sections]".freeze
232
+
233
+ def middle(isoxml, out)
234
+ # NIST documents don't repeat the title
235
+ #middle_title(out)
236
+ clause isoxml, out
237
+ bibliography isoxml, out
238
+ annex isoxml, out
239
+ end
240
+
241
+ def info(isoxml, out)
242
+ @meta.keywords isoxml, out
243
+ @meta.series isoxml, out
244
+ @meta.commentperiod isoxml, out
245
+ @meta.note isoxml, out
246
+ super
247
+ end
248
+
249
+ SECTIONS_XPATH =
250
+ "//foreword | //introduction | //reviewnote | //executivesummary | //annex | "\
251
+ "//sections/clause | //bibliography/references | "\
252
+ "//bibliography/clause".freeze
253
+
254
+ def initial_anchor_names(d)
255
+ d.xpath("//xmlns:preface/child::*").each do |c|
256
+ preface_names(c)
257
+ end
258
+ sequential_asset_names(d.xpath("//xmlns:preface/child::*"))
259
+ clause_names(d, 0)
260
+ middle_section_asset_names(d)
261
+ termnote_anchor_names(d)
262
+ termexample_anchor_names(d)
263
+ end
264
+
265
+ def back_anchor_names(docxml)
266
+ docxml.xpath(ns("//annex")).each_with_index do |c, i|
267
+ annex_names(c, (65 + i).chr.to_s)
268
+ end
269
+ docxml.xpath(ns("//bibliography/clause | "\
270
+ "//bibliography/references")).each do |b|
271
+ preface_names(b)
272
+ end
273
+ docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |ref|
274
+ reference_names(ref)
275
+ end
276
+ end
277
+
278
+ def middle_section_asset_names(d)
279
+ middle_sections =
280
+ "//xmlns:preface/child::* | //xmlns:sections/child::*"
281
+ sequential_asset_names(d.xpath(middle_sections))
282
+ end
283
+
284
+ def sequential_asset_names(clause)
285
+ super
286
+ sequential_permission_names(clause)
287
+ sequential_requirement_names(clause)
288
+ sequential_recommendation_names(clause)
289
+ end
290
+
291
+ def sequential_permission_names(clause)
292
+ clause.xpath(ns(".//permission")).each_with_index do |t, i|
293
+ next if t["id"].nil? || t["id"].empty?
294
+ @anchors[t["id"]] = anchor_struct(i + 1, t, "Permission", "permission")
295
+ end
296
+ end
297
+
298
+ def sequential_requirement_names(clause)
299
+ clause.xpath(ns(".//requirement")).each_with_index do |t, i|
300
+ next if t["id"].nil? || t["id"].empty?
301
+ @anchors[t["id"]] = anchor_struct(i + 1, t, "Requirement", "requirement")
302
+ end
303
+ end
304
+
305
+ def sequential_recommendation_names(clause)
306
+ clause.xpath(ns(".//recommendation")).each_with_index do |t, i|
307
+ next if t["id"].nil? || t["id"].empty?
308
+ @anchors[t["id"]] = anchor_struct(i + 1, t, "Recommendation", "recommendation")
309
+ end
310
+ end
311
+
312
+
313
+ def hierarchical_asset_names(clause, num)
314
+ super
315
+ hierarchical_permission_names(clause, num)
316
+ hierarchical_requirement_names(clause, num)
317
+ hierarchical_recommendation_names(clause, num)
318
+ end
319
+
320
+ def hierarchical_permission_names(clause, num)
321
+ clause.xpath(ns(".//permission")).each_with_index do |t, i|
322
+ next if t["id"].nil? || t["id"].empty?
323
+ @anchors[t["id"]] = anchor_struct("#{num}.#{i + 1}",
324
+ t, "Permission", "permission")
325
+ end
326
+ end
327
+
328
+ def hierarchical_requirement_names(clause, num)
329
+ clause.xpath(ns(".//requirement")).each_with_index do |t, i|
330
+ next if t["id"].nil? || t["id"].empty?
331
+ @anchors[t["id"]] = anchor_struct("#{num}.#{i + 1}",
332
+ t, "Requirement", "requirement")
333
+ end
334
+ end
335
+
336
+ def hierarchical_recommendation_names(clause, num)
337
+ clause.xpath(ns(".//recommendation")).each_with_index do |t, i|
338
+ next if t["id"].nil? || t["id"].empty?
339
+ @anchors[t["id"]] = anchor_struct("#{num}.#{i + 1}",
340
+ t, "Recommendation", "recommendation")
341
+ end
342
+ end
343
+
344
+ def clause_names(docxml, sect_num)
345
+ q = "//xmlns:sections/child::*"
346
+ docxml.xpath(q).each_with_index do |c, i|
347
+ section_names(c, (i + sect_num), 1)
348
+ end
349
+ end
350
+
351
+ def get_linkend(node)
352
+ link = anchor_linkend(node, docid_l10n(node["target"] || "[#{node['citeas']}]"))
353
+ link += eref_localities(node.xpath(ns("./locality")), link)
354
+ contents = node.children.select { |c| c.name != "locality" }
355
+ return link if contents.nil? || contents.empty?
356
+ Nokogiri::XML::NodeSet.new(node.document, contents).to_xml
357
+ # so not <origin bibitemid="ISO7301" citeas="ISO 7301">
358
+ # <locality type="section"><reference>3.1</reference></locality></origin>
359
+ end
360
+
361
+ def load_yaml(lang, script)
362
+ y = if @i18nyaml then YAML.load_file(@i18nyaml)
363
+ elsif lang == "en"
364
+ YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
365
+ else
366
+ YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
367
+ end
368
+ super.merge(y)
369
+ end
370
+
371
+ def annex_name_lbl(clause, num)
372
+ l10n("<b>#{@annex_lbl} #{num}</b>")
373
+ end
374
+
375
+ def annex_name(annex, name, div)
376
+ div.h1 **{ class: "Annex" } do |t|
377
+ t << "#{get_anchors[annex['id']][:label]} &mdash; "
378
+ t.b do |b|
379
+ if @bibliographycount == 1 && annex.at(ns("./references"))
380
+ b << "References"
381
+ else
382
+ name&.children&.each { |c2| parse(c2, b) }
383
+ end
384
+ end
385
+ end
386
+ end
387
+
388
+ def hiersep
389
+ "-"
390
+ end
391
+
392
+ def annex_names(clause, num)
393
+ @anchors[clause["id"]] = { label: annex_name_lbl(clause, num), type: "clause",
394
+ xref: "#{@annex_lbl} #{num}", level: 1 }
395
+ clause.xpath(ns("./clause | ./terms | ./term | ./references")).each_with_index do |c, i|
396
+ annex_names1(c, "#{num}.#{i + 1}", 2)
397
+ end
398
+ hierarchical_asset_names(clause, num)
399
+ end
400
+
401
+ def annex_names1(clause, num, level)
402
+ @anchors[clause["id"]] = { label: num, xref: "#{@annex_lbl} #{num}",
403
+ level: level, type: "clause" }
404
+ clause.xpath(ns("./clause | ./terms | ./term | ./references")).each_with_index do |c, i|
405
+ annex_names1(c, "#{num}.#{i + 1}", level + 1)
406
+ end
407
+ end
408
+
409
+ def terms_parse(node, out)
410
+ out.div **attr_code(id: node["id"]) do |div|
411
+ node.at(ns("./title")) and
412
+ clause_parse_title(node, div, node.at(ns("./title")), out)
413
+ term_defs_boilerplate(div, node.xpath(ns(".//termdocsource")),
414
+ node.at(ns(".//term")), node.at(ns("./p")))
415
+ node.elements.each do |e|
416
+ parse(e, div) unless %w{title source}.include? e.name
417
+ end
418
+ end
419
+ end
420
+
421
+ def bibliography_parse(node, out)
422
+ title = node&.at(ns("./title"))&.text || ""
423
+ out.div do |div|
424
+ node.parent.name == "annex" or
425
+ div.h2 title, **{ class: "Section3" }
426
+ node.elements.reject do |e|
427
+ ["reference", "title", "bibitem"].include? e.name
428
+ end.each { |e| parse(e, div) }
429
+ biblio_list(node, div, true)
430
+ end
431
+ end
432
+ end
433
+ end
434
+ end