metanorma-iso 1.4.3 → 1.5.0

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