metanorma-nist 1.0.8 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +0 -1
  3. data/.github/workflows/ubuntu.yml +10 -7
  4. data/.github/workflows/windows.yml +0 -1
  5. data/README.adoc +22 -0
  6. data/Rakefile +2 -0
  7. data/lib/asciidoctor/nist/biblio.rng +14 -4
  8. data/lib/asciidoctor/nist/cleanup.rb +5 -4
  9. data/lib/asciidoctor/nist/converter.rb +13 -18
  10. data/lib/asciidoctor/nist/front.rb +1 -0
  11. data/lib/asciidoctor/nist/front_id.rb +73 -23
  12. data/lib/asciidoctor/nist/isodoc.rng +444 -1
  13. data/lib/asciidoctor/nist/reqt.rng +23 -0
  14. data/lib/isodoc/nist/base_convert.rb +66 -62
  15. data/lib/isodoc/nist/html/_coverpage.scss +1 -1
  16. data/lib/isodoc/nist/html/html_nist_titlepage.html +1 -1
  17. data/lib/isodoc/nist/html/nist.scss +1 -2
  18. data/lib/isodoc/nist/html/nist_cswp.scss +1 -2
  19. data/lib/isodoc/nist/html/wordstyle.scss +0 -1
  20. data/lib/isodoc/nist/html/wordstyle_cswp.scss +0 -1
  21. data/lib/isodoc/nist/html_convert.rb +30 -68
  22. data/lib/isodoc/nist/metadata.rb +0 -6
  23. data/lib/isodoc/nist/nist.cswp.xsl +1116 -359
  24. data/lib/isodoc/nist/nist.sp.xsl +1276 -512
  25. data/lib/isodoc/nist/pdf_convert.rb +4 -15
  26. data/lib/isodoc/nist/presentation_xml_convert.rb +10 -0
  27. data/lib/isodoc/nist/refs.rb +44 -2
  28. data/lib/isodoc/nist/section.rb +56 -0
  29. data/lib/isodoc/nist/word_convert.rb +2 -42
  30. data/lib/isodoc/nist/word_convert_toc.rb +2 -2
  31. data/lib/isodoc/nist/{xrefs.rb → xref.rb} +2 -2
  32. data/lib/metanorma-nist.rb +2 -0
  33. data/lib/metanorma/nist/processor.rb +6 -8
  34. data/lib/metanorma/nist/version.rb +1 -1
  35. data/metanorma-nist.gemspec +4 -2
  36. metadata +41 -12
@@ -30,9 +30,22 @@
30
30
  <data type="boolean"/>
31
31
  </attribute>
32
32
  </optional>
33
+ <optional>
34
+ <attribute name="number"/>
35
+ </optional>
33
36
  <optional>
34
37
  <attribute name="subsequence"/>
35
38
  </optional>
39
+ <optional>
40
+ <attribute name="keep-with-next">
41
+ <data type="boolean"/>
42
+ </attribute>
43
+ </optional>
44
+ <optional>
45
+ <attribute name="keep-lines-together">
46
+ <data type="boolean"/>
47
+ </attribute>
48
+ </optional>
36
49
  <attribute name="id">
37
50
  <data type="ID"/>
38
51
  </attribute>
@@ -141,6 +154,16 @@
141
154
  <data type="boolean"/>
142
155
  </attribute>
143
156
  </optional>
157
+ <optional>
158
+ <attribute name="keep-with-next">
159
+ <data type="boolean"/>
160
+ </attribute>
161
+ </optional>
162
+ <optional>
163
+ <attribute name="keep-lines-together">
164
+ <data type="boolean"/>
165
+ </attribute>
166
+ </optional>
144
167
  <oneOrMore>
145
168
  <ref name="BasicBlock"/>
146
169
  </oneOrMore>
@@ -1,19 +1,19 @@
1
1
  require "isodoc"
2
2
  require_relative "metadata"
3
- require_relative "xrefs"
3
+ require_relative "xref"
4
4
  require_relative "refs"
5
+ require_relative "section"
5
6
  require "fileutils"
6
7
 
7
8
  module IsoDoc
8
9
  module NIST
9
10
  module BaseConvert
10
- def abstract(isoxml, out)
11
- f = isoxml.at(ns("//preface/abstract")) || return
12
- #page_break(out)
13
- out.div **attr_code(id: f["id"]) do |s|
14
- clause_name(nil, @abstract_lbl, s, class: "AbstractTitle")
15
- f.elements.each { |e| parse(e, s) unless e.name == "title" }
16
- end
11
+ def metadata_init(lang, script, labels)
12
+ @meta = Metadata.new(lang, script, labels)
13
+ end
14
+
15
+ def xref_init(lang, script, klass, labels, options)
16
+ @xrefs = Xref.new(lang, script, klass, labels, options)
17
17
  end
18
18
 
19
19
  def keywords(_docxml, out)
@@ -25,27 +25,8 @@ module IsoDoc
25
25
  end
26
26
  end
27
27
 
28
- FRONT_CLAUSE = "//*[parent::preface][not(local-name() = 'abstract' or local-name() = 'foreword')]".freeze
29
-
30
- # All "[preface]" sections should have class "IntroTitle" to prevent
31
- # page breaks
32
- # But for the Exec Summary
33
- def preface(isoxml, out)
34
- isoxml.xpath(ns(FRONT_CLAUSE)).each do |c|
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(anchor(c['id'], :label), title, 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
28
+ FRONT_CLAUSE = "//*[parent::preface][not(local-name() = 'abstract' or "\
29
+ "local-name() = 'foreword')]".freeze
49
30
 
50
31
  def skip_render(c, isoxml)
51
32
  return false unless c.name == "reviewernote"
@@ -121,7 +102,7 @@ module IsoDoc
121
102
 
122
103
  def errata_parse(node, out)
123
104
  out.a **{ name: "errata_XYZZY" }
124
- out.table **make_table_attr(node) do |t|
105
+ out.table **table_attrs(node) do |t|
125
106
  errata_head(t)
126
107
  errata_body(t, node)
127
108
  end
@@ -153,17 +134,18 @@ module IsoDoc
153
134
  end
154
135
  end
155
136
 
156
- MIDDLE_CLAUSE = "//clause[parent::sections] | "\
157
- "//terms[parent::sections]".freeze
137
+ def middle_clause
138
+ "//clause[parent::sections] | //terms[parent::sections]"
139
+ end
158
140
 
159
141
  def middle(isoxml, out)
142
+ middle_admonitions(isoxml, out)
160
143
  clause isoxml, out
161
144
  bibliography isoxml, out
162
145
  annex isoxml, out
163
146
  end
164
147
 
165
148
  def info(isoxml, out)
166
- @meta.keywords isoxml, out
167
149
  @meta.series isoxml, out
168
150
  @meta.commentperiod isoxml, out
169
151
  @meta.note isoxml, out
@@ -176,13 +158,15 @@ module IsoDoc
176
158
  end
177
159
 
178
160
  def get_linkend(node)
179
- link = anchor_linkend(node, docid_l10n(node["target"] || wrap_brackets(node['citeas'])))
180
- link += eref_localities(node.xpath(ns("./locality | ./localityStack")), link)
181
- contents = node.children.select { |c| !%w{locality localityStack}.include? c.name }
161
+ link = anchor_linkend(node, docid_l10n(node["target"] ||
162
+ wrap_brackets(node['citeas'])))
163
+ link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
164
+ link)
165
+ contents = node.children.select do |c|
166
+ !%w{locality localityStack}.include? c.name
167
+ end
182
168
  return link if contents.nil? || contents.empty?
183
169
  Nokogiri::XML::NodeSet.new(node.document, contents).to_xml
184
- # so not <origin bibitemid="ISO7301" citeas="ISO 7301">
185
- # <locality type="section"><reference>3.1</reference></locality></origin>
186
170
  end
187
171
 
188
172
  def load_yaml(lang, script)
@@ -205,36 +189,56 @@ module IsoDoc
205
189
  end
206
190
  end
207
191
 
208
- def bibliography_parse(node, out)
209
- title = node&.at(ns("./title"))&.text || ""
210
- out.div do |div|
211
- unless suppress_biblio_title(node)
212
- anchor(node['id'], :label, false) and
213
- clause_parse_title(node, div, node.at(ns("./title")), out) or
214
- div.h2 title, **{ class: "Section3" }
215
- end
216
- biblio_list(node, div, true)
192
+ def termref_parse(node, out)
193
+ end
194
+
195
+ def term_cleanup(docxml)
196
+ docxml.xpath("//table[@class = 'terms_dl']").each do |d|
197
+ prev = d.previous_element
198
+ next unless prev && prev.name == "table" &&
199
+ prev["class"] == "terms_dl"
200
+ d.children.each { |n| prev.add_child(n.remove) }
201
+ d.remove
217
202
  end
203
+ docxml
218
204
  end
219
205
 
220
- def suppress_biblio_title(node)
221
- return false unless node.parent.name == "annex"
222
- return false if node.parent.xpath("./references | ./clause | "\
223
- "./terms | ./definitions").size > 1
224
- title1 = node&.at(ns("./title"))&.text
225
- return true unless title1
226
- title2 = node&.parent&.at(ns("./title"))&.text
227
- title1&.casecmp(title2) == 0
206
+ def term_and_termref_parse(node, dt)
207
+ pref = node.at(ns("./preferred"))
208
+ source = node.xpath(ns("./termsource"))
209
+ pref.children.each { |n| parse(n, dt) }
210
+ return if source.empty?
211
+ dt << "<br/>"
212
+ source.each_with_index do |s, i|
213
+ i > 0 and dt << "; "
214
+ s.elements.each { |n| parse(n, dt) }
215
+ end
228
216
  end
229
217
 
230
- def foreword(isoxml, out)
231
- f = isoxml.at(ns("//foreword")) || return
232
- out.div **attr_code(id: f["id"]) do |s|
233
- title = f.at(ns("./title"))
234
- s.h1(**{ class: "ForewordTitle" }) do |h1|
235
- title and title.children.each { |e| parse(e, h1) }
218
+ def term_rest_parse(node, dd)
219
+ set_termdomain("")
220
+ node.children.each do |n|
221
+ parse(n, dd) unless %w(preferred termsource).include?(n.name)
222
+ end
223
+ end
224
+
225
+ def modification_parse(node, out)
226
+ out << @modified_lbl
227
+ node.at(ns("./p[text()[normalize-space() != '']]")) and
228
+ out << " &mdash; "
229
+ node.at(ns("./p")).children.each { |n| parse(n, out) }
230
+ end
231
+
232
+ def annex_name(annex, name, div)
233
+ div.h1 **{ class: "Annex" } do |t|
234
+ t << "#{@xrefs.anchor(annex['id'], :label)} &mdash; "
235
+ t.b do |b|
236
+ if @bibliographycount == 1 && annex.at(ns("./references"))
237
+ b << "References"
238
+ else
239
+ name&.children&.each { |c2| parse(c2, b) }
240
+ end
236
241
  end
237
- f.elements.each { |e| parse(e, s) unless e.name == "title" }
238
242
  end
239
243
  end
240
244
  end
@@ -66,7 +66,7 @@ img#NIST-logo {
66
66
  height: auto;
67
67
  }
68
68
 
69
- .authors-container {
69
+ .authors-container, .currency {
70
70
  margin-top: 2em;
71
71
  }
72
72
 
@@ -163,7 +163,7 @@
163
163
 
164
164
 
165
165
  {% unless unpublished %}
166
- <div class="coverpage-logo">
166
+ <div class="currency">
167
167
  <span>{{ issueddate_monthyear }}</span>
168
168
  {%if confirmeddate and confirmeddate != "XXX" %}
169
169
  <br/>Publication is current as of {{ confirmeddate_MMMddyyyy }}
@@ -693,7 +693,7 @@ div.Admonition {
693
693
  mso-ansi-language:EN-AU;
694
694
  }
695
695
 
696
- div Admonotion p {
696
+ div.Admonition p {
697
697
  margin-top:6.0pt;margin-right:0cm;
698
698
  margin-bottom:6.0pt;margin-left:0cm;text-align:left;mso-pagination:widow-orphan;
699
699
  mso-hyphenate:auto;background:#dddddd;mso-layout-grid-align:auto;mso-vertical-align-alt:
@@ -1008,4 +1008,3 @@ table.dl
1008
1008
  div.recommend {
1009
1009
  margin-left: 2cm;
1010
1010
  }
1011
-
@@ -643,7 +643,7 @@ div.Admonition {
643
643
  mso-ansi-language:EN-AU;
644
644
  }
645
645
 
646
- div Admonotion p {
646
+ div.Admonition p {
647
647
  margin-top:6.0pt;margin-right:0cm;
648
648
  margin-bottom:6.0pt;margin-left:0cm;text-align:left;mso-pagination:widow-orphan;
649
649
  mso-hyphenate:auto;background:#dddddd;mso-layout-grid-align:auto;mso-vertical-align-alt:
@@ -953,4 +953,3 @@ table.dl
953
953
  div.recommend {
954
954
  margin-left: 2cm;
955
955
  }
956
-
@@ -1346,4 +1346,3 @@ ol
1346
1346
  ul
1347
1347
  {margin-bottom:0cm;
1348
1348
  margin-left:18pt;}
1349
-
@@ -1024,4 +1024,3 @@ ol
1024
1024
  ul
1025
1025
  {margin-bottom:0cm;
1026
1026
  margin-left:18pt;}
1027
-
@@ -20,9 +20,11 @@ module IsoDoc
20
20
 
21
21
  def default_fonts(options)
22
22
  {
23
- bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Libre Baskerville",serif'),
24
- headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Libre Baskerville",serif'),
25
- monospacefont: '"Space Mono",monospace'
23
+ bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' :
24
+ '"Libre Baskerville",serif'),
25
+ headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' :
26
+ '"Libre Baskerville",serif'),
27
+ monospacefont: '"Space Mono",monospace'
26
28
  }
27
29
  end
28
30
 
@@ -35,10 +37,6 @@ module IsoDoc
35
37
  }
36
38
  end
37
39
 
38
- def metadata_init(lang, script, labels)
39
- @meta = Metadata.new(lang, script, labels)
40
- end
41
-
42
40
  def googlefonts
43
41
  <<~HEAD.freeze
44
42
  <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,600,600i" rel="stylesheet">
@@ -48,28 +46,34 @@ module IsoDoc
48
46
  end
49
47
 
50
48
  def toclevel
51
- ret = toclevel_classes.map { |l| "#{l}:not(:empty):not(.TermNum):not(.noTOC):not(.AbstractTitle):not(.IntroTitle):not(.ForewordTitle)" }
52
- <<~HEAD.freeze
49
+ ret = toclevel_classes.map do |l|
50
+ "#{l}:not(:empty):not(.TermNum):not(.noTOC):not(.AbstractTitle):"\
51
+ "not(.IntroTitle):not(.ForewordTitle)"
52
+ end
53
+ <<~HEAD.freeze
53
54
  function toclevel() { return "#{ret.join(',')}";}
54
- HEAD
55
- end
55
+ HEAD
56
+ end
56
57
 
57
58
  def html_toc(docxml)
58
- idx = docxml.at("//div[@id = 'toc']") or return docxml
59
- toc = "<ul>"
60
- path = toclevel_classes.map do |l|
61
- "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')][not(text())][not(@class = 'AbstractTitle')][not(@class = 'IntroTitle')][not(@class = 'ForewordTitle')]"
62
- end
63
- docxml.xpath(path.join(" | ")).each_with_index do |h, tocidx|
64
- h["id"] ||= "toc#{tocidx}"
65
- toc += html_toc_entry(h.name, h)
59
+ idx = docxml.at("//div[@id = 'toc']") or return docxml
60
+ toc = "<ul>"
61
+ path = toclevel_classes.map do |l|
62
+ "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')]"\
63
+ "[text()][not(@class = 'AbstractTitle')]"\
64
+ "[not(@class = 'IntroTitle')][not(@class = 'ForewordTitle')]"
65
+ end
66
+ docxml.xpath(path.join(" | ")).each_with_index do |h, tocidx|
67
+ h["id"] ||= "toc#{tocidx}"
68
+ toc += html_toc_entry(h.name, h)
69
+ end
70
+ idx.children = "#{toc}</ul>"
71
+ docxml
66
72
  end
67
- idx.children = "#{toc}</ul>"
68
- docxml
69
- end
70
73
 
71
74
  def make_body(xml, docxml)
72
- body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72", "xml:lang": "EN-US", class: "container" }
75
+ body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72",
76
+ "xml:lang": "EN-US", class: "container" }
73
77
  xml.body **body_attr do |body|
74
78
  make_body1(body, docxml)
75
79
  make_body2(body, docxml)
@@ -77,10 +81,6 @@ module IsoDoc
77
81
  end
78
82
  end
79
83
 
80
- def html_toc(docxml)
81
- docxml
82
- end
83
-
84
84
  def authority_cleanup(docxml)
85
85
  dest = docxml.at("//div[@id = 'authority']") || return
86
86
  auth = docxml.at("//div[@class = 'authority']") || return
@@ -102,6 +102,7 @@ module IsoDoc
102
102
  super
103
103
  term_cleanup(docxml)
104
104
  requirement_cleanup(docxml)
105
+ docxml
105
106
  end
106
107
 
107
108
  def make_body3(body, docxml)
@@ -117,56 +118,17 @@ module IsoDoc
117
118
  end
118
119
  end
119
120
 
120
- def bibliography(isoxml, out)
121
- f = isoxml.at(ns("//bibliography/clause | //bibliography/references")) || return
122
- page_break(out)
123
- isoxml.xpath(ns("//bibliography/clause | //bibliography/references")).each do |f|
124
- out.div do |div|
125
- div.h1 **{ class: "Section3" } do |h1|
126
- if @bibliographycount == 1 then h1 << "References"
127
- else
128
- f&.at(ns("./title"))&.children.each { |n| parse(n, h1) }
129
- end
130
- end
131
- biblio_list(f, div, false)
132
- end
133
- end
134
- end
135
-
136
- def keywords(_docxml, out)
137
- kw = @meta.get[:keywords]
138
- kw.empty? and return
139
- out.div **{ class: "Section3" } do |div|
140
- out.div do |div|
141
- clause_name(nil, "Keywords", div, class: "IntroTitle")
142
- div.p kw.sort.join("; ")
143
- end
144
- end
145
- end
146
-
147
121
  def termdef_parse(node, out)
148
- pref = node.at(ns("./preferred"))
149
122
  out.dl **{ class: "terms_dl" } do |dl|
150
123
  dl.dt do |dt|
151
- pref.children.each { |n| parse(n, dt) }
124
+ term_and_termref_parse(node, dt)
152
125
  end
153
- set_termdomain("")
154
126
  dl.dd do |dd|
155
- node.children.each { |n| parse(n, dd) unless n.name == "preferred" }
127
+ term_rest_parse(node, dd)
156
128
  end
157
129
  end
158
130
  end
159
131
 
160
- def term_cleanup(docxml)
161
- docxml.xpath("//table[@class = 'terms_dl']").each do |d|
162
- prev = d.previous_element
163
- next unless prev and prev.name == "table" and prev["class"] == "terms_dl"
164
- d.children.each { |n| prev.add_child(n.remove) }
165
- d.remove
166
- end
167
- docxml
168
- end
169
-
170
132
  include BaseConvert
171
133
  end
172
134
  end
@@ -116,12 +116,6 @@ module IsoDoc
116
116
  Date.parse(isodate).strftime("%m-%d-%Y")
117
117
  end
118
118
 
119
- def keywords(ixml, _out)
120
- keywords = []
121
- ixml.xpath(ns("//bibdata/keyword")).each { |kw| keywords << kw.text }
122
- set(:keywords, keywords)
123
- end
124
-
125
119
  def commentperiod(ixml, _out)
126
120
  from = ixml.at(ns("//bibdata/ext/commentperiod/from"))&.text
127
121
  to = ixml.at(ns("//bibdata/ext/commentperiod/to"))&.text