plurimath 0.11.1 → 0.11.3

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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop_todo.yml +108 -175
  4. data/Gemfile +1 -0
  5. data/README.adoc +282 -6
  6. data/lib/plurimath/asciimath/parse.rb +6 -1
  7. data/lib/plurimath/asciimath/transform.rb +2 -0
  8. data/lib/plurimath/base_number_prefix.rb +43 -0
  9. data/lib/plurimath/configuration.rb +9 -1
  10. data/lib/plurimath/errors/evaluation/division_by_zero_error.rb +13 -0
  11. data/lib/plurimath/errors/evaluation/error.rb +9 -0
  12. data/lib/plurimath/errors/evaluation/invalid_binding_error.rb +14 -0
  13. data/lib/plurimath/errors/evaluation/invalid_binding_key_error.rb +14 -0
  14. data/lib/plurimath/errors/evaluation/math_domain_error.rb +9 -0
  15. data/lib/plurimath/errors/evaluation/missing_variable_error.rb +13 -0
  16. data/lib/plurimath/errors/evaluation/non_finite_result_error.rb +13 -0
  17. data/lib/plurimath/errors/evaluation/unsupported_expression_error.rb +13 -0
  18. data/lib/plurimath/errors/evaluation.rb +18 -0
  19. data/lib/plurimath/errors.rb +1 -0
  20. data/lib/plurimath/formatter/numbers/base_notation.rb +54 -31
  21. data/lib/plurimath/formatter/numbers/formatted_notation.rb +62 -0
  22. data/lib/plurimath/formatter/numbers/formatted_number.rb +87 -0
  23. data/lib/plurimath/formatter/numbers/fraction.rb +1 -1
  24. data/lib/plurimath/formatter/numbers/mathml_renderer.rb +56 -0
  25. data/lib/plurimath/formatter/numbers/notation_renderer.rb +30 -29
  26. data/lib/plurimath/formatter/numbers/number_renderer.rb +10 -9
  27. data/lib/plurimath/formatter/numbers/omml_renderer.rb +74 -0
  28. data/lib/plurimath/formatter/numbers/source.rb +29 -4
  29. data/lib/plurimath/formatter/numbers/text_renderer.rb +52 -0
  30. data/lib/plurimath/formatter/numbers.rb +6 -2
  31. data/lib/plurimath/html/parse.rb +5 -0
  32. data/lib/plurimath/html/transform.rb +2 -0
  33. data/lib/plurimath/latex/parse.rb +5 -0
  34. data/lib/plurimath/latex/transform.rb +2 -0
  35. data/lib/plurimath/math/core.rb +52 -0
  36. data/lib/plurimath/math/evaluation/evaluator.rb +147 -0
  37. data/lib/plurimath/math/evaluation/expression_parser.rb +215 -0
  38. data/lib/plurimath/math/evaluation/iteration.rb +63 -0
  39. data/lib/plurimath/math/evaluation.rb +13 -0
  40. data/lib/plurimath/math/formula.rb +9 -0
  41. data/lib/plurimath/math/function/abs.rb +4 -0
  42. data/lib/plurimath/math/function/arccos.rb +4 -0
  43. data/lib/plurimath/math/function/arcsin.rb +4 -0
  44. data/lib/plurimath/math/function/arctan.rb +4 -0
  45. data/lib/plurimath/math/function/ceil.rb +4 -0
  46. data/lib/plurimath/math/function/cos.rb +4 -0
  47. data/lib/plurimath/math/function/cosh.rb +4 -0
  48. data/lib/plurimath/math/function/cot.rb +4 -0
  49. data/lib/plurimath/math/function/coth.rb +4 -0
  50. data/lib/plurimath/math/function/csc.rb +4 -0
  51. data/lib/plurimath/math/function/csch.rb +4 -0
  52. data/lib/plurimath/math/function/exp.rb +4 -0
  53. data/lib/plurimath/math/function/fenced.rb +4 -0
  54. data/lib/plurimath/math/function/floor.rb +4 -0
  55. data/lib/plurimath/math/function/frac.rb +7 -0
  56. data/lib/plurimath/math/function/gcd.rb +9 -0
  57. data/lib/plurimath/math/function/lcm.rb +9 -0
  58. data/lib/plurimath/math/function/lg.rb +4 -0
  59. data/lib/plurimath/math/function/ln.rb +4 -0
  60. data/lib/plurimath/math/function/log.rb +19 -0
  61. data/lib/plurimath/math/function/max.rb +4 -0
  62. data/lib/plurimath/math/function/min.rb +4 -0
  63. data/lib/plurimath/math/function/mod.rb +15 -0
  64. data/lib/plurimath/math/function/power.rb +10 -0
  65. data/lib/plurimath/math/function/prod.rb +10 -0
  66. data/lib/plurimath/math/function/root.rb +7 -0
  67. data/lib/plurimath/math/function/sec.rb +4 -0
  68. data/lib/plurimath/math/function/sech.rb +4 -0
  69. data/lib/plurimath/math/function/sin.rb +4 -0
  70. data/lib/plurimath/math/function/sinh.rb +4 -0
  71. data/lib/plurimath/math/function/sqrt.rb +4 -0
  72. data/lib/plurimath/math/function/sum.rb +10 -0
  73. data/lib/plurimath/math/function/tan.rb +4 -0
  74. data/lib/plurimath/math/function/tanh.rb +4 -0
  75. data/lib/plurimath/math/function/text.rb +17 -0
  76. data/lib/plurimath/math/number.rb +40 -29
  77. data/lib/plurimath/math/symbols/cdot.rb +4 -0
  78. data/lib/plurimath/math/symbols/div.rb +4 -0
  79. data/lib/plurimath/math/symbols/hat.rb +4 -0
  80. data/lib/plurimath/math/symbols/minus.rb +4 -0
  81. data/lib/plurimath/math/symbols/pi.rb +5 -1
  82. data/lib/plurimath/math/symbols/plus.rb +4 -0
  83. data/lib/plurimath/math/symbols/slash.rb +4 -0
  84. data/lib/plurimath/math/symbols/symbol.rb +45 -0
  85. data/lib/plurimath/math/symbols/times.rb +4 -0
  86. data/lib/plurimath/math.rb +1 -0
  87. data/lib/plurimath/mathml/constants.rb +18 -0
  88. data/lib/plurimath/number_formatter.rb +47 -28
  89. data/lib/plurimath/setup/opal.rb.erb +13 -0
  90. data/lib/plurimath/unicode_math/parse.rb +5 -1
  91. data/lib/plurimath/unicode_math/transform.rb +469 -755
  92. data/lib/plurimath/utility.rb +1 -1
  93. data/lib/plurimath/version.rb +1 -1
  94. data/lib/plurimath.rb +1 -0
  95. metadata +21 -3
  96. 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, :precision, :localize_number, :localizer_symbols
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
- source = Formatter::Numbers::Source.new(number_string)
27
- options = format_options(source, locale, precision,
28
- validated_format(format))
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
@@ -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
- (digits.as(:whole) >> op_decimal.as(:decimal) >> digits.as(:fractional)).as(:decimal_number) |
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