lib/isodoc/presentation_function/math.rb in isodoc-2.10.5 vs lib/isodoc/presentation_function/math.rb in isodoc-2.10.6

- old
+ new

@@ -26,26 +26,24 @@ x.delete("data-metanorma-numberformat") explicit_number_formatter(x, locale, fmt) else implicit_number_formatter(x, locale) end rescue ArgumentError - rescue Error => e - warn "Failure to localised MathML/mn\n#{node.parent.to_xml}\n#{e}" + rescue StandardError, RuntimeError => e + warn "Failure to localise MathML/mn\n#{node.parent.to_xml}\n#{e}" end end def normalise_number(num) n = BigDecimal(num).to_s("F") /\.\d/.match?(num) or n.sub!(/\.\d+$/, "") n end def implicit_number_formatter(num, locale) - fmt = { digit_count: num_totaldigits(num.text) }.compact + fmt = { significant: num_totaldigits(num.text) }.compact n = normalise_number(num.text) - # Plurimath confused by exponent notation - #warn "IMPLICIT: precision: #{num_precision(num.text)} ; symbols: #{fmt}, n: #{n}; output: #{@numfmt.localized_number(n, locale:, format: fmt, precision: num_precision(num.text))}" @numfmt.localized_number(n, locale:, format: fmt, precision: num_precision(num.text)) end def numberformat_extract(options) @@ -55,11 +53,12 @@ acc[m[1].to_sym] = m[2].sub(/^(["'])(.+)\1$/, "\\2") end end def numberformat_type(ret) - %i(precision digit_count group_digits fraction_group_digits).each do |i| + %i(precision significant digit_count group_digits fraction_group_digits) + .each do |i| ret[i] &&= ret[i].to_i end %i(notation exponent_sign locale).each do |i| ret[i] &&= ret[i].to_sym end @@ -67,24 +66,24 @@ end def explicit_number_formatter(num, locale, options) ret = numberformat_type(numberformat_extract(options)) l = ret[:locale] || locale - precision, symbols, digit_count = explicit_number_formatter_cfg(num, ret) + precision, symbols, significant = explicit_number_formatter_cfg(num, ret) n = normalise_number(num.text) - # Plurimath confused by exponent notation - #warn "EXPLICIT: precision: #{precision} ; symbols: #{symbols}, n: #{n}; output: #{Plurimath::NumberFormatter.new(l, localizer_symbols: symbols).localized_number(n, precision:, format: symbols.merge(digit_count:))}" - Plurimath::NumberFormatter.new(l, localizer_symbols: symbols) + Plurimath::NumberFormatter.new(l) .localized_number(n, precision:, - format: symbols.merge(digit_count:)) + format: symbols.merge(significant:)) end def explicit_number_formatter_cfg(num, fmt) symbols = twitter_cldr_localiser_symbols.dup.merge(fmt) - precision = symbols[:precision]&.to_i || num_precision(num.text) - symbols[:precision] or digit_count = num_totaldigits(num.text) - [precision, symbols, digit_count] + precision = symbols[:precision] || num_precision(num.text) + signif = symbols[:significant] + (symbols.keys & %i(precision digit_count)).empty? and + signif ||= num_totaldigits(num.text) + [precision, symbols, signif] end def num_precision(num) precision = nil /\.(?!\d+e)/.match?(num) and @@ -94,12 +93,12 @@ end def num_totaldigits(num) totaldigits = nil /\.(?=\d+e)/.match?(num) and - totaldigits = twitter_cldr_localiser_symbols[:digit_count] || - num.sub(/^.*\./, "").sub(/e.*$/, "").size + totaldigits = twitter_cldr_localiser_symbols[:significant] || + num.sub(/^0\./, ".").sub(/^.*\./, "").sub(/e.*$/, "").size totaldigits end def twitter_cldr_localiser_symbols {} @@ -107,18 +106,20 @@ def asciimath_dup(node) @suppressasciimathdup || node.parent.at(ns("./asciimath")) and return math = node.to_xml.gsub(/ xmlns=["'][^"']+["']/, "") .gsub(%r{<[^:/>]+:}, "<").gsub(%r{</[^:/>]+:}, "</") + .gsub(%r{ data-metanorma-numberformat="[^"]+"}, "") ret = Plurimath::Math.parse(math, "mathml").to_asciimath node.next = "<asciimath>#{@c.encode(ret, :basic)}</asciimath>" rescue StandardError => e warn "Failure to convert MathML to AsciiMath\n#{node.parent.to_xml}\n#{e}" end def maths_just_numeral(node) - mn = node.at(".//m:mn", MATHML).children + mn = node.at(".//m:mn", MATHML).children.text + .sub(/\^([0-9+-]+)$/, "<sup>\\1</sup>") if node.parent.name == "stem" node.parent.replace(mn) else node.replace(mn) end @@ -140,14 +141,27 @@ node.replace(<<~OUTPUT) <math-with-linebreak>#{ret.children}</math-with-linebreak><math-no-linebreak>#{node.to_xml}</math-no-linebreak> OUTPUT end + # convert any Ascii superscripts to correct(ish) MathML + # Not bothering to match times, base of 1.0 x 10^-20, just ^-20 + def mn_to_msup(node) + node.xpath(".//m:mn", MATHML).each do |n| + m = %r{^(.+)\^([0-9+-]+)$}.match(n.text) or next + n.replace("<msup><mn>#{m[1]}</mn><mn>#{m[2]}</mn></msup>") + end + end + def mathml_number(node, locale) justnumeral = numeric_mathml?(node) justnumeral or asciimath_dup(node) localize_maths(node, locale) - justnumeral and maths_just_numeral(node) + if justnumeral + maths_just_numeral(node) + else + mn_to_msup(node) + end end def numeric_mathml?(node) m = {} node.traverse do |x|