plurimath 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/plurimath/formatter/number_formatter.rb +114 -0
- data/lib/plurimath/formatter/twitter_cldr_rb/fraction.rb +55 -0
- data/lib/plurimath/formatter/twitter_cldr_rb/integer.rb +16 -0
- data/lib/plurimath/formatter/twitter_cldr_rb/number_formatter.rb +23 -0
- data/lib/plurimath/math.rb +1 -0
- data/lib/plurimath/number_formatter.rb +32 -0
- data/lib/plurimath/version.rb +1 -1
- data/plurimath.gemspec +1 -0
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: def00e41e6010e06ea7df51573e342c4ed8b815e079bcbad3a7776cc5d625e02
|
4
|
+
data.tar.gz: d46595b7a57d2a391e849d58a6b23f7e449e042e891797967f13cee0364c32df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e5c0c02a41fcd2fdbebbd11ca103228ec5c9a2b4e68e98a364c39d988540ebfa844ad06785ced1538186ae7a0583978fe8c1a548c1da135d243d633557cc298
|
7
|
+
data.tar.gz: 15463a536fac275fe0935b360dd754ed787a202d4d77b4ef3f4934359e45ec4393e0c95bd6a7ce7f02a9e655f21eeeec312f932462354965a287e08e92b55e89
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require "twitter_cldr"
|
2
|
+
require_relative "twitter_cldr_rb/integer"
|
3
|
+
require_relative "twitter_cldr_rb/fraction"
|
4
|
+
require_relative "twitter_cldr_rb/number_formatter"
|
5
|
+
|
6
|
+
module Plurimath
|
7
|
+
module Formatter
|
8
|
+
class NumberFormatter
|
9
|
+
attr_accessor :locale, :localize_number, :localizer_symbols
|
10
|
+
|
11
|
+
LOCALIZE_NUMBER_REGEX = %r{(?<group>[^#])?(?<groupdigits>#+0)(?<decimal>.)(?<fractdigits>#+)(?<fractgroup>[^#])?}
|
12
|
+
SUPPORTED_NOTATIONS = %i[e scientific engineering].freeze
|
13
|
+
|
14
|
+
def initialize(locale, localize_number:, localizer_symbols:)
|
15
|
+
@locale = locale
|
16
|
+
@localize_number = localize_number
|
17
|
+
@localizer_symbols = localizer_symbols
|
18
|
+
@twitter_cldr_reader = twitter_cldr_reader(locale)
|
19
|
+
end
|
20
|
+
|
21
|
+
def localized_number(number_string, locale:, precision:, format:)
|
22
|
+
options_instance_variables(number_string, format, precision)
|
23
|
+
@twitter_cldr_reader.merge!(format)
|
24
|
+
return send("#{@notation}_format", number_string) if SUPPORTED_NOTATIONS.include?(@notation&.to_sym)
|
25
|
+
|
26
|
+
localize_number(number_string)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def twitter_cldr_reader(locale)
|
32
|
+
num = TwitterCldr::DataReaders::NumberDataReader.new(locale)
|
33
|
+
num.symbols
|
34
|
+
.merge!(@localizer_symbols)
|
35
|
+
.merge!(parse_localize_number)
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_localize_number
|
39
|
+
@localize_number or return {}
|
40
|
+
m = LOCALIZE_NUMBER_REGEX.match(@localize_number) or return {}
|
41
|
+
ret = {
|
42
|
+
decimal: m[:decimal],
|
43
|
+
group_digits: m[:groupdigits].size,
|
44
|
+
fraction_group_digits: m[:fractdigits].size,
|
45
|
+
group: m[:group] == " " ? "\u00A0" : (m[:group] || ""),
|
46
|
+
fraction_group: m[:fractgroup] == " " ? "\u00A0" : (m[:fractgroup] || "")
|
47
|
+
}.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def localize_number(num)
|
51
|
+
num = num.match?(/\./) ? num.to_f : num.to_i
|
52
|
+
localized = BigDecimal(num.to_s).localize(@locale)
|
53
|
+
return localized.to_s if @precision.zero?
|
54
|
+
|
55
|
+
localized.to_decimal.to_s(precision: @precision)
|
56
|
+
end
|
57
|
+
|
58
|
+
def e_format(num_str)
|
59
|
+
notations_formatting(num_str).join(@e.to_s)
|
60
|
+
end
|
61
|
+
|
62
|
+
def scientific_format(num_str)
|
63
|
+
notations_formatting(num_str).join(" #{@times} 10^")
|
64
|
+
end
|
65
|
+
|
66
|
+
def engineering_format(num_str)
|
67
|
+
@precision = num_str.length - 1 unless @precision > 0
|
68
|
+
chars = notation_chars(num_str)
|
69
|
+
update_string_index(chars, chars.last.to_i % 3)
|
70
|
+
chars[0] = localize_number(chars[0])
|
71
|
+
chars.join(" #{@times} 10^")
|
72
|
+
end
|
73
|
+
|
74
|
+
def update_exponent_sign(str)
|
75
|
+
str.gsub!("e", "e+") if @exponent_sign == :plus
|
76
|
+
end
|
77
|
+
|
78
|
+
def notation_chars(num_str)
|
79
|
+
notation_number = ("%.#{@precision}e" %num_str)
|
80
|
+
update_exponent_sign(notation_number.gsub!("+0", ""))
|
81
|
+
notation_number.split("e")
|
82
|
+
end
|
83
|
+
|
84
|
+
def notations_formatting(num_str)
|
85
|
+
chars = notation_chars(num_str)
|
86
|
+
chars[0] = localize_number(chars[0])
|
87
|
+
chars
|
88
|
+
end
|
89
|
+
|
90
|
+
def options_instance_variables(string, format, precision)
|
91
|
+
@e = format.delete(:e)&.to_sym || :e
|
92
|
+
@times = format.delete(:times)&.to_sym || "\u{d7}"
|
93
|
+
@notation = format.delete(:notation)&.to_sym || nil
|
94
|
+
@precision = update_precision(string, precision)
|
95
|
+
@exponent_sign = format.delete(:exponent_sign)&.to_sym || nil
|
96
|
+
end
|
97
|
+
|
98
|
+
def update_precision(num, precision)
|
99
|
+
return precision if precision
|
100
|
+
return num.sub(/\./, "").size - 1 if SUPPORTED_NOTATIONS.include?(@notation&.to_sym)
|
101
|
+
|
102
|
+
/\./.match?(num) ? num.sub(/^.*\./, "").size : 0
|
103
|
+
end
|
104
|
+
|
105
|
+
def update_string_index(chars, index)
|
106
|
+
return if index.zero?
|
107
|
+
|
108
|
+
chars.first.delete!(".")
|
109
|
+
chars.first.insert(index + 1, ".")
|
110
|
+
chars[-1] = (chars[-1].to_i - index).to_s
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TwitterCldr
|
4
|
+
module Formatters
|
5
|
+
module Numbers
|
6
|
+
class Fraction
|
7
|
+
attr_reader :format, :decimal, :precision, :separator, :group
|
8
|
+
|
9
|
+
def initialize(token, symbols = {})
|
10
|
+
@format = token ? token.value.split('.').pop : ''
|
11
|
+
@decimal = symbols[:decimal] || '.'
|
12
|
+
@separator = symbols[:fraction_group] || " "
|
13
|
+
@group = symbols[:fraction_group_digits] || 3
|
14
|
+
@digit_count = symbols[:digit_count] || nil
|
15
|
+
@precision = @format.length
|
16
|
+
end
|
17
|
+
|
18
|
+
def apply(fraction, options = {}, int = "")
|
19
|
+
precision = options[:precision] || self.precision
|
20
|
+
return "" unless precision > 0
|
21
|
+
|
22
|
+
number = interpolate(format(options), fraction, :left)
|
23
|
+
number = digit_count_format(int, fraction, number) if @digit_count
|
24
|
+
decimal + change_format(precision, number)
|
25
|
+
end
|
26
|
+
|
27
|
+
def format(options)
|
28
|
+
precision = options[:precision] || self.precision
|
29
|
+
precision ? '0' * precision : @format
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def change_format(precision, string)
|
35
|
+
tokens = []
|
36
|
+
tokens << string&.slice!(0, group) until string&.empty?
|
37
|
+
tokens.compact.join(separator)
|
38
|
+
end
|
39
|
+
|
40
|
+
def digit_count_format(int, fraction, number)
|
41
|
+
integer = int + "." + fraction
|
42
|
+
float = integer.to_f
|
43
|
+
int_length = integer.length - 1
|
44
|
+
@digit_count ||= int_length
|
45
|
+
if int_length > @digit_count
|
46
|
+
float.round(@digit_count - int.length).to_s.split(".").last
|
47
|
+
elsif int_length < @digit_count
|
48
|
+
number += "0" * (@digit_count - int_length)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TwitterCldr
|
4
|
+
module Formatters
|
5
|
+
module Numbers
|
6
|
+
class Integer
|
7
|
+
def initialize(token, symbols = {})
|
8
|
+
format = token.value.split('.')[0]
|
9
|
+
@format = prepare_format(format, symbols)
|
10
|
+
@groups = Array(symbols[:group_digits] || parse_groups(format))
|
11
|
+
@separator = symbols[:group] || ','
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TwitterCldr
|
4
|
+
module Formatters
|
5
|
+
class NumberFormatter
|
6
|
+
def format(tokens, number, options = {})
|
7
|
+
options[:precision] ||= precision_from(number)
|
8
|
+
options[:type] ||= :decimal
|
9
|
+
|
10
|
+
prefix, suffix, integer_format, fraction_format = *partition_tokens(tokens)
|
11
|
+
number = truncate_number(number, integer_format.format.length)
|
12
|
+
|
13
|
+
int, fraction = parse_number(number, options)
|
14
|
+
result = integer_format.apply(int, options)
|
15
|
+
result << fraction_format.apply(fraction, options, int) if fraction
|
16
|
+
|
17
|
+
number_system.transliterate(
|
18
|
+
"#{prefix.to_s}#{result}#{suffix.to_s}"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/plurimath/math.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "plurimath/formatter/number_formatter"
|
2
|
+
|
3
|
+
module Plurimath
|
4
|
+
class NumberFormatter
|
5
|
+
attr_accessor :locale, :localize_number, :localizer_symbols
|
6
|
+
|
7
|
+
def initialize(locale = "en", localize_number: nil, localizer_symbols: {})
|
8
|
+
@locale = supported_locale(locale)
|
9
|
+
@localize_number = localize_number
|
10
|
+
@localizer_symbols = localizer_symbols
|
11
|
+
end
|
12
|
+
|
13
|
+
def localized_number(number_string, locale: @locale, precision: nil, format: {})
|
14
|
+
Formatter::NumberFormatter.new(
|
15
|
+
supported_locale(locale),
|
16
|
+
localize_number: localize_number,
|
17
|
+
localizer_symbols: localizer_symbols,
|
18
|
+
).localized_number(
|
19
|
+
number_string,
|
20
|
+
locale: supported_locale(locale),
|
21
|
+
precision: precision,
|
22
|
+
format: format,
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def supported_locale(locale)
|
29
|
+
TwitterCldr.supported_locale?(locale.to_sym) ? locale.to_sym : :en
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/plurimath/version.rb
CHANGED
data/plurimath.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.bindir = "exe"
|
25
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
26
|
spec.require_paths = ["lib"]
|
27
|
+
spec.add_dependency 'twitter_cldr'
|
27
28
|
spec.add_dependency 'parslet'
|
28
29
|
spec.add_dependency 'ox'
|
29
30
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plurimath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: twitter_cldr
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: parslet
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,6 +84,10 @@ files:
|
|
70
84
|
- lib/plurimath/asciimath/parse.rb
|
71
85
|
- lib/plurimath/asciimath/parser.rb
|
72
86
|
- lib/plurimath/asciimath/transform.rb
|
87
|
+
- lib/plurimath/formatter/number_formatter.rb
|
88
|
+
- lib/plurimath/formatter/twitter_cldr_rb/fraction.rb
|
89
|
+
- lib/plurimath/formatter/twitter_cldr_rb/integer.rb
|
90
|
+
- lib/plurimath/formatter/twitter_cldr_rb/number_formatter.rb
|
73
91
|
- lib/plurimath/html.rb
|
74
92
|
- lib/plurimath/html/constants.rb
|
75
93
|
- lib/plurimath/html/parse.rb
|
@@ -214,6 +232,7 @@ files:
|
|
214
232
|
- lib/plurimath/mathml/constants.rb
|
215
233
|
- lib/plurimath/mathml/parser.rb
|
216
234
|
- lib/plurimath/mathml/transform.rb
|
235
|
+
- lib/plurimath/number_formatter.rb
|
217
236
|
- lib/plurimath/omml.rb
|
218
237
|
- lib/plurimath/omml/parser.rb
|
219
238
|
- lib/plurimath/omml/transform.rb
|
@@ -259,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
259
278
|
- !ruby/object:Gem::Version
|
260
279
|
version: '0'
|
261
280
|
requirements: []
|
262
|
-
rubygems_version: 3.3.
|
281
|
+
rubygems_version: 3.3.27
|
263
282
|
signing_key:
|
264
283
|
specification_version: 4
|
265
284
|
summary: Converts LaTeX math into MathML.
|