metanorma-iso 2.0.2 → 2.0.5

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