isodoc 2.0.4 → 2.0.5

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/isodoc/convert.rb +36 -18
  3. data/lib/isodoc/function/inline.rb +24 -13
  4. data/lib/isodoc/function/references.rb +1 -1
  5. data/lib/isodoc/i18n.rb +20 -7
  6. data/lib/isodoc/metadata_contributor.rb +1 -1
  7. data/lib/isodoc/presentation_function/bibdata.rb +26 -9
  8. data/lib/isodoc/presentation_function/inline.rb +111 -75
  9. data/lib/isodoc/presentation_function/math.rb +1 -0
  10. data/lib/isodoc/presentation_function/xrefs.rb +100 -0
  11. data/lib/isodoc/version.rb +1 -1
  12. data/lib/isodoc/word_function/body.rb +11 -1
  13. data/lib/isodoc/word_function/postprocess.rb +4 -6
  14. data/lib/isodoc/word_function/postprocess_cover.rb +82 -1
  15. data/lib/isodoc/xref/xref_anchor.rb +1 -0
  16. data/lib/isodoc/xref/xref_gen.rb +2 -1
  17. data/lib/isodoc/xref/xref_sect_gen.rb +14 -8
  18. data/lib/isodoc/xslfo_convert.rb +19 -19
  19. data/lib/isodoc-yaml/i18n-ar.yaml +11 -0
  20. data/lib/isodoc-yaml/i18n-de.yaml +11 -0
  21. data/lib/isodoc-yaml/i18n-en.yaml +11 -0
  22. data/lib/isodoc-yaml/i18n-es.yaml +11 -0
  23. data/lib/isodoc-yaml/i18n-fr.yaml +11 -0
  24. data/lib/isodoc-yaml/i18n-ru.yaml +11 -0
  25. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +11 -0
  26. data/spec/isodoc/blocks_spec.rb +1 -1
  27. data/spec/isodoc/inline_spec.rb +528 -22
  28. data/spec/isodoc/metadata_spec.rb +1 -1
  29. data/spec/isodoc/postproc_spec.rb +466 -2
  30. data/spec/isodoc/presentation_xml_spec.rb +139 -0
  31. data/spec/isodoc/ref_spec.rb +7 -7
  32. data/spec/isodoc/section_spec.rb +1 -2
  33. data/spec/isodoc/terms_spec.rb +8 -8
  34. data/spec/isodoc/xref_spec.rb +60 -1188
  35. data/spec/isodoc/xslfo_convert_spec.rb +12 -7
  36. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a9645f7c8069398010a6b360e94069382fec990f4d8c2563e2c35ccde801b45
4
- data.tar.gz: 3209942625f1f64ba90e9de9dfd1780de61368d227830cbdc36e65046697eb06
3
+ metadata.gz: e1cd1a1265557222ad7684ab50c08fd55d8cc92b46a3997a298f61c0e8b151bc
4
+ data.tar.gz: 394d232d1f1b9e9b4d138df36b555b090b923c96a3f848e7a88cd9d72a3e173a
5
5
  SHA512:
6
- metadata.gz: cdee63b9b9d3e2b0b4b4fa7b1dea74f5faa50c07d5ed3637744f5f52521821554513f3f4812bd57e5de9c0f6c61c4e73005be0d46127f39347f0f19e5912915c
7
- data.tar.gz: 4d01286691c228c29100d79f78bb7f819a832fe05a730f56a8416422a1e59eb70c6a900242fb41fd631a63592600f3950e8dbe8079f1731754738a0aed8d6d4c
6
+ metadata.gz: 38809fca460021e23cdebe0beb21ba510e59120edba915a760ccbe5248cb73381b0694c0842cfd8bedc00f7d45298765281a36a84ad6bd4283e608f80424f67d
7
+ data.tar.gz: d2ea4b7bb2b0f461ff511da937a9e1ee359321bb228eba89c9ad2808b1e39c92b39af45100503be594c94f74fea0d0571641314f22e0cef645e91c7555e014b5
@@ -40,6 +40,9 @@ module IsoDoc
40
40
  # every 40-odd chars
41
41
  # sectionsplit: split up HTML output on sections
42
42
  # bare: do not insert any prefatory material (coverpage, boilerplate)
43
+ # tocfigures: add ToC for figures
44
+ # toctables: add ToC for tables
45
+ # tocrecommendations: add ToC for rcommendations
43
46
  def initialize(options)
44
47
  @libdir ||= File.dirname(__FILE__) # rubocop:disable Lint/DisjunctiveAssignmentInConstructor
45
48
  options.merge!(default_fonts(options)) do |_, old, new|
@@ -50,25 +53,14 @@ module IsoDoc
50
53
  @options = options
51
54
  @files_to_delete = []
52
55
  @tempfile_cache = []
53
- @htmlstylesheet_name = options[:htmlstylesheet]
54
- @wordstylesheet_name = options[:wordstylesheet]
55
- @htmlstylesheet_override_name = options[:htmlstylesheet_override]
56
- @wordstylesheet_override_name = options[:wordstylesheet_override]
57
- @standardstylesheet_name = options[:standardstylesheet]
58
56
  @sourcefilename = options[:sourcefilename]
59
- @header = options[:header]
60
- @htmlcoverpage = options[:htmlcoverpage]
61
- @wordcoverpage = options[:wordcoverpage]
62
- @htmlintropage = options[:htmlintropage]
63
- @wordintropage = options[:wordintropage]
57
+ init_stylesheets(options)
58
+ init_covers(options)
59
+ init_toc(options)
64
60
  @normalfontsize = options[:normalfontsize]
65
61
  @smallerfontsize = options[:smallerfontsize]
66
62
  @monospacefontsize = options[:monospacefontsize]
67
63
  @footnotefontsize = options[:footnotefontsize]
68
- @scripts = options[:scripts] ||
69
- File.join(File.dirname(__FILE__), "base_style", "scripts.html")
70
- @scripts_pdf = options[:scripts_pdf]
71
- @scripts_override = options[:scripts_override]
72
64
  @i18nyaml = options[:i18nyaml]
73
65
  @ulstyle = options[:ulstyle]
74
66
  @olstyle = options[:olstyle]
@@ -96,10 +88,6 @@ module IsoDoc
96
88
  @script = options[:script] || "Latn"
97
89
  @maxwidth = 1200
98
90
  @maxheight = 800
99
- @wordToClevels = options[:doctoclevels].to_i
100
- @wordToClevels = 2 if @wordToClevels.zero?
101
- @htmlToClevels = options[:htmltoclevels].to_i
102
- @htmlToClevels = 2 if @htmlToClevels.zero?
103
91
  @bookmarks_allocated = { "X" => true }
104
92
  @fn_bookmarks = {}
105
93
  @baseassetpath = options[:baseassetpath]
@@ -108,6 +96,36 @@ module IsoDoc
108
96
  @tmpfilesdir_suffix = tmpfilesdir_suffix
109
97
  end
110
98
 
99
+ def init_covers(options)
100
+ @header = options[:header]
101
+ @htmlcoverpage = options[:htmlcoverpage]
102
+ @wordcoverpage = options[:wordcoverpage]
103
+ @htmlintropage = options[:htmlintropage]
104
+ @wordintropage = options[:wordintropage]
105
+ @scripts = options[:scripts] ||
106
+ File.join(File.dirname(__FILE__), "base_style", "scripts.html")
107
+ @scripts_pdf = options[:scripts_pdf]
108
+ @scripts_override = options[:scripts_override]
109
+ end
110
+
111
+ def init_stylesheets(options)
112
+ @htmlstylesheet_name = options[:htmlstylesheet]
113
+ @wordstylesheet_name = options[:wordstylesheet]
114
+ @htmlstylesheet_override_name = options[:htmlstylesheet_override]
115
+ @wordstylesheet_override_name = options[:wordstylesheet_override]
116
+ @standardstylesheet_name = options[:standardstylesheet]
117
+ end
118
+
119
+ def init_toc(options)
120
+ @wordToClevels = options[:doctoclevels].to_i
121
+ @wordToClevels = 2 if @wordToClevels.zero?
122
+ @htmlToClevels = options[:htmltoclevels].to_i
123
+ @htmlToClevels = 2 if @htmlToClevels.zero?
124
+ @tocfigures = options[:tocfigures]
125
+ @toctables = options[:toctables]
126
+ @tocrecommendations = options[:tocrecommendations]
127
+ end
128
+
111
129
  def tmpimagedir_suffix
112
130
  "_#{SecureRandom.hex(8)}_images"
113
131
  end
@@ -34,30 +34,41 @@ module IsoDoc
34
34
  end
35
35
 
36
36
  def suffix_url(url)
37
- return url if %r{^https?://}.match?(url)
37
+ return url if url.nil? || %r{^https?://|^#}.match?(url)
38
38
  return url unless File.extname(url).empty?
39
39
 
40
40
  url.sub(/#{File.extname(url)}$/, ".html")
41
41
  end
42
42
 
43
43
  def eref_target(node)
44
- return "##{node['bibitemid']}" unless (!@bibitems.nil? &&
45
- url = @bibitems[node["bibitemid"]]&.at(ns("./uri[@type = 'citation']")))
44
+ url = suffix_url(eref_url(node["bibitemid"]))
45
+ anchor = node&.at(ns(".//locality[@type = 'anchor']"))
46
+ return url if url.nil? || /^#/.match?(url) || !anchor
46
47
 
47
- href = suffix_url(url.text)
48
- anchor = node&.at(ns(".//locality[@type = 'anchor']"))&.text&.strip
49
- anchor and href += "##{anchor}"
50
- href
48
+ "#{url}##{anchor.text.strip}"
49
+ end
50
+
51
+ def eref_url(bibitemid)
52
+ return nil if @bibitems.nil? || @bibitems[bibitemid].nil?
53
+
54
+ if url = @bibitems[bibitemid].at(ns("./uri[@type = 'citation']"))
55
+ url.text
56
+ elsif @bibitems[bibitemid]["hidden"] == "true"
57
+ @bibitems[bibitemid]&.at(ns("./uri"))&.text
58
+ else "##{bibitemid}"
59
+ end
51
60
  end
52
61
 
53
62
  def eref_parse(node, out)
54
- href = eref_target(node)
55
- if node["type"] == "footnote"
56
- out.sup do |s|
57
- s.a(**{ href: href }) { |l| no_locality_parse(node, l) }
63
+ if href = eref_target(node)
64
+ if node["type"] == "footnote"
65
+ out.sup do |s|
66
+ s.a(**{ href: href }) { |l| no_locality_parse(node, l) }
67
+ end
68
+ else
69
+ out.a(**{ href: href }) { |l| no_locality_parse(node, l) }
58
70
  end
59
- else
60
- out.a(**{ href: href }) { |l| no_locality_parse(node, l) }
71
+ else no_locality_parse(node, out)
61
72
  end
62
73
  end
63
74
 
@@ -118,7 +118,7 @@ module IsoDoc
118
118
  date_note = bib.at(ns("./note[@type = 'Unpublished-Status']"))
119
119
  return if date_note.nil?
120
120
 
121
- date_note.children.first.replace("<p>#{date_note.content}</p>")
121
+ date_note.children = "<p>#{date_note.content}</p>"
122
122
  footnote_parse(date_note, ref)
123
123
  end
124
124
 
data/lib/isodoc/i18n.rb CHANGED
@@ -104,15 +104,28 @@ module IsoDoc
104
104
  xml.to_xml.gsub(/<b>/, "").gsub("</b>", "").gsub(/<\?[^>]+>/, "")
105
105
  end
106
106
 
107
- def multiple_and(names, andword)
108
- return "" if names.empty?
109
- return names[0] if names.length == 1
110
-
111
- (names.length == 2) &&
112
- (return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script))
113
- l10n(names[0..-2].join(", ") + " #{andword} #{names[-1]}", @lang, @script)
107
+ def boolean_conj(list, conn)
108
+ case list.size
109
+ when 0 then ""
110
+ when 1 then list.first
111
+ when 2 then @labels["binary_#{conn}"].sub(/%1/, list[0])
112
+ .sub(/%2/, list[1])
113
+ else
114
+ @labels["multiple_#{conn}"]
115
+ .sub(/%1/, l10n(list[0..-2].join(", "), @lang, @script))
116
+ .sub(/%2/, list[-1])
117
+ end
114
118
  end
115
119
 
120
+ # def multiple_and(names, andword)
121
+ # return "" if names.empty?
122
+ # return names[0] if names.length == 1
123
+ #
124
+ # (names.length == 2) &&
125
+ # (return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script))
126
+ # l10n(names[0..-2].join(", ") + " #{andword} #{names[-1]}", @lang, @script)
127
+ # end
128
+
116
129
  include Function::Utils
117
130
  # module_function :l10n
118
131
  end
@@ -75,7 +75,7 @@ module IsoDoc
75
75
  def agency(xml)
76
76
  agency, publisher = agency1(xml)
77
77
  set(:agency, agency.sub(%r{/$}, ""))
78
- set(:publisher, @i18n.multiple_and(publisher, @labels["and"]))
78
+ set(:publisher, @i18n.boolean_conj(publisher, "and"))
79
79
  agency_addr(xml)
80
80
  end
81
81
 
@@ -1,15 +1,30 @@
1
1
  module IsoDoc
2
2
  class PresentationXMLConvert < ::IsoDoc::Convert
3
3
  def bibdata(docxml)
4
+ toc_metadata(docxml)
4
5
  docid_prefixes(docxml)
5
6
  a = bibdata_current(docxml) or return
6
7
  address_precompose(a)
7
8
  bibdata_i18n(a)
8
9
  a.next =
9
- "<localized-strings>#{i8n_name(trim_hash(@i18n.get), '').join('')}"\
10
+ "<localized-strings>#{i8n_name(trim_hash(@i18n.get), '').join}"\
10
11
  "</localized-strings>"
11
12
  end
12
13
 
14
+ def toc_metadata(docxml)
15
+ return unless @tocfigures || @toctables || @tocrecommendations
16
+
17
+ ins = docxml.at(ns("//misc-container")) ||
18
+ docxml.at(ns("//bibdata")).after("<misc-container/>").next_element
19
+ @tocfigures and
20
+ ins << "<toc type='figure'><title>#{@i18n.toc_figures}</title></toc>"
21
+ @toctables and
22
+ ins << "<toc type='table'><title>#{@i18n.toc_tables}</title></toc>"
23
+ @tocfigures and
24
+ ins << "<toc type='recommendation'><title>#{@i18n.toc_recommendations}"\
25
+ "</title></toc>"
26
+ end
27
+
13
28
  def address_precompose(bib)
14
29
  bib.xpath(ns("//bibdata//address")).each do |b|
15
30
  next if b.at(ns("./formattedAddress"))
@@ -66,8 +81,9 @@ module IsoDoc
66
81
  end
67
82
 
68
83
  def i8n_name(hash, pref)
69
- if hash.is_a? Hash then i8n_name1(hash, pref)
70
- elsif hash.is_a? Array
84
+ case hash
85
+ when Hash then i8n_name1(hash, pref)
86
+ when Array
71
87
  hash.reject { |a| blank?(a) }.each_with_object([])
72
88
  .with_index do |(v1, g), i|
73
89
  i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
@@ -78,8 +94,9 @@ module IsoDoc
78
94
 
79
95
  def i8n_name1(hash, pref)
80
96
  hash.reject { |_k, v| blank?(v) }.each_with_object([]) do |(k, v), g|
81
- if v.is_a? Hash then i8n_name(v, i18n_safe(k)).each { |x| g << x }
82
- elsif v.is_a? Array
97
+ case v
98
+ when Hash then i8n_name(v, i18n_safe(k)).each { |x| g << x }
99
+ when Array
83
100
  v.reject { |a| blank?(a) }.each_with_index do |v1, i|
84
101
  i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
85
102
  end
@@ -109,11 +126,11 @@ module IsoDoc
109
126
  hash.each_with_object({}) do |(k, v), g|
110
127
  next if blank?(v)
111
128
 
112
- g[k] = if v.is_a? Hash then trim_hash1(hash[k])
113
- elsif v.is_a? Array
129
+ g[k] = case v
130
+ when Hash then trim_hash1(hash[k])
131
+ when Array
114
132
  hash[k].map { |a| trim_hash1(a) }.reject { |a| blank?(a) }
115
- else
116
- v
133
+ else v
117
134
  end
118
135
  end
119
136
  end
@@ -1,56 +1,8 @@
1
1
  require "metanorma-utils"
2
+ require_relative "xrefs"
2
3
 
3
4
  module IsoDoc
4
5
  class PresentationXMLConvert < ::IsoDoc::Convert
5
- def prefix_container(container, linkend, _target)
6
- l10n("#{@xrefs.anchor(container, :xref)}, #{linkend}")
7
- end
8
-
9
- def anchor_value(id)
10
- @xrefs.anchor(id, :value) || @xrefs.anchor(id, :label) ||
11
- @xrefs.anchor(id, :xref)
12
- end
13
-
14
- def anchor_linkend(node, linkend)
15
- if node["citeas"].nil? && node["bibitemid"]
16
- return @xrefs.anchor(node["bibitemid"], :xref) || "???"
17
- elsif node["target"] && node["droploc"]
18
- return anchor_value(node["target"]) || "???"
19
- elsif node["target"] && !/.#./.match(node["target"])
20
- linkend = anchor_linkend1(node)
21
- end
22
-
23
- linkend || "???"
24
- end
25
-
26
- def anchor_linkend1(node)
27
- linkend = @xrefs.anchor(node["target"], :xref)
28
- container = @xrefs.anchor(node["target"], :container, false)
29
- (container && get_note_container_id(node) != container &&
30
- @xrefs.get[node["target"]]) and
31
- linkend = prefix_container(container, linkend, node["target"])
32
- capitalise_xref(node, linkend, anchor_value(node["target"]))
33
- end
34
-
35
- def capitalise_xref(node, linkend, label)
36
- linktext = linkend.gsub(/<[^>]+>/, "")
37
- (label && !label.empty? && /^#{Regexp.escape(label)}/.match?(linktext)) ||
38
- linktext[0, 1].match?(/\p{Upper}/) and return linkend
39
- node["case"] and
40
- return Common::case_with_markup(linkend, node["case"], @script)
41
-
42
- capitalise_xref1(node, linkend)
43
- end
44
-
45
- def capitalise_xref1(node, linkend)
46
- prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
47
- node.xpath("./preceding::text()")
48
- if prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map(&:text).join)
49
- Common::case_with_markup(linkend, "capital", @script)
50
- else linkend
51
- end
52
- end
53
-
54
6
  def nearest_block_parent(node)
55
7
  until %w(p title td th name formula li dt dd sourcecode pre)
56
8
  .include?(node.name)
@@ -61,7 +13,7 @@ module IsoDoc
61
13
 
62
14
  def non_locality_elems(node)
63
15
  node.children.reject do |c|
64
- %w{locality localityStack}.include? c.name
16
+ %w{locality localityStack location}.include? c.name
65
17
  end
66
18
  end
67
19
 
@@ -85,53 +37,137 @@ module IsoDoc
85
37
  end
86
38
 
87
39
  def eref_localities(refs, target, node)
88
- ret = ""
89
- refs.each_with_index do |r, i|
90
- delim = ","
91
- delim = ";" if r.name == "localityStack" && i.positive?
92
- ret = eref_locality_stack(r, i, target, delim, ret, node)
40
+ if can_conflate_eref_rendering?(refs)
41
+ l10n(", #{eref_localities_conflated(refs, target, node)}")
42
+ else
43
+ ret = resolve_eref_connectives(eref_locality_stacks(refs, target, node))
44
+ l10n(ret.join)
45
+ end
46
+ end
47
+
48
+ def eref_localities_conflated(refs, target, node)
49
+ droploc = node["droploc"]
50
+ node["droploc"] = true
51
+ ret = resolve_eref_connectives(eref_locality_stacks(refs, target,
52
+ node))
53
+ node["droploc"] = droploc
54
+ eref_localities1(target,
55
+ refs.first.at(ns("./locality/@type")).text,
56
+ l10n(ret[1..-1].join), nil, node, @lang)
57
+ end
58
+
59
+ def can_conflate_eref_rendering?(refs)
60
+ (refs.size > 1 &&
61
+ refs.all? { |r| r.name == "localityStack" } &&
62
+ refs.all? { |r| r.xpath(ns("./locality")).size == 1 }) or return false
63
+
64
+ first = refs.first.at(ns("./locality/@type")).text
65
+ refs.all? do |r|
66
+ r.at(ns("./locality/@type")).text == first
93
67
  end
94
- ret
95
68
  end
96
69
 
97
- def eref_locality_stack(ref, idx, target, delim, ret, node)
70
+ def resolve_eref_connectives(locs)
71
+ locs = resolve_comma_connectives(locs)
72
+ locs = resolve_to_connectives(locs)
73
+ return locs if locs.size < 3
74
+
75
+ locs = locs.each_slice(2).with_object([]) do |a, m|
76
+ m << { conn: a[0], target: a[1] }
77
+ end
78
+ [", ", combine_conn(locs)]
79
+ end
80
+
81
+ def resolve_comma_connectives(locs)
82
+ locs1 = []
83
+ add = ""
84
+ until locs.empty?
85
+ if [", ", " "].include?(locs[1])
86
+ add += locs[0..2].join
87
+ locs.shift(3)
88
+ else
89
+ locs1 << add unless add.empty?
90
+ add = ""
91
+ locs1 << locs.shift
92
+ end
93
+ end
94
+ locs1 << add unless add.empty?
95
+ locs1
96
+ end
97
+
98
+ def resolve_to_connectives(locs)
99
+ locs1 = []
100
+ until locs.empty?
101
+ if locs[1] == "to"
102
+ locs1 << @i18n.chain_to.sub(/%1/, locs[0]).sub(/%2/, locs[2])
103
+ locs.shift(3)
104
+ else locs1 << locs.shift
105
+ end
106
+ end
107
+ locs1
108
+ end
109
+
110
+ def eref_locality_stacks(refs, target, node)
111
+ ret = refs.each_with_index.with_object([]) do |(r, i), m|
112
+ added = eref_locality_stack(r, i, target, node)
113
+ added.empty? and next
114
+ added.each { |a| m << a }
115
+ next if i == refs.size - 1
116
+
117
+ m << if r&.next_element&.name == "localityStack"
118
+ r.next_element["connective"]
119
+ else locality_delimiter(r)
120
+ end
121
+ end
122
+ ret.empty? ? ret : [", "] + ret
123
+ end
124
+
125
+ def eref_locality_stack(ref, idx, target, node)
126
+ ret = []
98
127
  if ref.name == "localityStack"
99
128
  ref.elements.each_with_index do |rr, j|
100
- ret += eref_localities0(rr, j, target, delim, node)
101
- delim = ","
129
+ l = eref_localities0(rr, j, target, node) or next
130
+
131
+ ret << l
132
+ ret << locality_delimiter(rr) unless j == ref.elements.size - 1
102
133
  end
103
- else ret += eref_localities0(ref, idx, target, delim, node)
134
+ else
135
+ l = eref_localities0(ref, idx, target, node) and ret << l
104
136
  end
105
137
  ret
106
138
  end
107
139
 
108
- def eref_localities0(ref, _idx, target, delim, node)
109
- if ref["type"] == "whole" then l10n("#{delim} #{@i18n.wholeoftext}")
140
+ def locality_delimiter(_loc)
141
+ ", "
142
+ end
143
+
144
+ def eref_localities0(ref, _idx, target, node)
145
+ if ref["type"] == "whole" then @i18n.wholeoftext
110
146
  else
111
- eref_localities1(target, ref["type"], ref.at(ns("./referenceFrom")),
112
- ref.at(ns("./referenceTo")), delim, node, @lang)
147
+ eref_localities1(target, ref["type"],
148
+ ref&.at(ns("./referenceFrom"))&.text,
149
+ ref&.at(ns("./referenceTo"))&.text, node, @lang)
113
150
  end
114
151
  end
115
152
 
116
153
  # TODO: move to localization file
117
- def eref_localities1_zh(_target, type, from, upto, node, delim)
118
- ret = "#{delim} 第#{from.text}" if from
119
- ret += "&ndash;#{upto.text}" if upto
120
- loc = (@i18n.locality[type] || type.sub(/^locality:/, "").capitalize)
154
+ def eref_localities1_zh(_target, type, from, upto, node)
155
+ ret = "第#{from}" if from
156
+ ret += "&ndash;#{upto}" if upto
157
+ loc = eref_locality_populate(type, node)
121
158
  ret += " #{loc}" unless node["droploc"] == "true"
122
159
  ret
123
160
  end
124
161
 
125
162
  # TODO: move to localization file
126
- def eref_localities1(target, type, from, upto, delim, node, lang = "en")
127
- return "" if type == "anchor"
163
+ def eref_localities1(target, type, from, upto, node, lang = "en")
164
+ return nil if type == "anchor"
128
165
 
129
166
  lang == "zh" and
130
- return l10n(eref_localities1_zh(target, type, from, upto, node, delim))
131
- ret = delim
132
- ret += eref_locality_populate(type, node)
133
- ret += " #{from.text}" if from
134
- ret += "&ndash;#{upto.text}" if upto
167
+ return l10n(eref_localities1_zh(target, type, from, upto, node))
168
+ ret = eref_locality_populate(type, node)
169
+ ret += " #{from}" if from
170
+ ret += "&ndash;#{upto}" if upto
135
171
  l10n(ret)
136
172
  end
137
173
 
@@ -20,6 +20,7 @@ module IsoDoc
20
20
  num = BigDecimal(x.text)
21
21
  precision = /\./.match?(x.text) ? x.text.sub(/^.*\./, "").size : 0
22
22
  x.children = localized_number(num, locale, precision)
23
+ rescue ArgumentError => e
23
24
  end
24
25
  end
25
26
 
@@ -0,0 +1,100 @@
1
+ module IsoDoc
2
+ class PresentationXMLConvert < ::IsoDoc::Convert
3
+ def prefix_container(container, linkend, _target)
4
+ l10n("#{@xrefs.anchor(container, :xref)}, #{linkend}")
5
+ end
6
+
7
+ def anchor_value(id)
8
+ @xrefs.anchor(id, :value) || @xrefs.anchor(id, :label) ||
9
+ @xrefs.anchor(id, :xref)
10
+ end
11
+
12
+ def anchor_linkend(node, linkend)
13
+ if node["citeas"].nil? && node["bibitemid"]
14
+ return @xrefs.anchor(node["bibitemid"], :xref) || "???"
15
+ elsif node.at(ns("./location"))
16
+ linkend = combine_xref_locations(node)
17
+ elsif node["target"] && node["droploc"]
18
+ return anchor_value(node["target"]) || "???"
19
+ elsif node["target"] && !/.#./.match(node["target"])
20
+ linkend = anchor_linkend1(node)
21
+ end
22
+
23
+ linkend || "???"
24
+ end
25
+
26
+ def anchor_linkend1(node)
27
+ linkend = @xrefs.anchor(node["target"], :xref)
28
+ container = @xrefs.anchor(node["target"], :container, false)
29
+ (container && get_note_container_id(node) != container &&
30
+ @xrefs.get[node["target"]]) and
31
+ linkend = prefix_container(container, linkend, node["target"])
32
+ capitalise_xref(node, linkend, anchor_value(node["target"]))
33
+ end
34
+
35
+ def combine_xref_locations(node)
36
+ locs = gather_xref_locations(node)
37
+ linkend = if can_conflate_xref_rendering?(locs)
38
+ out = locs.each { |l| l[:target] = anchor_value(l[:target]) }
39
+ l10n("#{locs.first[:elem]} #{combine_conn(out)}")
40
+ else
41
+ out = locs.each { |l| l[:target] = anchor_linked1(l[:node]) }
42
+ l10n(combine_conn(out))
43
+ end
44
+ capitalise_xref(node, linkend, anchor_value(node["target"]))
45
+ end
46
+
47
+ def gather_xref_locations(node)
48
+ node.xpath(ns("./location")).each_with_object([]) do |l, m|
49
+ type = @xrefs.anchor(l["target"], :type)
50
+ m << { conn: l["connective"], target: l["target"],
51
+ type: type, node: l, elem: @xrefs.anchor(l["target"], :elem),
52
+ container: @xrefs.anchor(node["target"], :container, false) ||
53
+ %w(termnote).include?(type) }
54
+ end
55
+ end
56
+
57
+ def combine_conn(list)
58
+ return list.first[:target] if list.size == 1
59
+
60
+ if list[1..-1].all? { |l| l[:conn] == "and" }
61
+ @i18n.boolean_conj(list.map { |l| l[:target] }, "and")
62
+ elsif list[1..-1].all? { |l| l[:conn] == "or" }
63
+ @i18n.boolean_conj(list.map { |l| l[:target] }, "or")
64
+ else
65
+ ret = list[0][:target]
66
+ list[1..-1].each { |l| ret = i18n_chain_boolean(ret, l) }
67
+ ret
68
+ end
69
+ end
70
+
71
+ def i18n_chain_boolean(value, entry)
72
+ @i18n.send("chain_#{entry[:conn]}").sub(/%1/, value)
73
+ .sub(/%2/, entry[:target])
74
+ end
75
+
76
+ def can_conflate_xref_rendering?(locs)
77
+ !locs.all? { |l| l[:container].nil? } &&
78
+ locs.all? { |l| l[:type] == locs[0][:type] }
79
+ end
80
+
81
+ def capitalise_xref(node, linkend, label)
82
+ linktext = linkend.gsub(/<[^>]+>/, "")
83
+ (label && !label.empty? && /^#{Regexp.escape(label)}/.match?(linktext)) ||
84
+ linktext[0, 1].match?(/\p{Upper}/) and return linkend
85
+ node["case"] and
86
+ return Common::case_with_markup(linkend, node["case"], @script)
87
+
88
+ capitalise_xref1(node, linkend)
89
+ end
90
+
91
+ def capitalise_xref1(node, linkend)
92
+ prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
93
+ node.xpath("./preceding::text()")
94
+ if prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map(&:text).join)
95
+ Common::case_with_markup(linkend, "capital", @script)
96
+ else linkend
97
+ end
98
+ end
99
+ end
100
+ end
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "2.0.4".freeze
2
+ VERSION = "2.0.5".freeze
3
3
  end
@@ -233,11 +233,21 @@ module IsoDoc
233
233
  end
234
234
 
235
235
  def suffix_url(url)
236
- return url if %r{^https?://}.match?(url)
236
+ return url if url.nil? || %r{^https?://}.match?(url)
237
237
  return url unless File.extname(url).empty?
238
238
 
239
239
  url.sub(/#{File.extname(url)}$/, ".doc")
240
240
  end
241
+
242
+ def info(isoxml, out)
243
+ @tocfigurestitle =
244
+ isoxml&.at(ns("//misc-container/toc[@type = 'figure']/title"))&.text
245
+ @toctablestitle =
246
+ isoxml&.at(ns("//misc-container/toc[@type = 'table']/title"))&.text
247
+ @tocrecommendationstitle = isoxml
248
+ &.at(ns("//misc-container/toc[@type = 'recommendation']/title"))&.text
249
+ super
250
+ end
241
251
  end
242
252
  end
243
253
  end