isodoc 1.6.4 → 1.7.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.rubocop.yml +1 -1
  4. data/isodoc.gemspec +2 -1
  5. data/lib/isodoc-yaml/i18n-ar.yaml +19 -25
  6. data/lib/isodoc-yaml/i18n-de.yaml +1 -0
  7. data/lib/isodoc-yaml/i18n-en.yaml +2 -0
  8. data/lib/isodoc-yaml/i18n-es.yaml +1 -0
  9. data/lib/isodoc-yaml/i18n-fr.yaml +2 -0
  10. data/lib/isodoc-yaml/i18n-ru.yaml +1 -0
  11. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +2 -0
  12. data/lib/isodoc/convert.rb +4 -2
  13. data/lib/isodoc/function/blocks.rb +6 -5
  14. data/lib/isodoc/function/references.rb +33 -52
  15. data/lib/isodoc/function/section.rb +0 -1
  16. data/lib/isodoc/function/table.rb +21 -22
  17. data/lib/isodoc/function/terms.rb +6 -7
  18. data/lib/isodoc/gem_tasks.rb +8 -9
  19. data/lib/isodoc/html_convert.rb +5 -1
  20. data/lib/isodoc/html_function/comments.rb +12 -12
  21. data/lib/isodoc/html_function/html.rb +2 -2
  22. data/lib/isodoc/html_function/postprocess.rb +195 -185
  23. data/lib/isodoc/html_function/sectionsplit.rb +244 -0
  24. data/lib/isodoc/metadata.rb +22 -20
  25. data/lib/isodoc/metadata_contributor.rb +31 -28
  26. data/lib/isodoc/presentation_function/bibdata.rb +7 -0
  27. data/lib/isodoc/presentation_function/block.rb +7 -4
  28. data/lib/isodoc/presentation_function/inline.rb +7 -12
  29. data/lib/isodoc/presentation_function/section.rb +38 -1
  30. data/lib/isodoc/presentation_xml_convert.rb +2 -0
  31. data/lib/isodoc/version.rb +1 -1
  32. data/lib/isodoc/xref.rb +10 -7
  33. data/lib/isodoc/xref/xref_anchor.rb +45 -44
  34. data/lib/isodoc/xref/xref_counter.rb +113 -103
  35. data/lib/isodoc/xref/xref_gen.rb +39 -11
  36. data/spec/isodoc/blocks_spec.rb +184 -447
  37. data/spec/isodoc/cleanup_spec.rb +40 -42
  38. data/spec/isodoc/i18n_spec.rb +694 -821
  39. data/spec/isodoc/inline_spec.rb +197 -208
  40. data/spec/isodoc/metadata_spec.rb +384 -379
  41. data/spec/isodoc/postproc_spec.rb +121 -30
  42. data/spec/isodoc/presentation_xml_spec.rb +4 -4
  43. data/spec/isodoc/ref_spec.rb +5 -5
  44. data/spec/isodoc/section_spec.rb +216 -199
  45. data/spec/isodoc/sectionsplit_spec.rb +190 -0
  46. data/spec/isodoc/table_spec.rb +41 -42
  47. data/spec/isodoc/terms_spec.rb +1 -1
  48. data/spec/isodoc/xref_spec.rb +684 -1020
  49. metadata +19 -3
@@ -1,6 +1,7 @@
1
1
  module IsoDoc
2
2
  class PresentationXMLConvert < ::IsoDoc::Convert
3
3
  def bibdata(docxml)
4
+ docid_prefixes(docxml)
4
5
  a = bibdata_current(docxml) or return
5
6
  address_precompose(a)
6
7
  bibdata_i18n(a)
@@ -9,6 +10,12 @@ module IsoDoc
9
10
  "</localized-strings>"
10
11
  end
11
12
 
13
+ def docid_prefixes(docxml)
14
+ docxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
15
+ i.children = @xrefs.klass.docid_prefix(i["type"], i.text)
16
+ end
17
+ end
18
+
12
19
  def address_precompose(bib)
13
20
  bib.xpath(ns("//bibdata//address")).each do |b|
14
21
  next if b.at(ns("./formattedAddress"))
@@ -19,12 +19,15 @@ module IsoDoc
19
19
  end
20
20
  end
21
21
 
22
- def svg_extract(f)
23
- return unless %r{^data:image/svg\+xml;base64,}.match?(f["src"])
22
+ def svg_extract(elem)
23
+ return unless %r{^data:image/svg\+xml;base64,}.match?(elem["src"])
24
24
 
25
- svg = Base64.strict_decode64(f["src"]
25
+ svg = Base64.strict_decode64(elem["src"]
26
26
  .sub(%r{^data:image/svg\+xml;base64,}, ""))
27
- f.replace(svg.sub(/<\?xml[^>]*>/, ""))
27
+ x = Nokogiri::XML.fragment(svg.sub(/<\?xml[^>]*>/, "")) do |config|
28
+ config.huge
29
+ end
30
+ elem.replace(x)
28
31
  end
29
32
 
30
33
  def figure1(f)
@@ -129,10 +129,8 @@ module IsoDoc
129
129
 
130
130
  loc = @i18n.locality[type] || type.sub(/^locality:/, "")
131
131
  loc = case node["case"]
132
- when "capital" then loc.capitalize
133
132
  when "lowercase" then loc.downcase
134
- else
135
- loc.capitalize
133
+ else loc.capitalize
136
134
  end
137
135
  " #{loc}"
138
136
  end
@@ -162,15 +160,12 @@ module IsoDoc
162
160
  end
163
161
 
164
162
  def concept1(node)
165
- content = node.first_element_child.children.reject do |c|
166
- %w{locality localityStack}.include? c.name
167
- end.select { |c| !c.text? || /\S/.match(c) }
168
- n = if content.empty?
169
- @i18n.term_defined_in.sub(/%/, node.first_element_child.to_xml)
170
- else
171
- "<em>#{node.children.to_xml}</em>"
172
- end
173
- node.replace(n)
163
+ node&.at(ns("./refterm"))&.remove
164
+ d = node&.at(ns("./renderterm"))
165
+ d&.name = "em"
166
+ r = node.at(ns("./xref | ./eref | ./termref"))
167
+ r.replace(@i18n.term_defined_in.sub(/%/, r.to_xml))
168
+ node.replace(node.children)
174
169
  end
175
170
 
176
171
  def variant(docxml)
@@ -44,10 +44,47 @@ module IsoDoc
44
44
  prefix_name(elem, "", "#{lbl}#{clausedelim}", "name")
45
45
  end
46
46
 
47
- def references(docxml); end
47
+ def references(docxml)
48
+ end
49
+
50
+ def docid_prefixes(docxml)
51
+ docxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
52
+ i.children = @xrefs.klass.docid_prefix(i["type"], i.text)
53
+ end
54
+ end
48
55
 
49
56
  def index(docxml)
50
57
  docxml.xpath(ns("//index | //index-xref | //indexsect")).each(&:remove)
51
58
  end
59
+
60
+ def display_order_at(docxml, xpath, idx)
61
+ return idx unless c = docxml.at(ns(xpath))
62
+
63
+ idx += 1
64
+ c["displayorder"] = idx
65
+ idx
66
+ end
67
+
68
+ def display_order_xpath(docxml, xpath, idx)
69
+ docxml.xpath(ns(xpath)).each do |c|
70
+ idx += 1
71
+ c["displayorder"] = idx
72
+ end
73
+ idx
74
+ end
75
+
76
+ def display_order(docxml)
77
+ i = 0
78
+ i = display_order_xpath(docxml, "//preface/*", i)
79
+ i = display_order_at(docxml, "//clause[@type = 'scope']", i)
80
+ i = display_order_at(docxml, @xrefs.klass.norm_ref_xpath, i)
81
+ i = display_order_at(docxml, "//sections/terms | "\
82
+ "//sections/clause[descendant::terms]", i)
83
+ i = display_order_at(docxml, "//sections/definitions", i)
84
+ i = display_order_xpath(docxml, @xrefs.klass.middle_clause(docxml), i)
85
+ i = display_order_xpath(docxml, "//annex", i)
86
+ i = display_order_xpath(docxml, @xrefs.klass.bibliography_xpath, i)
87
+ display_order_xpath(docxml, "//indexsect", i)
88
+ end
52
89
  end
53
90
  end
@@ -22,6 +22,7 @@ module IsoDoc
22
22
 
23
23
  def conversions(docxml)
24
24
  bibdata docxml
25
+ @xrefs.parse docxml
25
26
  section docxml
26
27
  block docxml
27
28
  inline docxml
@@ -33,6 +34,7 @@ module IsoDoc
33
34
  term docxml
34
35
  references docxml
35
36
  index docxml
37
+ display_order docxml
36
38
  end
37
39
 
38
40
  def block(docxml)
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.6.4".freeze
2
+ VERSION = "1.7.0".freeze
3
3
  end
data/lib/isodoc/xref.rb CHANGED
@@ -11,6 +11,8 @@ module IsoDoc
11
11
  include XrefGen::Blocks
12
12
  include XrefGen::Sections
13
13
 
14
+ attr_reader :klass
15
+
14
16
  def initialize(lang, script, klass, i18n, options = {})
15
17
  @anchors = {}
16
18
  @lang = lang
@@ -26,16 +28,16 @@ module IsoDoc
26
28
  @anchors
27
29
  end
28
30
 
29
- def anchor(id, lbl, warning = true)
30
- return nil if id.nil? || id.empty?
31
+ def anchor(ident, lbl, warning = true)
32
+ return nil if ident.nil? || ident.empty?
31
33
 
32
- if warning && !@anchors[id]
34
+ if warning && !@anchors[ident]
33
35
  @seen ||= Seen_Anchor.instance
34
- @seen.seen(id) or warn "No label has been processed for ID #{id}"
35
- @seen.add(id)
36
- return "[#{id}]"
36
+ @seen.seen(ident) or warn "No label has been processed for ID #{ident}"
37
+ @seen.add(ident)
38
+ return "[#{ident}]"
37
39
  end
38
- @anchors.dig(id, lbl)
40
+ @anchors.dig(ident, lbl)
39
41
  end
40
42
 
41
43
  # extract names for all anchors, xref and label
@@ -48,6 +50,7 @@ module IsoDoc
48
50
  note_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
49
51
  example_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
50
52
  list_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
53
+ deflist_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
51
54
  bookmark_anchor_names(docxml)
52
55
  end
53
56
 
@@ -1,61 +1,62 @@
1
1
  require "singleton"
2
2
 
3
- module IsoDoc::XrefGen
4
- module Anchor
5
- class Seen_Anchor
6
- include Singleton
3
+ module IsoDoc
4
+ module XrefGen
5
+ module Anchor
6
+ class Seen_Anchor
7
+ include Singleton
8
+
9
+ def initialize
10
+ @seen = {}
11
+ end
12
+
13
+ def seen(elem)
14
+ @seen.has_key?(elem)
15
+ end
16
+
17
+ def add(elem)
18
+ @seen[elem] = true
19
+ end
20
+ end
7
21
 
8
22
  def initialize
9
- @seen = {}
23
+ @anchors = {}
10
24
  end
11
25
 
12
- def seen(x)
13
- @seen.has_key?(x)
26
+ def get_anchors
27
+ @anchors
14
28
  end
15
29
 
16
- def add(x)
17
- @seen[x] = true
30
+ def anchor_struct_label(lbl, elem)
31
+ case elem
32
+ when @labels["appendix"] then l10n("#{elem} #{lbl}")
33
+ else
34
+ lbl.to_s
35
+ end
18
36
  end
19
- end
20
-
21
- def initialize()
22
- @anchors = {}
23
- end
24
-
25
- def get_anchors
26
- @anchors
27
- end
28
37
 
29
- def anchor_struct_label(lbl, elem)
30
- case elem
31
- when @labels["appendix"] then l10n("#{elem} #{lbl}")
32
- else
33
- lbl.to_s
38
+ def anchor_struct_xref(lbl, elem)
39
+ l10n("#{elem} #{anchor_struct_value(lbl, elem)}")
34
40
  end
35
- end
36
-
37
- def anchor_struct_xref(lbl, elem)
38
- l10n("#{elem} #{anchor_struct_value(lbl, elem)}")
39
- end
40
41
 
41
- def anchor_struct_value(lbl, elem)
42
- case elem
43
- when @labels["formula"] then "(#{lbl})"
44
- when @labels["inequality"] then "(#{lbl})"
45
- else
46
- lbl
42
+ def anchor_struct_value(lbl, elem)
43
+ case elem
44
+ when @labels["formula"], @labels["inequality"] then "(#{lbl})"
45
+ else
46
+ lbl
47
+ end
47
48
  end
48
- end
49
49
 
50
- def anchor_struct(lbl, container, elem, type, unnumbered = false)
51
- ret = {}
52
- ret[:label] = unnumbered == "true" ? nil : anchor_struct_label(lbl, elem)
53
- ret[:xref] = anchor_struct_xref(unnumbered == "true" ? "(??)" : lbl, elem)
54
- ret[:xref].gsub!(/ $/, "")
55
- ret[:container] = @klass.get_clause_id(container) unless container.nil?
56
- ret[:type] = type
57
- ret[:value] = anchor_struct_value(lbl, elem)
58
- ret
50
+ def anchor_struct(lbl, container, elem, type, unnumb = false)
51
+ ret = {}
52
+ ret[:label] = unnumb == "true" ? nil : anchor_struct_label(lbl, elem)
53
+ ret[:xref] = anchor_struct_xref(unnumb == "true" ? "(??)" : lbl, elem)
54
+ ret[:xref].gsub!(/ $/, "")
55
+ ret[:container] = @klass.get_clause_id(container) unless container.nil?
56
+ ret[:type] = type
57
+ ret[:value] = anchor_struct_value(lbl, elem)
58
+ ret
59
+ end
59
60
  end
60
61
  end
61
62
  end
@@ -1,33 +1,37 @@
1
1
  require "roman-numerals"
2
2
 
3
- module IsoDoc::XrefGen
4
- class Counter
5
- def initialize(num = 0, opts = { numerals: :arabic })
6
- @num = num
7
- @letter = ""
8
- @subseq = ""
9
- @letter_override = nil
10
- @number_override = nil
11
- @style = opts[:numerals]
12
- @skip_i = opts[:skip_i]
13
- @base = ""
14
- if num.is_a? String
15
- if /^\d+$/.match?(num)
16
- @num = num.to_i
17
- else
18
- @num = nil
19
- @base = num[0..-2]
20
- @letter = num[-1]
3
+ module IsoDoc
4
+ module XrefGen
5
+ class Counter
6
+ def initialize(num = 0, opts = { numerals: :arabic })
7
+ @num = num
8
+ @letter = ""
9
+ @subseq = ""
10
+ @letter_override = nil
11
+ @number_override = nil
12
+ @style = opts[:numerals]
13
+ @skip_i = opts[:skip_i]
14
+ @base = ""
15
+ if num.is_a? String
16
+ if /^\d+$/.match?(num)
17
+ @num = num.to_i
18
+ else
19
+ @num = nil
20
+ @base = num[0..-2]
21
+ @letter = num[-1]
22
+ end
21
23
  end
22
24
  end
23
- end
24
25
 
25
- def new_subseq_increment(node)
26
- @subseq = node["subsequence"]
27
- @num += 1 unless @num.nil?
28
- @letter = node["subsequence"] ? "a" : ""
29
- @base = ""
30
- if node["number"]
26
+ def new_subseq_increment(node)
27
+ @subseq = node["subsequence"]
28
+ @num += 1 unless @num.nil?
29
+ @letter = node["subsequence"] ? "a" : ""
30
+ @base = ""
31
+ new_subseq_increment1(node) if node["number"]
32
+ end
33
+
34
+ def new_subseq_increment1(node)
31
35
  /^(?<b>.*?)(?<n>\d*)(?<a>[a-zA-Z]*)$/ =~ node["number"]
32
36
  if !n.empty? || !a.empty?
33
37
  @letter_override = @letter = a unless a.empty?
@@ -38,108 +42,114 @@ module IsoDoc::XrefGen
38
42
  @letter = @letter_override if /^[a-zA-Z]$/.match?(@letter_override)
39
43
  end
40
44
  end
41
- end
42
45
 
43
- def sequence_increment(node)
44
- if node["number"]
45
- @base = @letter_override = @number_override = ""
46
- /^(?<b>.*?)(?<n>\d+)$/ =~ node["number"]
47
- if blank?(n)
48
- @num = nil
49
- @base = node["number"][0..-2]
50
- @letter = @letter_override = node["number"][-1]
51
- else
52
- @number_override = @num = n.to_i
53
- @base = b
54
- @letter = ""
46
+ def sequence_increment(node)
47
+ if node["number"]
48
+ @base = @letter_override = @number_override = ""
49
+ /^(?<b>.*?)(?<n>\d+)$/ =~ node["number"]
50
+ if blank?(n)
51
+ @num = nil
52
+ @base = node["number"][0..-2]
53
+ @letter = @letter_override = node["number"][-1]
54
+ else
55
+ @number_override = @num = n.to_i
56
+ @base = b
57
+ @letter = ""
58
+ end
59
+ else @num += 1
55
60
  end
56
- else
57
- @num += 1
58
61
  end
59
- end
60
62
 
61
- def subsequence_increment(node)
62
- if node["number"]
63
+ def subsequence_increment(node)
64
+ return increment_letter unless node["number"]
65
+
63
66
  @base = ""
64
67
  @letter_override = node["number"]
65
68
  /^(?<b>.*?)(?<n>\d*)(?<a>[a-zA-Z])$/ =~ node["number"]
66
- if blank?(a)
67
- if /^\d+$/.match?(node["number"])
68
- @letter_override = @letter = ""
69
- @number_override = @num = node["number"].to_i
70
- else
71
- /^(?<b>.*)(?<a>[a-zA-Z])$/ =~ node["number"]
72
- unless blank?(a)
73
- @letter = @letter_override = a
74
- @base = b
75
- end
76
- end
69
+ if blank?(a) then subsequence_increment_no_letter(node)
77
70
  else
78
71
  @letter_override = @letter = a
79
72
  @base = b
80
73
  @number_override = @num = n.to_i unless n.empty?
81
74
  end
82
- else
83
- increment_letter
84
75
  end
85
- end
86
76
 
87
- def increment_letter
88
- case @letter
89
- when "Z"
90
- @letter = "@"
91
- @base = @base.empty? ? "A" : @base[0..-2] + (@base[-1].ord + 1).chr.to_s
92
- when "z"
93
- @letter = "`"
94
- @base = @base.empty? ? "a" : @base[0..-2] + (@base[-1].ord + 1).chr.to_s
77
+ def subsequence_increment_no_letter(node)
78
+ if /^\d+$/.match?(node["number"])
79
+ @letter_override = @letter = ""
80
+ @number_override = @num = node["number"].to_i
81
+ else
82
+ /^(?<b>.*)(?<a>[a-zA-Z])$/ =~ node["number"]
83
+ unless blank?(a)
84
+ @letter = @letter_override = a
85
+ @base = b
86
+ end
87
+ end
88
+ end
89
+
90
+ def string_inc(str, start)
91
+ return start if str.empty?
92
+
93
+ str[0..-2] + (str[-1].ord + 1).chr.to_s
95
94
  end
96
- @letter = (@letter.ord + 1).chr.to_s
97
- @skip_i && %w(i I).include?(@letter) and
95
+
96
+ def increment_letter
97
+ case @letter
98
+ when "Z"
99
+ @letter = "@"
100
+ @base = string_inc(@base, "A")
101
+ when "z"
102
+ @letter = "`"
103
+ @base = string_inc(@base, "a")
104
+ end
98
105
  @letter = (@letter.ord + 1).chr.to_s
99
- end
106
+ @skip_i && %w(i I).include?(@letter) and
107
+ @letter = (@letter.ord + 1).chr.to_s
108
+ end
100
109
 
101
- def blank?(str)
102
- str.nil? || str.empty?
103
- end
110
+ def blank?(str)
111
+ str.nil? || str.empty?
112
+ end
104
113
 
105
- def increment(node)
106
- return self if node["unnumbered"]
114
+ def increment(node)
115
+ return self if node["unnumbered"]
107
116
 
108
- @letter_override = nil
109
- @number_override = nil
110
- if node["subsequence"] != @subseq &&
111
- !(blank?(node["subsequence"]) && blank?(@subseq))
112
- new_subseq_increment(node)
113
- elsif @letter.empty? then sequence_increment(node)
114
- else subsequence_increment(node)
117
+ @letter_override = nil
118
+ @number_override = nil
119
+ if node["subsequence"] != @subseq &&
120
+ !(blank?(node["subsequence"]) && blank?(@subseq))
121
+ new_subseq_increment(node)
122
+ elsif @letter.empty? then sequence_increment(node)
123
+ else subsequence_increment(node)
124
+ end
125
+ self
115
126
  end
116
- self
117
- end
118
127
 
119
- def print
120
- num = @number_override || @num
121
- out = @style == :roman && !num.nil? ? RomanNumerals.to_roman(num) : num
122
- "#{@base}#{out}#{@letter_override || @letter}"
123
- end
128
+ def print
129
+ num = @number_override || @num
130
+ out = @style == :roman && !num.nil? ? RomanNumerals.to_roman(num) : num
131
+ "#{@base}#{out}#{@letter_override || @letter}"
132
+ end
124
133
 
125
- def ol_type(list, depth)
126
- return list["type"].to_sym if list["type"]
127
- return :arabic if [2, 7].include? depth
128
- return :alphabet if [1, 6].include? depth
129
- return :alphabet_upper if [4, 9].include? depth
130
- return :roman if [3, 8].include? depth
131
- return :roman_upper if [5, 10].include? depth
134
+ def ol_type(list, depth)
135
+ return list["type"].to_sym if list["type"]
136
+ return :arabic if [2, 7].include? depth
137
+ return :alphabet if [1, 6].include? depth
138
+ return :alphabet_upper if [4, 9].include? depth
139
+ return :roman if [3, 8].include? depth
140
+ return :roman_upper if [5, 10].include? depth
132
141
 
133
- :arabic
134
- end
142
+ :arabic
143
+ end
135
144
 
136
- def listlabel(list, depth)
137
- case ol_type(list, depth)
138
- when :arabic then @num.to_s
139
- when :alphabet then (96 + @num).chr.to_s
140
- when :alphabet_upper then (64 + @num).chr.to_s
141
- when :roman then RomanNumerals.to_roman(@num).downcase
142
- when :roman_upper then RomanNumerals.to_roman(@num).upcase
145
+ def listlabel(list, depth)
146
+ case ol_type(list, depth)
147
+ when :arabic then @num.to_s
148
+ when :alphabet then (96 + @num).chr.to_s
149
+ when :alphabet_upper then (64 + @num).chr.to_s
150
+ when :roman then RomanNumerals.to_roman(@num).downcase
151
+ when :roman_upper then RomanNumerals.to_roman(@num).upcase
152
+ end
143
153
  end
144
154
  end
145
155
  end