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
|
@@ -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(
|
|
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)
|
|
@@ -25,8 +25,8 @@ module IsoDoc
|
|
|
25
25
|
# <locality type="section"><reference>3.1</reference></locality></origin>
|
|
26
26
|
|
|
27
27
|
def unnest_linkend(node)
|
|
28
|
-
node.at(ns("./xref[@nested]")) or return
|
|
29
|
-
node.xpath(ns("./xref[@nested]")).each { |x| x.delete("nested") }
|
|
28
|
+
node.at(ns("./fmt-xref[@nested]")) or return
|
|
29
|
+
node.xpath(ns("./fmt-xref[@nested]")).each { |x| x.delete("nested") }
|
|
30
30
|
node.xpath(ns("./location | ./locationStack")).each(&:remove)
|
|
31
31
|
node.replace(node.children)
|
|
32
32
|
end
|
|
@@ -39,31 +39,56 @@ module IsoDoc
|
|
|
39
39
|
def anchor_id_postprocess(node); end
|
|
40
40
|
|
|
41
41
|
def xref(docxml)
|
|
42
|
-
docxml.xpath(ns("//
|
|
43
|
-
docxml.xpath(ns("//xref
|
|
42
|
+
#docxml.xpath(ns("//display-text")).each { |f| f.replace(f.children) }
|
|
43
|
+
docxml.xpath(ns("//fmt-xref")).each { |f| xref1(f) }
|
|
44
|
+
docxml.xpath(ns("//fmt-xref//fmt-xref")).each { |f| f.replace(f.children) }
|
|
45
|
+
docxml.xpath(ns("//fmt-xref//xref")).each { |f| f.replace(f.children) }
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def eref(docxml)
|
|
47
|
-
docxml.xpath(ns("//eref")).each { |f|
|
|
48
|
-
docxml.xpath(ns("//eref
|
|
49
|
+
docxml.xpath(ns("//eref[@deleteme]")).each { |f| redundant_eref(f) }
|
|
50
|
+
docxml.xpath(ns("//fmt-eref")).each { |f| xref1(f) }
|
|
51
|
+
docxml.xpath(ns("//fmt-eref//fmt-xref")).each { |f| f.replace(f.children) }
|
|
49
52
|
docxml.xpath(ns("//erefstack")).each { |f| erefstack1(f) }
|
|
50
53
|
end
|
|
51
54
|
|
|
55
|
+
# redundant eref copied from quote/source
|
|
56
|
+
def redundant_eref(elem)
|
|
57
|
+
if elem.next.name == "semx"
|
|
58
|
+
elem.next.elements.first.delete("deleteme")
|
|
59
|
+
elem.next.replace(elem.next.children)
|
|
60
|
+
end
|
|
61
|
+
elem.remove
|
|
62
|
+
end
|
|
63
|
+
|
|
52
64
|
def origin(docxml)
|
|
53
|
-
docxml.xpath(ns("//origin[not(termref)]")).each { |f| xref1(f) }
|
|
65
|
+
docxml.xpath(ns("//fmt-origin[not(.//termref)]")).each { |f| xref1(f) }
|
|
54
66
|
end
|
|
55
67
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
docxml.xpath(ns("//quote
|
|
68
|
+
# KILL
|
|
69
|
+
def quotesourcex(docxml)
|
|
70
|
+
docxml.xpath(ns("//quote//source")).each { |f| xref1(f) }
|
|
71
|
+
docxml.xpath(ns("//quote//source//xref")).each do |f|
|
|
59
72
|
f.replace(f.children)
|
|
60
73
|
end
|
|
61
74
|
end
|
|
62
75
|
|
|
76
|
+
# do not change to Presentation XML rendering
|
|
77
|
+
def sem_xml_descendant?(node)
|
|
78
|
+
!node.ancestors("preferred, admitted, deprecated, related, " \
|
|
79
|
+
"definition, termsource").empty? and return true
|
|
80
|
+
!node.ancestors("xref, eref, origin, link").empty? and return true
|
|
81
|
+
!node.ancestors("requirement, recommendation, permission").empty? &&
|
|
82
|
+
node.ancestors("fmt-provision").empty? and return true
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
|
|
63
86
|
def xref1(node)
|
|
87
|
+
sem_xml_descendant?(node) and return
|
|
64
88
|
get_linkend(node)
|
|
65
89
|
end
|
|
66
90
|
|
|
91
|
+
# there should be no //variant in bibdata now
|
|
67
92
|
def variant(xml)
|
|
68
93
|
b = xml.xpath(ns("//bibdata//variant"))
|
|
69
94
|
(xml.xpath(ns("//variant")) - b).each { |f| variant1(f) }
|
|
@@ -85,7 +110,10 @@ module IsoDoc
|
|
|
85
110
|
|
|
86
111
|
def identifier(docxml)
|
|
87
112
|
docxml.xpath(ns("//identifier")).each do |n|
|
|
88
|
-
|
|
113
|
+
%w(bibdata bibitem requirement recommendation permission)
|
|
114
|
+
.include?(n.parent.name) and next
|
|
115
|
+
s = semx_fmt_dup(n)
|
|
116
|
+
n.next = "<fmt-identifier><tt>#{to_xml(s)}</tt></fmt-identifier>"
|
|
89
117
|
end
|
|
90
118
|
end
|
|
91
119
|
|
|
@@ -98,7 +126,10 @@ module IsoDoc
|
|
|
98
126
|
|
|
99
127
|
def date1(elem)
|
|
100
128
|
elem["value"] && elem["format"] or return
|
|
101
|
-
|
|
129
|
+
val = @i18n.date(elem["value"], elem["format"].strip)
|
|
130
|
+
d = semx_fmt_dup(elem)
|
|
131
|
+
d << val
|
|
132
|
+
elem.next = "<fmt-date>#{to_xml(d)}</fmt-date>"
|
|
102
133
|
end
|
|
103
134
|
|
|
104
135
|
def inline_format(docxml)
|
|
@@ -160,9 +191,9 @@ module IsoDoc
|
|
|
160
191
|
def passthrough1(elem, formats)
|
|
161
192
|
(elem["formats"] && !elem["formats"].empty?) or elem["formats"] = "all"
|
|
162
193
|
f = elem["formats"].split(",")
|
|
163
|
-
(f - formats).size == f.size or
|
|
164
|
-
|
|
165
|
-
elem["formats"] = "
|
|
194
|
+
(f - formats).size == f.size or f = "all"
|
|
195
|
+
f == ["all"] and f = formats.dup
|
|
196
|
+
elem["formats"] = " #{f.join(' ')} "
|
|
166
197
|
end
|
|
167
198
|
|
|
168
199
|
def extract_custom_charsets(docxml)
|
|
@@ -7,9 +7,13 @@ module IsoDoc
|
|
|
7
7
|
MATHML = { "m" => "http://www.w3.org/1998/Math/MathML" }.freeze
|
|
8
8
|
|
|
9
9
|
def mathml(docxml)
|
|
10
|
-
docxml.xpath("//
|
|
11
|
-
locale =
|
|
10
|
+
docxml.xpath(ns("//stem")).each { |s| stem_dup(s) }
|
|
11
|
+
locale = @lang.to_sym
|
|
12
|
+
@numfmt = Plurimath::NumberFormatter
|
|
13
|
+
.new(locale, localize_number: @localizenumber,
|
|
14
|
+
localizer_symbols: twitter_cldr_localiser_symbols)
|
|
12
15
|
docxml.xpath("//m:math", MATHML).each do |f| # rubocop:disable Style/CombinableLoops
|
|
16
|
+
f.parent&.parent&.name == "fmt-stem" or next
|
|
13
17
|
mathml1(f, locale)
|
|
14
18
|
end
|
|
15
19
|
end
|
|
@@ -18,81 +22,124 @@ module IsoDoc
|
|
|
18
22
|
# TwitterCldr::DataReaders::NumberDataReader.new(locale).symbols
|
|
19
23
|
def localize_maths(node, locale)
|
|
20
24
|
node.xpath(".//m:mn", MATHML).each do |x|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
x.children =
|
|
25
|
+
fmt = x["data-metanorma-numberformat"]
|
|
26
|
+
x.delete("data-metanorma-numberformat")
|
|
27
|
+
x.children =
|
|
28
|
+
if !fmt.nil? && !fmt.empty?
|
|
29
|
+
explicit_number_formatter(x, locale, fmt)
|
|
30
|
+
else implicit_number_formatter(x, locale)
|
|
31
|
+
end
|
|
24
32
|
rescue ArgumentError
|
|
33
|
+
rescue StandardError, RuntimeError => e
|
|
34
|
+
warn "Failure to localise MathML/mn\n#{node.parent.to_xml}\n#{e}"
|
|
25
35
|
end
|
|
26
36
|
end
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return localized unless twitter_cldr_reader_symbols[:decimal]
|
|
34
|
-
|
|
35
|
-
integer, fraction = localized.split(twitter_cldr_reader_symbols[:decimal])
|
|
36
|
-
return localized if fraction.nil? || fraction.empty?
|
|
38
|
+
def normalise_number(num)
|
|
39
|
+
n = BigDecimal(num).to_s("F")
|
|
40
|
+
/\.\d/.match?(num) or n.sub!(/\.\d+$/, "")
|
|
41
|
+
n
|
|
42
|
+
end
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
def implicit_number_formatter(num, locale)
|
|
45
|
+
num.ancestors("formula").empty? or return
|
|
46
|
+
## by default, no formatting in formulas
|
|
47
|
+
fmt = { significant: num_totaldigits(num.text) }.compact
|
|
48
|
+
n = normalise_number(num.text)
|
|
49
|
+
@numfmt.localized_number(n, locale:, format: fmt,
|
|
50
|
+
precision: num_precision(num.text))
|
|
40
51
|
end
|
|
41
52
|
|
|
42
|
-
def
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
def numberformat_extract(options)
|
|
54
|
+
options.gsub!(/([a-z_]+)='/, %('\\1=))
|
|
55
|
+
CSV.parse_line(options, quote_char: "'").each_with_object({}) do |x, acc|
|
|
56
|
+
m = /^(.+?)=(.+)?$/.match(x) or next
|
|
57
|
+
acc[m[1].to_sym] = m[2].sub(/^(["'])(.+)\1$/, "\\2")
|
|
47
58
|
end
|
|
48
59
|
end
|
|
49
60
|
|
|
50
|
-
def
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
def numberformat_type(ret)
|
|
62
|
+
%i(precision significant digit_count group_digits fraction_group_digits)
|
|
63
|
+
.each do |i|
|
|
64
|
+
ret[i] &&= ret[i].to_i
|
|
65
|
+
end
|
|
66
|
+
%i(notation exponent_sign number_sign locale).each do |i|
|
|
67
|
+
ret[i] &&= ret[i].to_sym
|
|
57
68
|
end
|
|
58
|
-
|
|
69
|
+
ret
|
|
59
70
|
end
|
|
60
71
|
|
|
61
|
-
def
|
|
62
|
-
|
|
72
|
+
def explicit_number_formatter(num, locale, options)
|
|
73
|
+
ret = numberformat_type(numberformat_extract(options))
|
|
74
|
+
l = ret[:locale] || locale
|
|
75
|
+
precision, symbols, significant = explicit_number_formatter_cfg(num, ret)
|
|
76
|
+
n = normalise_number(num.text)
|
|
77
|
+
Plurimath::NumberFormatter.new(l)
|
|
78
|
+
.localized_number(n, precision:,
|
|
79
|
+
format: symbols.merge(significant:))
|
|
63
80
|
end
|
|
64
81
|
|
|
65
|
-
def
|
|
66
|
-
|
|
82
|
+
def explicit_number_formatter_cfg(num, fmt)
|
|
83
|
+
symbols = twitter_cldr_localiser_symbols.dup.transform_values do |v|
|
|
84
|
+
v.is_a?(String) ? HTMLEntities.new.decode(v) : v
|
|
85
|
+
end.merge(fmt)
|
|
86
|
+
symbols = large_notation_fmt(symbols, num.text)
|
|
87
|
+
[symbols[:precision] || num_precision(num.text), symbols,
|
|
88
|
+
explicit_number_formatter_signif(num, symbols)]
|
|
89
|
+
end
|
|
67
90
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
def explicit_number_formatter_signif(num, symbols)
|
|
92
|
+
signif = symbols[:significant]
|
|
93
|
+
(symbols.keys & %i(precision digit_count)).empty? and
|
|
94
|
+
signif ||= num_totaldigits(num.text)
|
|
95
|
+
signif
|
|
72
96
|
end
|
|
73
97
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
98
|
+
def large_notation_fmt(symbols, num)
|
|
99
|
+
n = symbols[:large_notation]
|
|
100
|
+
min = BigDecimal(symbols[:large_notation_min] || "1e-6")
|
|
101
|
+
max = BigDecimal(symbols[:large_notation_max] || "1e6")
|
|
102
|
+
n1 = large_notation_fmt1(num, n, min, max) and symbols[:notation] = n1
|
|
103
|
+
symbols.delete(:large_notation)
|
|
104
|
+
symbols.delete(:large_notation_min)
|
|
105
|
+
symbols.delete(:large_notation_max)
|
|
106
|
+
symbols
|
|
78
107
|
end
|
|
79
108
|
|
|
80
|
-
def
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
109
|
+
def large_notation_fmt1(num, notation, min, max)
|
|
110
|
+
notation.nil? || notation == "nil" and return nil
|
|
111
|
+
val = BigDecimal(num).abs
|
|
112
|
+
val.zero? and return nil
|
|
113
|
+
val < min and return notation
|
|
114
|
+
val > max and return notation
|
|
115
|
+
nil
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def num_precision(num)
|
|
119
|
+
precision = nil
|
|
120
|
+
/\.(?!\d+e)/.match?(num) and
|
|
121
|
+
precision = twitter_cldr_localiser_symbols[:precision] ||
|
|
122
|
+
num.sub(/^.*\./, "").size
|
|
123
|
+
precision
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def num_totaldigits(num)
|
|
127
|
+
totaldigits = nil
|
|
128
|
+
/\.(?=\d+e)/.match?(num) and
|
|
129
|
+
totaldigits = twitter_cldr_localiser_symbols[:significant] ||
|
|
130
|
+
num.sub(/^0\./, ".").sub(/^.*\./, "").sub(/e.*$/, "").size
|
|
131
|
+
totaldigits
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def twitter_cldr_localiser_symbols
|
|
135
|
+
{}
|
|
90
136
|
end
|
|
91
137
|
|
|
92
138
|
def asciimath_dup(node)
|
|
93
139
|
@suppressasciimathdup || node.parent.at(ns("./asciimath")) and return
|
|
94
140
|
math = node.to_xml.gsub(/ xmlns=["'][^"']+["']/, "")
|
|
95
141
|
.gsub(%r{<[^:/>]+:}, "<").gsub(%r{</[^:/>]+:}, "</")
|
|
142
|
+
.gsub(%r{ data-metanorma-numberformat="[^"]+"}, "")
|
|
96
143
|
ret = Plurimath::Math.parse(math, "mathml").to_asciimath
|
|
97
144
|
node.next = "<asciimath>#{@c.encode(ret, :basic)}</asciimath>"
|
|
98
145
|
rescue StandardError => e
|
|
@@ -100,12 +147,13 @@ module IsoDoc
|
|
|
100
147
|
end
|
|
101
148
|
|
|
102
149
|
def maths_just_numeral(node)
|
|
103
|
-
mn = node.at(".//m:mn", MATHML).children
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
150
|
+
mn = node.at(".//m:mn", MATHML).children.text
|
|
151
|
+
.sub(/\^([0-9+-]+)$/, "<sup>\\1</sup>")
|
|
152
|
+
#if node.parent.parent.name == "stem"
|
|
153
|
+
#node.replace(mn)
|
|
154
|
+
#else
|
|
107
155
|
node.replace(mn)
|
|
108
|
-
end
|
|
156
|
+
#end
|
|
109
157
|
end
|
|
110
158
|
|
|
111
159
|
def mathml1(node, locale)
|
|
@@ -113,24 +161,33 @@ module IsoDoc
|
|
|
113
161
|
mathml_number(node, locale)
|
|
114
162
|
end
|
|
115
163
|
|
|
116
|
-
def
|
|
117
|
-
node
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
164
|
+
def stem_dup(node)
|
|
165
|
+
sem_xml_descendant?(node) and return
|
|
166
|
+
ret = semx_fmt_dup(node)
|
|
167
|
+
f = Nokogiri::XML::Node.new("fmt-stem", node.document)
|
|
168
|
+
t = node["type"] and f["type"] = t
|
|
169
|
+
f << ret
|
|
170
|
+
node.next = f
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# convert any Ascii superscripts to correct(ish) MathML
|
|
174
|
+
# Not bothering to match times, base of 1.0 x 10^-20, just ^-20
|
|
175
|
+
def mn_to_msup(node)
|
|
176
|
+
node.xpath(".//m:mn", MATHML).each do |n|
|
|
177
|
+
m = %r{^(.+)\^([0-9+-]+)$}.match(n.text) or next
|
|
178
|
+
n.replace("<msup><mn>#{m[1]}</mn><mn>#{m[2]}</mn></msup>")
|
|
123
179
|
end
|
|
124
|
-
node.replace(<<~OUTPUT)
|
|
125
|
-
<math-with-linebreak>#{ret.children}</math-with-linebreak><math-no-linebreak>#{node.to_xml}</math-no-linebreak>
|
|
126
|
-
OUTPUT
|
|
127
180
|
end
|
|
128
181
|
|
|
129
182
|
def mathml_number(node, locale)
|
|
130
183
|
justnumeral = numeric_mathml?(node)
|
|
131
184
|
justnumeral or asciimath_dup(node)
|
|
132
185
|
localize_maths(node, locale)
|
|
133
|
-
justnumeral
|
|
186
|
+
if justnumeral
|
|
187
|
+
maths_just_numeral(node)
|
|
188
|
+
else
|
|
189
|
+
mn_to_msup(node)
|
|
190
|
+
end
|
|
134
191
|
end
|
|
135
192
|
|
|
136
193
|
def numeric_mathml?(node)
|
|
@@ -152,11 +209,11 @@ module IsoDoc
|
|
|
152
209
|
def mathml_number_to_number(node)
|
|
153
210
|
(node.elements.size == 1 && node.elements.first.name == "mn") or return
|
|
154
211
|
repl = node.at("./m:mn", MATHML).children
|
|
155
|
-
if node.parent.name == "stem"
|
|
156
|
-
node.parent.replace(repl)
|
|
157
|
-
else
|
|
212
|
+
#if node.parent.name == "stem"
|
|
213
|
+
#node.parent.replace(repl)
|
|
214
|
+
#else
|
|
158
215
|
node.replace(repl)
|
|
159
|
-
end
|
|
216
|
+
#end
|
|
160
217
|
end
|
|
161
218
|
end
|
|
162
219
|
end
|
|
@@ -3,13 +3,35 @@ module IsoDoc
|
|
|
3
3
|
def metadata(docxml)
|
|
4
4
|
toc_metadata(docxml)
|
|
5
5
|
fonts_metadata(docxml)
|
|
6
|
-
|
|
6
|
+
attachments_extract(docxml)
|
|
7
|
+
localized_strings(docxml)
|
|
8
|
+
a = docxml.at(ns("//metanorma-extension")) or return
|
|
9
|
+
a.elements.empty? and a.remove
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def localized_strings(docxml)
|
|
7
13
|
a = docxml.at(ns("//bibdata")) or return
|
|
8
14
|
a.next =
|
|
9
15
|
"<localized-strings>#{i8n_name(trim_hash(@i18n.get), '').join}" \
|
|
10
16
|
"</localized-strings>"
|
|
11
17
|
end
|
|
12
18
|
|
|
19
|
+
def attachments_extract(docxml)
|
|
20
|
+
docxml.at(ns("//metanorma-extension/attachment")) or return
|
|
21
|
+
dir = File.join(@localdir, "_#{@outputfile}_attachments")
|
|
22
|
+
FileUtils.rm_rf(dir)
|
|
23
|
+
FileUtils.mkdir_p(dir)
|
|
24
|
+
docxml.xpath(ns("//metanorma-extension/attachment")).each do |a|
|
|
25
|
+
save_attachment(a, dir)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def save_attachment(attachment, dir)
|
|
30
|
+
n = File.join(dir, File.basename(attachment["name"]))
|
|
31
|
+
c = attachment.text.sub(%r{^data:[^;]+;(?:charset=[^;]+;)?base64,}, "")
|
|
32
|
+
File.open(n, "wb") { |f| f.write(Base64.decode64(c)) }
|
|
33
|
+
end
|
|
34
|
+
|
|
13
35
|
def extension_insert(xml, path = [])
|
|
14
36
|
ins = extension_insert_pt(xml)
|
|
15
37
|
path.each do |n|
|
|
@@ -20,9 +42,11 @@ module IsoDoc
|
|
|
20
42
|
|
|
21
43
|
def extension_insert_pt(xml)
|
|
22
44
|
xml.at(ns("//metanorma-extension")) ||
|
|
23
|
-
xml.at(ns("//bibdata"))
|
|
45
|
+
xml.at(ns("//bibdata"))
|
|
46
|
+
&.after("<metanorma-extension> </metanorma-extension>")
|
|
24
47
|
&.next_element ||
|
|
25
|
-
xml.root.elements.first
|
|
48
|
+
xml.root.elements.first
|
|
49
|
+
.before("<metanorma-extension> </metanorma-extension>")
|
|
26
50
|
.previous_element
|
|
27
51
|
end
|
|
28
52
|
|
|
@@ -41,7 +65,7 @@ module IsoDoc
|
|
|
41
65
|
def fonts_metadata(xmldoc)
|
|
42
66
|
ins = presmeta_insert_pt(xmldoc)
|
|
43
67
|
@fontist_fonts and CSV.parse_line(@fontist_fonts, col_sep: ";")
|
|
44
|
-
.map(&:strip).
|
|
68
|
+
.map(&:strip).reverse_each do |f|
|
|
45
69
|
ins.next = presmeta("fonts", f)
|
|
46
70
|
end
|
|
47
71
|
@fontlicenseagreement and
|
|
@@ -50,7 +74,7 @@ module IsoDoc
|
|
|
50
74
|
|
|
51
75
|
def presmeta_insert_pt(xmldoc)
|
|
52
76
|
xmldoc.at(ns("//presentation-metadata")) ||
|
|
53
|
-
xmldoc
|
|
77
|
+
extension_insert_pt(xmldoc).children.last
|
|
54
78
|
end
|
|
55
79
|
|
|
56
80
|
def presmeta(name, value)
|
|
@@ -58,67 +82,6 @@ module IsoDoc
|
|
|
58
82
|
"</presentation-metadata>"
|
|
59
83
|
end
|
|
60
84
|
|
|
61
|
-
def preprocess_xslt_insert(docxml)
|
|
62
|
-
content = ""
|
|
63
|
-
p = passthrough_xslt and content += p
|
|
64
|
-
p = preprocess_xslt_read and content += File.read(p)
|
|
65
|
-
content.empty? and return
|
|
66
|
-
ins = extension_insert(docxml, %w(render))
|
|
67
|
-
ins << content
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
COPY_XSLT =
|
|
71
|
-
'<xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>'.freeze
|
|
72
|
-
COPY_CHILDREN_XSLT =
|
|
73
|
-
'<xsl:apply-templates select="node()"/>'.freeze
|
|
74
|
-
|
|
75
|
-
def xslt_template(content)
|
|
76
|
-
<<~XSLT
|
|
77
|
-
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
|
|
78
|
-
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
|
|
79
|
-
<xsl:template match="@* | node()">#{COPY_XSLT}</xsl:template>
|
|
80
|
-
#{content}
|
|
81
|
-
</xsl:stylesheet>
|
|
82
|
-
XSLT
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def passthrough_xslt
|
|
86
|
-
@output_formats.nil? and return nil
|
|
87
|
-
@output_formats.empty? and return nil
|
|
88
|
-
@output_formats.each_key.with_object([]) do |k, m|
|
|
89
|
-
m << <<~XSLT
|
|
90
|
-
<preprocess-xslt format="#{k}">
|
|
91
|
-
#{xslt_template(<<~XSLT1)
|
|
92
|
-
<xsl:template match="*[local-name() = 'passthrough']">
|
|
93
|
-
<xsl:if test="contains(@formats,',#{k},')"> <!-- delimited -->
|
|
94
|
-
#{COPY_XSLT}
|
|
95
|
-
</xsl:if>
|
|
96
|
-
</xsl:template>
|
|
97
|
-
XSLT1
|
|
98
|
-
}
|
|
99
|
-
</preprocess-xslt>
|
|
100
|
-
XSLT
|
|
101
|
-
m << <<~XSLT
|
|
102
|
-
<preprocess-xslt format="#{k}">
|
|
103
|
-
#{xslt_template(<<~XSLT1)
|
|
104
|
-
<xsl:template match="*[local-name() = 'math-with-linebreak']">
|
|
105
|
-
#{k == 'pdf' ? COPY_CHILDREN_XSLT : ''}
|
|
106
|
-
</xsl:template>
|
|
107
|
-
<xsl:template match="*[local-name() = 'math-no-linebreak']">
|
|
108
|
-
#{k == 'pdf' ? '' : COPY_CHILDREN_XSLT}
|
|
109
|
-
</xsl:template>
|
|
110
|
-
XSLT1
|
|
111
|
-
}
|
|
112
|
-
</preprocess-xslt>
|
|
113
|
-
XSLT
|
|
114
|
-
end.join("\n")
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# read in from file, but with `<preprocess-xslt @format="">` wrapper
|
|
118
|
-
def preprocess_xslt_read
|
|
119
|
-
html_doc_path("preprocess.xslt")
|
|
120
|
-
end
|
|
121
|
-
|
|
122
85
|
def i18n_tag(key, value)
|
|
123
86
|
"<localized-string key='#{key}' language='#{@lang}'>#{value}" \
|
|
124
87
|
"</localized-string>"
|