metanorma-iso 2.0.2 → 2.0.5

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/lib/isodoc/iso/html/html_iso_titlepage.html +1 -1
  4. data/lib/isodoc/iso/html/isodoc.css +1 -2
  5. data/lib/isodoc/iso/html/isodoc.scss +0 -1
  6. data/lib/isodoc/iso/html/word_iso_titlepage.html +1 -1
  7. data/lib/isodoc/iso/html/wordstyle.css +20 -0
  8. data/lib/isodoc/iso/html/wordstyle.scss +20 -0
  9. data/lib/isodoc/iso/i18n-en.yaml +29 -2
  10. data/lib/isodoc/iso/i18n-fr.yaml +27 -3
  11. data/lib/isodoc/iso/i18n-ru.yaml +45 -0
  12. data/lib/isodoc/iso/i18n-zh-Hans.yaml +27 -3
  13. data/lib/isodoc/iso/i18n.rb +1 -0
  14. data/lib/isodoc/iso/init.rb +1 -2
  15. data/lib/isodoc/iso/iso.amendment.xsl +1752 -807
  16. data/lib/isodoc/iso/iso.international-standard.xsl +1752 -807
  17. data/lib/isodoc/iso/metadata.rb +12 -2
  18. data/lib/isodoc/iso/presentation_xml_convert.rb +58 -21
  19. data/lib/metanorma/iso/basicdoc.rng +5 -3
  20. data/lib/metanorma/iso/biblio.rng +5 -3
  21. data/lib/metanorma/iso/boilerplate-fr.xml +3 -3
  22. data/lib/metanorma/iso/boilerplate-ru.xml +39 -0
  23. data/lib/metanorma/iso/boilerplate.xml +3 -3
  24. data/lib/metanorma/iso/cleanup.rb +42 -11
  25. data/lib/metanorma/iso/front.rb +1 -1
  26. data/lib/metanorma/iso/front_id.rb +1 -0
  27. data/lib/metanorma/iso/isodoc.rng +73 -3
  28. data/lib/metanorma/iso/processor.rb +14 -7
  29. data/lib/metanorma/iso/validate.rb +30 -2
  30. data/lib/metanorma/iso/validate_image.rb +3 -3
  31. data/lib/metanorma/iso/validate_list.rb +107 -0
  32. data/lib/metanorma/iso/validate_section.rb +42 -34
  33. data/lib/metanorma/iso/validate_style.rb +32 -2
  34. data/lib/metanorma/iso/validate_title.rb +13 -1
  35. data/lib/metanorma/iso/version.rb +1 -1
  36. data/spec/isodoc/amd_spec.rb +10 -5
  37. data/spec/isodoc/i18n_spec.rb +350 -9
  38. data/spec/isodoc/inline_spec.rb +127 -10
  39. data/spec/isodoc/metadata_spec.rb +153 -3
  40. data/spec/isodoc/postproc_spec.rb +3 -4
  41. data/spec/isodoc/section_spec.rb +1 -0
  42. data/spec/isodoc/terms_spec.rb +4 -4
  43. data/spec/isodoc/xref_spec.rb +18 -18
  44. data/spec/metanorma/base_spec.rb +434 -375
  45. data/spec/metanorma/cleanup_spec.rb +11 -11
  46. data/spec/metanorma/refs_spec.rb +333 -65
  47. data/spec/metanorma/section_spec.rb +15 -20
  48. data/spec/metanorma/validate_spec.rb +449 -14
  49. data/spec/spec_helper.rb +6 -4
  50. data/spec/vcr_cassettes/docrels.yml +211 -16
  51. data/spec/vcr_cassettes/withdrawn_iso.yml +301 -0
  52. metadata +6 -3
  53. data/spec/vcr_cassettes/sortrefs.yml +0 -599
@@ -72,12 +72,14 @@ module IsoDoc
72
72
  case lang
73
73
  when "en" then "Part"
74
74
  when "fr" then "Partie"
75
+ when "ru" then "Часть"
75
76
  end
76
77
  end
77
78
 
78
79
  def amd_label(lang)
79
80
  case lang
80
81
  when "en", "fr" then "AMENDMENT"
82
+ when "ru" then "ПОПРАВКА"
81
83
  end
82
84
  end
83
85
 
@@ -85,6 +87,7 @@ module IsoDoc
85
87
  case lang
86
88
  when "en" then "TECHNICAL CORRIGENDUM"
87
89
  when "fr" then "RECTIFICATIF TECHNIQUE"
90
+ when "ru" then "ТЕХНИЧЕСКОЕ ИСПРАВЛЕНИЕ"
88
91
  end
89
92
  end
90
93
 
@@ -140,7 +143,11 @@ module IsoDoc
140
143
  end
141
144
 
142
145
  def title(isoxml, _out)
143
- lang = @lang == "fr" ? "fr" : "en"
146
+ lang = case @lang
147
+ when "fr" then "fr"
148
+ when "ru" then "ru"
149
+ else "en"
150
+ end
144
151
  intro, main, part, amd = title_parts(isoxml, lang)
145
152
  partnumber, subpartnumber, amdnumber, corrnumber = title_nums(isoxml)
146
153
 
@@ -159,7 +166,10 @@ module IsoDoc
159
166
  end
160
167
 
161
168
  def subtitle(isoxml, _out)
162
- lang = @lang == "fr" ? "en" : "fr"
169
+ lang = case @lang
170
+ when "fr", "ru" then "en"
171
+ else "fr"
172
+ end
163
173
  intro, main, part, amd = title_parts(isoxml, lang)
164
174
  partnumber, subpartnumber, amdnumber, corrnumber = title_nums(isoxml)
165
175
 
@@ -47,37 +47,74 @@ module IsoDoc
47
47
 
48
48
  def eref_delim(delim, type)
49
49
  if delim == ";" then ";"
50
- else type == "list" ? "" : delim
50
+ else type == "list" ? " " : delim
51
51
  end
52
52
  end
53
53
 
54
- def eref_localities1_zh(target, type, from, upto, node, delim)
55
- subsection = from&.text&.match(/\./)
56
- ret = eref_delim(delim, type)
57
- ret += " 第#{from.text}" if from
58
- ret += "–#{upto.text}" if upto
59
- loc = (@i18n.locality[type] || type.sub(/^locality:/, "").capitalize)
60
- ret += " #{loc}" unless (subsection && type == "clause") ||
61
- type == "list" || target.match(/^IEV$|^IEC 60050-/) ||
62
- node["droploc"] == "true"
54
+ def can_conflate_eref_rendering?(refs)
55
+ super or return false
56
+
57
+ first = subclause?(nil, refs.first.at(ns("./locality/@type"))&.text,
58
+ refs.first.at(ns("./locality/referenceFrom"))&.text)
59
+ refs.all? do |r|
60
+ subclause?(nil, r.at(ns("./locality/@type"))&.text,
61
+ r.at(ns("./locality/referenceFrom"))&.text) == first
62
+ end
63
+ end
64
+
65
+ def locality_delimiter(loc)
66
+ loc&.next_element&.attribute("type")&.text == "list" and return " "
67
+ super
68
+ end
69
+
70
+ def eref_localities_conflated(refs, target, node)
71
+ droploc = node["droploc"]
72
+ node["droploc"] = true
73
+ ret = resolve_eref_connectives(eref_locality_stacks(refs, target,
74
+ node))
75
+ node["droploc"] = droploc
76
+ eref_localities1(target,
77
+ prefix_clause(target, refs.first.at(ns("./locality"))),
78
+ l10n(ret[1..-1].join), nil, node, @lang)
79
+ end
80
+
81
+ def prefix_clause(target, loc)
82
+ loc["type"] == "clause" or return loc["type"]
83
+
84
+ if subclause?(target, loc["type"], loc&.at(ns("./referenceFrom"))&.text)
85
+ ""
86
+ else
87
+ "clause"
88
+ end
89
+ end
90
+
91
+ def subclause?(target, type, from)
92
+ (from&.match?(/\./) && type == "clause") ||
93
+ type == "list" || target&.match(/^IEV$|^IEC 60050-/)
94
+ end
95
+
96
+ def eref_localities1_zh(target, type, from, upto, node)
97
+ ret = " 第#{from}" if from
98
+ ret += "–#{upto}" if upto
99
+ if node["droploc"] != "true" && !subclause?(target, type, from)
100
+ ret += eref_locality_populate(type, node)
101
+ end
63
102
  ret += ")" if type == "list"
64
103
  ret
65
104
  end
66
105
 
67
- def eref_localities1(target, type, from, upto, delim, node, lang = "en")
68
- return "" if type == "anchor"
106
+ def eref_localities1(target, type, from, upto, node, lang = "en")
107
+ return nil if type == "anchor"
69
108
 
70
- subsection = from&.text&.match(/\./)
71
109
  type = type.downcase
72
110
  lang == "zh" and
73
- return l10n(eref_localities1_zh(target, type, from, upto, node,
74
- delim))
75
- ret = eref_delim(delim, type)
76
- ret += eref_locality_populate(type, node) unless (subsection &&
77
- type == "clause") || type == "list" ||
78
- target.match(/^IEV$|^IEC 60050-/)
79
- ret += " #{from.text}" if from
80
- ret += "–#{upto.text}" if upto
111
+ return l10n(eref_localities1_zh(target, type, from, upto, node))
112
+ ret = if node["droploc"] != "true" && !subclause?(target, type, from)
113
+ eref_locality_populate(type, node)
114
+ else ""
115
+ end
116
+ ret += " #{from}" if from
117
+ ret += "–#{upto}" if upto
81
118
  ret += ")" if type == "list"
82
119
  l10n(ret)
83
120
  end
@@ -173,9 +173,11 @@
173
173
  <data type="dateTime"/>
174
174
  </attribute>
175
175
  </optional>
176
- <attribute name="from">
177
- <data type="IDREF"/>
178
- </attribute>
176
+ <optional>
177
+ <attribute name="from">
178
+ <data type="IDREF"/>
179
+ </attribute>
180
+ </optional>
179
181
  <optional>
180
182
  <attribute name="to">
181
183
  <data type="IDREF"/>
@@ -209,9 +209,6 @@
209
209
  <zeroOrMore>
210
210
  <ref name="contact"/>
211
211
  </zeroOrMore>
212
- <zeroOrMore>
213
- <ref name="uri"/>
214
- </zeroOrMore>
215
212
  </element>
216
213
  </define>
217
214
  <define name="fullname">
@@ -828,6 +825,11 @@
828
825
  <optional>
829
826
  <attribute name="scope"/>
830
827
  </optional>
828
+ <optional>
829
+ <attribute name="primary">
830
+ <data type="boolean"/>
831
+ </attribute>
832
+ </optional>
831
833
  <text/>
832
834
  </element>
833
835
  </define>
@@ -2,7 +2,7 @@
2
2
  <copyright-statement>
3
3
  <clause>
4
4
  <title>DOCUMENT PROTÉGÉ PAR COPYRIGHT</title>
5
- <p id="boilerplate-year">&copy; {{ agency }} {{ docyear }}</p>
5
+ <p id="boilerplate-year">&#xa9; {{ agency }} {{ docyear }}</p>
6
6
 
7
7
  <p id="boilerplate-message">
8
8
  Droits de reproduction réservés. Sauf indication contraire, aucune partie de cette publication ne
@@ -16,8 +16,8 @@ l’adresse ci-après ou au comité membre de l’ISO dans le pays du demandeur.
16
16
  ISO copyright office<br/>
17
17
  Ch. de Blandonnet 8 &#x2022; CP 401<br/>
18
18
  CH-1214 Vernier, Geneva, Switzerland<br/>
19
- Tel.&nbsp;&nbsp;+ 41 22 749 01 11<br/>
20
- Fax&nbsp;&nbsp;+ 41 22 749 09 47<br/>
19
+ Tel.&#xa0;&#xa0;+ 41 22 749 01 11<br/>
20
+ Fax&#xa0;&#xa0;+ 41 22 749 09 47<br/>
21
21
  Email: copyright@iso.org<br/>
22
22
  Website: www.iso.org
23
23
  </p>
@@ -0,0 +1,39 @@
1
+ <boilerplate>
2
+ <copyright-statement>
3
+ <clause>
4
+ <title>ДОКУМЕНТ, ОХРАНЯЕМЫЙ АВТОРСКИМ ПРАВОМ</title>
5
+ <p id="boilerplate-year">
6
+ &#xa9; {{ agency }} {{ docyear }}
7
+ </p>
8
+
9
+ <p id="boilerplate-message">
10
+ Все права защищены. Если иначе не определено, никакая часть этой публикации не может быть воспроизведена или использована иначе в любой форме или каким-либо образом, электронным или механическим, включая фотокопирование, или публикацию в Интернете или интранете, без предварительного письменного разрешения. Разрешение может быть запрошено ISO по адресу, указанному ниже, или у органа — члена ISO страны запрашивающего.
11
+ </p>
12
+
13
+ <p id="boilerplate-address" align="left">
14
+ Бюро ISO по охране авторских прав<br/>
15
+ Ch. de Blandonnet 8 &#x2022; CP 401<br/>
16
+ CH-1214 Vernier, Geneva, Switzerland<br/>
17
+ Tel.&#xa0;&#xa0;+ 41 22 749 01 11<br/>
18
+ Fax&#xa0;&#xa0;+ 41 22 749 09 47<br/>
19
+ Электронная почта: copyright@iso.org<br/>
20
+ Сайт: www.iso.org
21
+ </p>
22
+ <p id="boilerplate-place">
23
+ Издано в Швейцарии
24
+ </p>
25
+ </clause>
26
+ </copyright-statement>
27
+
28
+ {% if unpublished %}
29
+ <license-statement>
30
+ <clause>
31
+ <title>Предупреждение для WD и CD</title>
32
+
33
+ <p>Этот документ не является международным стандартом ISO. Распространяется для ознакомления и комментариев. Оно может быть изменено без предварительного уведомления и не может упоминаться как международный стандарт.</p>
34
+
35
+ <p>Получателям этого проекта предлагается представить вместе со своими комментариями уведомление о любых соответствующих патентных правах, о которых им известно, и предоставить подтверждающую документацию.</p>
36
+ </clause>
37
+ </license-statement>
38
+ {% endif %}
39
+ </boilerplate>
@@ -3,7 +3,7 @@
3
3
  <clause>
4
4
  <title>COPYRIGHT PROTECTED DOCUMENT</title>
5
5
  <p id="boilerplate-year">
6
- &copy; {{ agency }} {{ docyear }}
6
+ &#xa9; {{ agency }} {{ docyear }}
7
7
  </p>
8
8
 
9
9
  <p id="boilerplate-message">
@@ -19,8 +19,8 @@ at the address below or ISO's member body in the country of the requester.
19
19
  ISO copyright office<br/>
20
20
  Ch. de Blandonnet 8 &#x2022; CP 401<br/>
21
21
  CH-1214 Vernier, Geneva, Switzerland<br/>
22
- Tel.&nbsp;&nbsp;+ 41 22 749 01 11<br/>
23
- Fax&nbsp;&nbsp;+ 41 22 749 09 47<br/>
22
+ Tel.&#xa0;&#xa0;+ 41 22 749 01 11<br/>
23
+ Fax&#xa0;&#xa0;+ 41 22 749 09 47<br/>
24
24
  Email: copyright@iso.org<br/>
25
25
  Website: www.iso.org
26
26
  </p>
@@ -37,13 +37,11 @@ module Metanorma
37
37
  end
38
38
 
39
39
  def get_id_prefix(xmldoc)
40
- prefix = []
41
40
  xmldoc.xpath("//bibdata/contributor[role/@type = 'publisher']"\
42
- "/organization").each do |x|
41
+ "/organization").each_with_object([]) do |x, prefix|
43
42
  x1 = x.at("abbreviation")&.text || x.at("name")&.text
44
43
  (x1 == "ISO" and prefix.unshift("ISO")) or prefix << x1
45
44
  end
46
- prefix
47
45
  end
48
46
 
49
47
  # ISO as a prefix goes first
@@ -125,7 +123,11 @@ module Metanorma
125
123
  end
126
124
 
127
125
  def boilerplate_file(_xmldoc)
128
- file = @lang == "fr" ? "boilerplate-fr.xml" : "boilerplate.xml"
126
+ file = case @lang
127
+ when "fr" then "boilerplate-fr.xml"
128
+ when "ru" then "boilerplate-ru.xml"
129
+ else "boilerplate.xml"
130
+ end
129
131
  File.join(@libdir, file)
130
132
  end
131
133
 
@@ -136,8 +138,7 @@ module Metanorma
136
138
 
137
139
  def unpub_footnotes(xmldoc)
138
140
  xmldoc.xpath("//bibitem/note[@type = 'Unpublished-Status']").each do |n|
139
- id = n.parent["id"]
140
- e = xmldoc.at("//eref[@bibitemid = '#{id}']") or next
141
+ e = xmldoc.at("//eref[@bibitemid = '#{n.parent['id']}']") or next
141
142
  fn = n.children.to_xml
142
143
  n&.elements&.first&.name == "p" or fn = "<p>#{fn}</p>"
143
144
  e.next = "<fn>#{fn}</fn>"
@@ -147,21 +148,46 @@ module Metanorma
147
148
  def bibitem_cleanup(xmldoc)
148
149
  super
149
150
  unpublished_note(xmldoc)
151
+ withdrawn_note(xmldoc)
150
152
  end
151
153
 
152
154
  def unpublished_note(xmldoc)
153
- xmldoc.xpath("//bibitem[not(note[@type = 'Unpublished-Status'])]")
154
- .each do |b|
155
+ xmldoc.xpath("//bibitem[not(./ancestor::bibitem)]"\
156
+ "[not(note[@type = 'Unpublished-Status'])]").each do |b|
155
157
  next if pub_class(b) > 2
156
158
  next unless (s = b.at("./status/stage")) && (s.text.to_i < 60)
157
159
 
158
160
  id = b.at("docidentifier").text
159
- b.at("./language | ./script | ./abstract | ./status")
160
- .previous = %(<note type="Unpublished-Status">
161
- <p>#{@i18n.under_preparation.sub(/%/, id)}</p></note>)
161
+ insert_unpub_note(b, @i18n.under_preparation.sub(/%/, id))
162
162
  end
163
163
  end
164
164
 
165
+ def withdrawn_note(xmldoc)
166
+ xmldoc.xpath("//bibitem[not(note[@type = 'Unpublished-Status'])]")
167
+ .each do |b|
168
+ next if pub_class(b) > 2
169
+ next unless (s = b.at("./status/stage")) && (s.text.to_i >= 90)
170
+
171
+ if id = replacement_standard(b)
172
+ insert_unpub_note(b, @i18n.cancelled_and_replaced.sub(/%/, id))
173
+ else
174
+ insert_unpub_note(b, @i18n.withdrawn)
175
+ end
176
+ end
177
+ end
178
+
179
+ def replacement_standard(biblio)
180
+ r = biblio.at("./relation[@type = 'updates']/bibitem") or return nil
181
+ id = r.at("./formattedref | ./docidentifier[@primary = 'true'] | "\
182
+ "./docidentifier | ./formattedref") or return nil
183
+ id.text
184
+ end
185
+
186
+ def insert_unpub_note(biblio, msg)
187
+ biblio.at("./language | ./script | ./abstract | ./status")
188
+ .previous = %(<note type="Unpublished-Status"><p>#{msg}</p></note>)
189
+ end
190
+
165
191
  def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
166
192
  once = true
167
193
  super
@@ -171,6 +197,11 @@ module Metanorma
171
197
  @vocab and src.empty? and return
172
198
  super
173
199
  end
200
+
201
+ def section_names_terms_cleanup(xml)
202
+ @vocab and return
203
+ super
204
+ end
174
205
  end
175
206
  end
176
207
  end
@@ -135,7 +135,7 @@ module Metanorma
135
135
  end
136
136
 
137
137
  def title(node, xml)
138
- ["en", "fr"].each do |lang|
138
+ %w(en ru fr).each do |lang|
139
139
  at = { language: lang, format: "text/plain" }
140
140
  title_full(node, xml, lang, at)
141
141
  title_intro(node, xml, lang, at)
@@ -106,6 +106,7 @@ module Metanorma
106
106
  suffix = case lang
107
107
  when "en" then "(E)"
108
108
  when "fr" then "(F)"
109
+ when "ru" then "(R)"
109
110
  else
110
111
  "(X)"
111
112
  end
@@ -152,9 +152,7 @@
152
152
  <data type="boolean"/>
153
153
  </attribute>
154
154
  </optional>
155
- <oneOrMore>
156
- <ref name="PureTextElement"/>
157
- </oneOrMore>
155
+ <ref name="XrefBody"/>
158
156
  </element>
159
157
  </define>
160
158
  <define name="erefType">
@@ -188,6 +186,42 @@
188
186
  <ref name="PureTextElement"/>
189
187
  </oneOrMore>
190
188
  </define>
189
+ <define name="localityStack">
190
+ <element name="localityStack">
191
+ <optional>
192
+ <attribute name="connective">
193
+ <choice>
194
+ <value>and</value>
195
+ <value>or</value>
196
+ <value>from</value>
197
+ <value>to</value>
198
+ <value/>
199
+ </choice>
200
+ </attribute>
201
+ </optional>
202
+ <zeroOrMore>
203
+ <ref name="locality"/>
204
+ </zeroOrMore>
205
+ </element>
206
+ </define>
207
+ <define name="sourceLocalityStack">
208
+ <element name="sourceLocalityStack">
209
+ <optional>
210
+ <attribute name="connective">
211
+ <choice>
212
+ <value>and</value>
213
+ <value>or</value>
214
+ <value>from</value>
215
+ <value>to</value>
216
+ <value/>
217
+ </choice>
218
+ </attribute>
219
+ </optional>
220
+ <zeroOrMore>
221
+ <ref name="sourceLocality"/>
222
+ </zeroOrMore>
223
+ </element>
224
+ </define>
191
225
  <define name="ul">
192
226
  <element name="ul">
193
227
  <attribute name="id">
@@ -1098,6 +1132,16 @@
1098
1132
  </define>
1099
1133
  </include>
1100
1134
  <!-- end overrides -->
1135
+ <define name="image" combine="choice">
1136
+ <element name="svg">
1137
+ <oneOrMore>
1138
+ <choice>
1139
+ <text/>
1140
+ <ref name="AnyElement"/>
1141
+ </choice>
1142
+ </oneOrMore>
1143
+ </element>
1144
+ </define>
1101
1145
  <define name="MultilingualRenderingType">
1102
1146
  <choice>
1103
1147
  <value>common</value>
@@ -2631,4 +2675,30 @@
2631
2675
  </zeroOrMore>
2632
2676
  </element>
2633
2677
  </define>
2678
+ <define name="XrefBody">
2679
+ <zeroOrMore>
2680
+ <ref name="XrefTarget"/>
2681
+ </zeroOrMore>
2682
+ <oneOrMore>
2683
+ <ref name="PureTextElement"/>
2684
+ </oneOrMore>
2685
+ </define>
2686
+ <define name="XrefTarget">
2687
+ <element name="location">
2688
+ <attribute name="target">
2689
+ <data type="string">
2690
+ <param name="pattern">\i\c*|\c+#\c+</param>
2691
+ </data>
2692
+ </attribute>
2693
+ <attribute name="connective">
2694
+ <choice>
2695
+ <value>and</value>
2696
+ <value>or</value>
2697
+ <value>from</value>
2698
+ <value>to</value>
2699
+ <value/>
2700
+ </choice>
2701
+ </attribute>
2702
+ </element>
2703
+ </define>
2634
2704
  </grammar>
@@ -45,19 +45,26 @@ module Metanorma
45
45
  def output(isodoc_node, inname, outname, format, options={})
46
46
  case format
47
47
  when :html
48
- IsoDoc::Iso::HtmlConvert.new(options).convert(inname, isodoc_node, nil, outname)
48
+ IsoDoc::Iso::HtmlConvert.new(options)
49
+ .convert(inname, isodoc_node, nil, outname)
49
50
  when :html_alt
50
- IsoDoc::Iso::HtmlConvert.new(options.merge(alt: true)).convert(inname, isodoc_node, nil, outname)
51
+ IsoDoc::Iso::HtmlConvert.new(options.merge(alt: true))
52
+ .convert(inname, isodoc_node, nil, outname)
51
53
  when :doc
52
- IsoDoc::Iso::WordConvert.new(options).convert(inname, isodoc_node, nil, outname)
54
+ IsoDoc::Iso::WordConvert.new(options)
55
+ .convert(inname, isodoc_node, nil, outname)
53
56
  when :pdf
54
- IsoDoc::Iso::PdfConvert.new(options).convert(inname, isodoc_node, nil, outname)
57
+ IsoDoc::Iso::PdfConvert.new(options)
58
+ .convert(inname, isodoc_node, nil, outname)
55
59
  when :sts
56
- IsoDoc::Iso::StsConvert.new(options).convert(inname, isodoc_node, nil, outname)
60
+ IsoDoc::Iso::StsConvert.new(options)
61
+ .convert(inname, isodoc_node, nil, outname)
57
62
  when :isosts
58
- IsoDoc::Iso::IsoStsConvert.new(options).convert(inname, isodoc_node, nil, outname)
63
+ IsoDoc::Iso::IsoStsConvert.new(options)
64
+ .convert(inname, isodoc_node, nil, outname)
59
65
  when :presentation
60
- IsoDoc::Iso::PresentationXMLConvert.new(options).convert(inname, isodoc_node, nil, outname)
66
+ IsoDoc::Iso::PresentationXMLConvert.new(options)
67
+ .convert(inname, isodoc_node, nil, outname)
61
68
  else
62
69
  super
63
70
  end
@@ -4,6 +4,7 @@ require_relative "./validate_requirements"
4
4
  require_relative "./validate_section"
5
5
  require_relative "./validate_title"
6
6
  require_relative "./validate_image"
7
+ require_relative "./validate_list"
7
8
  require "nokogiri"
8
9
  require "jing"
9
10
  require "iev"
@@ -35,7 +36,7 @@ module Metanorma
35
36
  /\b(see| refer to)\s*\Z/mi.match(preceding)
36
37
 
37
38
  (target = root.at("//*[@id = '#{t['target']}']")) || next
38
- if target&.at("./ancestor-or-self::*[@obligation = 'normative']")
39
+ if target.at("./ancestor-or-self::*[@obligation = 'normative']")
39
40
  @log.add("Style", t,
40
41
  "'see #{t['target']}' is pointing to a normative section")
41
42
  end
@@ -75,6 +76,30 @@ module Metanorma
75
76
  regex.match(text) && @log.add("Style", elem, "#{term}: #{msg}")
76
77
  end
77
78
 
79
+ # https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-r-ref_clause3
80
+ def term_xrefs_validate(xmldoc)
81
+ termids = xmldoc
82
+ .xpath("//sections/terms | //sections/clause[.//terms] | "\
83
+ "//annex[.//terms]").each_with_object({}) do |t, m|
84
+ t.xpath(".//*/@id").each { |a| m[a.text] = true }
85
+ t.name == "terms" and m[t["id"]] = true
86
+ end
87
+ xmldoc.xpath(".//xref").each do |x|
88
+ term_xrefs_validate1(x, termids)
89
+ end
90
+ end
91
+
92
+ def term_xrefs_validate1(xref, termids)
93
+ (termids[xref["target"]] && !termids[xref.parent["id"]]) and
94
+ @log.add("Style", xref,
95
+ "only terms clauses can cross-reference terms clause "\
96
+ "(#{xref['target']})")
97
+ (!termids[xref["target"]] && termids[xref.parent["id"]]) and
98
+ @log.add("Style", xref,
99
+ "non-terms clauses cannot cross-reference terms clause "\
100
+ "(#{xref['target']})")
101
+ end
102
+
78
103
  # ISO/IEC DIR 2, 16.5.6
79
104
  def termdef_style(xmldoc)
80
105
  xmldoc.xpath("//term").each do |t|
@@ -98,7 +123,7 @@ module Metanorma
98
123
 
99
124
  def script_validate(xmldoc)
100
125
  script = xmldoc&.at("//bibdata/script")&.text
101
- script == "Latn" or
126
+ %w(Cyrl Latn).include?(script) or
102
127
  @log.add("Document Attributes", nil,
103
128
  "#{script} is not a recognised script")
104
129
  end
@@ -139,11 +164,14 @@ module Metanorma
139
164
  onlychild_clause_validate(doc.root)
140
165
  termdef_style(doc.root)
141
166
  see_xrefs_validate(doc.root)
167
+ term_xrefs_validate(doc.root)
142
168
  see_erefs_validate(doc.root)
143
169
  locality_erefs_validate(doc.root)
144
170
  bibdata_validate(doc.root)
145
171
  bibitem_validate(doc.root)
146
172
  figure_validate(doc.root)
173
+ listcount_validate(doc)
174
+ list_punctuation(doc)
147
175
  end
148
176
 
149
177
  def bibitem_validate(xmldoc)
@@ -78,9 +78,9 @@ module Metanorma
78
78
  xmldoc.xpath("//image").each do |i|
79
79
  next if i["src"].start_with?("data:")
80
80
 
81
- if /^ISO_\d+_/.match?(File.basename(i["src"]))
82
- elsif /^(SL)?#{prefix}fig/.match?(File.basename(i["src"]))
83
- image_name_validate1(i, prefix)
81
+ case File.basename(i["src"])
82
+ when /^ISO_\d+_/
83
+ when /^(SL)?#{prefix}fig/ then image_name_validate1(i, prefix)
84
84
  else
85
85
  @log.add("Style", i,
86
86
  "image name #{i['src']} does not match DRG requirements: expect #{prefix}fig")