metanorma-iso 3.0.6 → 3.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.
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
3
- <!-- VERSION v2.0.4 -->
3
+ <!-- VERSION v2.0.6 -->
4
4
 
5
5
  <!--
6
6
  ALERT: cannot have root comments, because of https://github.com/metanorma/metanorma/issues/437
@@ -36,6 +36,12 @@
36
36
  </zeroOrMore>
37
37
  </element>
38
38
  </define>
39
+ <define name="IdRefType">
40
+ <a:documentation>Cross-references are not normalised to xsd:IDREF in Semantic XML: that is deferred to Presentation XML.
41
+ All IdRefType instances point not to `@id` in Semantic XML, which is the Content GUID for an element,
42
+ but to `@anchor`, the user-supplied cross-reference</a:documentation>
43
+ <text/>
44
+ </define>
39
45
  <define name="index-primary">
40
46
  <element name="primary">
41
47
  <oneOrMore>
@@ -238,7 +244,7 @@
238
244
  <a:documentation>Notes specific to this block</a:documentation>
239
245
  </ref>
240
246
  </zeroOrMore>
241
- <ref name="TermSource">
247
+ <ref name="BlockSource">
242
248
  <a:documentation>A source for the table</a:documentation>
243
249
  </ref>
244
250
  </define>
@@ -262,10 +268,112 @@ and is intended to be referenced by a callout within the source code</a:document
262
268
  <a:documentation>Notes whose scope is the current block</a:documentation>
263
269
  </ref>
264
270
  </zeroOrMore>
265
- <ref name="TermSource">
271
+ <ref name="BlockSource">
272
+ <a:documentation>A source for the block</a:documentation>
273
+ </ref>
274
+ </define>
275
+ <define name="FigureBody">
276
+ <optional>
277
+ <ref name="tname">
278
+ <a:documentation>The caption of the block</a:documentation>
279
+ </ref>
280
+ </optional>
281
+ <choice>
282
+ <a:documentation>Content of the figure</a:documentation>
283
+ <ref name="image"/>
284
+ <ref name="video"/>
285
+ <ref name="audio"/>
286
+ <ref name="pre"/>
287
+ <oneOrMore>
288
+ <ref name="paragraph-with-footnote"/>
289
+ </oneOrMore>
290
+ <zeroOrMore>
291
+ <ref name="figure"/>
292
+ </zeroOrMore>
293
+ </choice>
294
+ <zeroOrMore>
295
+ <ref name="fn">
296
+ <a:documentation>Footnotes specific to the figure</a:documentation>
297
+ </ref>
298
+ </zeroOrMore>
299
+ <optional>
300
+ <ref name="dl">
301
+ <a:documentation>An optional definitions list defining any symbols used in the figure</a:documentation>
302
+ </ref>
303
+ </optional>
304
+ <zeroOrMore>
305
+ <ref name="note">
306
+ <a:documentation>Notes whose scope is the current block</a:documentation>
307
+ </ref>
308
+ </zeroOrMore>
309
+ <ref name="BlockSource">
310
+ <a:documentation>A source for the block</a:documentation>
311
+ </ref>
312
+ </define>
313
+ <define name="FigureNoIdBody">
314
+ <optional>
315
+ <ref name="source">
316
+ <a:documentation>A URI or other reference intended to link to an externally hosted image (or equivalent)</a:documentation>
317
+ </ref>
318
+ </optional>
319
+ <optional>
320
+ <ref name="tname">
321
+ <a:documentation>The caption of the block</a:documentation>
322
+ </ref>
323
+ </optional>
324
+ <choice>
325
+ <a:documentation>Content of the figure</a:documentation>
326
+ <ref name="image-no-id"/>
327
+ <ref name="video-no-id"/>
328
+ <ref name="audio-no-id"/>
329
+ <ref name="pre-no-id"/>
330
+ <oneOrMore>
331
+ <ref name="paragraph-with-footnote-no-id"/>
332
+ </oneOrMore>
333
+ <zeroOrMore>
334
+ <ref name="figure-no-id"/>
335
+ </zeroOrMore>
336
+ </choice>
337
+ <zeroOrMore>
338
+ <ref name="fn">
339
+ <a:documentation>Footnotes specific to the figure</a:documentation>
340
+ </ref>
341
+ </zeroOrMore>
342
+ <optional>
343
+ <ref name="dl-no-id">
344
+ <a:documentation>An optional definitions list defining any symbols used in the figure</a:documentation>
345
+ </ref>
346
+ </optional>
347
+ <zeroOrMore>
348
+ <ref name="note-no-id">
349
+ <a:documentation>Notes whose scope is the current block</a:documentation>
350
+ </ref>
351
+ </zeroOrMore>
352
+ <ref name="BlockSource">
266
353
  <a:documentation>A source for the block</a:documentation>
267
354
  </ref>
268
355
  </define>
356
+ <define name="source">
357
+ <element name="source">
358
+ <attribute name="status">
359
+ <a:documentation>The status of the term as it is used in this document, relative to its definition in the original document</a:documentation>
360
+ <ref name="SourceStatusType"/>
361
+ </attribute>
362
+ <attribute name="type">
363
+ <a:documentation>The type of the managed term in the present context</a:documentation>
364
+ <ref name="SourceTypeType"/>
365
+ </attribute>
366
+ <ref name="origin">
367
+ <a:documentation>The original document and location where the term definition has been obtained from</a:documentation>
368
+ </ref>
369
+ <optional>
370
+ <ref name="modification">
371
+ <a:documentation>Any changes that the definition of the term has undergone relative to the original document,
372
+ in order to be applicable in this standardisation document</a:documentation>
373
+ </ref>
374
+ </optional>
375
+ </element>
376
+ </define>
269
377
  <define name="sourcecodebody">
270
378
  <a:documentation>The computer code or other such text presented in the block, as a single unformatted string.
271
379
  (The string should be treated as pre-formatted text, with whitespace treated as significant)</a:documentation>
@@ -687,6 +795,32 @@ titlecase, or lowercase</a:documentation>
687
795
  </attribute>
688
796
  </optional>
689
797
  </define>
798
+ <define name="RequiredId" combine="interleave">
799
+ <optional>
800
+ <attribute name="anchor">
801
+ <a:documentation>User-supplied anchor of element; replaced by content-based id, with all references to the anchor updated accordingly</a:documentation>
802
+ </attribute>
803
+ </optional>
804
+ <optional>
805
+ <attribute name="source">
806
+ <a:documentation>Sourcing of the current element in an external data model</a:documentation>
807
+ <ref name="IdRefType"/>
808
+ </attribute>
809
+ </optional>
810
+ </define>
811
+ <define name="OptionalId" combine="interleave">
812
+ <optional>
813
+ <attribute name="anchor">
814
+ <a:documentation> User-supplied anchor of element; replaced by content-based id, with all references to the anchor updated accordingly</a:documentation>
815
+ </attribute>
816
+ </optional>
817
+ <optional>
818
+ <attribute name="source">
819
+ <a:documentation>Sourcing of the current element in an external data model</a:documentation>
820
+ <ref name="IdRefType"/>
821
+ </attribute>
822
+ </optional>
823
+ </define>
690
824
  <define name="ObligationType">
691
825
  <a:documentation>The force of a clause in a standard document: whether it has normative or informative effect</a:documentation>
692
826
  <choice>
@@ -832,6 +966,7 @@ titlecase, or lowercase</a:documentation>
832
966
  is used in particular to capture mutually agreed definitions of codepoints in Unicode Private Use Area</a:documentation>
833
967
  </attribute>
834
968
  </optional>
969
+ <ref name="OptionalId"/>
835
970
  <oneOrMore>
836
971
  <ref name="TextElement">
837
972
  <a:documentation>Textual content of span</a:documentation>
@@ -1081,7 +1216,7 @@ That concept may be defined as a term within the current document, or it may be
1081
1216
  <element name="label">
1082
1217
  <!-- Identifier of form input element that this element is a label of -->
1083
1218
  <attribute name="for">
1084
- <data type="IDREF"/>
1219
+ <ref name="IdRefType"/>
1085
1220
  </attribute>
1086
1221
  <zeroOrMore>
1087
1222
  <ref name="PureTextElement"/>
@@ -2121,7 +2256,7 @@ used in document amendments</a:documentation>
2121
2256
  </define>
2122
2257
  <define name="termsource">
2123
2258
  <a:documentation>The bibliographic source where a term is defined in the sense applicable in this standardisation document</a:documentation>
2124
- <element name="termsource">
2259
+ <element name="source">
2125
2260
  <attribute name="status">
2126
2261
  <a:documentation>The status of the term as it is used in this document, relative to its definition in the original document</a:documentation>
2127
2262
  <ref name="SourceStatusType"/>
@@ -2503,6 +2638,11 @@ Normative References contents contain normative references, but as a clause in t
2503
2638
  <ref name="termsource"/>
2504
2639
  </zeroOrMore>
2505
2640
  </define>
2641
+ <define name="BlockSource">
2642
+ <zeroOrMore>
2643
+ <ref name="source"/>
2644
+ </zeroOrMore>
2645
+ </define>
2506
2646
  <start>
2507
2647
  <ref name="standard-document"/>
2508
2648
  </start>
@@ -29,36 +29,61 @@ module Metanorma
29
29
  # does not deal with preceding text marked up
30
30
  def see_xrefs_validate(root)
31
31
  @lang == "en" or return
32
+ anchors = extract_anchor_norm(root)
32
33
  root.xpath("//xref").each do |t|
33
34
  preceding = t.at("./preceding-sibling::text()[last()]")
34
- next unless !preceding.nil? &&
35
- /\b(see| refer to)\p{Zs}*\Z/mi.match(preceding)
36
-
37
- (target = root.at("//*[@id = '#{t['target']}']")) || next
38
- target.at("./ancestor-or-self::*[@obligation = 'normative']") &&
39
- !target.at("./ancestor::sections") and
35
+ !preceding.nil? &&
36
+ /\b(see| refer to)\p{Zs}*\Z/mi.match(preceding) or next
37
+ anchors[t["target"]] and
40
38
  @log.add("Style", t,
41
39
  "'see #{t['target']}' is pointing to a normative section")
42
40
  end
43
41
  end
44
42
 
43
+ def extract_anchor_norm(root)
44
+ nodes = root.xpath("//annex[@obligation = 'normative'] | " \
45
+ "//references[@obligation = 'normative']")
46
+ ret = nodes.each_with_object({}) do |n, m|
47
+ n["anchor"] and m[n["anchor"]] = true
48
+ end
49
+ nodes.each do |n|
50
+ n.xpath(".//*[@anchor]").each { |n1| ret[n1["anchor"]] = true }
51
+ end
52
+ ret
53
+ end
54
+
45
55
  # ISO/IEC DIR 2, 15.5.3
46
56
  def see_erefs_validate(root)
47
57
  @lang == "en" or return
58
+ bibitemids = extract_bibitem_anchors(root)
48
59
  root.xpath("//eref").each do |t|
49
60
  prec = t.at("./preceding-sibling::text()[last()]")
50
61
  !prec.nil? && /\b(see|refer to)\p{Zs}*\Z/mi.match(prec) or next
51
- unless target = root.at("//*[@id = '#{t['bibitemid']}']")
62
+ unless target = bibitemids[t["bibitemid"]]
63
+ #unless target = root.at("//bibitem[@anchor = '#{t['bibitemid']}']")
52
64
  @log.add("Bibliography", t,
53
65
  "'#{t} is not pointing to a real reference")
54
66
  next
55
67
  end
56
- target.at("./ancestor::references[@normative = 'true']") and
68
+ #target.at("./ancestor::references[@normative = 'true']") and
69
+ target[:norm] and
57
70
  @log.add("Style", t,
58
71
  "'see #{t}' is pointing to a normative reference")
59
72
  end
60
73
  end
61
74
 
75
+ def extract_bibitem_anchors(root)
76
+ ret = root.xpath("//references[@normative = 'true']//bibitem")
77
+ .each_with_object({}) do |b, m|
78
+ m[b["anchor"]] = { bib: b, norm: true }
79
+ end
80
+ root.xpath("//references[not(@normative = 'true')]//bibitem")
81
+ .each do |b|
82
+ ret[b["anchor"]] = { bib: b, norm: false }
83
+ end
84
+ ret
85
+ end
86
+
62
87
  # ISO/IEC DIR 2, 10.4
63
88
  def locality_erefs_validate(root)
64
89
  root.xpath("//eref[descendant::locality]").each do |t|
@@ -80,8 +105,9 @@ module Metanorma
80
105
  termids = xmldoc
81
106
  .xpath("//sections/terms | //sections/clause[.//terms] | " \
82
107
  "//annex[.//terms]").each_with_object({}) do |t, m|
108
+ t.xpath(".//*/@anchor").each { |a| m[a.text] = true }
83
109
  t.xpath(".//*/@id").each { |a| m[a.text] = true }
84
- t.name == "terms" and m[t["id"]] = true
110
+ t.name == "terms" and m[t["anchor"] || t["id"]] = true
85
111
  end
86
112
  xmldoc.xpath(".//xref").each do |x|
87
113
  term_xrefs_validate1(x, termids)
@@ -114,8 +140,8 @@ module Metanorma
114
140
  .join(" | ")
115
141
  (xmldoc.xpath(xpath) - xmldoc.xpath(exc)).each do |x|
116
142
  x["unnumbered"] == "true" and next
117
- @doc_xrefs[x["id"]] or
118
- @log.add("Style", x, "#{name} #{x['id']} has not been " \
143
+ @doc_xrefs[x["anchor"]] or
144
+ @log.add("Style", x, "#{name} #{x['anchor']} has not been " \
119
145
  "cross-referenced within document",
120
146
  severity: xpath == "//formula" ? 2 : 1)
121
147
  end
@@ -186,7 +212,7 @@ module Metanorma
186
212
  xmldoc.xpath("//bibitem[date/on = '–']").each do |b|
187
213
  b.at("./note[@type = 'Unpublished-Status']") or
188
214
  @log.add("Style", b,
189
- "Reference #{b&.at('./@id')&.text} does not have an " \
215
+ "Reference does not have an " \
190
216
  "associated footnote indicating unpublished status")
191
217
  end
192
218
  end
@@ -118,17 +118,17 @@ module Metanorma
118
118
  if elem.nil? || elem.name != "clause"
119
119
  @log.add("Style", elem, "Document must contain at least one clause")
120
120
  end
121
- elem&.at("./self::clause") ||
121
+ elem&.at("./self::clause") or
122
122
  @log.add("Style", elem, "Document must contain clause after " \
123
123
  "Terms and Definitions")
124
- elem&.at("./self::clause[@type = 'scope']") &&
124
+ elem&.at("./self::clause[@type = 'scope']") and
125
125
  @log.add("Style", elem,
126
- "Scope must occur before Terms and Definitions")
126
+ "Scope must not occur after Terms and Definitions")
127
127
  elem = names.shift
128
128
  while elem&.name == "clause"
129
- elem&.at("./self::clause[@type = 'scope']")
130
- @log.add("Style", elem,
131
- "Scope must occur before Terms and Definitions")
129
+ elem&.at("./self::clause[@type = 'scope']") and
130
+ @log.add("Style", elem,
131
+ "Scope must not occur after Terms and Definitions")
132
132
  elem = names.shift
133
133
  end
134
134
  %w(annex references).include? elem&.name or
@@ -216,12 +216,8 @@ module Metanorma
216
216
  # ISO/IEC DIR 2, 22.3.2
217
217
  def onlychild_clause_validate(root)
218
218
  root.xpath(Standoc::Utils::SUBCLAUSE_XPATH).each do |c|
219
- next unless c.xpath("../clause").size == 1
220
-
221
- title = c.at("./title")
222
- location = c["id"] || "#{c.text[0..60]}..."
223
- location += ":#{title.text}" if c["id"] && !title.nil?
224
- @log.add("Style", nil, "#{location}: subclause is only child")
219
+ c.xpath("../clause").size == 1 or next
220
+ @log.add("Style", c, "subclause is only child")
225
221
  end
226
222
  end
227
223
 
@@ -8,8 +8,8 @@ module Metanorma
8
8
  def extract_text(node)
9
9
  node.nil? and return ""
10
10
  node1 = Nokogiri::XML.fragment(node.to_s)
11
- node1.xpath(".//link | .//locality | .//localityStack | .//stem")
12
- .each(&:remove)
11
+ node1.xpath(".//link | .//locality | .//localityStack | " \
12
+ ".//stem | .//sourcecode").each(&:remove)
13
13
  ret = ""
14
14
  node1.traverse { |x| ret += x.text if x.text? }
15
15
  HTMLEntities.new.decode(ret)
@@ -218,7 +218,7 @@ module Metanorma
218
218
  end
219
219
 
220
220
  ASSETS_TO_STYLE =
221
- "//termsource | //formula | //termnote | " \
221
+ "//term//source | //formula | //termnote | " \
222
222
  "//p[not(ancestor::boilerplate)] | //li[not(p)] | //dt | " \
223
223
  "//dd[not(p)] | //td[not(p)] | //th[not(p)]".freeze
224
224
 
@@ -82,7 +82,7 @@ module Metanorma
82
82
  withtitle = false
83
83
  xpath.each do |s|
84
84
  title_all_siblings(s.xpath("./clause | ./terms | ./references"),
85
- s&.at("./title")&.text || s["id"])
85
+ s&.at("./title")&.text || s["anchor"])
86
86
  subtitle = s.at("./title")
87
87
  notitle = notitle || (!subtitle || subtitle.text.empty?)
88
88
  withtitle = withtitle || (subtitle && !subtitle.text.empty?)
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module Iso
3
- VERSION = "3.0.6".freeze
3
+ VERSION = "3.0.8".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-iso
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.6
4
+ version: 3.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-29 00:00:00.000000000 Z
11
+ date: 2025-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: metanorma-standoc