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.
- checksums.yaml +4 -4
- data/README.adoc +163 -18
- data/lib/asciidoctor/nist/biblio.rng +3 -0
- data/lib/asciidoctor/nist/boilerplate.rb +53 -3
- data/lib/asciidoctor/nist/cleanup.rb +41 -1
- data/lib/asciidoctor/nist/converter.rb +5 -6
- data/lib/asciidoctor/nist/front.rb +124 -63
- data/lib/asciidoctor/nist/isodoc.rng +38 -8
- data/lib/asciidoctor/nist/isostandard.rng +0 -8
- data/lib/asciidoctor/nist/nist.rng +145 -34
- data/lib/asciidoctor/nist/nist_intro.xml +6 -4
- data/lib/isodoc/nist/base_convert.rb +434 -0
- data/lib/isodoc/nist/html/header.html +30 -26
- data/lib/isodoc/nist/html/html_nist_titlepage.html +7 -3
- data/lib/isodoc/nist/html/word_nist_titlepage.html +1219 -155
- data/lib/isodoc/nist/html_convert.rb +7 -411
- data/lib/isodoc/nist/i18n-en.yaml +6 -1
- data/lib/isodoc/nist/metadata.rb +132 -20
- data/lib/isodoc/nist/pdf_convert.rb +19 -426
- data/lib/isodoc/nist/word_convert.rb +9 -442
- data/lib/metanorma/nist/version.rb +1 -1
- data/metanorma-nist.gemspec +1 -0
- metadata +17 -2
@@ -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:
|
50
|
-
|
51
|
-
|
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]} — "
|
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
|