metanorma-nist 0.0.7 → 0.0.8

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