isodoc 1.6.4 → 1.7.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 +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