metanorma-iec 1.4.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -32
  3. data/.gitignore +14 -0
  4. data/Gemfile +6 -0
  5. data/Rakefile +1 -1
  6. data/lib/isodoc/iec/base_convert.rb +25 -59
  7. data/lib/isodoc/iec/html/htmlstyle.css +38 -6
  8. data/lib/isodoc/iec/html/htmlstyle.scss +35 -6
  9. data/lib/isodoc/iec/html/isodoc.css +1 -2
  10. data/lib/isodoc/iec/html/isodoc.scss +1 -2
  11. data/lib/isodoc/iec/html/scripts.html +0 -1
  12. data/lib/isodoc/iec/html/wordstyle.css +13 -11
  13. data/lib/isodoc/iec/html/wordstyle.scss +13 -11
  14. data/lib/isodoc/iec/html_convert.rb +2 -1
  15. data/lib/isodoc/iec/iec.international-standard.xsl +724 -330
  16. data/lib/isodoc/iec/presentation_xml_convert.rb +193 -5
  17. data/lib/isodoc/iec/xref.rb +9 -8
  18. data/lib/{asciidoctor → metanorma}/iec/basicdoc.rng +0 -0
  19. data/lib/{asciidoctor → metanorma}/iec/biblio.rng +0 -0
  20. data/lib/metanorma/iec/converter.rb +143 -0
  21. data/lib/{asciidoctor → metanorma}/iec/front.rb +3 -4
  22. data/lib/{asciidoctor → metanorma}/iec/iec.rng +48 -0
  23. data/lib/{asciidoctor → metanorma}/iec/iec_intro_en.xml +0 -0
  24. data/lib/{asciidoctor → metanorma}/iec/iec_intro_fr.xml +0 -0
  25. data/lib/{asciidoctor → metanorma}/iec/isodoc.rng +90 -18
  26. data/lib/{asciidoctor → metanorma}/iec/isostandard.rng +14 -0
  27. data/lib/metanorma/iec/processor.rb +15 -8
  28. data/lib/{asciidoctor → metanorma}/iec/reqt.rng +0 -0
  29. data/lib/metanorma/iec/version.rb +1 -1
  30. data/lib/metanorma-iec.rb +1 -1
  31. data/metanorma-iec.gemspec +3 -3
  32. data/spec/isodoc/iev_spec.rb +462 -120
  33. data/spec/isodoc/postproc_spec.rb +2 -5
  34. data/spec/isodoc/ref_spec.rb +359 -353
  35. data/spec/isodoc/terms_spec.rb +183 -181
  36. data/spec/{asciidoctor → metanorma}/base_spec.rb +1 -5
  37. data/spec/{asciidoctor → metanorma}/blocks_spec.rb +1 -1
  38. data/spec/metanorma/cleanup_spec.rb +374 -0
  39. data/spec/metanorma/iev_spec.rb +248 -0
  40. data/spec/{asciidoctor → metanorma}/inline_spec.rb +1 -1
  41. data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
  42. data/spec/metanorma/processor_spec.rb +139 -44
  43. data/spec/{asciidoctor → metanorma}/section_spec.rb +1 -1
  44. data/spec/{asciidoctor → metanorma}/validate_spec.rb +1 -1
  45. data/spec/spec_helper.rb +12 -14
  46. metadata +26 -26
  47. data/lib/asciidoctor/iec/converter.rb +0 -105
  48. data/spec/asciidoctor/cleanup_spec.rb +0 -345
  49. data/spec/asciidoctor/iev_spec.rb +0 -243
@@ -4,6 +4,14 @@ require "isodoc"
4
4
  module IsoDoc
5
5
  module Iec
6
6
  class PresentationXMLConvert < IsoDoc::Iso::PresentationXMLConvert
7
+ def i18n_init(lang, script, i18nyaml = nil)
8
+ super
9
+ @i18n_lg = {}
10
+ @i18n_lg["en"] = I18n.new("en", "Latn", i18nyaml || @i18nyaml)
11
+ @i18n_lg["fr"] = I18n.new("fr", "Latn", i18nyaml || @i18nyaml)
12
+ @i18n_lg["default"] = @i18n
13
+ end
14
+
7
15
  def clause(docxml)
8
16
  docxml.xpath(ns("//clause[not(ancestor::annex)] | "\
9
17
  "//definitions | //references | "\
@@ -29,16 +37,196 @@ module IsoDoc
29
37
  .call(elem)
30
38
  end
31
39
 
40
+ DICT_PATHS = { doctype_dict: "./ext/doctype", stage_dict: "./status/stage",
41
+ substage_dict: "./status/substage",
42
+ function_dict: "./ext/function",
43
+ horizontal_dict: "./ext/horizontal" }.freeze
44
+
32
45
  def bibdata_i18n(bib)
33
46
  fr = IsoDoc::Iec::I18n.new("fr", "Latn")
34
47
  en = IsoDoc::Iec::I18n.new("en", "Latn")
35
48
  [{ lang: "en", i18n: en }, { lang: "fr", i18n: fr }].each do |v|
36
- { doctype_dict: "./ext/doctype", stage_dict: "./status/stage",
37
- substage_dict: "./status/substage", function_dict: "./ext/function",
38
- horizontal_dict: "./ext/horizontal" }.each do |lbl, xpath|
39
- hash_translate(bib, v[:i18n].get[lbl.to_s], xpath, v[:lang])
40
- end
49
+ DICT_PATHS.each do |lbl, xpath|
50
+ hash_translate(bib, v[:i18n].get[lbl.to_s], xpath, v[:lang])
51
+ end
52
+ end
53
+ end
54
+
55
+ def concept(docxml)
56
+ @is_iev and concept_iev(docxml)
57
+ super
58
+ end
59
+
60
+ def concept_iev(docxml)
61
+ labels = @xrefs.get_anchors.each_with_object({}) do |(k, v), m|
62
+ m[v[:label]] = k
63
+ end
64
+ docpart = docxml&.at(ns("//bibdata/ext/structuredidentifier/"\
65
+ "project-number/@part"))&.text or return
66
+ docxml.xpath(ns("//termref[@base = 'IEV']")).each do |t|
67
+ concept_iev1(t, docpart, labels)
68
+ end
69
+ end
70
+
71
+ def concept_iev1(termref, docpart, labels)
72
+ /^#{docpart}-/.match?(termref["target"]) or return
73
+ newtarget = labels[termref["target"]] or return
74
+ termref.name = "xref"
75
+ termref.delete("base")
76
+ termref["target"] = newtarget
77
+ end
78
+
79
+ def terms(docxml)
80
+ otherlang_designations(docxml)
81
+ super
82
+ merge_fr_into_en_term(docxml)
83
+ end
84
+
85
+ def merge_fr_into_en_term(docxml)
86
+ return unless @is_iev
87
+
88
+ docxml.xpath(ns("//term[@language = 'en'][@tag]")).each do |en|
89
+ fr = docxml.at(ns("//term[@language = 'fr'][@tag = '#{en['tag']}']"))
90
+ merge_fr_into_en_term1(en, fr) if fr
91
+ end
92
+ @xrefs.parse docxml
93
+ docxml.xpath(ns("//term/name")).each(&:remove)
94
+ term(docxml)
95
+ end
96
+
97
+ def merge_fr_into_en_term1(en_term, fr_term)
98
+ dl = en_term&.at(ns("./dl[@type = 'other-lang']"))&.remove
99
+ en_term << fr_term.remove.children
100
+ en_term << dl if dl
101
+ en_term["language"] = "en,fr"
102
+ en_term.delete("tag")
103
+ end
104
+
105
+ def otherlang_designations(docxml)
106
+ return unless @is_iev
107
+
108
+ docxml.xpath(ns("//term")).each do |t|
109
+ otherlang_designations1(t, t["language"]&.split(/,/) || %w(en fr))
110
+ end
111
+ end
112
+
113
+ def extract_otherlang_designations(term, lgs)
114
+ term.xpath(ns(".//preferred/expression[@language]"))
115
+ .each_with_object([]) do |d, m|
116
+ lg = d["language"]
117
+ d.delete("language")
118
+ next if lgs.include?(lg)
119
+
120
+ p = d.parent
121
+ designation_annotate(p, d.at(ns("./name")))
122
+ m << { lang: lg, script: Metanorma::Utils.default_script(lg),
123
+ designation: l10n_recursive(p.remove, lg).to_xml.strip }
124
+ end
125
+ end
126
+
127
+ def l10n_recursive(xml, lang)
128
+ script = Metanorma::Utils.default_script(lang)
129
+ c = HTMLEntities.new
130
+ xml.traverse do |x|
131
+ next unless x.text?
132
+
133
+ text = c.encode(c.decode(x.text), :hexadecimal)
134
+ x.replace(cleanup_entities(l10n(text, lang, script), is_xml: false))
41
135
  end
136
+ xml
137
+ end
138
+
139
+ def merge_otherlang_designations(desgn)
140
+ h = desgn.each_with_object({}) do |e, m|
141
+ if m[e[:lang]]
142
+ m[e[:lang]][:designation] += e[:designation]
143
+ else m[e[:lang]] = e
144
+ end
145
+ end
146
+ h.keys.sort.each_with_object([]) { |k, m| m << h[k] }
147
+ end
148
+
149
+ def otherlang_designations1(term, lgs)
150
+ pr = merge_otherlang_designations(
151
+ extract_otherlang_designations(term, lgs),
152
+ )
153
+ return if pr.empty?
154
+
155
+ prefs = pr.map do |p|
156
+ "<dt>#{p[:lang]}</dt>"\
157
+ "<dd language='#{p[:lang]}' script='#{p[:script]}'>"\
158
+ "#{cleanup_entities(p[:designation])}</dd>"
159
+ end
160
+ term << "<dl type='other-lang'>#{prefs.join}</dl>"
161
+ end
162
+
163
+ def related(docxml)
164
+ docxml.xpath(ns("//term[related]")).each { |f| move_related(f) }
165
+ super
166
+ end
167
+
168
+ def move_related(term)
169
+ defn = term.at(ns("./definition")) or return
170
+ term.xpath(ns("./related")).reverse.each do |r|
171
+ defn.next = r.remove
172
+ end
173
+ end
174
+
175
+ def related1(node)
176
+ lg = node&.at("./ancestor::xmlns:term/@language")&.text
177
+ @i18n = @i18n_lg[lg] if lg && @i18n_lg[lg]
178
+ p = node.at(ns("./preferred"))
179
+ ref = node.at(ns("./xref | ./eref | ./termref"))
180
+ label = @i18n.relatedterms[node["type"]].upcase
181
+ node.replace(l10n("<p>#{label}: "\
182
+ "#{p.children.to_xml} (#{ref.to_xml})</p>"))
183
+ @i18n = @i18n_lg["default"]
184
+ end
185
+
186
+ def termsource_modification(node)
187
+ lg = node&.at("./ancestor::xmlns:term/@language")&.text
188
+ @i18n = @i18n_lg[lg] if lg && @i18n_lg[lg]
189
+ super
190
+ @i18n = @i18n_lg["default"]
191
+ end
192
+
193
+ def termsource1(node)
194
+ lg = node&.at("./ancestor::xmlns:term/@language")&.text
195
+ @i18n = @i18n_lg[lg] if lg && @i18n_lg[lg]
196
+ if @is_iev then termsource1_iev(node)
197
+ else super
198
+ end
199
+ @i18n = @i18n_lg["default"]
200
+ end
201
+
202
+ def termsource1_iev(elem)
203
+ while elem&.next_element&.name == "termsource"
204
+ elem << l10n("; #{elem.next_element.remove.children.to_xml}")
205
+ end
206
+ elem.children = l10n("#{@i18n.source}: #{elem.children.to_xml.strip}")
207
+ end
208
+
209
+ def termexample(docxml)
210
+ docxml.xpath(ns("//termexample")).each do |f|
211
+ termexample1(f)
212
+ end
213
+ end
214
+
215
+ def termexample1(elem)
216
+ lg = elem&.at("./ancestor::xmlns:term/@language")&.text
217
+ @i18n = @i18n_lg[lg] if lg && @i18n_lg[lg]
218
+ example1(elem)
219
+ @i18n = @i18n_lg["default"]
220
+ end
221
+
222
+ def termnote1(elem)
223
+ lg = elem&.at("./ancestor::xmlns:term/@language")&.text
224
+ @i18n = @i18n_lg[lg] if lg && @i18n_lg[lg]
225
+
226
+ val = @xrefs.anchor(elem["id"], :value) || "???"
227
+ lbl = @i18n.termnote.gsub(/%/, val)
228
+ prefix_name(elem, "", lower2cap(lbl), "name")
229
+ @i18n = @i18n_lg["default"]
42
230
  end
43
231
 
44
232
  include Init
@@ -16,6 +16,7 @@ module IsoDoc
16
16
  def initial_anchor_names(d)
17
17
  super
18
18
  return unless @is_iev
19
+
19
20
  terms_iev_names(d)
20
21
  middle_section_asset_names(d)
21
22
  termnote_anchor_names(d)
@@ -24,21 +25,21 @@ module IsoDoc
24
25
 
25
26
  def terms_iev_names(d)
26
27
  d.xpath(ns("//sections/clause/terms")).each_with_index do |t, i|
27
- num = "#{@iev_part}-%02d" % [i+1]
28
+ num = "#{@iev_part}-%02d" % [i + 1]
28
29
  @anchors[t["id"]] =
29
- { label: num, xref: l10n("#{@labels["section_iev"]}-#{num}"), level: 2,
30
- type: "clause" }
31
- t.xpath(ns("./term")).each_with_index do |c, i|
32
- num2 = "%02d" % [i+1]
30
+ { label: num, xref: l10n("#{@labels['section_iev']} #{num}"),
31
+ level: 2, type: "clause" }
32
+ t.xpath(ns("./term")).each_with_index do |c, j|
33
+ num2 = "%02d" % [j + 1]
33
34
  section_names1(c, "#{num}-#{num2}", 3)
34
35
  end
35
36
  end
36
37
  end
37
38
 
38
39
  def annex_name_lbl(clause, num)
39
- obl = l10n("(#{@labels["inform_annex"]})")
40
- obl = l10n("(#{@labels["norm_annex"]})") if clause["obligation"] == "normative"
41
- l10n("<strong>#{@labels["annex"]} #{num}</strong><br/>#{obl}")
40
+ obl = l10n("(#{@labels['inform_annex']})")
41
+ obl = l10n("(#{@labels['norm_annex']})") if clause["obligation"] == "normative"
42
+ l10n("<strong>#{@labels['annex']} #{num}</strong><br/>#{obl}")
42
43
  end
43
44
  end
44
45
  end
File without changes
File without changes
@@ -0,0 +1,143 @@
1
+ require "asciidoctor"
2
+ require "metanorma-iso"
3
+ require "metanorma/iso/converter"
4
+ require_relative "./front"
5
+
6
+ module Metanorma
7
+ module Iec
8
+ class Converter < ISO::Converter
9
+ XML_ROOT_TAG = "iec-standard".freeze
10
+ XML_NAMESPACE = "https://www.metanorma.org/ns/iec".freeze
11
+
12
+ register_for "iec"
13
+
14
+ def init(node)
15
+ super
16
+ if @is_iev = node.attr("docnumber") == "60050"
17
+ @vocab = true
18
+ node.set_attr("docsubtype", "vocabulary")
19
+ end
20
+ end
21
+
22
+ def boilerplate_file(x_orig)
23
+ lang = case x_orig&.at("//bibdata/language")&.text
24
+ when "fr" then "fr"
25
+ else
26
+ "en"
27
+ end
28
+ File.join(@libdir, "iec_intro_#{lang}.xml")
29
+ end
30
+
31
+ def doctype_validate(xmldoc)
32
+ doctype = xmldoc&.at("//bibdata/ext/doctype")&.text
33
+ %w(international-standard technical-specification technical-report
34
+ publicly-available-specification international-workshop-agreement
35
+ guide interpretation-sheet).include? doctype or
36
+ @log.add("Document Attributes", nil,
37
+ "#{doctype} is not a recognised document type")
38
+ if function = xmldoc&.at("//bibdata/ext/function")&.text
39
+ %w(emc quality-assurance safety environment).include? function or
40
+ @log.add("Document Attributes", nil,
41
+ "#{function} is not a recognised document function")
42
+ end
43
+ end
44
+
45
+ def validate(doc)
46
+ content_validate(doc)
47
+ schema_validate(formattedstr_strip(doc.dup),
48
+ File.join(File.dirname(__FILE__), "iec.rng"))
49
+ end
50
+
51
+ def html_converter(node)
52
+ if node.nil?
53
+ IsoDoc::Iec::HtmlConvert.new({})
54
+ else
55
+ IsoDoc::Iec::HtmlConvert.new(html_extract_attributes(node))
56
+ end
57
+ end
58
+
59
+ def doc_converter(node)
60
+ if node.nil?
61
+ IsoDoc::Iec::WordConvert.new({})
62
+ else
63
+ IsoDoc::Iec::WordConvert.new(doc_extract_attributes(node))
64
+ end
65
+ end
66
+
67
+ def pdf_converter(node)
68
+ return if node.attr("no-pdf")
69
+
70
+ if node.nil?
71
+ IsoDoc::Iec::PdfConvert.new({})
72
+ else
73
+ IsoDoc::Iec::PdfConvert.new(pdf_extract_attributes(node))
74
+ end
75
+ end
76
+
77
+ def presentation_xml_converter(node)
78
+ if node.nil?
79
+ IsoDoc::Iec::PresentationXMLConvert.new({})
80
+ else
81
+ IsoDoc::Iec::PresentationXMLConvert.new(doc_extract_attributes(node))
82
+ end
83
+ end
84
+
85
+ def norm_ref_preface(node)
86
+ return super unless @is_iev
87
+
88
+ node.at("./title").next =
89
+ "<p>#{@i18n.norm_empty_pref}</p>"
90
+ end
91
+
92
+ def term_defs_boilerplate(div, source, term, preface, isodoc)
93
+ return super unless @is_iev
94
+ end
95
+
96
+ def sections_names_cleanup(xml)
97
+ super
98
+ @is_iev and replace_title(xml, "//introduction",
99
+ @i18n&.introduction_iev)
100
+ end
101
+
102
+ def note(note)
103
+ if note.title == "Note from TC/SC Officers"
104
+ noko do |xml|
105
+ xml.tc_sc_officers_note do |c|
106
+ wrap_in_para(note, c)
107
+ end
108
+ end.join("\n")
109
+ else
110
+ super
111
+ end
112
+ end
113
+
114
+ def note_cleanup(xmldoc)
115
+ super
116
+ n = xmldoc.at("//tc-sc-officers-note") and
117
+ xmldoc.at("//bibdata/ext").add_child(n.remove)
118
+ end
119
+
120
+ def image_name_validate(xmldoc); end
121
+
122
+ def toc_cleanup(xmldoc)
123
+ toc_iev_cleanup(xmldoc) if @is_iev
124
+ super
125
+ end
126
+
127
+ def toc_iev_cleanup(xmldoc)
128
+ iev_variant_titles(xmldoc)
129
+ end
130
+
131
+ def iev_variant_titles(xmldoc)
132
+ id = xmldoc&.at("//bibdata/docidentifier[@type = 'ISO']")&.text
133
+ m = /60050-(\d+)/.match(id) or return
134
+ xmldoc.xpath("//sections/clause/terms/title").each_with_index do |t, i|
135
+ num = "%02d" % [i + 1]
136
+ t.next = "<variant-title type='toc'>"\
137
+ "#{@i18n.section_iev} #{m[1]}-#{num} &#x2013; "\
138
+ "#{t.children.to_xml}</variant-title>"
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -1,4 +1,4 @@
1
- module Asciidoctor
1
+ module Metanorma
2
2
  module Iec
3
3
  class Converter < ISO::Converter
4
4
  def metadata_author(node, xml)
@@ -199,9 +199,8 @@ module Asciidoctor
199
199
  end
200
200
  end
201
201
 
202
- def metadata_doctype(node, xml)
203
- xml.doctype doctype(node)
204
- xml.horizontal (node.attr("horizontal") || "false")
202
+ def metadata_subdoctype(node, xml)
203
+ super
205
204
  a = node.attr("function") and xml.function a
206
205
  end
207
206
 
@@ -57,6 +57,54 @@
57
57
  <ref name="tc-sc-officers-note"/>
58
58
  </optional>
59
59
  </define>
60
+ <define name="term">
61
+ <element name="term">
62
+ <optional>
63
+ <attribute name="id">
64
+ <data type="ID"/>
65
+ </attribute>
66
+ </optional>
67
+ <optional>
68
+ <attribute name="language"/>
69
+ </optional>
70
+ <optional>
71
+ <attribute name="script"/>
72
+ </optional>
73
+ <optional>
74
+ <attribute name="tag"/>
75
+ </optional>
76
+ <optional>
77
+ <attribute name="multilingual-rendering">
78
+ <ref name="MultilingualRenderingType"/>
79
+ </attribute>
80
+ </optional>
81
+ <oneOrMore>
82
+ <ref name="preferred"/>
83
+ </oneOrMore>
84
+ <zeroOrMore>
85
+ <ref name="admitted"/>
86
+ </zeroOrMore>
87
+ <zeroOrMore>
88
+ <ref name="deprecates"/>
89
+ </zeroOrMore>
90
+ <optional>
91
+ <ref name="termdomain"/>
92
+ </optional>
93
+ <ref name="termdefinition"/>
94
+ <zeroOrMore>
95
+ <ref name="termnote"/>
96
+ </zeroOrMore>
97
+ <zeroOrMore>
98
+ <ref name="termexample"/>
99
+ </zeroOrMore>
100
+ <zeroOrMore>
101
+ <ref name="termsource"/>
102
+ </zeroOrMore>
103
+ <zeroOrMore>
104
+ <ref name="term"/>
105
+ </zeroOrMore>
106
+ </element>
107
+ </define>
60
108
  </include>
61
109
  <!-- end overrides -->
62
110
  <define name="function">
File without changes
File without changes