isodoc 2.10.0 → 3.0.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/isodoc.gemspec +9 -4
- data/lib/isodoc/base_style/all.css +96 -0
- data/lib/isodoc/base_style/reset.css +96 -0
- data/lib/isodoc/base_style/reset.scss +75 -0
- data/lib/isodoc/base_style/scripts.html +45 -14
- data/lib/isodoc/class_utils.rb +4 -2
- data/lib/isodoc/convert.rb +0 -21
- data/lib/isodoc/css.rb +2 -4
- data/lib/isodoc/function/blocks.rb +37 -52
- data/lib/isodoc/function/blocks_example_note.rb +75 -29
- data/lib/isodoc/function/cleanup.rb +9 -44
- data/lib/isodoc/function/inline.rb +67 -13
- data/lib/isodoc/function/lists.rb +20 -14
- data/lib/isodoc/function/references.rb +9 -126
- data/lib/isodoc/function/reqt.rb +4 -3
- data/lib/isodoc/function/section.rb +30 -35
- data/lib/isodoc/function/section_titles.rb +22 -11
- data/lib/isodoc/function/table.rb +3 -3
- data/lib/isodoc/function/terms.rb +49 -26
- data/lib/isodoc/function/to_word_html.rb +46 -16
- data/lib/isodoc/function/utils.rb +11 -12
- data/lib/isodoc/gem_tasks.rb +1 -1
- data/lib/isodoc/html_function/footnotes.rb +2 -1
- data/lib/isodoc/html_function/html.rb +5 -7
- data/lib/isodoc/html_function/postprocess.rb +25 -6
- data/lib/isodoc/html_function/postprocess_cover.rb +13 -7
- data/lib/isodoc/html_function/postprocess_footnotes.rb +52 -47
- data/lib/isodoc/init.rb +31 -0
- data/lib/isodoc/metadata.rb +20 -13
- data/lib/isodoc/metadata_contributor.rb +5 -10
- data/lib/isodoc/metadata_date.rb +1 -1
- data/lib/isodoc/presentation_function/autonum.rb +153 -0
- data/lib/isodoc/presentation_function/bibdata.rb +4 -5
- data/lib/isodoc/presentation_function/block.rb +107 -40
- data/lib/isodoc/presentation_function/concepts.rb +184 -19
- data/lib/isodoc/presentation_function/docid.rb +78 -0
- data/lib/isodoc/presentation_function/erefs.rb +55 -31
- data/lib/isodoc/presentation_function/image.rb +64 -19
- data/lib/isodoc/presentation_function/index.rb +180 -0
- data/lib/isodoc/presentation_function/inline.rb +47 -16
- data/lib/isodoc/presentation_function/math.rb +128 -71
- data/lib/isodoc/presentation_function/metadata.rb +29 -66
- data/lib/isodoc/presentation_function/refs.rb +75 -28
- data/lib/isodoc/presentation_function/reqt.rb +7 -4
- data/lib/isodoc/presentation_function/section.rb +51 -129
- data/lib/isodoc/presentation_function/sourcecode.rb +52 -19
- data/lib/isodoc/presentation_function/terms.rb +107 -118
- data/lib/isodoc/presentation_function/title.rb +107 -0
- data/lib/isodoc/presentation_function/xrefs.rb +37 -17
- data/lib/isodoc/presentation_xml_convert.rb +24 -10
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_function/body.rb +9 -37
- data/lib/isodoc/word_function/comments.rb +0 -1
- data/lib/isodoc/word_function/footnotes.rb +1 -1
- data/lib/isodoc/word_function/lists.rb +13 -9
- data/lib/isodoc/word_function/postprocess.rb +6 -0
- data/lib/isodoc/word_function/postprocess_cover.rb +6 -4
- data/lib/isodoc/word_function/postprocess_table.rb +1 -1
- data/lib/isodoc/word_function/postprocess_toc.rb +10 -6
- data/lib/isodoc/word_function/table.rb +2 -2
- data/lib/isodoc/xref/clause_order.rb +41 -0
- data/lib/isodoc/xref/xref_anchor.rb +31 -16
- data/lib/isodoc/xref/xref_counter.rb +18 -3
- data/lib/isodoc/xref/xref_counter_types.rb +14 -0
- data/lib/isodoc/xref/xref_gen.rb +61 -37
- data/lib/isodoc/xref/xref_gen_seq.rb +148 -81
- data/lib/isodoc/xref/xref_sect_gen.rb +84 -88
- data/lib/isodoc/xref/xref_util.rb +53 -4
- data/lib/isodoc/xref.rb +29 -10
- data/lib/isodoc/xslfo_convert.rb +14 -9
- data/lib/isodoc-yaml/i18n-ar.yaml +17 -13
- data/lib/isodoc-yaml/i18n-de.yaml +17 -13
- data/lib/isodoc-yaml/i18n-en.yaml +18 -17
- data/lib/isodoc-yaml/i18n-es.yaml +17 -13
- data/lib/isodoc-yaml/i18n-fr.yaml +17 -13
- data/lib/isodoc-yaml/i18n-ja.yaml +56 -52
- data/lib/isodoc-yaml/i18n-ru.yaml +17 -16
- data/lib/isodoc-yaml/i18n-zh-Hans.yaml +17 -13
- data/lib/nokogiri/xml/node.rb +14 -0
- data/lib/relaton/render-isodoc/config.yml +1 -1
- metadata +90 -13
|
@@ -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 { |x| to_xml(x.children) }
|
|
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 = to_xml(num.children).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 = to_xml(ident.children)
|
|
61
|
+
ident.sub(/^\[/, "").sub(/\]$/, "")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def unbracket(ident)
|
|
65
|
+
if ident.respond_to?(:size)
|
|
66
|
+
ident.map { |x| unbracket1(x) }.join(" / ")
|
|
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,10 +3,24 @@ require "metanorma-utils"
|
|
|
3
3
|
module IsoDoc
|
|
4
4
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
|
5
5
|
def citeas(xmldoc)
|
|
6
|
-
xmldoc.xpath(ns("//eref | //origin | //
|
|
6
|
+
xmldoc.xpath(ns("//fmt-eref | //fmt-origin | //fmt-link"))
|
|
7
|
+
.each do |e|
|
|
8
|
+
sem_xml_descendant?(e) and next
|
|
7
9
|
e["bibitemid"] && e["citeas"] or next
|
|
8
|
-
a = @xrefs.anchor(e["bibitemid"], :xref, false)
|
|
10
|
+
a = @xrefs.anchor(e["bibitemid"], :xref, false) or next
|
|
11
|
+
e["citeas"] = citeas_cleanup(a)
|
|
12
|
+
# link generated in collection postprocessing from eref
|
|
13
|
+
e.name == "fmt-link" && e.text.empty? and e.children = e["citeas"]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def citeas_cleanup(ref)
|
|
18
|
+
if /</.match?(ref)
|
|
19
|
+
xml = Nokogiri::XML("<root>#{ref}</root>")
|
|
20
|
+
xml.xpath("//semx").each { |x| x.replace(x.children) }
|
|
21
|
+
ref = to_xml(xml.at("//root").children)
|
|
9
22
|
end
|
|
23
|
+
ref
|
|
10
24
|
end
|
|
11
25
|
|
|
12
26
|
def expand_citeas(text)
|
|
@@ -15,11 +29,13 @@ module IsoDoc
|
|
|
15
29
|
end
|
|
16
30
|
|
|
17
31
|
def erefstack1(elem)
|
|
18
|
-
locs = elem.xpath(ns("./eref")).map do |e|
|
|
19
|
-
[e["connective"], to_xml(e)]
|
|
32
|
+
locs = elem.xpath(ns("./semx/fmt-eref")).map do |e|
|
|
33
|
+
[e["connective"], to_xml(e.parent.remove)]
|
|
20
34
|
end.flatten
|
|
21
35
|
ret = resolve_eref_connectives(locs)
|
|
22
|
-
elem
|
|
36
|
+
elem["id"] ||= "_#{UUIDTools::UUID.random_create}"
|
|
37
|
+
elem.next = "<semx element='erefstack' source='#{elem['id']}'>#{ret[1]}</semx>"
|
|
38
|
+
#elem.replace(ret[1])
|
|
23
39
|
end
|
|
24
40
|
|
|
25
41
|
def eref_localities(refs, target, node)
|
|
@@ -38,9 +54,9 @@ module IsoDoc
|
|
|
38
54
|
ret = resolve_eref_connectives(eref_locality_stacks(refs, target,
|
|
39
55
|
node))
|
|
40
56
|
node.delete("droploc") unless droploc
|
|
41
|
-
eref_localities1({ target
|
|
57
|
+
eref_localities1({ target:, number: "pl",
|
|
42
58
|
type: refs.first.at(ns("./locality/@type")).text,
|
|
43
|
-
from: l10n(ret[1
|
|
59
|
+
from: l10n(ret[1..].join), node:, lang: @lang })
|
|
44
60
|
end
|
|
45
61
|
|
|
46
62
|
def can_conflate_eref_rendering?(refs)
|
|
@@ -48,16 +64,13 @@ module IsoDoc
|
|
|
48
64
|
refs.all? { |r| r.name == "localityStack" } &&
|
|
49
65
|
refs.all? { |r| r.xpath(ns("./locality")).size == 1 }) or return false
|
|
50
66
|
first = refs.first.at(ns("./locality/@type")).text
|
|
51
|
-
refs.all?
|
|
52
|
-
r.at(ns("./locality/@type")).text == first
|
|
53
|
-
end
|
|
67
|
+
refs.all? { |r| r.at(ns("./locality/@type")).text == first }
|
|
54
68
|
end
|
|
55
69
|
|
|
56
70
|
def resolve_eref_connectives(locs)
|
|
57
71
|
locs = resolve_comma_connectives(locs)
|
|
58
72
|
locs = resolve_to_connectives(locs)
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
locs.size < 3 and return locs
|
|
61
74
|
locs = locs.each_slice(2).with_object([]) do |a, m|
|
|
62
75
|
m << { conn: a[0], label: a[1] }
|
|
63
76
|
end
|
|
@@ -90,7 +103,8 @@ module IsoDoc
|
|
|
90
103
|
locs1 = []
|
|
91
104
|
until locs.empty?
|
|
92
105
|
if locs[1] == "to"
|
|
93
|
-
locs1 << @i18n.chain_to.sub("%1", locs[0])
|
|
106
|
+
locs1 << connectives_spans(@i18n.chain_to.sub("%1", locs[0])
|
|
107
|
+
.sub("%2", locs[2]))
|
|
94
108
|
locs.shift(3)
|
|
95
109
|
else locs1 << locs.shift
|
|
96
110
|
end
|
|
@@ -143,14 +157,13 @@ module IsoDoc
|
|
|
143
157
|
def eref_localities0(ref, _idx, target, node)
|
|
144
158
|
if ref["type"] == "whole" then @i18n.wholeoftext
|
|
145
159
|
else
|
|
146
|
-
eref_localities1({ target
|
|
160
|
+
eref_localities1({ target:, type: ref["type"], number: "sg",
|
|
147
161
|
from: ref.at(ns("./referenceFrom"))&.text,
|
|
148
|
-
upto: ref.at(ns("./referenceTo"))&.text, node
|
|
162
|
+
upto: ref.at(ns("./referenceTo"))&.text, node:,
|
|
149
163
|
lang: @lang })
|
|
150
164
|
end
|
|
151
165
|
end
|
|
152
166
|
|
|
153
|
-
# def eref_localities1_zh(_target, type, from, upto, node)
|
|
154
167
|
def eref_localities1_zh(opt)
|
|
155
168
|
ret = "第#{opt[:from]}" if opt[:from]
|
|
156
169
|
ret += "–#{opt[:upto]}" if opt[:upto]
|
|
@@ -159,11 +172,9 @@ module IsoDoc
|
|
|
159
172
|
ret
|
|
160
173
|
end
|
|
161
174
|
|
|
162
|
-
# def eref_localities1(target, type, from, upto, node, lang = "en")
|
|
163
175
|
def eref_localities1(opt)
|
|
164
176
|
opt[:type] == "anchor" and return nil
|
|
165
177
|
opt[:lang] == "zh" and
|
|
166
|
-
# return l10n(eref_localities1_zh(target, type, from, upto, node))
|
|
167
178
|
return l10n(eref_localities1_zh(opt))
|
|
168
179
|
ret = eref_locality_populate(opt[:type], opt[:node], opt[:number])
|
|
169
180
|
ret += " #{opt[:from]}" if opt[:from]
|
|
@@ -184,18 +195,20 @@ module IsoDoc
|
|
|
184
195
|
end
|
|
185
196
|
|
|
186
197
|
def eref2link(docxml)
|
|
187
|
-
docxml.xpath(ns("//
|
|
198
|
+
docxml.xpath(ns("//display-text")).each { |f| f.replace(f.children) }
|
|
199
|
+
docxml.xpath(ns("//fmt-eref | //fmt-origin[not(.//termref)]"))
|
|
188
200
|
.each do |e|
|
|
201
|
+
sem_xml_descendant?(e) and next
|
|
189
202
|
href = eref_target(e) or next
|
|
190
203
|
e.xpath(ns("./locality | ./localityStack")).each(&:remove)
|
|
191
|
-
if
|
|
204
|
+
if href[:type] == :anchor then eref2xref(e)
|
|
192
205
|
else eref2link1(e, href)
|
|
193
206
|
end
|
|
194
207
|
end
|
|
195
208
|
end
|
|
196
209
|
|
|
197
210
|
def eref2xref(node)
|
|
198
|
-
node.name = "xref"
|
|
211
|
+
node.name = "fmt-xref"
|
|
199
212
|
node["target"] = node["bibitemid"]
|
|
200
213
|
node.delete("bibitemid")
|
|
201
214
|
node.delete("citeas")
|
|
@@ -203,7 +216,9 @@ module IsoDoc
|
|
|
203
216
|
end
|
|
204
217
|
|
|
205
218
|
def eref2link1(node, href)
|
|
206
|
-
|
|
219
|
+
url = href[:link]
|
|
220
|
+
att = href[:type] == :attachment ? "attachment='true'" : ""
|
|
221
|
+
repl = "<fmt-link #{att} target='#{url}'>#{node.children}</link>"
|
|
207
222
|
node["type"] == "footnote" and repl = "<sup>#{repl}</sup>"
|
|
208
223
|
node.replace(repl)
|
|
209
224
|
end
|
|
@@ -215,20 +230,29 @@ module IsoDoc
|
|
|
215
230
|
end
|
|
216
231
|
|
|
217
232
|
def eref_target(node)
|
|
218
|
-
|
|
233
|
+
u = eref_url(node["bibitemid"]) or return nil
|
|
234
|
+
url = suffix_url(u[:link])
|
|
219
235
|
anchor = node.at(ns(".//locality[@type = 'anchor']"))
|
|
220
|
-
|
|
236
|
+
/^#/.match?(url) || !anchor and return { link: url, type: u[:type] }
|
|
237
|
+
{ link: "#{url}##{anchor.text.strip}", type: u[:type] }
|
|
238
|
+
end
|
|
221
239
|
|
|
222
|
-
|
|
240
|
+
def eref_url_prep(id)
|
|
241
|
+
@bibitem_lookup.nil? and return nil
|
|
242
|
+
@bibitem_lookup[id]
|
|
223
243
|
end
|
|
224
244
|
|
|
225
245
|
def eref_url(id)
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
"
|
|
246
|
+
b = eref_url_prep(id) or return nil
|
|
247
|
+
%i(attachment citation).each do |x|
|
|
248
|
+
u = b.at(ns("./uri[@type = '#{x}'][@language = '#{@lang}']")) ||
|
|
249
|
+
b.at(ns("./uri[@type = '#{x}']")) and return { link: u.text, type: x }
|
|
250
|
+
end
|
|
251
|
+
if b["hidden"] == "true"
|
|
252
|
+
u = b.at(ns("./uri")) or return nil
|
|
253
|
+
{ link: u.text, type: :citation }
|
|
254
|
+
else { link: "##{id}", type: :anchor }
|
|
255
|
+
end
|
|
232
256
|
end
|
|
233
257
|
end
|
|
234
258
|
end
|
|
@@ -20,8 +20,11 @@ module IsoDoc
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def svgmap_extract(elem)
|
|
23
|
-
if
|
|
24
|
-
|
|
23
|
+
if elem.at(ns("./figure"))# then elem.replace(f)
|
|
24
|
+
n = semx_fmt_dup(elem)
|
|
25
|
+
n.xpath(ns("./target")).each(&:remove)
|
|
26
|
+
elem.next = n
|
|
27
|
+
#else elem.remove
|
|
25
28
|
end
|
|
26
29
|
end
|
|
27
30
|
|
|
@@ -38,21 +41,59 @@ module IsoDoc
|
|
|
38
41
|
|
|
39
42
|
svg = Base64.strict_decode64(elem["src"]
|
|
40
43
|
.sub(%r{^data:image/svg\+xml;(charset=[^;]+;)?base64,}, ""))
|
|
41
|
-
x = Nokogiri::XML.fragment(svg.sub(/<\?xml[
|
|
42
|
-
config.huge
|
|
43
|
-
end
|
|
44
|
+
x = Nokogiri::XML.fragment(svg.sub(/<\?xml[^<>]*>/, ""), &:huge)
|
|
44
45
|
elem["src"] = ""
|
|
45
46
|
elem.children = x
|
|
46
47
|
end
|
|
47
48
|
|
|
49
|
+
def subfigure_delim
|
|
50
|
+
""
|
|
51
|
+
# "<span class='fmt-label-delim'>)</span>"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def figure_delim(_elem)
|
|
55
|
+
block_delim
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def figure_name(elem)
|
|
59
|
+
"<span class='fmt-element-name'>#{figure_label(elem)}</span> "
|
|
60
|
+
end
|
|
61
|
+
|
|
48
62
|
def figure1(elem)
|
|
49
|
-
|
|
50
|
-
elem
|
|
51
|
-
|
|
63
|
+
elem["class"] == "pseudocode" || elem["type"] == "pseudocode" and
|
|
64
|
+
return sourcecode1(elem)
|
|
65
|
+
figure_fn(elem)
|
|
66
|
+
figure_key(elem.at(ns("./dl")))
|
|
67
|
+
lbl = @xrefs.anchor(elem["id"], :label, false)
|
|
68
|
+
lbl and a = autonum(elem["id"], lbl)
|
|
69
|
+
figname = figure_name(elem)
|
|
70
|
+
(elem.parent.name == "figure") && a and
|
|
71
|
+
a += subfigure_delim
|
|
72
|
+
lbl && figure_label?(elem) and s = "#{figname}#{a}"
|
|
73
|
+
prefix_name(elem, { caption: figure_delim(elem) }, l10n(s&.strip), "name")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# move footnotes into key, and get rid of footnote reference
|
|
77
|
+
# since it is in diagram
|
|
78
|
+
def figure_fn(elem)
|
|
79
|
+
fn = elem.xpath(ns(".//fn")) - elem.xpath(ns("./name//fn"))
|
|
80
|
+
fn.empty? and return
|
|
81
|
+
dl = figure_key_insert_pt(elem)
|
|
82
|
+
fn.each do |f|
|
|
83
|
+
dl.previous = "<dt><p><sup>#{f['reference']}</sup></p></dt>" \
|
|
84
|
+
"<dd>#{f.remove.children.to_xml}</dd>"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
52
87
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
88
|
+
def figure_key_insert_pt(elem)
|
|
89
|
+
elem.at(ns("//dl/name"))&.next ||
|
|
90
|
+
elem.at(ns("//dl"))&.children&.first ||
|
|
91
|
+
elem.add_child("<dl> </dl>").first.children.first
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def figure_label?(elem)
|
|
95
|
+
elem.at(ns("./figure")) && !elem.at(ns("./name")) and return false
|
|
96
|
+
true
|
|
56
97
|
end
|
|
57
98
|
|
|
58
99
|
def figure_label(elem)
|
|
@@ -61,6 +102,14 @@ module IsoDoc
|
|
|
61
102
|
lower2cap klasslbl
|
|
62
103
|
end
|
|
63
104
|
|
|
105
|
+
def figure_key(dlist)
|
|
106
|
+
dlist or return
|
|
107
|
+
dlist["class"] = "formula_dl"
|
|
108
|
+
dlist.at(ns("./name")) and return
|
|
109
|
+
dlist.previous =
|
|
110
|
+
"<p keep-with-next='true'><strong>#{@i18n.key}</strong></p>"
|
|
111
|
+
end
|
|
112
|
+
|
|
64
113
|
def eps2svg(img)
|
|
65
114
|
return unless eps?(img["mimetype"])
|
|
66
115
|
|
|
@@ -74,7 +123,8 @@ module IsoDoc
|
|
|
74
123
|
def svg_emf_double(img)
|
|
75
124
|
if emf?(img["mimetype"])
|
|
76
125
|
img = emf_encode(img)
|
|
77
|
-
img.children.first.previous = emf_to_svg(img)
|
|
126
|
+
# img.children.first.previous = emf_to_svg(img)
|
|
127
|
+
img.add_first_child emf_to_svg(img)
|
|
78
128
|
elsif img["mimetype"] == "image/svg+xml"
|
|
79
129
|
src = svg_to_emf(img) or return
|
|
80
130
|
img.add_child("<emf/>")
|
|
@@ -123,16 +173,11 @@ module IsoDoc
|
|
|
123
173
|
|
|
124
174
|
def svg_to_emf(node)
|
|
125
175
|
@output_formats[:doc] or return
|
|
126
|
-
|
|
127
176
|
svg_impose_height_attr(node)
|
|
128
|
-
|
|
129
|
-
if node.elements&.first&.name == "svg" || %r{^data:}.match?(node["src"])
|
|
177
|
+
node.elements&.first&.name == "svg" || %r{^data:}.match?(node["src"]) and
|
|
130
178
|
return svg_to_emf_from_node(node)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
179
|
target_path = imgfile_suffix(node["src"], "emf")
|
|
134
|
-
|
|
135
|
-
|
|
180
|
+
File.exist?(target_path) and return target_path
|
|
136
181
|
svg_to_emf_from_node(node, target_path)
|
|
137
182
|
end
|
|
138
183
|
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
module IsoDoc
|
|
2
|
+
class PresentationXMLConvert < ::IsoDoc::Convert
|
|
3
|
+
def enable_indexsect
|
|
4
|
+
false
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def add_id
|
|
8
|
+
%(id="_#{UUIDTools::UUID.random_create}")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def strip_index(docxml)
|
|
12
|
+
docxml.xpath(ns("//index | //index-xref | //indexsect")).each(&:remove)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def index(xml)
|
|
16
|
+
if enable_indexsect && xml.at(ns("//index"))
|
|
17
|
+
i = xml.at(ns("//indexsect")) ||
|
|
18
|
+
xml.root.add_child("<indexsect #{add_id}><title>#{@i18n.index}" \
|
|
19
|
+
"</title></indexsect>").first
|
|
20
|
+
index = sort_indexterms(xml.xpath(ns("//index")),
|
|
21
|
+
xml.xpath(ns("//index-xref[@also = 'false']")),
|
|
22
|
+
xml.xpath(ns("//index-xref[@also = 'true']")))
|
|
23
|
+
index1(xml, i, index)
|
|
24
|
+
else strip_index(xml)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def index1(docxml, indexsect, index)
|
|
29
|
+
c = indexsect.add_child("<ul></ul>").first
|
|
30
|
+
index.keys.sort.each do |k|
|
|
31
|
+
words = index[k].keys.each_with_object({}) do |w, v|
|
|
32
|
+
v[sortable(w).downcase] = w
|
|
33
|
+
end
|
|
34
|
+
words.keys.localize(@lang.to_sym).sort.to_a.each do |w|
|
|
35
|
+
c.add_child index_entries(words, index[k], w)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
index1_cleanup(docxml)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def index1_cleanup(docxml)
|
|
42
|
+
docxml.xpath(ns("//indexsect//xref")).each do |x|
|
|
43
|
+
x.children.remove
|
|
44
|
+
end
|
|
45
|
+
@xrefs.bookmark_anchor_names(docxml)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def sortable(str)
|
|
49
|
+
str or return " "
|
|
50
|
+
HTMLEntities.new.decode(Nokogiri::XML.fragment(str).text)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def index_entries_opt
|
|
54
|
+
{ xref_lbl: ", ", see_lbl: ", #{see_lbl}", also_lbl: ", #{also_lbl}" }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def index_entries(words, index, primary)
|
|
58
|
+
ret = index_entries_head(words[primary],
|
|
59
|
+
index.dig(words[primary], nil, nil),
|
|
60
|
+
index_entries_opt)
|
|
61
|
+
words2 = index[words[primary]]&.keys&.compact
|
|
62
|
+
&.each_with_object({}) { |w, v| v[w.downcase] = w }
|
|
63
|
+
unless words2.empty?
|
|
64
|
+
ret += "<ul>"
|
|
65
|
+
words2.keys.localize(@lang.to_sym).sort.to_a.each do |w|
|
|
66
|
+
ret += index_entries2(words2, index[words[primary]], w)
|
|
67
|
+
end
|
|
68
|
+
ret += "</ul>"
|
|
69
|
+
end
|
|
70
|
+
"#{ret}</li>"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def index_entries2(words, index, secondary)
|
|
74
|
+
ret = index_entries_head(words[secondary],
|
|
75
|
+
index.dig(words[secondary], nil),
|
|
76
|
+
index_entries_opt)
|
|
77
|
+
words3 = index[words[secondary]]&.keys&.compact
|
|
78
|
+
&.each_with_object({}) { |w, v| v[w.downcase] = w }
|
|
79
|
+
unless words3.empty?
|
|
80
|
+
ret += "<ul>"
|
|
81
|
+
words3.keys.localize(@lang.to_sym).sort.to_a.each do |w|
|
|
82
|
+
ret += (index_entries_head(words3[w],
|
|
83
|
+
index[words[secondary]][words3[w]],
|
|
84
|
+
index_entries_opt) + "</li>")
|
|
85
|
+
end
|
|
86
|
+
ret += "</ul>"
|
|
87
|
+
end
|
|
88
|
+
"#{ret}</li>"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def index_entries_head(head, entries, opt)
|
|
92
|
+
ret = "<li>#{head}"
|
|
93
|
+
xref = entries&.dig(:xref)&.join(", ")
|
|
94
|
+
see = index_entries_see(entries, :see)
|
|
95
|
+
also = index_entries_see(entries, :also)
|
|
96
|
+
ret += "#{opt[:xref_lbl]} #{xref}" if xref
|
|
97
|
+
ret += "#{opt[:see_lbl]} #{see}" if see
|
|
98
|
+
ret += "#{opt[:also_lbl]} #{also}" if also
|
|
99
|
+
ret
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def index_entries_see(entries, label)
|
|
103
|
+
see_sort = entries&.dig(label) or return nil
|
|
104
|
+
x = see_sort.each_with_object({}) do |w, v|
|
|
105
|
+
v[sortable(w).downcase] = w
|
|
106
|
+
end
|
|
107
|
+
x.keys.localize(@lang.to_sym).sort.to_a.map do |k|
|
|
108
|
+
# see_sort[k]
|
|
109
|
+
x[k]
|
|
110
|
+
end.join(", ")
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def see_lbl
|
|
114
|
+
@lang == "en" ? @i18n.see : "<em>#{@i18n.see}</em>"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def also_lbl
|
|
118
|
+
@lang == "en" ? @i18n.see_also : "<em>#{@i18n.see_also}</em>"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def sort_indexterms(terms, see, also)
|
|
122
|
+
index = extract_indexterms(terms)
|
|
123
|
+
index = extract_indexsee(index, see, :see)
|
|
124
|
+
index = extract_indexsee(index, also, :also)
|
|
125
|
+
index.keys.sort.each_with_object({}) do |k, v|
|
|
126
|
+
v[sortable(k)[0].upcase.transliterate] ||= {}
|
|
127
|
+
v[sortable(k)[0].upcase.transliterate][k] = index[k]
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def extract_indexsee(val, terms, label)
|
|
132
|
+
terms.each_with_object(val) do |t, v|
|
|
133
|
+
term, term2, term3 = extract_indexterms_init(t)
|
|
134
|
+
term_hash_init(v, term, term2, term3, label)
|
|
135
|
+
v[term][term2][term3][label] << to_xml(t.at(ns("./target"))&.children)
|
|
136
|
+
t.remove
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def xml_encode_attr(str)
|
|
141
|
+
HTMLEntities.new.encode(str, :basic, :hexadecimal)
|
|
142
|
+
.gsub(/&#x([^;]+);/) do |_x|
|
|
143
|
+
"&#x#{$1.upcase};"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# attributes are decoded into UTF-8,
|
|
148
|
+
# elements in extract_indexsee are still in entities
|
|
149
|
+
def extract_indexterms(terms)
|
|
150
|
+
terms.each_with_object({}) do |t, v|
|
|
151
|
+
term, term2, term3 = extract_indexterms_init(t)
|
|
152
|
+
to = t["to"] ? "to='#{t['to']}' " : ""
|
|
153
|
+
index2bookmark(t)
|
|
154
|
+
term_hash_init(v, term, term2, term3, :xref)
|
|
155
|
+
v[term][term2][term3][:xref] << "<xref target='#{t['id']}' " \
|
|
156
|
+
"#{to}pagenumber='true'/>"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def extract_indexterms_init(term)
|
|
161
|
+
%w(primary secondary tertiary).each_with_object([]) do |x, m|
|
|
162
|
+
m << to_xml(term.at(ns("./#{x}"))&.children)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def term_hash_init(hash, term, term2, term3, label)
|
|
167
|
+
hash[term] ||= {}
|
|
168
|
+
hash[term][term2] ||= {}
|
|
169
|
+
hash[term][term2][term3] ||= {}
|
|
170
|
+
hash[term][term2][term3][label] ||= []
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def index2bookmark(node)
|
|
174
|
+
node.name = "bookmark"
|
|
175
|
+
node.children.each(&:remove)
|
|
176
|
+
node["id"] = "_#{UUIDTools::UUID.random_create}"
|
|
177
|
+
node.delete("to")
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|