plurimath 0.11.1 → 0.11.4
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/.gitignore +3 -0
- data/.rubocop_todo.yml +108 -175
- data/Gemfile +1 -0
- data/README.adoc +282 -6
- data/lib/plurimath/asciimath/parse.rb +6 -1
- data/lib/plurimath/asciimath/transform.rb +2 -0
- data/lib/plurimath/base_number_prefix.rb +43 -0
- data/lib/plurimath/cli.rb +1 -1
- data/lib/plurimath/configuration.rb +9 -1
- data/lib/plurimath/errors/evaluation/division_by_zero_error.rb +13 -0
- data/lib/plurimath/errors/evaluation/error.rb +9 -0
- data/lib/plurimath/errors/evaluation/invalid_binding_error.rb +14 -0
- data/lib/plurimath/errors/evaluation/invalid_binding_key_error.rb +14 -0
- data/lib/plurimath/errors/evaluation/math_domain_error.rb +9 -0
- data/lib/plurimath/errors/evaluation/missing_variable_error.rb +13 -0
- data/lib/plurimath/errors/evaluation/non_finite_result_error.rb +13 -0
- data/lib/plurimath/errors/evaluation/unsupported_expression_error.rb +13 -0
- data/lib/plurimath/errors/evaluation.rb +18 -0
- data/lib/plurimath/errors.rb +1 -0
- data/lib/plurimath/formatter/numbers/base_notation.rb +54 -31
- data/lib/plurimath/formatter/numbers/formatted_notation.rb +62 -0
- data/lib/plurimath/formatter/numbers/formatted_number.rb +87 -0
- data/lib/plurimath/formatter/numbers/fraction.rb +1 -1
- data/lib/plurimath/formatter/numbers/mathml_renderer.rb +56 -0
- data/lib/plurimath/formatter/numbers/notation_renderer.rb +30 -29
- data/lib/plurimath/formatter/numbers/number_renderer.rb +10 -9
- data/lib/plurimath/formatter/numbers/omml_renderer.rb +74 -0
- data/lib/plurimath/formatter/numbers/source.rb +29 -4
- data/lib/plurimath/formatter/numbers/text_renderer.rb +52 -0
- data/lib/plurimath/formatter/numbers.rb +6 -2
- data/lib/plurimath/html/parse.rb +5 -0
- data/lib/plurimath/html/transform.rb +2 -0
- data/lib/plurimath/latex/parse.rb +5 -0
- data/lib/plurimath/latex/transform.rb +2 -0
- data/lib/plurimath/math/core.rb +52 -0
- data/lib/plurimath/math/evaluation/evaluator.rb +147 -0
- data/lib/plurimath/math/evaluation/expression_parser.rb +215 -0
- data/lib/plurimath/math/evaluation/iteration.rb +63 -0
- data/lib/plurimath/math/evaluation.rb +13 -0
- data/lib/plurimath/math/formula.rb +10 -1
- data/lib/plurimath/math/function/abs.rb +4 -0
- data/lib/plurimath/math/function/arccos.rb +4 -0
- data/lib/plurimath/math/function/arcsin.rb +4 -0
- data/lib/plurimath/math/function/arctan.rb +4 -0
- data/lib/plurimath/math/function/ceil.rb +4 -0
- data/lib/plurimath/math/function/cos.rb +4 -0
- data/lib/plurimath/math/function/cosh.rb +4 -0
- data/lib/plurimath/math/function/cot.rb +4 -0
- data/lib/plurimath/math/function/coth.rb +4 -0
- data/lib/plurimath/math/function/csc.rb +4 -0
- data/lib/plurimath/math/function/csch.rb +4 -0
- data/lib/plurimath/math/function/exp.rb +4 -0
- data/lib/plurimath/math/function/fenced.rb +4 -0
- data/lib/plurimath/math/function/floor.rb +4 -0
- data/lib/plurimath/math/function/frac.rb +7 -0
- data/lib/plurimath/math/function/gcd.rb +9 -0
- data/lib/plurimath/math/function/lcm.rb +9 -0
- data/lib/plurimath/math/function/lg.rb +4 -0
- data/lib/plurimath/math/function/ln.rb +4 -0
- data/lib/plurimath/math/function/log.rb +19 -0
- data/lib/plurimath/math/function/max.rb +4 -0
- data/lib/plurimath/math/function/min.rb +4 -0
- data/lib/plurimath/math/function/mod.rb +15 -0
- data/lib/plurimath/math/function/power.rb +10 -0
- data/lib/plurimath/math/function/prod.rb +10 -0
- data/lib/plurimath/math/function/root.rb +7 -0
- data/lib/plurimath/math/function/sec.rb +4 -0
- data/lib/plurimath/math/function/sech.rb +4 -0
- data/lib/plurimath/math/function/sin.rb +4 -0
- data/lib/plurimath/math/function/sinh.rb +4 -0
- data/lib/plurimath/math/function/sqrt.rb +4 -0
- data/lib/plurimath/math/function/sum.rb +10 -0
- data/lib/plurimath/math/function/tan.rb +4 -0
- data/lib/plurimath/math/function/tanh.rb +4 -0
- data/lib/plurimath/math/function/text.rb +17 -0
- data/lib/plurimath/math/number.rb +40 -29
- data/lib/plurimath/math/symbols/cdot.rb +4 -0
- data/lib/plurimath/math/symbols/div.rb +4 -0
- data/lib/plurimath/math/symbols/hat.rb +4 -0
- data/lib/plurimath/math/symbols/minus.rb +4 -0
- data/lib/plurimath/math/symbols/pi.rb +5 -1
- data/lib/plurimath/math/symbols/plus.rb +4 -0
- data/lib/plurimath/math/symbols/slash.rb +4 -0
- data/lib/plurimath/math/symbols/symbol.rb +45 -0
- data/lib/plurimath/math/symbols/times.rb +4 -0
- data/lib/plurimath/math.rb +1 -0
- data/lib/plurimath/mathml/constants.rb +18 -0
- data/lib/plurimath/number_formatter.rb +47 -28
- data/lib/plurimath/omml/formula_transformation.rb +17 -2
- data/lib/plurimath/omml/translator.rb +2 -0
- data/lib/plurimath/setup/opal.rb.erb +13 -0
- data/lib/plurimath/unicode_math/parse.rb +5 -1
- data/lib/plurimath/unicode_math/transform.rb +469 -755
- data/lib/plurimath/utility.rb +2 -2
- data/lib/plurimath/version.rb +1 -1
- data/lib/plurimath.rb +1 -0
- data/plurimath.gemspec +1 -1
- metadata +23 -5
- data/lib/plurimath/formatter/numbers/parts_renderer.rb +0 -30
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Plurimath
|
|
4
4
|
class NumberFormatter
|
|
5
|
-
attr_accessor :locale, :
|
|
5
|
+
attr_accessor :locale, :localize_number, :localizer_symbols, :precision
|
|
6
6
|
|
|
7
7
|
def initialize(
|
|
8
8
|
locale = "en",
|
|
@@ -21,11 +21,27 @@ module Plurimath
|
|
|
21
21
|
locale: @locale,
|
|
22
22
|
precision: @precision,
|
|
23
23
|
format: {}
|
|
24
|
+
)
|
|
25
|
+
result = formatted_number(
|
|
26
|
+
number_string,
|
|
27
|
+
locale: locale,
|
|
28
|
+
precision: precision,
|
|
29
|
+
format: format,
|
|
30
|
+
)
|
|
31
|
+
result.to_s
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def formatted_number(
|
|
35
|
+
number_string,
|
|
36
|
+
locale: @locale,
|
|
37
|
+
precision: @precision,
|
|
38
|
+
format: {}
|
|
24
39
|
)
|
|
25
40
|
locale = supported_locale(locale)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
format = validated_format(format)
|
|
42
|
+
base = format.fetch(:base, Formatter::Numbers::Base::DEFAULT_BASE)
|
|
43
|
+
source = Formatter::Numbers::Source.new(number_string, base: base)
|
|
44
|
+
options = format_options(source, locale, precision, format)
|
|
29
45
|
|
|
30
46
|
if options.notation_supported?
|
|
31
47
|
return notation_renderer(options).render(source, options.notation)
|
|
@@ -34,34 +50,20 @@ module Plurimath
|
|
|
34
50
|
render_localized_number(source, options)
|
|
35
51
|
end
|
|
36
52
|
|
|
53
|
+
# Formula-aware entry point. Returns a FormattedNumber,
|
|
54
|
+
# FormattedNotation, or String. Override in subclasses that need the
|
|
55
|
+
# Formula/Number context for rendering decisions; the default delegates
|
|
56
|
+
# to #formatted_number with the merged format hash.
|
|
57
|
+
def format_number(_formula, number, format: {})
|
|
58
|
+
formatted_number(number.value.to_s, format: format)
|
|
59
|
+
end
|
|
60
|
+
|
|
37
61
|
def twitter_cldr_reader(locale: @locale)
|
|
38
62
|
symbols_for(supported_locale(locale), {})
|
|
39
63
|
end
|
|
40
64
|
|
|
41
65
|
private
|
|
42
66
|
|
|
43
|
-
# localize_number/localizer_symbols are not per-option-hardened — they feed
|
|
44
|
-
# SymbolResolver directly — so validate their types at the point of use (see
|
|
45
|
-
# #symbol_resolver). That single check covers the constructor, the public
|
|
46
|
-
# writers, and any later mutation, raising a clean ConfigurationError
|
|
47
|
-
# instead of leaking a TypeError out of SymbolResolver.
|
|
48
|
-
def validated_localize_number(value)
|
|
49
|
-
return value if value.nil? || value.is_a?(String)
|
|
50
|
-
|
|
51
|
-
raise Plurimath::ConfigurationError.new(
|
|
52
|
-
:invalid_formatter_option, option: :localize_number, value: value, supported: "a String"
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def validated_localizer_symbols(value)
|
|
57
|
-
return {} if value.nil?
|
|
58
|
-
return value if value.is_a?(Hash)
|
|
59
|
-
|
|
60
|
-
raise Plurimath::ConfigurationError.new(
|
|
61
|
-
:invalid_formatter_option, option: :localizer_symbols, value: value, supported: "a Hash"
|
|
62
|
-
)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
67
|
def format_options(source, locale, precision, format)
|
|
66
68
|
Formatter::Numbers::FormatOptions.new(
|
|
67
69
|
source,
|
|
@@ -98,9 +100,9 @@ module Plurimath
|
|
|
98
100
|
symbol_resolver(locale).resolve.merge(format)
|
|
99
101
|
end
|
|
100
102
|
|
|
103
|
+
# Locale always falls back to :en for any unsupported value, including
|
|
104
|
+
# nil and non-string/symbol types; it never raises.
|
|
101
105
|
def supported_locale(locale)
|
|
102
|
-
# Locale always falls back to :en for any unsupported value, including
|
|
103
|
-
# nil and non-string/symbol types; it never raises.
|
|
104
106
|
return :en unless locale.is_a?(String) || locale.is_a?(Symbol)
|
|
105
107
|
|
|
106
108
|
Formatter::SupportedLocales::LOCALES.key?(locale.to_sym) ? locale.to_sym : :en
|
|
@@ -119,5 +121,22 @@ module Plurimath
|
|
|
119
121
|
|
|
120
122
|
format
|
|
121
123
|
end
|
|
124
|
+
|
|
125
|
+
def validated_localize_number(value)
|
|
126
|
+
return value if value.nil? || value.is_a?(String)
|
|
127
|
+
|
|
128
|
+
raise Plurimath::ConfigurationError.new(
|
|
129
|
+
:invalid_formatter_option, option: :localize_number, value: value, supported: "a String"
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def validated_localizer_symbols(value)
|
|
134
|
+
return {} if value.nil?
|
|
135
|
+
return value if value.is_a?(Hash)
|
|
136
|
+
|
|
137
|
+
raise Plurimath::ConfigurationError.new(
|
|
138
|
+
:invalid_formatter_option, option: :localizer_symbols, value: value, supported: "a Hash"
|
|
139
|
+
)
|
|
140
|
+
end
|
|
122
141
|
end
|
|
123
142
|
end
|
|
@@ -102,21 +102,36 @@ module Plurimath
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
def linebreak_child?(node, child)
|
|
105
|
+
return true if ct_br_child?(child)
|
|
106
|
+
|
|
105
107
|
child == "" && node.respond_to?(:br) && node.br == ""
|
|
106
108
|
end
|
|
107
109
|
|
|
110
|
+
def ct_br_child?(child)
|
|
111
|
+
return false unless child.is_a?(Object)
|
|
112
|
+
|
|
113
|
+
Lutaml::Model::Utils.base_class_name(child.class.name) == "CTBr"
|
|
114
|
+
end
|
|
115
|
+
|
|
108
116
|
def styled_run?(children)
|
|
109
117
|
children.length > 1 && !children.first.is_a?(Math::Core)
|
|
110
118
|
end
|
|
111
119
|
|
|
112
120
|
def styled_run_value(children)
|
|
113
|
-
|
|
121
|
+
fonts, content = children.partition do |child|
|
|
122
|
+
font_style_class?(child)
|
|
123
|
+
end
|
|
124
|
+
font = fonts.first
|
|
114
125
|
font.new(
|
|
115
|
-
Utility.filter_values(
|
|
126
|
+
Utility.filter_values(content),
|
|
116
127
|
Utility::FONT_STYLES.key(font).to_s,
|
|
117
128
|
)
|
|
118
129
|
end
|
|
119
130
|
|
|
131
|
+
def font_style_class?(value)
|
|
132
|
+
value.is_a?(Class) && value <= Math::Function::FontStyle
|
|
133
|
+
end
|
|
134
|
+
|
|
120
135
|
def script_function_value(script_class, node)
|
|
121
136
|
script_class.new(
|
|
122
137
|
omml_argument_value(node.sub),
|
|
@@ -58,6 +58,8 @@ module Plurimath
|
|
|
58
58
|
"CTCtrlPr", "CTBoxPr" then nil
|
|
59
59
|
when "CTRPr" then word_run_properties_to_plurimath(node)
|
|
60
60
|
when "CTRPR" then math_run_properties_to_plurimath(node)
|
|
61
|
+
when "CTBr" then Math::Function::Linebreak.new
|
|
62
|
+
when "CTWordprocessingEmpty", "CTWordprocessingText" then nil
|
|
61
63
|
else
|
|
62
64
|
unsupported_node!(node)
|
|
63
65
|
end
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# Preload Math namespace/core so symbol classes resolve correctly in Opal.
|
|
2
2
|
require 'plurimath/math'
|
|
3
3
|
require 'plurimath/math/core'
|
|
4
|
+
require 'plurimath/math/evaluation'
|
|
5
|
+
require 'plurimath/errors/evaluation'
|
|
6
|
+
require 'plurimath/errors/evaluation/error'
|
|
7
|
+
require 'plurimath/errors/evaluation/missing_variable_error'
|
|
8
|
+
require 'plurimath/errors/evaluation/unsupported_expression_error'
|
|
9
|
+
require 'plurimath/errors/evaluation/division_by_zero_error'
|
|
10
|
+
require 'plurimath/errors/evaluation/invalid_binding_error'
|
|
11
|
+
require 'plurimath/errors/evaluation/invalid_binding_key_error'
|
|
12
|
+
require 'plurimath/errors/evaluation/math_domain_error'
|
|
13
|
+
require 'plurimath/errors/evaluation/non_finite_result_error'
|
|
14
|
+
require 'plurimath/math/evaluation/evaluator'
|
|
15
|
+
require 'plurimath/math/evaluation/expression_parser'
|
|
16
|
+
require 'plurimath/math/evaluation/iteration'
|
|
4
17
|
require 'plurimath/math/symbols/symbol'
|
|
5
18
|
require 'plurimath/math/symbols/paren'
|
|
6
19
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module Plurimath
|
|
4
4
|
class UnicodeMath
|
|
5
5
|
class Parse < Parslet::Parser
|
|
6
|
+
include Plurimath::BaseNumberPrefix::Parser
|
|
6
7
|
include ParsingRules::Masked
|
|
7
8
|
include ParsingRules::SubSup
|
|
8
9
|
include ParsingRules::CommonRules
|
|
@@ -162,7 +163,10 @@ module Plurimath
|
|
|
162
163
|
end
|
|
163
164
|
|
|
164
165
|
rule(:number) do
|
|
165
|
-
|
|
166
|
+
hex_number |
|
|
167
|
+
binary_number |
|
|
168
|
+
octal_number |
|
|
169
|
+
(digits.as(:whole) >> op_decimal.as(:decimal) >> digits.as(:fractional)).as(:decimal_number) |
|
|
166
170
|
(op_decimal.as(:decimal) >> digits.as(:whole) >> space?).as(:decimal_number) |
|
|
167
171
|
digits.as(:digit)
|
|
168
172
|
end
|