metanorma-iso 1.4.3 → 1.5.0

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asciidoctor/iso/base.rb +8 -19
  3. data/lib/asciidoctor/iso/cleanup.rb +2 -3
  4. data/lib/asciidoctor/iso/front.rb +0 -1
  5. data/lib/asciidoctor/iso/front_id.rb +1 -1
  6. data/lib/asciidoctor/iso/isodoc.rng +12 -6
  7. data/lib/asciidoctor/iso/section.rb +5 -11
  8. data/lib/asciidoctor/iso/term_lookup_cleanup.rb +0 -1
  9. data/lib/asciidoctor/iso/validate_section.rb +30 -44
  10. data/lib/isodoc/iso/base_convert.rb +3 -64
  11. data/lib/isodoc/iso/html_convert.rb +2 -1
  12. data/lib/{asciidoctor → isodoc}/iso/i18n-en.yaml +0 -0
  13. data/lib/{asciidoctor → isodoc}/iso/i18n-fr.yaml +0 -0
  14. data/lib/{asciidoctor → isodoc}/iso/i18n-zh-Hans.yaml +0 -0
  15. data/lib/isodoc/iso/i18n.rb +19 -0
  16. data/lib/isodoc/iso/init.rb +33 -0
  17. data/lib/isodoc/iso/metadata.rb +1 -1
  18. data/lib/isodoc/iso/presentation_xml_convert.rb +99 -1
  19. data/lib/isodoc/iso/sections.rb +3 -8
  20. data/lib/isodoc/iso/word_convert.rb +2 -1
  21. data/lib/isodoc/iso/xref.rb +2 -0
  22. data/lib/metanorma/iso/version.rb +1 -1
  23. data/metanorma-iso.gemspec +2 -2
  24. data/spec/asciidoctor-iso/cleanup_spec.rb +4 -4
  25. data/spec/asciidoctor-iso/inline_spec.rb +1 -1
  26. data/spec/asciidoctor-iso/refs_spec.rb +3 -3
  27. data/spec/asciidoctor-iso/section_spec.rb +9 -6
  28. data/spec/asciidoctor-iso/validate_spec.rb +13 -21
  29. data/spec/isodoc/amd_spec.rb +309 -153
  30. data/spec/isodoc/blocks_spec.rb +362 -28
  31. data/spec/isodoc/i18n_spec.rb +468 -108
  32. data/spec/isodoc/inline_spec.rb +99 -31
  33. data/spec/isodoc/iso_spec.rb +95 -29
  34. data/spec/isodoc/postproc_spec.rb +114 -149
  35. data/spec/isodoc/ref_spec.rb +175 -3
  36. data/spec/isodoc/section_spec.rb +148 -82
  37. data/spec/isodoc/table_spec.rb +142 -5
  38. data/spec/isodoc/terms_spec.rb +78 -53
  39. data/spec/isodoc/xref_spec.rb +831 -658
  40. data/spec/metanorma/processor_spec.rb +2 -1
  41. metadata +11 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e88ecac9a1d970682830fc23fc1b808c7b83dedc00a3e6a3adcad7822225622
4
- data.tar.gz: 413f8bb0aac5a124b33992bdaf7977d3e89da0e701512a4d877af68255fd8ba1
3
+ metadata.gz: 273b7adabd08054e60d229e796432e3ef8942a7b622212dc1cb2dcb94f6a1280
4
+ data.tar.gz: 250a5632e1fdda7a675a9584ba49b9ef1262ed21431f94bca33dc5c972efd131
5
5
  SHA512:
6
- metadata.gz: 7b9b163582c5602c131691c8aa484fe20cf4fe02f2fca00b66ef6d50b5515673b8794e0cd4e4a4e404ff169697221551e7a521dac9c7ebb2998b406de7d9b649
7
- data.tar.gz: 26f82fb95d062ddc527a2ac2cefa798edee6771d332307713759ab494fa27a8f16a1e8b27b4f817c088da7ee9e6beac7ea41221618cfd12cfe01dc3f561d309d
6
+ metadata.gz: f3604191621287fba4dc69014fc2e95aaf2c541e9078c3d25d392cc8973d7546003f25a0ac99e3b6ae76f438d8a0cadd97818f64f400efce20e2f63ee35b9255
7
+ data.tar.gz: b5f217e565a26601afb35d9d785be29ef6bea6db86cd260363a209ea5d2c216d1a8ac11fbbb172306290ef5a2449707c7e96b04fde743b182d082ee11fe99be2
@@ -3,7 +3,6 @@ require "nokogiri"
3
3
  require "json"
4
4
  require "pathname"
5
5
  require "open-uri"
6
- require "pp"
7
6
  require "isodoc"
8
7
  require "fileutils"
9
8
  require 'asciidoctor/iso/macros'
@@ -53,26 +52,16 @@ module Asciidoctor
53
52
  def outputs(node, ret)
54
53
  File.open(@filename + ".xml", "w:UTF-8") { |f| f.write(ret) }
55
54
  presentation_xml_converter(node).convert(@filename + ".xml")
56
- html_converter_alt(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}_alt.html")
57
- html_converter(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}.html")
58
- doc_converter(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}.doc")
59
- pdf_converter(node)&.convert(@filename + ".presentation.xml", nil, false, "#{@filename}.pdf")
55
+ html_converter_alt(node).convert(@filename + ".presentation.xml",
56
+ nil, false, "#{@filename}_alt.html")
57
+ html_converter(node).convert(@filename + ".presentation.xml",
58
+ nil, false, "#{@filename}.html")
59
+ doc_converter(node).convert(@filename + ".presentation.xml",
60
+ nil, false, "#{@filename}.doc")
61
+ pdf_converter(node)&.convert(@filename + ".presentation.xml",
62
+ nil, false, "#{@filename}.pdf")
60
63
  #sts_converter(node)&.convert(@filename + ".xml")
61
64
  end
62
-
63
- def load_yaml(lang, script)
64
- y = if @i18nyaml then YAML.load_file(@i18nyaml)
65
- elsif lang == "en"
66
- YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
67
- elsif lang == "fr"
68
- YAML.load_file(File.join(File.dirname(__FILE__), "i18n-fr.yaml"))
69
- elsif lang == "zh" && script == "Hans"
70
- YAML.load_file(File.join(File.dirname(__FILE__), "i18n-zh-Hans.yaml"))
71
- else
72
- YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
73
- end
74
- super.merge(y)
75
- end
76
65
  end
77
66
  end
78
67
  end
@@ -4,20 +4,19 @@ require "htmlentities"
4
4
  require "json"
5
5
  require "pathname"
6
6
  require "open-uri"
7
- require "pp"
8
7
  require "asciidoctor/iso/term_lookup_cleanup"
9
8
 
10
9
  module Asciidoctor
11
10
  module ISO
12
11
  class Converter < Standoc::Converter
13
12
  PRE_NORMREF_FOOTNOTES = "//preface//fn | "\
14
- "//clause[title = 'Scope']//fn".freeze
13
+ "//clause[@type = 'scope']//fn".freeze
15
14
 
16
15
  NORMREF_FOOTNOTES =
17
16
  "//references[@normative = 'true']//fn".freeze
18
17
 
19
18
  POST_NORMREF_FOOTNOTES =
20
- "//sections//clause[not(title = 'Scope')]//fn | "\
19
+ "//sections//clause[not(@type = 'scope')]//fn | "\
21
20
  "//annex//fn | "\
22
21
  "//references[@normative = 'false']//fn".freeze
23
22
 
@@ -4,7 +4,6 @@ require "htmlentities"
4
4
  require "json"
5
5
  require "pathname"
6
6
  require "open-uri"
7
- require "pp"
8
7
  require_relative "front_id"
9
8
 
10
9
  module Asciidoctor
@@ -133,7 +133,7 @@ module Asciidoctor
133
133
  end
134
134
 
135
135
  def id_stage_abbr(stage, substage, node)
136
- ret = IsoDoc::Iso::Metadata.new("en", "Latn", {}).
136
+ ret = IsoDoc::Iso::Metadata.new("en", "Latn", @i18n).
137
137
  status_abbrev(stage_abbr(stage, substage, node.attr("doctype")),
138
138
  substage, node.attr("iteration"),
139
139
  node.attr("draft"), node.attr("doctype"))
@@ -922,6 +922,9 @@
922
922
  <optional>
923
923
  <attribute name="script"/>
924
924
  </optional>
925
+ <optional>
926
+ <attribute name="type"/>
927
+ </optional>
925
928
  <optional>
926
929
  <attribute name="obligation">
927
930
  <choice>
@@ -961,9 +964,6 @@
961
964
  </define>
962
965
  <define name="content-subsection">
963
966
  <element name="clause">
964
- <optional>
965
- <attribute name="type"/>
966
- </optional>
967
967
  <ref name="Content-Section"/>
968
968
  </element>
969
969
  </define>
@@ -992,6 +992,9 @@
992
992
  </choice>
993
993
  </attribute>
994
994
  </optional>
995
+ <optional>
996
+ <attribute name="type"/>
997
+ </optional>
995
998
  <optional>
996
999
  <ref name="section-title"/>
997
1000
  </optional>
@@ -1011,9 +1014,6 @@
1011
1014
  </define>
1012
1015
  <define name="clause">
1013
1016
  <element name="clause">
1014
- <optional>
1015
- <attribute name="type"/>
1016
- </optional>
1017
1017
  <ref name="Clause-Section"/>
1018
1018
  </element>
1019
1019
  </define>
@@ -1042,6 +1042,9 @@
1042
1042
  </choice>
1043
1043
  </attribute>
1044
1044
  </optional>
1045
+ <optional>
1046
+ <attribute name="type"/>
1047
+ </optional>
1045
1048
  <optional>
1046
1049
  <ref name="section-title"/>
1047
1050
  </optional>
@@ -1180,6 +1183,9 @@
1180
1183
  <optional>
1181
1184
  <attribute name="script"/>
1182
1185
  </optional>
1186
+ <optional>
1187
+ <attribute name="type"/>
1188
+ </optional>
1183
1189
  <optional>
1184
1190
  <attribute name="obligation">
1185
1191
  <choice>
@@ -5,13 +5,15 @@ module Asciidoctor
5
5
  module ISO
6
6
  class Converter < Standoc::Converter
7
7
  def clause_parse(attrs, xml, node)
8
- title = node&.attr("heading")&.downcase ||
9
- node.title.gsub(/<[^>]+>/, "").downcase
10
- title == "scope" and return scope_parse(attrs, xml, node)
11
8
  node.option? "appendix" and return appendix_parse(attrs, xml, node)
12
9
  super
13
10
  end
14
11
 
12
+ def scope_parse(attrs, xml, node)
13
+ attrs = attrs.merge(type: "scope") unless @amd
14
+ clause_parse(attrs, xml, node)
15
+ end
16
+
15
17
  def appendix_parse(attrs, xml, node)
16
18
  attrs["inline-header".to_sym] = node.option? "inline-header"
17
19
  set_obligation(attrs, node)
@@ -28,14 +30,6 @@ module Asciidoctor
28
30
  xml << node.content
29
31
  end
30
32
 
31
- def scope_parse(attrs, xml, node)
32
- xml.clause **attr_code(attrs) do |xml_section|
33
- xml_section.title { |t| t << "Scope" }
34
- content = node.content
35
- xml_section << content
36
- end
37
- end
38
-
39
33
  def section_attributes(node)
40
34
  super.merge(
41
35
  change: @amd ? node.attr("change") : nil,
@@ -75,7 +75,6 @@ module Asciidoctor
75
75
 
76
76
  def unique_text_id(text)
77
77
  return "term-#{text}" if xmldoc.at("//*[@id = 'term-#{text}']").nil?
78
-
79
78
  (1..Float::INFINITY).lazy.each do |index|
80
79
  if xmldoc.at("//*[@id = 'term-#{text}-#{index}']").nil?
81
80
  break("term-#{text}-#{index}")
@@ -46,10 +46,11 @@ module Asciidoctor
46
46
  end
47
47
 
48
48
  def seqcheck(names, msg, accepted)
49
- n = names.shift
50
- unless accepted.include? n
49
+ n = names.shift
50
+ return [] if n.nil?
51
+ test = accepted.map { |a| n.at(a) }
52
+ if test.all? { |a| a.nil? }
51
53
  @log.add("Style", nil, msg)
52
- names = []
53
54
  end
54
55
  names
55
56
  end
@@ -60,32 +61,20 @@ module Asciidoctor
60
61
  [
61
62
  {
62
63
  msg: "Initial section must be (content) Foreword",
63
- val: [{ tag: "foreword", title: "Foreword" }],
64
+ val: ["./self::foreword"]
64
65
  },
65
66
  {
66
67
  msg: "Prefatory material must be followed by (clause) Scope",
67
- val: [{ tag: "introduction", title: "Introduction" },
68
- { tag: "clause", title: "Scope" }],
68
+ val: ["./self::introduction", "./self::clause[@type = 'scope']" ]
69
69
  },
70
70
  {
71
71
  msg: "Prefatory material must be followed by (clause) Scope",
72
- val: [{ tag: "clause", title: "Scope" }],
72
+ val: ["./self::clause[@type = 'scope']" ]
73
73
  },
74
74
  {
75
75
  msg: "Normative References must be followed by "\
76
76
  "Terms and Definitions",
77
- val: [
78
- { tag: "terms", title: "Terms and definitions" },
79
- { tag: "clause", title: "Terms and definitions" },
80
- {
81
- tag: "terms",
82
- title: "Terms, definitions, symbols and abbreviated terms",
83
- },
84
- {
85
- tag: "clause",
86
- title: "Terms, definitions, symbols and abbreviated terms",
87
- },
88
- ],
77
+ val: ["./self::terms | .//terms"]
89
78
  },
90
79
  ].freeze
91
80
 
@@ -95,50 +84,47 @@ module Asciidoctor
95
84
  "//clause[descendant::references][not(parent::clause)]".freeze
96
85
 
97
86
  def sections_sequence_validate(root)
98
- f = root.xpath(SECTIONS_XPATH)
99
- names = f.map { |s| { tag: s.name, title: s&.at("./title")&.text } }
100
- names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val]) || return
87
+ names = root.xpath(SECTIONS_XPATH)
88
+ names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val])
101
89
  n = names[0]
102
- names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val]) || return
103
- if n == { tag: "introduction", title: "Introduction" }
104
- names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val]) || return
90
+ names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val])
91
+ if n&.at("./self::introduction")
92
+ names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val])
105
93
  end
106
- names = seqcheck(names, SEQ[3][:msg], SEQ[3][:val]) || return
94
+ names = seqcheck(names, SEQ[3][:msg], SEQ[3][:val])
107
95
  n = names.shift
108
- if n == { tag: "definitions", title: nil }
109
- n = names.shift || return
96
+ if n&.at("./self::definitions")
97
+ n = names.shift
110
98
  end
111
- unless n
99
+ if n.nil? || n.name != "clause"
112
100
  @log.add("Style", nil, "Document must contain at least one clause")
113
- return
114
101
  end
115
- n[:tag] == "clause" ||
102
+ n&.at("./self::clause") ||
116
103
  @log.add("Style", nil, "Document must contain clause after "\
117
104
  "Terms and Definitions")
118
- n == { tag: "clause", title: "Scope" } &&
105
+ n&.at("./self::clause[@type = 'scope']") &&
119
106
  @log.add("Style", nil, "Scope must occur before Terms and Definitions")
120
- n = names.shift || return
121
- while n[:tag] == "clause"
122
- n[:title] == "Scope" &&
107
+ n = names.shift
108
+ while n&.name == "clause"
109
+ n&.at("./self::clause[@type = 'scope']")
123
110
  @log.add("Style", nil, "Scope must occur before Terms and Definitions")
124
- n = names.shift || return
111
+ n = names.shift
125
112
  end
126
- unless n[:tag] == "annex" || n[:tag] == "references"
113
+ unless %w(annex references).include? n&.name
127
114
  @log.add("Style", nil, "Only annexes and references can follow clauses")
128
115
  end
129
- while n[:tag] == "annex"
116
+ while n&.name == "annex"
130
117
  n = names.shift
131
118
  if n.nil?
132
119
  @log.add("Style", nil, "Document must include (references) "\
133
120
  "Normative References")
134
- return
135
121
  end
136
122
  end
137
- n == { tag: "references", title: "Normative References" } ||
123
+ n&.at("./self::references[@normative = 'true']") ||
138
124
  @log.add("Style", nil, "Document must include (references) "\
139
125
  "Normative References")
140
- n = names.shift
141
- n == { tag: "references", title: "Bibliography" } ||
126
+ n = names&.shift
127
+ n&.at("./self::references[@normative = 'false']") ||
142
128
  @log.add("Style", nil, "Final section must be (references) Bibliography")
143
129
  names.empty? ||
144
130
  @log.add("Style", nil, "There are sections after the final Bibliography")
@@ -157,8 +143,8 @@ module Asciidoctor
157
143
  def section_style(root)
158
144
  foreword_style(root.at("//foreword"))
159
145
  introduction_style(root.at("//introduction"))
160
- scope_style(root.at("//clause[title = 'Scope']"))
161
- scope = root.at("//clause[title = 'Scope']/clause")
146
+ scope_style(root.at("//clause[@type = 'scope']"))
147
+ scope = root.at("//clause[@type = 'scope']/clause")
162
148
  # ISO/IEC DIR 2, 14.4
163
149
  scope.nil? || style_warning(scope, SCOPE_WARN, nil)
164
150
  end
@@ -1,25 +1,10 @@
1
1
  require "isodoc"
2
- require_relative "metadata"
3
2
  require_relative "sections"
4
- require_relative "xref"
5
3
  require "fileutils"
6
4
 
7
5
  module IsoDoc
8
6
  module Iso
9
7
  module BaseConvert
10
- def metadata_init(lang, script, labels)
11
- @meta = Metadata.new(lang, script, labels)
12
- end
13
-
14
- def xref_init(lang, script, klass, labels, options)
15
- @xrefs = Xref.new(lang, script, klass, labels, options)
16
- end
17
-
18
- def amd(docxml)
19
- doctype = docxml&.at(ns("//bibdata/ext/doctype"))&.text
20
- %w(amendment technical-corrigendum).include? doctype
21
- end
22
-
23
8
  def convert1(docxml, filename, dir)
24
9
  if amd(docxml)
25
10
  @oldsuppressheadingnumbers = @suppressheadingnumbers
@@ -41,46 +26,10 @@ module IsoDoc
41
26
  end
42
27
  end
43
28
 
44
- def eref_localities1_zh(target, type, from, to, delim)
45
- subsection = from&.text&.match(/\./)
46
- ret = (delim == ";") ? ";" : (type == "list") ? "" : delim
47
- ret += " 第#{from.text}" if from
48
- ret += "&ndash;#{to}" if to
49
- loc = (@locality[type] || type.sub(/^locality:/, "").capitalize )
50
- ret += " #{loc}" unless subsection && type == "clause" ||
51
- type == "list" || target.match(/^IEV$|^IEC 60050-/)
52
- ret += ")" if type == "list"
53
- ret
54
- end
55
-
56
- def eref_localities1(target, type, from, to, delim, lang = "en")
57
- return "" if type == "anchor"
58
- subsection = from&.text&.match(/\./)
59
- type = type.downcase
60
- return l10n(eref_localities1_zh(target, type, from, to, delim)) if lang == "zh"
61
- ret = (delim == ";") ? ";" : (type == "list") ? "" : delim
62
- loc = @locality[type] || type.sub(/^locality:/, "").capitalize
63
- ret += " #{loc}" unless subsection && type == "clause" ||
64
- type == "list" || target.match(/^IEV$|^IEC 60050-/)
65
- ret += " #{from.text}" if from
66
- ret += "&ndash;#{to.text}" if to
67
- ret += ")" if type == "list"
68
- l10n(ret)
69
- end
70
-
71
- def prefix_container(container, linkend, target)
72
- delim = @xrefs.anchor(target, :type) == "listitem" ? " " : ", "
73
- l10n(@xrefs.anchor(container, :xref) + delim + linkend)
74
- end
75
-
76
29
  def example_span_label(node, div, name)
77
- n = @xrefs.get[node["id"]]
30
+ return if name.nil?
78
31
  div.span **{ class: "example_label" } do |p|
79
- lbl = (n.nil? || n[:label].nil? || n[:label].empty?) ? @example_lbl :
80
- l10n("#{@example_lbl} #{n[:label]}")
81
- p << lbl
82
- name and !lbl.nil? and p << "&nbsp;&mdash; "
83
- name and name.children.each { |n| parse(n, div) }
32
+ name.children.each { |n| parse(n, div) }
84
33
  end
85
34
  end
86
35
 
@@ -142,10 +91,6 @@ module IsoDoc
142
91
  super
143
92
  end
144
93
 
145
- def clausedelim
146
- ""
147
- end
148
-
149
94
  def cleanup(docxml)
150
95
  super
151
96
  table_th_center(docxml)
@@ -165,7 +110,7 @@ module IsoDoc
165
110
  dl&.at(ns("./dd"))&.elements&.size == 1 &&
166
111
  dl&.at(ns("./dd/p")))
167
112
  out.span **{ class: "zzMoveToFollowing" } do |s|
168
- s << "#{@where_lbl} "
113
+ s << "#{@i18n.where} "
169
114
  dl.at(ns("./dt")).children.each { |n| parse(n, s) }
170
115
  s << " "
171
116
  end
@@ -202,13 +147,7 @@ module IsoDoc
202
147
  end
203
148
 
204
149
  def figure_name_parse(node, div, name)
205
- lbl = @xrefs.anchor(node['id'], :label, false)
206
- lbl = nil if labelled_ancestor(node) && node.ancestors("figure").empty?
207
- return if lbl.nil? && name.nil?
208
150
  div.p **{ class: "FigureTitle", style: "text-align:center;" } do |p|
209
- figname = node.parent.name == "figure" ? "" : "#{@figure_lbl} "
210
- lbl.nil? or p << l10n("#{figname}#{lbl}")
211
- name and !lbl.nil? and p << "&nbsp;&mdash; "
212
151
  name and name.children.each { |n| parse(n, div) }
213
152
  end
214
153
  end
@@ -1,6 +1,6 @@
1
1
  require_relative "base_convert"
2
+ require_relative "init"
2
3
  require "isodoc"
3
- require_relative "metadata"
4
4
 
5
5
  module IsoDoc
6
6
  module Iso
@@ -49,6 +49,7 @@ module IsoDoc
49
49
  end
50
50
 
51
51
  include BaseConvert
52
+ include Init
52
53
  end
53
54
  end
54
55
  end