isodoc 2.12.0 → 2.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/isodoc.gemspec +2 -2
  3. data/lib/isodoc/convert.rb +0 -21
  4. data/lib/isodoc/function/blocks.rb +19 -48
  5. data/lib/isodoc/function/blocks_example_note.rb +75 -29
  6. data/lib/isodoc/function/cleanup.rb +3 -40
  7. data/lib/isodoc/function/inline.rb +39 -9
  8. data/lib/isodoc/function/lists.rb +5 -5
  9. data/lib/isodoc/function/references.rb +9 -133
  10. data/lib/isodoc/function/reqt.rb +2 -2
  11. data/lib/isodoc/function/section.rb +25 -28
  12. data/lib/isodoc/function/section_titles.rb +16 -13
  13. data/lib/isodoc/function/table.rb +3 -3
  14. data/lib/isodoc/function/terms.rb +21 -20
  15. data/lib/isodoc/function/to_word_html.rb +8 -5
  16. data/lib/isodoc/function/utils.rb +1 -1
  17. data/lib/isodoc/html_function/footnotes.rb +2 -1
  18. data/lib/isodoc/html_function/html.rb +1 -5
  19. data/lib/isodoc/init.rb +31 -0
  20. data/lib/isodoc/metadata.rb +9 -0
  21. data/lib/isodoc/metadata_contributor.rb +1 -1
  22. data/lib/isodoc/metadata_date.rb +1 -1
  23. data/lib/isodoc/presentation_function/autonum.rb +139 -0
  24. data/lib/isodoc/presentation_function/block.rb +95 -36
  25. data/lib/isodoc/presentation_function/docid.rb +78 -0
  26. data/lib/isodoc/presentation_function/erefs.rb +6 -4
  27. data/lib/isodoc/presentation_function/image.rb +52 -13
  28. data/lib/isodoc/presentation_function/inline.rb +6 -6
  29. data/lib/isodoc/presentation_function/math.rb +0 -14
  30. data/lib/isodoc/presentation_function/metadata.rb +0 -62
  31. data/lib/isodoc/presentation_function/refs.rb +44 -14
  32. data/lib/isodoc/presentation_function/reqt.rb +1 -1
  33. data/lib/isodoc/presentation_function/section.rb +46 -121
  34. data/lib/isodoc/presentation_function/sourcecode.rb +7 -4
  35. data/lib/isodoc/presentation_function/terms.rb +27 -2
  36. data/lib/isodoc/presentation_function/title.rb +107 -0
  37. data/lib/isodoc/presentation_function/xrefs.rb +17 -10
  38. data/lib/isodoc/presentation_xml_convert.rb +6 -2
  39. data/lib/isodoc/version.rb +1 -1
  40. data/lib/isodoc/word_function/body.rb +8 -36
  41. data/lib/isodoc/word_function/footnotes.rb +1 -1
  42. data/lib/isodoc/word_function/lists.rb +12 -10
  43. data/lib/isodoc/word_function/postprocess_cover.rb +0 -2
  44. data/lib/isodoc/word_function/postprocess_table.rb +1 -1
  45. data/lib/isodoc/word_function/table.rb +2 -2
  46. data/lib/isodoc/xref/clause_order.rb +2 -2
  47. data/lib/isodoc/xref/xref_anchor.rb +31 -16
  48. data/lib/isodoc/xref/xref_counter_types.rb +3 -2
  49. data/lib/isodoc/xref/xref_gen.rb +57 -33
  50. data/lib/isodoc/xref/xref_gen_seq.rb +145 -56
  51. data/lib/isodoc/xref/xref_sect_gen.rb +64 -47
  52. data/lib/isodoc/xref/xref_util.rb +49 -1
  53. data/lib/isodoc/xref.rb +3 -0
  54. data/lib/isodoc-yaml/i18n-ar.yaml +9 -9
  55. data/lib/isodoc-yaml/i18n-de.yaml +9 -9
  56. data/lib/isodoc-yaml/i18n-en.yaml +9 -9
  57. data/lib/isodoc-yaml/i18n-es.yaml +9 -9
  58. data/lib/isodoc-yaml/i18n-fr.yaml +9 -9
  59. data/lib/isodoc-yaml/i18n-ja.yaml +10 -10
  60. data/lib/isodoc-yaml/i18n-ru.yaml +9 -9
  61. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +9 -9
  62. data/lib/nokogiri/xml/node.rb +1 -0
  63. metadata +9 -6
@@ -42,7 +42,7 @@ module IsoDoc
42
42
 
43
43
  def bibdate(isoxml, _out)
44
44
  isoxml.xpath(ns("//bibdata/date")).each do |d|
45
- set("#{d['type'].gsub(/-/, '_')}date".to_sym, Common::date_range(d))
45
+ set("#{d['type'].tr('-', '_')}date".to_sym, Common::date_range(d))
46
46
  end
47
47
  end
48
48
  end
@@ -0,0 +1,139 @@
1
+ module IsoDoc
2
+ class PresentationXMLConvert < ::IsoDoc::Convert
3
+ def prefix_name(node, delims, label, elem)
4
+ label, delims = prefix_name_defaults(node, delims, label)
5
+ name, ins, ids, number = prefix_name_prep(node, elem)
6
+ ins.next = fmt_xref_label(label, number, ids)
7
+ # autonum can be empty, e.g single note in clause: "NOTE []"
8
+ number and node["autonum"] = number.gsub(/<[^>]+>/, "")
9
+ !node.at(ns("./fmt-#{elem}")) &&
10
+ (c = fmt_caption(label, elem, name, ids, delims)) and ins.next = c
11
+ prefix_name_postprocess(node, elem)
12
+ end
13
+
14
+ def prefix_name_defaults(node, delims, label)
15
+ label&.empty? and label = nil
16
+ delims.nil? and delims = {}
17
+ [label, delims]
18
+ end
19
+
20
+ def prefix_name_prep(node, elem)
21
+ lbls = prefix_name_labels(node)
22
+ name = node.at(ns("./#{elem}")) and name["id"] = lbls[:name]
23
+ ins = name || node.add_first_child("<sentinel/>").elements.first
24
+ node["unnumbered"] or
25
+ number = @xrefs.anchor(node["id"], :value, false)&.strip
26
+ [name, ins, lbls, number]
27
+ end
28
+
29
+ def prefix_name_labels(node)
30
+ { elem: node["id"],
31
+ name: "_#{UUIDTools::UUID.random_create}" }
32
+ end
33
+
34
+ def prefix_name_postprocess(node, elem)
35
+ node.at(ns("./sentinel"))&.remove
36
+ strip_duplicate_ids(node, node.at(ns("./#{elem}")),
37
+ node.at(ns("./fmt-#{elem}")))
38
+ end
39
+
40
+ def transfer_id(old, new)
41
+ old["id"] or return
42
+ new["id"] = old["id"]
43
+ old["original-id"] = old["id"]
44
+ old.delete("id")
45
+ end
46
+
47
+ def gather_all_ids(elem)
48
+ elem.xpath(".//*[@id]").each_with_object([]) do |i, m|
49
+ m << i["id"]
50
+ end
51
+ end
52
+
53
+ # remove ids duplicated between title and fmt-title
54
+ # index terms are assumed transferred to fmt-title from title
55
+ def strip_duplicate_ids(_node, sem_title, pres_title)
56
+ sem_title && pres_title or return
57
+ ids = gather_all_ids(pres_title)
58
+ sem_title.xpath(".//*[@id]").each do |x|
59
+ ids.include?(x["id"]) or next
60
+ x["original-id"] = x["id"]
61
+ x.delete("id")
62
+ end
63
+ sem_title.xpath(ns(".//index")).each(&:remove)
64
+ end
65
+
66
+ def semx(node, label, element = "autonum")
67
+ id = node["id"] || node[:id]
68
+ /<semx element='[^']+' source='#{id}'/.match?(label) and return label
69
+ l = stripsemx(label)
70
+ %(<semx element='#{element}' source='#{id}'>#{l}</semx>)
71
+ end
72
+
73
+ def autonum(id, num)
74
+ /<semx/.match?(num) and return num # already contains markup
75
+ "<semx element='autonum' source='#{id}'>#{num}</semx>"
76
+ end
77
+
78
+ def labelled_autonum(label, id, num)
79
+ elem = "<span class='fmt-element-name'>#{label}</span>"
80
+ num.blank? and return elem
81
+ l10n("#{elem} #{autonum(id, num)}")
82
+ end
83
+
84
+ def fmt_xref_label(label, _number, ids)
85
+ label or return ""
86
+ x = @xrefs.anchor(ids[:elem], :xref, false) or return ""
87
+ ret = "<fmt-xref-label>#{x}</fmt-xref-label>"
88
+ container = @xrefs.anchor(ids[:elem], :container, false)
89
+ y = prefix_container_fmt_xref_label(container, x)
90
+ y != x and
91
+ ret += "<fmt-xref-label container='#{container}'>#{y}</fmt-xref-label>"
92
+ ret
93
+ end
94
+
95
+ def prefix_container_fmt_xref_label(container, xref)
96
+ container or return xref
97
+ container_container = @xrefs.anchor(container, :container, false)
98
+ container_label =
99
+ prefix_container_fmt_xref_label(container_container,
100
+ @xrefs.anchor(container, :xref, false))
101
+ l10n(connectives_spans(@i18n.nested_xref
102
+ .sub("%1", "<span class='fmt-xref-container'>#{container_label}</span>")
103
+ .sub("%2", xref)))
104
+ end
105
+
106
+ # detect whether string which may contain XML markup is empty
107
+ def empty_xml?(str)
108
+ str.blank? and return true
109
+ x = Nokogiri::XML::DocumentFragment.parse(str)
110
+ x.to_str.strip.empty?
111
+ end
112
+
113
+ # Remove ".blank?" tests if want empty delim placeholders for manipulation
114
+ def fmt_caption(label, elem, name, ids, delims)
115
+ label = fmt_caption_label_wrap(label)
116
+ c = fmt_caption2(label, elem, name, ids, delims)
117
+ empty_xml?(c) and return
118
+ !delims[:label].blank? and
119
+ f = "<span class='fmt-label-delim'>#{delims[:label]}</span>"
120
+ "<fmt-#{elem}>#{c}#{f}</fmt-#{elem}>"
121
+ end
122
+
123
+ def fmt_caption_label_wrap(label)
124
+ empty_xml?(label) || %r{<span class=['"]fmt-caption-label['"]}.match?(label) or
125
+ label = "<span class='fmt-caption-label'>#{label}</span>"
126
+ label
127
+ end
128
+
129
+ def fmt_caption2(label, elem, name, ids, delims)
130
+ if name && !name.children.empty?
131
+ empty_xml?(label) or
132
+ d = "<span class='fmt-caption-delim'>#{delims[:caption]}</span>"
133
+ attr = " element='#{elem}' source='#{ids[:name]}'"
134
+ "#{label}#{d}<semx #{attr}>#{to_xml(name.children)}</semx>"
135
+ elsif label then label
136
+ end
137
+ end
138
+ end
139
+ end
@@ -1,31 +1,23 @@
1
1
  require_relative "image"
2
2
  require_relative "sourcecode"
3
+ require_relative "autonum"
3
4
  require "rouge"
4
5
 
5
6
  module IsoDoc
6
7
  class PresentationXMLConvert < ::IsoDoc::Convert
7
8
  def lower2cap(text)
8
- /^[[:upper:]][[:upper:]]/.match?(text) and return text
9
- text&.capitalize
9
+ text.nil? and return text
10
+ x = Nokogiri::XML("<a>#{text}</a>")
11
+ firsttext = x.at(".//text()[string-length(normalize-space(.))>0]") or return text
12
+ /^[[:upper:]][[:upper:]]/.match?(firsttext.text) and return text
13
+ firsttext.replace(firsttext.text.capitalize)
14
+ to_xml(x.root.children)
10
15
  end
11
16
 
12
17
  def block_delim
13
18
  "&#xa0;&#x2014; "
14
19
  end
15
20
 
16
- def prefix_name(node, delim, number, elem)
17
- number.nil? || number.empty? and return
18
- unless name = node.at(ns("./#{elem}"))
19
- #(node.children.empty? and node.add_child("<#{elem}></#{elem}>")) or
20
- # node.children.first.previous = "<#{elem}></#{elem}>"
21
- node.add_first_child "<#{elem}></#{elem}>"
22
- name = node.children.first
23
- end
24
- if name.children.empty? then name.add_child(cleanup_entities(number.strip))
25
- else (name.children.first.previous = "#{number.strip}#{delim}")
26
- end
27
- end
28
-
29
21
  def formula(docxml)
30
22
  docxml.xpath(ns("//formula")).each { |f| formula1(f) }
31
23
  end
@@ -33,7 +25,7 @@ module IsoDoc
33
25
  def formula1(elem)
34
26
  formula_where(elem.at(ns("./dl")))
35
27
  lbl = @xrefs.anchor(elem["id"], :label, false)
36
- prefix_name(elem, "", lbl, "name")
28
+ lbl.nil? || lbl.empty? or prefix_name(elem, {}, lbl, "name")
37
29
  end
38
30
 
39
31
  def formula_where(dlist)
@@ -49,25 +41,27 @@ module IsoDoc
49
41
 
50
42
  def example1(elem)
51
43
  n = @xrefs.get[elem["id"]]
52
- lbl = if n.nil? || n[:label].nil? || n[:label].empty?
53
- @i18n.example
54
- else l10n("#{@i18n.example} #{n[:label]}")
55
- end
56
- prefix_name(elem, block_delim, lbl, "name")
44
+ lbl = labelled_autonum(@i18n.example, elem["id"], n&.dig(:label))
45
+ prefix_name(elem, { caption: block_delim }, lbl, "name")
57
46
  end
58
47
 
59
48
  def note(docxml)
60
49
  docxml.xpath(ns("//note")).each { |f| note1(f) }
61
50
  end
62
51
 
52
+ def note_delim(_elem)
53
+ "<tab/>"
54
+ end
55
+
63
56
  def note1(elem)
64
57
  %w(bibdata bibitem).include?(elem.parent.name) ||
65
- elem["notag"] == "true" and return
58
+ elem["notag"] == "true" or lbl = note_label(elem)
59
+ prefix_name(elem, { label: note_delim(elem) }, lbl, "name")
60
+ end
61
+
62
+ def note_label(elem)
66
63
  n = @xrefs.get[elem["id"]]
67
- lbl = @i18n.note
68
- (n.nil? || n[:label].nil? || n[:label].empty?) or
69
- lbl = l10n("#{lbl} #{n[:label]}")
70
- prefix_name(elem, "", lbl, "name")
64
+ labelled_autonum(@i18n.note, elem["id"], n&.dig(:label))
71
65
  end
72
66
 
73
67
  def admonition(docxml)
@@ -77,16 +71,30 @@ module IsoDoc
77
71
  def admonition1(elem)
78
72
  if elem["type"] == "box"
79
73
  admonition_numbered1(elem)
74
+ elsif elem["notag"] == "true" || elem.at(ns("./name"))
75
+ prefix_name(elem, { label: admonition_delim(elem) }, nil, "name")
80
76
  else
81
- elem["notag"] == "true" || elem.at(ns("./name")) and return
82
- prefix_name(elem, "", @i18n.admonition[elem["type"]]&.upcase, "name")
77
+ label = admonition_label(elem, nil)
78
+ prefix_name(elem, { label: admonition_delim(elem) }, label, "name")
83
79
  end
84
80
  end
85
81
 
86
82
  def admonition_numbered1(elem)
87
- elem["unnumbered"] && !elem.at(ns("./name")) and return
88
- n = @xrefs.anchor(elem["id"], :label, false)
89
- prefix_name(elem, block_delim, l10n("#{@i18n.box} #{n}"), "name")
83
+ # elem["unnumbered"] && !elem.at(ns("./name")) and return
84
+ label = admonition_label(elem, @xrefs.anchor(elem["id"], :label, false))
85
+ prefix_name(elem, { caption: block_delim }, label, "name")
86
+ end
87
+
88
+ def admonition_label(elem, num)
89
+ lbl = if elem["type"] == "box" then @i18n.box
90
+ else @i18n.admonition[elem["type"]]&.upcase end
91
+ #lbl &&= "<span class='fmt-element-name'>#{lbl}</span>"
92
+ #num and lbl = l10n("#{lbl} #{autonum(elem['id'], num)}")
93
+ labelled_autonum(lbl, elem["id"], num)
94
+ end
95
+
96
+ def admonition_delim(_elem)
97
+ ""
90
98
  end
91
99
 
92
100
  def table(docxml)
@@ -95,11 +103,18 @@ module IsoDoc
95
103
  end
96
104
 
97
105
  def table1(elem)
106
+ table_fn(elem)
98
107
  labelled_ancestor(elem) and return
99
108
  elem["unnumbered"] && !elem.at(ns("./name")) and return
100
109
  n = @xrefs.anchor(elem["id"], :label, false)
101
- prefix_name(elem, block_delim, l10n("#{lower2cap @i18n.table} #{n}"),
102
- "name")
110
+ #lbl = "<span class='fmt-element-name'>#{lower2cap @i18n.table}</span> "\
111
+ #"#{autonum(elem['id'], n)}"
112
+ lbl = labelled_autonum(lower2cap(@i18n.table), elem["id"], n)
113
+ prefix_name(elem, { caption: table_delim }, l10n(lbl), "name")
114
+ end
115
+
116
+ def table_delim
117
+ block_delim
103
118
  end
104
119
 
105
120
  def table_long_strings_cleanup(docxml)
@@ -113,6 +128,15 @@ module IsoDoc
113
128
  end
114
129
  end
115
130
 
131
+ def table_fn(elem)
132
+ (elem.xpath(ns(".//fn")) - elem.xpath(ns("./name//fn")))
133
+ .each_with_index do |f, i|
134
+ table_fn1(elem, f, i)
135
+ end
136
+ end
137
+
138
+ def table_fn1(table, fnote, idx); end
139
+
116
140
  # we use this to eliminate the semantic amend blocks from rendering
117
141
  def amend(docxml)
118
142
  docxml.xpath(ns("//amend")).each { |f| amend1(f) }
@@ -126,6 +150,24 @@ module IsoDoc
126
150
  elem.replace(elem.children)
127
151
  end
128
152
 
153
+ def dl(docxml)
154
+ docxml.xpath(ns("//dl")).each { |f| dl1(f) }
155
+ end
156
+
157
+ def dl1(elem)
158
+ elem.at(ns("./name")) and
159
+ prefix_name(elem, {}, "", "name") # copy name to fmt-name
160
+ end
161
+
162
+ def ul(docxml)
163
+ docxml.xpath(ns("//ul")).each { |f| ul1(f) }
164
+ end
165
+
166
+ def ul1(elem)
167
+ elem.at(ns("./name")) and
168
+ prefix_name(elem, {}, "", "name") # copy name to fmt-name
169
+ end
170
+
129
171
  def ol(docxml)
130
172
  docxml.xpath(ns("//ol")).each { |f| ol1(f) }
131
173
  @xrefs.list_anchor_names(docxml.xpath(ns(@xrefs.sections_xpath)))
@@ -147,9 +189,8 @@ module IsoDoc
147
189
 
148
190
  def ol1(elem)
149
191
  elem["type"] ||= ol_depth(elem).to_s
150
- elem.xpath(ns("./li")).each do |li|
151
- li["id"] ||= "_#{UUIDTools::UUID.random_create}"
152
- end
192
+ elem.at(ns("./name")) and
193
+ prefix_name(elem, {}, "", "name") # copy name to fmt-name
153
194
  end
154
195
 
155
196
  def ol_label(elem)
@@ -182,5 +223,23 @@ module IsoDoc
182
223
  def source_modification(mod)
183
224
  termsource_modification(mod.parent)
184
225
  end
226
+
227
+ def quote(docxml)
228
+ docxml.xpath(ns("//quote")).each { |f| quote1(f) }
229
+ end
230
+
231
+ def quote1(elem)
232
+ author = elem.at(ns("./author"))
233
+ source = elem.at(ns("./source"))
234
+ author.nil? && source.nil? and return
235
+ p = "&#x2014; "
236
+ p += author.remove.to_xml if author
237
+ p += ", " if author && source
238
+ if source
239
+ source.name = "eref"
240
+ p += source.remove.to_xml
241
+ end
242
+ elem << "<attribution><p>#{l10n p}</p></attribution>"
243
+ end
185
244
  end
186
245
  end
@@ -0,0 +1,78 @@
1
+ module IsoDoc
2
+ class PresentationXMLConvert < ::IsoDoc::Convert
3
+ def docid_prefixes(docxml)
4
+ docxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
5
+ i.children = docid_prefix(i["type"], to_xml(i.children))
6
+ end
7
+ end
8
+
9
+ def pref_ref_code(bib)
10
+ bib["suppress_identifier"] == "true" and return nil
11
+ ret = bib.xpath(ns("./docidentifier[@scope = 'biblio-tag']"))
12
+ ret.empty? or return ret.map(&:text)
13
+ ret = pref_ref_code_parse(bib) or return nil
14
+ ins = bib.at(ns("./docidentifier[last()]"))
15
+ ret.reverse_each do |r|
16
+ ins.next = "<docidentifier scope='biblio-tag'>#{docid_l10n(r)}</docidentifier>"
17
+ end
18
+ ret
19
+ end
20
+
21
+ def pref_ref_code_parse(bib)
22
+ data, = @bibrender.parse(bib)
23
+ ret = data[:authoritative_identifier] or return nil
24
+ ret.empty? and return nil
25
+ ret
26
+ end
27
+
28
+ # returns [metanorma, non-metanorma, DOI/ISSN/ISBN] identifiers
29
+ def bibitem_ref_code(bib)
30
+ id, id1, id2, id3 = bibitem_ref_code_prep(bib)
31
+ id || id1 || id2 || id3 and return [id, id1, id2, id3]
32
+ bib["suppress_identifier"] == "true" and return [nil, nil, nil, nil]
33
+ [nil, no_identifier(bib), nil, nil]
34
+ end
35
+
36
+ def bibitem_ref_code_prep(bib)
37
+ id = bib.at(ns("./docidentifier[@type = 'metanorma']"))
38
+ id1 = pref_ref_code(bib)
39
+ id2 = bib.at(ns("./docidentifier[#{SKIP_DOCID}]"))
40
+ id3 = bib.at(ns("./docidentifier[@type = 'metanorma-ordinal']"))
41
+ [id, id1, id2, id3]
42
+ end
43
+
44
+ def no_identifier(bib)
45
+ @i18n.no_identifier or return nil
46
+ id = Nokogiri::XML::Node.new("docidentifier", bib.document)
47
+ id << @i18n.no_identifier
48
+ id
49
+ end
50
+
51
+ def bracket_if_num(num)
52
+ num.nil? and return nil
53
+ num = num.text.sub(/^\[/, "").sub(/\]$/, "")
54
+ /^\d+$/.match?(num) and return "[#{num}]"
55
+ num
56
+ end
57
+
58
+ def unbracket1(ident)
59
+ ident.nil? and return nil
60
+ ident.is_a?(String) or ident = ident.text
61
+ ident.sub(/^\[/, "").sub(/\]$/, "")
62
+ end
63
+
64
+ def unbracket(ident)
65
+ if ident.respond_to?(:size)
66
+ ident.map { |x| unbracket1(x) }.join("&#xA0;/ ")
67
+ else unbracket1(ident)
68
+ end
69
+ end
70
+
71
+ def render_identifier(ident)
72
+ { metanorma: bracket_if_num(ident[0]),
73
+ sdo: unbracket(ident[1]),
74
+ doi: unbracket(ident[2]),
75
+ ordinal: bracket_if_num(ident[3]) }
76
+ end
77
+ end
78
+ end
@@ -3,9 +3,10 @@ require "metanorma-utils"
3
3
  module IsoDoc
4
4
  class PresentationXMLConvert < ::IsoDoc::Convert
5
5
  def citeas(xmldoc)
6
- xmldoc.xpath(ns("//eref | //origin | //quote/source")).each do |e|
6
+ xmldoc.xpath(ns("//eref | //origin | //quote//source")).each do |e|
7
7
  e["bibitemid"] && e["citeas"] or next
8
- a = @xrefs.anchor(e["bibitemid"], :xref, false) and e["citeas"] = a
8
+ a = @xrefs.anchor(e["bibitemid"], :xref, false) and
9
+ e["citeas"] = a.gsub(%r{</?[^>]+>}, "")
9
10
  end
10
11
  end
11
12
 
@@ -87,7 +88,8 @@ module IsoDoc
87
88
  locs1 = []
88
89
  until locs.empty?
89
90
  if locs[1] == "to"
90
- locs1 << @i18n.chain_to.sub("%1", locs[0]).sub("%2", locs[2])
91
+ locs1 << connectives_spans(@i18n.chain_to.sub("%1", locs[0])
92
+ .sub("%2", locs[2]))
91
93
  locs.shift(3)
92
94
  else locs1 << locs.shift
93
95
  end
@@ -178,7 +180,7 @@ module IsoDoc
178
180
  end
179
181
 
180
182
  def eref2link(docxml)
181
- docxml.xpath(ns("//eref | //origin[not(termref)] | //quote/source"))
183
+ docxml.xpath(ns("//eref | //origin[not(termref)] | //quote//source"))
182
184
  .each do |e|
183
185
  href = eref_target(e) or next
184
186
  e.xpath(ns("./locality | ./localityStack")).each(&:remove)
@@ -43,14 +43,50 @@ module IsoDoc
43
43
  elem.children = x
44
44
  end
45
45
 
46
+ def subfigure_delim
47
+ ""
48
+ # "<span class='fmt-label-delim'>)</span>"
49
+ end
50
+
51
+ def figure_delim(_elem)
52
+ block_delim
53
+ end
54
+
55
+ def figure_name(elem)
56
+ "<span class='fmt-element-name'>#{figure_label(elem)}</span> "
57
+ end
58
+
46
59
  def figure1(elem)
47
60
  elem["class"] == "pseudocode" || elem["type"] == "pseudocode" and
48
61
  return sourcecode1(elem)
49
- figure_label?(elem) or return nil
50
- lbl = @xrefs.anchor(elem["id"], :label, false) or return
51
- # no xref, no label: this can be set in xref
52
- prefix_name(elem, block_delim,
53
- l10n("#{figure_label(elem)} #{lbl}"), "name")
62
+ figure_fn(elem)
63
+ figure_key(elem.at(ns("./dl")))
64
+ lbl = @xrefs.anchor(elem["id"], :label, false)
65
+ lbl and a = autonum(elem["id"], lbl)
66
+ figname = figure_name(elem)
67
+ if elem.parent.name == "figure"
68
+ a += subfigure_delim
69
+ end
70
+ lbl && figure_label?(elem) and s = "#{figname}#{a}"
71
+ prefix_name(elem, { caption: figure_delim(elem) }, l10n(s&.strip), "name")
72
+ end
73
+
74
+ # move footnotes into key, and get rid of footnote reference
75
+ # since it is in diagram
76
+ def figure_fn(elem)
77
+ fn = elem.xpath(ns(".//fn")) - elem.xpath(ns("./name//fn"))
78
+ fn.empty? and return
79
+ dl = figure_key_insert_pt(elem)
80
+ fn.each do |f|
81
+ dl.previous = "<dt><p><sup>#{f['reference']}</sup></p></dt>" \
82
+ "<dd>#{f.remove.children.to_xml}</dd>"
83
+ end
84
+ end
85
+
86
+ def figure_key_insert_pt(elem)
87
+ elem.at(ns("//dl/name"))&.next ||
88
+ elem.at(ns("//dl"))&.children&.first ||
89
+ elem.add_child("<dl> </dl>").first.children.first
54
90
  end
55
91
 
56
92
  def figure_label?(elem)
@@ -64,6 +100,14 @@ module IsoDoc
64
100
  lower2cap klasslbl
65
101
  end
66
102
 
103
+ def figure_key(dlist)
104
+ dlist or return
105
+ dlist["class"] = "formula_dl"
106
+ dlist.at(ns("./name")) and return
107
+ dlist.previous =
108
+ "<p keep-with-next='true'><strong>#{@i18n.key}</strong></p>"
109
+ end
110
+
67
111
  def eps2svg(img)
68
112
  return unless eps?(img["mimetype"])
69
113
 
@@ -77,7 +121,7 @@ module IsoDoc
77
121
  def svg_emf_double(img)
78
122
  if emf?(img["mimetype"])
79
123
  img = emf_encode(img)
80
- #img.children.first.previous = emf_to_svg(img)
124
+ # img.children.first.previous = emf_to_svg(img)
81
125
  img.add_first_child emf_to_svg(img)
82
126
  elsif img["mimetype"] == "image/svg+xml"
83
127
  src = svg_to_emf(img) or return
@@ -127,16 +171,11 @@ module IsoDoc
127
171
 
128
172
  def svg_to_emf(node)
129
173
  @output_formats[:doc] or return
130
-
131
174
  svg_impose_height_attr(node)
132
-
133
- if node.elements&.first&.name == "svg" || %r{^data:}.match?(node["src"])
175
+ node.elements&.first&.name == "svg" || %r{^data:}.match?(node["src"]) and
134
176
  return svg_to_emf_from_node(node)
135
- end
136
-
137
177
  target_path = imgfile_suffix(node["src"], "emf")
138
- return target_path if File.exist?(target_path)
139
-
178
+ File.exist?(target_path) and return target_path
140
179
  svg_to_emf_from_node(node, target_path)
141
180
  end
142
181
 
@@ -13,7 +13,7 @@ module IsoDoc
13
13
  node["style"] == "id" and anchor_id_postprocess(node)
14
14
  xref_empty?(node) or return
15
15
  target = docid_l10n(node["target"]) ||
16
- expand_citeas(docid_l10n(node["citeas"]))
16
+ docid_l10n(expand_citeas(node["citeas"]))
17
17
  link = anchor_linkend(node, target)
18
18
  link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
19
19
  link, node)
@@ -54,8 +54,8 @@ module IsoDoc
54
54
  end
55
55
 
56
56
  def quotesource(docxml)
57
- docxml.xpath(ns("//quote/source")).each { |f| xref1(f) }
58
- docxml.xpath(ns("//quote/source//xref")).each do |f|
57
+ docxml.xpath(ns("//quote//source")).each { |f| xref1(f) }
58
+ docxml.xpath(ns("//quote//source//xref")).each do |f|
59
59
  f.replace(f.children)
60
60
  end
61
61
  end
@@ -164,9 +164,9 @@ module IsoDoc
164
164
  def passthrough1(elem, formats)
165
165
  (elem["formats"] && !elem["formats"].empty?) or elem["formats"] = "all"
166
166
  f = elem["formats"].split(",")
167
- (f - formats).size == f.size or elem["formats"] = "all"
168
- elem["formats"] == "all" and elem["formats"] = formats.join(",")
169
- elem["formats"] = ",#{elem['formats']},"
167
+ (f - formats).size == f.size or f = "all"
168
+ f == ["all"] and f = formats.dup
169
+ elem["formats"] = " #{f.join(' ')} "
170
170
  end
171
171
 
172
172
  def extract_custom_charsets(docxml)
@@ -7,7 +7,6 @@ module IsoDoc
7
7
  MATHML = { "m" => "http://www.w3.org/1998/Math/MathML" }.freeze
8
8
 
9
9
  def mathml(docxml)
10
- docxml.xpath("//m:math", MATHML).each { |f| mathml_linebreak(f) }
11
10
  locale = @lang.to_sym
12
11
  @numfmt = Plurimath::NumberFormatter
13
12
  .new(locale, localize_number: @localizenumber,
@@ -160,19 +159,6 @@ module IsoDoc
160
159
  mathml_number(node, locale)
161
160
  end
162
161
 
163
- def mathml_linebreak(node)
164
- node.at(".//*/@linebreak") or return
165
- m = Plurimath::Math.parse(node.to_xml, :mathml)
166
- .to_mathml(split_on_linebreak: true)
167
- ret = Nokogiri::XML("<m>#{m}</m>").root
168
- ret.elements.each_with_index do |e, i|
169
- i.zero? or e.previous = "<br/>"
170
- end
171
- node.replace(<<~OUTPUT)
172
- <math-with-linebreak>#{ret.children}</math-with-linebreak><math-no-linebreak>#{node.to_xml}</math-no-linebreak>
173
- OUTPUT
174
- end
175
-
176
162
  # convert any Ascii superscripts to correct(ish) MathML
177
163
  # Not bothering to match times, base of 1.0 x 10^-20, just ^-20
178
164
  def mn_to_msup(node)