metanorma-iso 3.4.8 → 3.4.9

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -0
  3. data/lib/isodoc/iso/html/style-human.css +5 -0
  4. data/lib/isodoc/iso/html/style-iso.css +5 -0
  5. data/lib/isodoc/iso/iso.amendment.xsl +113 -66
  6. data/lib/isodoc/iso/iso.international-standard.xsl +113 -66
  7. data/lib/isodoc/iso/presentation_xml_convert.rb +16 -0
  8. data/lib/metanorma/iso/basicdoc.rng +1 -1
  9. data/lib/metanorma/iso/cleanup_biblio.rb +28 -24
  10. data/lib/metanorma/iso/front_id.rb +4 -0
  11. data/lib/metanorma/iso/{mathml3-content.rng → mathml4-content.rng} +104 -80
  12. data/lib/metanorma/iso/mathml4-core.rng +1041 -0
  13. data/lib/metanorma/iso/{mathml3-presentation.rng → mathml4-presentation.rng} +184 -1060
  14. data/lib/metanorma/iso/{mathml3-strict-content.rng → mathml4-strict-content.rng} +92 -8
  15. data/lib/metanorma/iso/mathml4.rng +30 -0
  16. data/lib/metanorma/iso/metanorma-mathml.rng +22 -8
  17. data/lib/metanorma/iso/processor.rb +32 -2
  18. data/lib/metanorma/iso/sts/transformer/back_transformer.rb +85 -0
  19. data/lib/metanorma/iso/sts/transformer/base.rb +118 -0
  20. data/lib/metanorma/iso/sts/transformer/block_dispatcher.rb +109 -0
  21. data/lib/metanorma/iso/sts/transformer/body_transformer.rb +39 -0
  22. data/lib/metanorma/iso/sts/transformer/content_text.rb +40 -0
  23. data/lib/metanorma/iso/sts/transformer/context.rb +64 -0
  24. data/lib/metanorma/iso/sts/transformer/def_list_transformer.rb +57 -0
  25. data/lib/metanorma/iso/sts/transformer/document_transformer.rb +30 -0
  26. data/lib/metanorma/iso/sts/transformer/example_transformer.rb +41 -0
  27. data/lib/metanorma/iso/sts/transformer/figure_transformer.rb +44 -0
  28. data/lib/metanorma/iso/sts/transformer/footnote_collector.rb +82 -0
  29. data/lib/metanorma/iso/sts/transformer/formula_transformer.rb +38 -0
  30. data/lib/metanorma/iso/sts/transformer/front_transformer.rb +56 -0
  31. data/lib/metanorma/iso/sts/transformer/id_generator.rb +181 -0
  32. data/lib/metanorma/iso/sts/transformer/inline_transformer.rb +293 -0
  33. data/lib/metanorma/iso/sts/transformer/iso_meta_transformer.rb +374 -0
  34. data/lib/metanorma/iso/sts/transformer/list_transformer.rb +65 -0
  35. data/lib/metanorma/iso/sts/transformer/nbsp_processor.rb +43 -0
  36. data/lib/metanorma/iso/sts/transformer/note_transformer.rb +43 -0
  37. data/lib/metanorma/iso/sts/transformer/paragraph_transformer.rb +28 -0
  38. data/lib/metanorma/iso/sts/transformer/quote_transformer.rb +17 -0
  39. data/lib/metanorma/iso/sts/transformer/reference_transformer.rb +136 -0
  40. data/lib/metanorma/iso/sts/transformer/section_transformer.rb +102 -0
  41. data/lib/metanorma/iso/sts/transformer/sourcecode_transformer.rb +18 -0
  42. data/lib/metanorma/iso/sts/transformer/standard.rb +33 -0
  43. data/lib/metanorma/iso/sts/transformer/table_transformer.rb +99 -0
  44. data/lib/metanorma/iso/sts/transformer/term_transformer.rb +227 -0
  45. data/lib/metanorma/iso/sts/transformer.rb +52 -0
  46. data/lib/metanorma/iso/sts.rb +38 -0
  47. data/lib/metanorma/iso/version.rb +1 -1
  48. data/lib/metanorma-iso.rb +1 -0
  49. data/metanorma-iso.gemspec +2 -0
  50. metadata +63 -7
  51. data/.hound.yml +0 -5
  52. data/lib/metanorma/iso/mathml3-common.rng +0 -257
  53. data/lib/metanorma/iso/mathml3.rng +0 -23
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::Context
7
+ attr_reader :source_document, :id_generator, :footnote_collector
8
+
9
+ def initialize(source_document)
10
+ @source_document = source_document
11
+ @id_generator = Transformer::IdGenerator.new(self)
12
+ @footnote_collector = Transformer::FootnoteCollector.new
13
+ end
14
+
15
+ def language
16
+ return nil unless @source_document
17
+
18
+ bibdata = @source_document.bibdata
19
+ return nil unless bibdata
20
+
21
+ lang = bibdata.language
22
+ lang.is_a?(Array) ? lang.first : lang
23
+ end
24
+
25
+ def script
26
+ return nil unless @source_document
27
+
28
+ bibdata = @source_document.bibdata
29
+ return nil unless bibdata
30
+
31
+ scr = bibdata.script
32
+ scr.is_a?(Array) ? scr.first : scr
33
+ end
34
+
35
+ def doctype
36
+ bibdata = @source_document.bibdata
37
+ bibdata&.ext&.doctype
38
+ end
39
+
40
+ def bibitem_lookup
41
+ @bibitem_lookup ||= build_bibitem_lookup
42
+ end
43
+
44
+ private
45
+
46
+ def build_bibitem_lookup
47
+ lookup = {}
48
+ bib = @source_document.bibliography
49
+ return lookup unless bib
50
+
51
+ bib.references&.each do |ref_section|
52
+ ref_section.references&.each do |bibitem|
53
+ next unless bibitem.id
54
+
55
+ lookup[bibitem.id] = bibitem
56
+ end
57
+ end
58
+
59
+ lookup
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::DefListTransformer < Transformer::Base
7
+ def transform(source)
8
+ build_ordered(::Sts::IsoSts::DefList) do |dl|
9
+ dl.id = source.id if source.id && !source.id.start_with?("_")
10
+ dl.list_type = source.key if source.key
11
+
12
+ source.each_mixed_content do |node|
13
+ next if node.is_a?(String)
14
+
15
+ case node
16
+ when Metanorma::Document::Components::Lists::DtElement
17
+ @current_dt = node
18
+ when Metanorma::Document::Components::Lists::DdElement
19
+ dl.def_item transform_def_item(@current_dt, node)
20
+ @current_dt = nil
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def transform_def_item(dt, dd)
29
+ build_ordered(::Sts::IsoSts::DefItem) do |item|
30
+ item.term transform_term(dt) if dt
31
+ item.def transform_def(dd) if dd
32
+ end
33
+ end
34
+
35
+ def transform_term(dt)
36
+ build_ordered(::Sts::IsoSts::Term) do |t|
37
+ t.id = dt.id if dt.id
38
+ inline_transformer.apply_inline_content(dt, t)
39
+ end
40
+ end
41
+
42
+ def transform_def(dd)
43
+ build_ordered(::Sts::IsoSts::Def) do |d|
44
+ if dd.p && !dd.p.empty?
45
+ dd.p.each do |para|
46
+ d.p paragraph_transformer.transform(para)
47
+ end
48
+ end
49
+
50
+ dd.ul&.each { |ul| d.p build_list_paragraph(ul) }
51
+ dd.ol&.each { |ol| d.p build_list_paragraph(ol) }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::DocumentTransformer < Transformer::Base
7
+ def transform(source)
8
+ build_ordered(::Sts::IsoSts::Standard) do |s|
9
+ s.lang = @context.language
10
+ s.front = Transformer::FrontTransformer.new(@context).transform(source)
11
+ s.body = Transformer::BodyTransformer.new(@context).transform(source)
12
+ s.back = Transformer::BackTransformer.new(@context).transform(source)
13
+ end
14
+ end
15
+
16
+ def transform_to_xml(source)
17
+ standard = transform(source)
18
+ xml = standard.to_xml
19
+ apply_nbsp_to_text(xml)
20
+ end
21
+
22
+ private
23
+
24
+ def apply_nbsp_to_text(xml)
25
+ Transformer::NbspProcessor.apply_to_text(xml)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::ExampleTransformer < Transformer::Base
7
+ def transform(source)
8
+ build_ordered(::Sts::IsoSts::NonNormativeExample) do |example|
9
+ example.id = source.id if source.id && !source.id.start_with?("_")
10
+
11
+ transform_example_content(source, example)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def transform_example_content(source, example)
18
+ source.each_mixed_content do |node|
19
+ next if node.is_a?(String)
20
+
21
+ dispatch_block(node, example)
22
+ end
23
+ end
24
+
25
+ def dispatch_block(node, target)
26
+ case node
27
+ when Metanorma::Document::Components::Paragraphs::ParagraphBlock
28
+ target.p paragraph_transformer.transform(node)
29
+ when Metanorma::Document::Components::Lists::UnorderedList,
30
+ Metanorma::Document::Components::Lists::OrderedList
31
+ target.list list_transformer.transform(node)
32
+ when Metanorma::Document::Components::Lists::DefinitionList
33
+ target.def_list def_list_transformer.transform(node)
34
+ when Metanorma::Document::Components::Blocks::NoteBlock
35
+ target.non_normative_note note_transformer.transform(node)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::FigureTransformer < Transformer::Base
7
+ def transform(figure)
8
+ build_ordered(::Sts::IsoSts::Fig) do |f|
9
+ f.id = id_for(figure)
10
+
11
+ figure_label = label_for(figure)
12
+ f.label figure_label if figure_label
13
+
14
+ if figure.title
15
+ caption = build_ordered(::Sts::IsoSts::Caption) do |c|
16
+ inline_transformer.apply_inline_content(figure.title, c)
17
+ end
18
+ f.title caption
19
+ end
20
+
21
+ if figure.image
22
+ images = figure.image.is_a?(Array) ? figure.image : [figure.image]
23
+ images.each do |img|
24
+ next unless img
25
+
26
+ graphic = build_ordered(::Sts::IsoSts::Graphic) do |g|
27
+ g.xlink_href = img.src if img.src
28
+ end
29
+ f.graphic graphic
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def label_for(figure)
38
+ autonum = figure.autonum if figure.class.method_defined?(:autonum)
39
+ autonum && !autonum.to_s.empty? ? ::Sts::IsoSts::Label.new(content: [autonum.to_s]) : nil
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::FootnoteCollector
7
+ def initialize
8
+ @footnotes = {}
9
+ @counter = 0
10
+ end
11
+
12
+ def register(footnote_text, paragraphs: nil)
13
+ normalized = footnote_text.strip
14
+ if @footnotes.key?(normalized)
15
+ @footnotes[normalized]
16
+ else
17
+ @counter += 1
18
+ entry = { id: "fn_#{@counter}", number: @counter,
19
+ paragraphs: paragraphs }
20
+ @footnotes[normalized] = entry
21
+ entry
22
+ end
23
+ end
24
+
25
+ def lookup(footnote_text)
26
+ @footnotes[footnote_text.strip]
27
+ end
28
+
29
+ def empty?
30
+ @footnotes.empty?
31
+ end
32
+
33
+ def count
34
+ @footnotes.size
35
+ end
36
+
37
+ def fn_group
38
+ return nil if @footnotes.empty?
39
+
40
+ group = build_ordered_fn_group
41
+
42
+ @footnotes.each do |text, entry|
43
+ fn = build_ordered_fn
44
+ fn.id = entry[:id]
45
+
46
+ fn_label = ::Sts::IsoSts::Label.new
47
+ fn_label.content = ["<sup>#{entry[:number]})</sup>"]
48
+ fn.label = fn_label
49
+
50
+ paras = entry[:paragraphs]
51
+ if paras && !paras.empty?
52
+ paras.each { |para| fn.paragraph para }
53
+ else
54
+ fn_para = ::Sts::IsoSts::Paragraph.new
55
+ fn_para.content = [text]
56
+ fn.paragraph fn_para
57
+ end
58
+
59
+ group.fn fn
60
+ end
61
+
62
+ group
63
+ end
64
+
65
+ private
66
+
67
+ def build_ordered_fn_group
68
+ inst = ::Sts::IsoSts::FnGroup.new
69
+ inst.instance_variable_set(:@__order_tracking__, true)
70
+ inst.content_type = "footnotes"
71
+ inst
72
+ end
73
+
74
+ def build_ordered_fn
75
+ inst = ::Sts::IsoSts::Fn.new
76
+ inst.instance_variable_set(:@__order_tracking__, true)
77
+ inst
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::FormulaTransformer < Transformer::Base
7
+ def transform(formula)
8
+ ::Sts::IsoSts::DispFormula.new do |f|
9
+ f.id = id_for(formula)
10
+
11
+ formula_label = label_for(formula)
12
+ f.label = formula_label if formula_label
13
+
14
+ if formula.stem
15
+ stem = formula.stem
16
+ if stem.math
17
+ math_el = ::Sts::IsoSts::Mathml2::Math.new
18
+ math_el.content = [stem.math.to_xml]
19
+ f.math = math_el
20
+ elsif stem.content
21
+ tex = ::Sts::NisoSts::TexMath.new
22
+ tex.content = [stem.content]
23
+ f.tex_math = tex
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def label_for(formula)
32
+ autonum = formula.autonum if formula.class.method_defined?(:autonum)
33
+ autonum && !autonum.to_s.empty? ? ::Sts::IsoSts::Label.new(content: [autonum.to_s]) : nil
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::FrontTransformer < Transformer::Base
7
+ def transform(source)
8
+ build_ordered(::Sts::IsoSts::Front) do |f|
9
+ f.iso_meta = Transformer::IsoMetaTransformer.new(@context).transform(source.bibdata)
10
+
11
+ preface = source.preface
12
+ if preface
13
+ transform_preface_sections(preface).each do |sec|
14
+ f.sec sec
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def transform_preface_sections(preface)
23
+ sections = []
24
+
25
+ if preface.foreword
26
+ sections << section_transformer.transform_foreword(preface.foreword)
27
+ end
28
+
29
+ if preface.abstract
30
+ sections << section_transformer.transform_abstract(preface.abstract)
31
+ end
32
+
33
+ if preface.introduction
34
+ sections << section_transformer.transform_introduction(preface.introduction)
35
+ end
36
+
37
+ if preface.clause
38
+ Array(preface.clause).each do |cl|
39
+ sections << section_transformer.transform(cl)
40
+ end
41
+ end
42
+
43
+ if preface.acknowledgements
44
+ sections << section_transformer.transform(preface.acknowledgements)
45
+ end
46
+
47
+ if preface.executivesummary
48
+ sections << section_transformer.transform(preface.executivesummary)
49
+ end
50
+
51
+ sections
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Iso
5
+ module Sts
6
+ class Transformer::IdGenerator
7
+ def initialize(context)
8
+ @context = context
9
+ @id_map = {}
10
+ @section_counters = {
11
+ table: 0,
12
+ figure: 0,
13
+ formula: 0,
14
+ biblref: 0,
15
+ fn: 0,
16
+ unnumbered_table: 0,
17
+ }
18
+ end
19
+
20
+ def register(source_id, sts_id)
21
+ @id_map[source_id] = sts_id
22
+ end
23
+
24
+ def remap(source_id)
25
+ @id_map[source_id] || source_id
26
+ end
27
+
28
+ def id_for(element)
29
+ case element
30
+ when Metanorma::IsoDocument::Sections::IsoForewordSection
31
+ "sec_foreword"
32
+ when Metanorma::IsoDocument::Sections::IsoAbstractSection
33
+ "sec_abstract"
34
+ when Metanorma::IsoDocument::Sections::IsoClauseSection
35
+ id_for_clause(element)
36
+ when Metanorma::IsoDocument::Sections::IsoAnnexSection
37
+ id_for_annex(element)
38
+ when Metanorma::IsoDocument::Sections::IsoTermsSection
39
+ id_for_terms(element)
40
+ when Metanorma::Document::Components::Tables::TableBlock
41
+ id_for_table(element)
42
+ when Metanorma::Document::Components::AncillaryBlocks::FigureBlock
43
+ id_for_figure(element)
44
+ when Metanorma::Document::Components::AncillaryBlocks::FormulaBlock
45
+ id_for_formula(element)
46
+ when Metanorma::Document::Components::Paragraphs::ParagraphBlock
47
+ id_for_paragraph(element)
48
+ when Metanorma::StandardDocument::Sections::StandardReferencesSection
49
+ id_for_ref_section(element)
50
+ else
51
+ id = element.id if element.class.method_defined?(:id)
52
+ id ? remap(id) : nil
53
+ end
54
+ end
55
+
56
+ def section_number(element)
57
+ if element.is_a?(Metanorma::IsoDocument::Sections::IsoClauseSection) ||
58
+ element.is_a?(Metanorma::IsoDocument::Sections::IsoAnnexSection) ||
59
+ element.is_a?(Metanorma::IsoDocument::Sections::IsoTermsSection)
60
+ element.number
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def id_for_clause(clause)
67
+ return remap(clause.id) if clause.id && @id_map.key?(clause.id)
68
+
69
+ number = clause.number
70
+ sts_id = if number && !number.empty?
71
+ "sec_#{number}"
72
+ elsif clause.type == "intro"
73
+ "sec_intro"
74
+ elsif clause.type == "scope"
75
+ "sec_scope"
76
+ else
77
+ clause.id ? remap(clause.id) : nil
78
+ end
79
+
80
+ register(clause.id, sts_id) if clause.id && sts_id
81
+ sts_id
82
+ end
83
+
84
+ def id_for_annex(annex)
85
+ return remap(annex.id) if annex.id && @id_map.key?(annex.id)
86
+
87
+ number = annex.number
88
+ sts_id = if number && !number.empty?
89
+ "sec_#{number}"
90
+ else
91
+ "sec_A"
92
+ end
93
+
94
+ register(annex.id, sts_id) if annex.id
95
+ sts_id
96
+ end
97
+
98
+ def id_for_terms(terms)
99
+ return remap(terms.id) if terms.id && @id_map.key?(terms.id)
100
+
101
+ number = terms.number
102
+ sts_id = if number && !number.empty?
103
+ "sec_#{number}"
104
+ else
105
+ "sec_terms"
106
+ end
107
+
108
+ register(terms.id, sts_id) if terms.id
109
+ sts_id
110
+ end
111
+
112
+ def id_for_table(table)
113
+ return remap(table.id) if table.id && @id_map.key?(table.id)
114
+
115
+ @section_counters[:table] += 1
116
+ number = table.autonum if table.class.method_defined?(:autonum)
117
+ number = nil if number && number.to_s.empty?
118
+ if number
119
+ sts_id = "tab_#{number}"
120
+ else
121
+ letter = ("a".ord + @section_counters[:unnumbered_table]).chr
122
+ @section_counters[:unnumbered_table] += 1
123
+ sts_id = "tab_#{letter}"
124
+ end
125
+
126
+ register(table.id, sts_id) if table.id
127
+ sts_id
128
+ end
129
+
130
+ def id_for_figure(figure)
131
+ return remap(figure.id) if figure.id && @id_map.key?(figure.id)
132
+
133
+ @section_counters[:figure] += 1
134
+ number = figure.autonum if figure.class.method_defined?(:autonum)
135
+ number = nil if number && number.to_s.empty?
136
+ sts_id = if number
137
+ "fig_#{number}"
138
+ else
139
+ "fig_#{@section_counters[:figure]}"
140
+ end
141
+
142
+ register(figure.id, sts_id) if figure.id
143
+ sts_id
144
+ end
145
+
146
+ def id_for_formula(formula)
147
+ return remap(formula.id) if formula.id && @id_map.key?(formula.id)
148
+
149
+ @section_counters[:formula] += 1
150
+ number = formula.autonum if formula.class.method_defined?(:autonum)
151
+ number = nil if number && number.to_s.empty?
152
+ sts_id = if number
153
+ num = number.to_s.gsub(/[()]/, "")
154
+ "formula_#{num}"
155
+ else
156
+ "formula_#{@section_counters[:formula]}"
157
+ end
158
+
159
+ register(formula.id, sts_id) if formula.id
160
+ sts_id
161
+ end
162
+
163
+ def id_for_paragraph(para)
164
+ return nil unless para.id && !para.id.start_with?("_")
165
+
166
+ remap(para.id)
167
+ end
168
+
169
+ def id_for_ref_section(ref_section)
170
+ return remap(ref_section.id) if ref_section.id && @id_map.key?(ref_section.id)
171
+
172
+ normative = ref_section.normative == "true"
173
+ sts_id = normative ? "sec_normrefs" : "sec_bibl"
174
+
175
+ register(ref_section.id, sts_id) if ref_section.id
176
+ sts_id
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end