metanorma-ieee 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -243,26 +243,61 @@
243
243
  </clause>
244
244
  <clause id="boilerplate-participants">
245
245
  <title>Participants</title>
246
+ <clause id="boilerplate-participants-wg">
246
247
  <p>At the time this draft {{ doctype }} was completed, the {{ working_group }} Working Group had the following membership:</p>
247
- <p align="center" type="officeholder"><strong>{{ wg_members["chair"] }}</strong>, <em>Chair</em></p>
248
- <p align="center" type="officeholder"><strong>{{ wg_members["vice-chair"] }}</strong>, <em>Vice Chair</em></p>
249
- {% if wg_members["secretary"] %}<p align="center" type="officeholder"><strong>{{ wg_members["secretary"] }}</strong>, <em>Secretary</em></p>{% endif %}
250
- {% for m in wg_members["members"] %}
251
- <p type="officemember">{{ m }}</p>
252
- {% endfor %}
253
- <p>The following members of the {{ balloting_group }} Standards Association balloting group voted on this {{ doctype }}. Balloters may have voted for approval, disapproval, or abstention.</p>
254
- {% for m in balloting_group_members %}
255
- <p type="officemember">{{ m }}</p>
256
- {% endfor %}
257
- <p>When the IEEE SA Standards Board approved this {{ doctype }} on {{ confirmed_date }}, it had the following membership:</p>
258
- <p align="center" type="officeholder"><strong>{{ std_board["chair"] }}</strong>, <em>Chair</em></p>
259
- <p align="center" type="officeholder"><strong>{{ std_board["vice-chair"] }}</strong>, <em>Vice Chair</em></p>
260
- <p align="center" type="officeholder"><strong>{{ std_board["past-chair"] }}</strong>, <em>Past Chair</em></p>
261
- <p align="center" type="officeholder"><strong>{{ std_board["secretary"] }}</strong>, <em>Secretary</em></p>
262
- {% for m in std_board["members"] %}
263
- <p type="officemember">{{ m }}</p>
264
- {% endfor %}
248
+ <membership>
249
+ <ul>
250
+ <li><dl><dt>name</dt><dd>&#x3c;Chair Name&#x3e;</dd><dt>role</dt><dd>Chair</dd></dl></li>
251
+ <li><dl><dt>name</dt><dd>&#x3c;Vice-chair Name&#x3e;</dd><dt>role</dt><dd>Vice Chair</dd></dl></li>
252
+ <li><dl><dt>name</dt><dd>Participant1</dd><dt>role</dt><dd>Member</dd></dl></li>
253
+ <li><dl><dt>name</dt><dd>Participant2</dd><dt>role</dt><dd>Member</dd></dl></li>
254
+ <li><dl><dt>name</dt><dd>Participant3</dd><dt>role</dt><dd>Member</dd></dl></li>
255
+ <li><dl><dt>name</dt><dd>Participant4</dd><dt>role</dt><dd>Member</dd></dl></li>
256
+ <li><dl><dt>name</dt><dd>Participant5</dd><dt>role</dt><dd>Member</dd></dl></li>
257
+ <li><dl><dt>name</dt><dd>Participant6</dd><dt>role</dt><dd>Member</dd></dl></li>
258
+ <li><dl><dt>name</dt><dd>Participant7</dd><dt>role</dt><dd>Member</dd></dl></li>
259
+ <li><dl><dt>name</dt><dd>Participant8</dd><dt>role</dt><dd>Member</dd></dl></li>
260
+ <li><dl><dt>name</dt><dd>Participant9</dd><dt>role</dt><dd>Member</dd></dl></li>
261
+ </ul>
262
+ </membership>
263
+ </clause>
264
+ <clause id="boilerplate-participants-bg">
265
+ <p>The following members of the {{ balloting_group_type }} {{ balloting_group }} Standards Association balloting group voted on this {{ doctype }}. Balloters may have voted for approval, disapproval, or abstention.</p>
266
+ <membership>
267
+ <ul>
268
+ <li><dl><dt>name</dt><dd>Balloter1</dd><dt>role</dt><dd>Member</dd></dl></li>
269
+ <li><dl><dt>name</dt><dd>Balloter2</dd><dt>role</dt><dd>Member</dd></dl></li>
270
+ <li><dl><dt>name</dt><dd>Balloter3</dd><dt>role</dt><dd>Member</dd></dl></li>
271
+ <li><dl><dt>name</dt><dd>Balloter4</dd><dt>role</dt><dd>Member</dd></dl></li>
272
+ <li><dl><dt>name</dt><dd>Balloter5</dd><dt>role</dt><dd>Member</dd></dl></li>
273
+ <li><dl><dt>name</dt><dd>Balloter6</dd><dt>role</dt><dd>Member</dd></dl></li>
274
+ <li><dl><dt>name</dt><dd>Balloter7</dd><dt>role</dt><dd>Member</dd></dl></li>
275
+ <li><dl><dt>name</dt><dd>Balloter8</dd><dt>role</dt><dd>Member</dd></dl></li>
276
+ <li><dl><dt>name</dt><dd>Balloter9</dd><dt>role</dt><dd>Member</dd></dl></li>
277
+ </ul>
278
+ </membership>
279
+ </clause>
280
+ <clause id="boilerplate-participants-sb">
281
+ <p>When the IEEE SA Standards Board approved this {{ doctype }} on {{ issueddate }}, it had the following membership:</p>
282
+ <membership>
283
+ <ul>
284
+ <li><dl><dt>name</dt><dd>&#x3c;Name&#x3e;</dd><dt>role</dt><dd>Chair</dd></dl></li>
285
+ <li><dl><dt>name</dt><dd>&#x3c;Name&#x3e;</dd><dt>role</dt><dd>Vice Chair</dd></dl></li>
286
+ <li><dl><dt>name</dt><dd>&#x3c;Name&#x3e;</dd><dt>role</dt><dd>Past Chair</dd></dl></li>
287
+ <li><dl><dt>name</dt><dd>&#x3c;Name&#x3e;</dd><dt>role</dt><dd>Secretary</dd></dl></li>
288
+ <li><dl><dt>name</dt><dd>SBMember1</dd><dt>role</dt><dd>Member</dd></dl></li>
289
+ <li><dl><dt>name</dt><dd>SBMember2</dd><dt>role</dt><dd>Member</dd></dl></li>
290
+ <li><dl><dt>name</dt><dd>SBMember3</dd><dt>role</dt><dd>Member</dd></dl></li>
291
+ <li><dl><dt>name</dt><dd>SBMember4</dd><dt>role</dt><dd>Member</dd></dl></li>
292
+ <li><dl><dt>name</dt><dd>SBMember5</dd><dt>role</dt><dd>Member</dd></dl></li>
293
+ <li><dl><dt>name</dt><dd>SBMember6</dd><dt>role</dt><dd>Member</dd></dl></li>
294
+ <li><dl><dt>name</dt><dd>SBMember7</dd><dt>role</dt><dd>Member</dd></dl></li>
295
+ <li><dl><dt>name</dt><dd>SBMember8</dd><dt>role</dt><dd>Member</dd></dl></li>
296
+ <li><dl><dt>name</dt><dd>SBMember9</dd><dt>role</dt><dd>Member</dd></dl></li>
297
+ </ul>
298
+ </membership>
265
299
  <p type="emeritus_sign">*Member Emeritus</p>
300
+ </clause>
266
301
  </clause>
267
302
  </legal-statement>
268
303
  <feedback-statement>
@@ -272,7 +307,7 @@
272
307
 
273
308
  <clause>
274
309
  <p>Copyright © {{ docyear }} by The Institute of Electrical and Electronics Engineers, Inc.</p>
275
- <p>All rights reserved. Published {{ issued_date }}. Printed in the United States of America.</p>
310
+ <p>All rights reserved. Published {{ issueddate }}. Printed in the United States of America.</p>
276
311
  </clause>
277
312
 
278
313
  <clause>
@@ -294,5 +329,19 @@
294
329
  <em>No part of this publication may be reproduced in any form, in an electronic retrieval system or otherwise, without the prior written permission of the publisher.</em></p>
295
330
  </clause>
296
331
  </feedback-statement>
332
+ {% if docsubtype == "Amendment" or docsubtype == "Corrigendum" %}
333
+ <note id="boilerplate_front">
334
+ <p>The editing instructions contained in this {{ docsubtype | downcase }} define how to merge the material contained therein into the existing base standard and its amendments to form the comprehensive standard.</p>
335
+ <p>The editing instructions are shown in <strong><em>bold italic</em></strong>. Four editing instructions are used: change, delete, insert, and replace. <strong><em>Change</em></strong> is used to make corrections in existing text or tables. The editing instruction specifies the location of the change and describes what is being changed by using <strike>strikethrough</strike> (to remove old material) and <underline>underscore</underline> (to add new material). <strong><em>Delete</em></strong> removes existing material. <strong><em>Insert</em></strong> adds new material without disturbing the existing material. Insertions may require renumbering. If so, renumbering instructions are given in the editing instruction. <strong><em>Replace</em></strong> is used to make changes in figures or equations by removing the existing figure or equation and replacing it with a new one. Editing instructions, change markings, and this NOTE will not be carried over into future editions because the changes will be incorporated into the base standard.</p>
336
+ </note>
337
+ {% else %}
338
+ <clause id="boilerplate_word_usage">
339
+ <title>Word usage</title>
340
+ <p>The word <em>shall</em> indicates mandatory requirements strictly to be followed in order to conform to the standard and from which no deviation is permitted (<em>shall</em> equals <em>is required to</em>).<fn><p>The use of the word <em>must</em> is deprecated and cannot be used when stating mandatory requirements; <em>must</em> is used only to describe unavoidable situations.</p></fn><fn><p>The use of <em>will</em> is deprecated and cannot be used when stating mandatory requirements; <em>will</em> is only used in statements of fact.</p></fn></p>
341
+ <p>The word <em>should</em> indicates that among several possibilities one is recommended as particularly suitable, without mentioning or excluding others; or that a certain course of action is preferred but not necessarily required (<em>should</em> equals <em>is recommended that</em>).</p>
342
+ <p>The word <em>may</em> is used to indicate a course of action permissible within the limits of the standard (<em>may</em> equals <em>is permitted to</em>).</p>
343
+ <p>The word <em>can</em> is used for statements of possibility and capability, whether material, physical, or causal (<em>can</em> equals <em>is able to</em>).</p>
344
+ </clause>
345
+ {% endif %}
297
346
  </boilerplate>
298
347
 
@@ -1,4 +1,5 @@
1
1
  require_relative "cleanup_ref"
2
+ require_relative "term_lookup_cleanup"
2
3
 
3
4
  module Metanorma
4
5
  module IEEE
@@ -6,6 +7,9 @@ module Metanorma
6
7
  def initial_boilerplate(xml, isodoc)
7
8
  intro_boilerplate(xml, isodoc)
8
9
  super
10
+ initial_note(xml)
11
+ word_usage(xml)
12
+ participants(xml)
9
13
  end
10
14
 
11
15
  def intro_boilerplate(xml, isodoc)
@@ -18,6 +22,22 @@ module Metanorma
18
22
  intro.next = "<admonition>#{adm}</admonition>"
19
23
  end
20
24
 
25
+ def initial_note(xml)
26
+ n = xml.at("//boilerplate//note[@id = 'boilerplate_front']")
27
+ s = xml.at("//sections")
28
+ (n && s) or return
29
+ s.children.empty? and s << " "
30
+ s.children.first.previous = n.remove
31
+ end
32
+
33
+ def word_usage(xml)
34
+ n = xml.at("//boilerplate//clause[@id = 'boilerplate_word_usage']")
35
+ &.remove
36
+ s = xml.at("//clause[@type = 'overview']")
37
+ (n && s) or return
38
+ s << n
39
+ end
40
+
21
41
  def obligations_cleanup_norm(xml)
22
42
  super
23
43
  xml.xpath("//sections/clause").each do |r|
@@ -53,39 +73,6 @@ module Metanorma
53
73
  ins << "<fn><p>#{@i18n.note_inform_fn}</p></fn>"
54
74
  end
55
75
 
56
- def termdef_cleanup(xmldoc)
57
- term_reorder(xmldoc)
58
- super
59
- end
60
-
61
- def term_reorder(xmldoc)
62
- xmldoc.xpath("//terms").each do |t|
63
- term_reorder1(t)
64
- end
65
- end
66
-
67
- def term_reorder1(terms)
68
- ins = terms.at("./term")&.previous_element or return
69
- coll = terms.xpath("./term")
70
- ret = sort_terms(coll)
71
- coll.each(&:remove)
72
- ret.reverse.each { |t| ins.next = t }
73
- end
74
-
75
- def sort_terms(terms)
76
- terms.sort do |a, b|
77
- sort_terms_key(a) <=> sort_terms_key(b)
78
- end
79
- end
80
-
81
- def sort_terms_key(term)
82
- d = term.at("./preferred/expression/name | "\
83
- "./preferred/letter-designation/name | "\
84
- "./preferred/graphical-symbol/figure/name | "\
85
- "./preferred/graphical-symbol/figure/@id")
86
- d.text.downcase
87
- end
88
-
89
76
  def table_footnote_renumber1(fnote, idx, seen)
90
77
  content = footnote_content(fnote)
91
78
  idx += 1
@@ -119,6 +106,82 @@ module Metanorma
119
106
  end
120
107
 
121
108
  def term_defs_boilerplate_cont(src, term, isodoc); end
109
+
110
+ def termlookup_cleanup(xmldoc)
111
+ Metanorma::IEEE::TermLookupCleanup.new(xmldoc, @log).call
112
+ end
113
+
114
+ def boilerplate_isodoc(xmldoc)
115
+ x = xmldoc.dup
116
+ x.root.add_namespace(nil, self.class::XML_NAMESPACE)
117
+ xml = Nokogiri::XML(x.to_xml)
118
+ i = isodoc(@lang, @script)
119
+ i.bibdata_i18n(xml.at("//xmlns:bibdata"))
120
+ i.info(xml, nil)
121
+ i
122
+ end
123
+
124
+ def participants(xml)
125
+ populate_participants(xml, "boilerplate-participants-wg",
126
+ "working group")
127
+ populate_participants(xml, "boilerplate-participants-bg",
128
+ "balloting group")
129
+ populate_participants(xml, "boilerplate-participants-sb",
130
+ "standards board")
131
+ p = xml.at(".//p[@type = 'emeritus_sign']")
132
+ ul = xml.at("//clause[@id = 'boilerplate-participants-sb']//ul")
133
+ p && ul and ul.next = p
134
+ xml.at("//clause[@type = 'participants']")&.remove
135
+ end
136
+
137
+ def populate_participants(xml, target, subtitle)
138
+ t = xml.at("//clause[@id = '#{target}']/membership")
139
+ s = xml.xpath("//clause[@type = 'participants']/clause").detect do |x|
140
+ n = x.at("./title") and n.text.strip.downcase == subtitle
141
+ end
142
+ t.replace(populate_participants1(s || t))
143
+ end
144
+
145
+ def populate_participants1(clause)
146
+ participants_dl_to_ul(clause)
147
+ clause.xpath(".//ul | .//ol").each do |ul|
148
+ ul.name = "ul"
149
+ ul.xpath("./li").each { |li| populate_participants2(li) }
150
+ ul.xpath(".//p[normalize-space() = '']").each(&:remove)
151
+ end
152
+ clause.children.to_xml
153
+ end
154
+
155
+ def participants_dl_to_ul(clause)
156
+ clause.xpath(".//dl[.//dl]").each do |dl|
157
+ dl.name = "ul"
158
+ dl.xpath("./dt").each(&:remove)
159
+ dl.xpath("./dd").each { |li| li.name = "li" }
160
+ end
161
+ end
162
+
163
+ def populate_participants2(list)
164
+ c = HTMLEntities.new
165
+ if dl = list.at("./dl")
166
+ ret = extract_participants(dl)
167
+ dl.children = ret.keys.map do |k|
168
+ "<dt>#{k}</dt><dd>#{c.encode(ret[k], :hexadecimal)}</dd>"
169
+ end.join
170
+ else
171
+ list.children = "<dl><dt>name</dt><dd>#{list.children.to_xml}</dd>"\
172
+ "<dt>role</dt><dd>member</dd></dl>"
173
+ end
174
+ end
175
+
176
+ def extract_participants(dlist)
177
+ key = ""
178
+ map = dlist.xpath("./dt | ./dd").each_with_object({}) do |dtd, m|
179
+ (dtd.name == "dt" and key = dtd.text.sub(/:+$/, "")) or
180
+ m[key.strip.downcase] = dtd.text.strip
181
+ end
182
+ map["role"] ||= "member"
183
+ map
184
+ end
122
185
  end
123
186
  end
124
187
  end
@@ -34,6 +34,7 @@ module Metanorma
34
34
  name = designator_or_name(bib)
35
35
  title = bib.at("./title[@type = 'main']")&.text ||
36
36
  bib.at("./title")&.text || bib.at("./formattedref")&.text
37
+ title.gsub!(/[[:punct:]]/, "")
37
38
  "#{name}. #{title}"
38
39
  end
39
40
 
@@ -34,10 +34,17 @@ module Metanorma
34
34
  when "Overview" then attrs[:type] = "overview"
35
35
  when "Scope" then attrs[:type] = "scope"
36
36
  when "Word Usage" then attrs[:type] = "word-usage"
37
+ when "Participants" then attrs[:type] = "participants"
37
38
  end
38
39
  super
39
40
  end
40
41
 
42
+ def termsource_attrs(node, matched)
43
+ ret = super
44
+ node.option? "adapted" and ret[:status] = "adapted"
45
+ ret
46
+ end
47
+
41
48
  def outputs(node, ret)
42
49
  File.open("#{@filename}.xml", "w:UTF-8") { |f| f.write(ret) }
43
50
  presentation_xml_converter(node).convert("#{@filename}.xml")
@@ -4,6 +4,9 @@ module Metanorma
4
4
  def metadata_committee(node, xml)
5
5
  return unless node.attr("committee") || node.attr("society")
6
6
 
7
+ node.attr("balloting-group") && !node.attr("balloting-group-type") and
8
+ node.set_attr("balloting-group-type", "individual")
9
+
7
10
  xml.editorialgroup do |a|
8
11
  committee_component("society", node, a)
9
12
  committee_component("balloting-group", node, a)
@@ -29,59 +32,6 @@ module Metanorma
29
32
  xml.docnumber node.attr("docnumber")
30
33
  end
31
34
 
32
- def metadata_author(node, xml)
33
- super
34
- wg_members(node, xml)
35
- bg_members(node, xml)
36
- std_board_members(node, xml)
37
- end
38
-
39
- def metadata_editor(name, role, xml)
40
- xml.contributor do |c|
41
- c.role role, **{ type: "editor" }
42
- c.person do |p|
43
- p.name do |n|
44
- n.completename name
45
- end
46
- end
47
- end
48
- end
49
-
50
- def metadata_multi_editors(names, role, xml)
51
- csv_split(names).each do |n|
52
- metadata_editor(n, role, xml)
53
- end
54
- end
55
-
56
- def wg_members(node, xml)
57
- a = node.attr("wg-chair") and
58
- metadata_editor(a, "Working Group Chair", xml)
59
- a = node.attr("wg-vicechair") and
60
- metadata_editor(a, "Working Group Vice-Chair", xml)
61
- a = node.attr("wg-secretary") and
62
- metadata_editor(a, "Working Group Secretary", xml)
63
- a = node.attr("wg-members") and
64
- metadata_multi_editors(a, "Working Group Member", xml)
65
- end
66
-
67
- def bg_members(node, xml)
68
- a = node.attr("balloting-group-members") and
69
- metadata_multi_editors(a, "Balloting Group Member", xml)
70
- end
71
-
72
- def std_board_members(node, xml)
73
- a = node.attr("std-board-chair") and
74
- metadata_editor(a, "Standards Board Chair", xml)
75
- a = node.attr("std-board-vicechair") and
76
- metadata_editor(a, "Standards Board Vice-Chair", xml)
77
- a = node.attr("std-board-pastchair") and
78
- metadata_editor(a, "Standards Board Past Chair", xml)
79
- a = node.attr("std-board-secretary") and
80
- metadata_editor(a, "Standards Board Secretary", xml)
81
- a = node.attr("balloting-group-members") and
82
- metadata_multi_editors(a, "Standards Board Member", xml)
83
- end
84
-
85
35
  def metadata_publisher(node, xml)
86
36
  publishers = node.attr("publisher") || "IEEE"
87
37
  csv_split(publishers).each do |p|
@@ -112,6 +62,23 @@ module Metanorma
112
62
  end
113
63
  end
114
64
 
65
+ def metadata_status(node, xml)
66
+ status = node.attr("status") || node.attr("docstage") ||
67
+ (node.attr("draft") ? "developing" : "active")
68
+ xml.status do |s|
69
+ s.stage status
70
+ end
71
+ end
72
+
73
+ def datetypes
74
+ super + %w{feedback-ended}
75
+ end
76
+
77
+ def metadata_subdoctype(node, xml)
78
+ xml.subdoctype (node.attr("docsubtype") || "document")
79
+ s = node.attr("trial-use") and xml.trial_use s
80
+ end
81
+
115
82
  def org_abbrev
116
83
  { "Institute of Electrical and Electronic Engineers" => "IEEE" }
117
84
  end
@@ -119,6 +86,26 @@ module Metanorma
119
86
  def relaton_relations
120
87
  super + %w(merges updates)
121
88
  end
89
+
90
+ def metadata_ext(node, xml)
91
+ super
92
+ structured_id(node, xml)
93
+ end
94
+
95
+ def structured_id(node, xml)
96
+ return unless node.attr("docnumber")
97
+
98
+ xml.structuredidentifier do |i|
99
+ i.docnumber node.attr("docnumber")
100
+ i.agency "IEEE"
101
+ i.class_ doctype(node)
102
+ a = node.attr("edition") and i.edition a
103
+ a = node.attr("draft") and i.version a
104
+ a = node.attr("amendment-number") and i.amendment a
105
+ a = node.attr("corrigendum-number") and i.corrigendum a
106
+ a = node.attr("copyright-year") and i.year a
107
+ end
108
+ end
122
109
  end
123
110
  end
124
111
  end
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <grammar ns="https://www.metanorma.org/ns/ieee" xmlns="http://relaxng.org/ns/structure/1.0">
2
+ <grammar ns="https://www.metanorma.org/ns/ieee" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
3
3
  <!--
4
4
  Currently we inherit from a namespaced grammar, isostandard. Until we inherit from isodoc,
5
5
  we cannot have a new default namespace: we will end up with a grammar with two different
@@ -16,6 +16,15 @@
16
16
  <value>standard</value>
17
17
  </choice>
18
18
  </define>
19
+ <define name="stage">
20
+ <element name="stage">
21
+ <choice>
22
+ <value>developing</value>
23
+ <value>active</value>
24
+ <value>inactive</value>
25
+ </choice>
26
+ </element>
27
+ </define>
19
28
  <define name="editorialgroup">
20
29
  <element name="editorialgroup">
21
30
  <ref name="society"/>
@@ -27,7 +36,11 @@
27
36
  </element>
28
37
  </define>
29
38
  <define name="DocumentSubtype">
30
- <value>trial-use</value>
39
+ <choice>
40
+ <value>amendment</value>
41
+ <value>corrigendum</value>
42
+ <value>erratum</value>
43
+ </choice>
31
44
  </define>
32
45
  <define name="BibDataExtensionType">
33
46
  <optional>
@@ -36,14 +49,31 @@
36
49
  <optional>
37
50
  <ref name="docsubtype"/>
38
51
  </optional>
52
+ <optional>
53
+ <ref name="trialuse"/>
54
+ </optional>
39
55
  <ref name="editorialgroup"/>
40
56
  <zeroOrMore>
41
57
  <ref name="ics"/>
42
58
  </zeroOrMore>
43
59
  </define>
44
60
  </include>
61
+ <define name="BibliographicDateType" combine="choice">
62
+ <value>feecback-ended</value>
63
+ </define>
64
+ <define name="trialuse">
65
+ <element name="trial-use">
66
+ <data type="boolean"/>
67
+ </element>
68
+ </define>
45
69
  <define name="balloting-group">
46
70
  <element name="balloting-group">
71
+ <attribute name="type">
72
+ <choice>
73
+ <value>individual</value>
74
+ <value>entity</value>
75
+ </choice>
76
+ </attribute>
47
77
  <text/>
48
78
  </element>
49
79
  </define>
@@ -2504,6 +2504,16 @@
2504
2504
  <text/>
2505
2505
  </element>
2506
2506
  </optional>
2507
+ <optional>
2508
+ <element name="amendment">
2509
+ <text/>
2510
+ </element>
2511
+ </optional>
2512
+ <optional>
2513
+ <element name="corrigendum">
2514
+ <text/>
2515
+ </element>
2516
+ </optional>
2507
2517
  <optional>
2508
2518
  <element name="language">
2509
2519
  <text/>
@@ -0,0 +1,11 @@
1
+ module Metanorma
2
+ module IEEE
3
+ class TermLookupCleanup < Metanorma::Standoc::TermLookupCleanup
4
+ def remove_missing_ref_term(node, _target)
5
+ node.at("../xrefrender")&.remove
6
+ node.replace("<preferred><expression><name>#{node.children.to_xml}"\
7
+ "</name></expression></preferred>")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -19,71 +19,30 @@ module Metanorma
19
19
  list_validate(doc)
20
20
  table_style(doc)
21
21
  figure_validate(doc)
22
+ amend_validate(doc)
22
23
  end
23
24
 
24
25
  def bibdata_validate(doc)
25
26
  doctype_validate(doc)
26
- # stage_validate(doc)
27
- # substage_validate(doc)
27
+ stage_validate(doc)
28
28
  end
29
29
 
30
30
  def doctype_validate(xmldoc)
31
31
  doctype = xmldoc&.at("//bibdata/ext/doctype")&.text
32
- %w(standard recommended-practice guide
33
- amendment technical-corrigendum).include? doctype or
32
+ %w(standard recommended-practice guide).include? doctype or
34
33
  @log.add("Document Attributes", nil,
35
34
  "#{doctype} is not a recognised document type")
35
+ docsubtype = xmldoc&.at("//bibdata/ext/subdoctype")&.text or return
36
+ %w(amendment corrigendum erratum document).include? docsubtype or
37
+ @log.add("Document Attributes", nil,
38
+ "#{docsubtype} is not a recognised document subtype")
36
39
  end
37
40
 
38
- def title_validate(xml)
39
- title_validate_type(xml)
40
- title_validate_capitalisation(xml)
41
- end
42
-
43
- # Style Manual 11.3
44
- def title_validate_type(xml)
45
- title = xml.at("//bibdata/title") or return
46
- draft = xml.at("//bibdata//draft")
47
- type = xml.at("//bibdata/ext/doctype")
48
- subtype = xml.at("//bibdata/ext/subdoctype")
49
- target = draft ? "Draft " : ""
50
- target += subtype ? "#{strict_capitalize_phrase(subtype.text)} " : ""
51
- target += type ? "#{strict_capitalize_phrase(type.text)} " : ""
52
- /^#{target}/.match?(title.text) or
53
- @log.add("Style", title,
54
- "Expected title to start as: #{target}")
55
- end
56
-
57
- def strict_capitalize_phrase(str)
58
- ret = str.split(/[ -]/).map do |w|
59
- letters = w.chars
60
- letters.first.upcase! unless /^[ -]/.match?(w)
61
- letters.join
62
- end.join(" ")
63
- ret = "Trial-Use" if ret == "Trial Use"
64
- ret
65
- end
66
-
67
- # Style Manual 11.3
68
- def title_validate_capitalisation(xml)
69
- title = xml.at("//bibdata/title") or return
70
- found = false
71
- title.text.split(/[ -]/).each do |w|
72
- /^[[:upper:]]/.match?(w) or preposition?(w) or
73
- found = true
74
- end
75
- found and @log.add("Style", title,
76
- "Title contains uncapitalised word other than preposition")
77
- end
78
-
79
- def preposition?(word)
80
- %w(aboard about above across after against along amid among anti around
81
- as at before behind below beneath beside besides between beyond but
82
- by concerning considering despite down during except excepting
83
- excluding following for from in inside into like minus near of off
84
- on onto opposite outside over past per plus regarding round save
85
- since than through to toward towards under underneath unlike until
86
- up upon versus via with within without a an the).include?(word)
41
+ def stage_validate(xmldoc)
42
+ stage = xmldoc&.at("//bibdata/status/stage")&.text
43
+ %w(active inactive developing).include? stage or
44
+ @log.add("Document Attributes", nil,
45
+ "#{stage} is not a recognised stage")
87
46
  end
88
47
 
89
48
  def locality_validate(root)
@@ -237,6 +196,51 @@ module Metanorma
237
196
  "More than one image in the table cell")
238
197
  end
239
198
  end
199
+
200
+ # Style manual 20.2.2
201
+ def amend_validate(xmldoc)
202
+ xmldoc.xpath("//amend").each do |a|
203
+ desc = a.at("./description")
204
+ if desc && !desc.text.strip.empty?
205
+ amend_validate1(a, desc.text.strip,
206
+ a.at("./newcontent//figure | "\
207
+ "./newcontent//formula"))
208
+ else @log.add("Style", a,
209
+ "Editorial instruction is missing from change")
210
+ end
211
+ end
212
+ end
213
+
214
+ def amend_validate1(amend, description, figure_or_formula)
215
+ case amend["change"]
216
+ when "add" then /^Insert /.match?(description) or
217
+ @log.add("Style", amend,
218
+ "'Add' change description should start with _Insert_")
219
+ when "delete" then /^Insert /.match?(description) or
220
+ @log.add("Style", amend,
221
+ "'Delete' change description should start with _Delete_")
222
+ when "modify"
223
+ amend_validate_modify(amend, description, figure_or_formula)
224
+ end
225
+ end
226
+
227
+ AMD_VALID_MOD = [
228
+ "'Modify' change description should start with _Change_ or _Replace_",
229
+ "'Modify' change description for change involving figure or equation "\
230
+ "should start with _Replace_",
231
+ "'Modify' change description for change not involving figure or "\
232
+ "equation should start with _Change_",
233
+ ].freeze
234
+
235
+ def amend_validate_modify(amend, description, figure_or_formula)
236
+ if !/^Change |^Replace/.match?(description)
237
+ @log.add("Style", amend, AMD_VALID_MOD[0])
238
+ elsif /^Change /.match?(description)
239
+ !figure_or_formula or @log.add("Style", amend, AMD_VALID_MOD[1])
240
+ else
241
+ figure_or_formula or @log.add("Style", amend, AMD_VALID_MOD[2])
242
+ end
243
+ end
240
244
  end
241
245
  end
242
246
  end