plurimath 0.8.13 → 0.8.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd471ff00338f1235d74433502b5589c0b95287f196c0088be89cbc91e65a456
4
- data.tar.gz: 3f30ce7bd235c3e9c07768240ffafea84e93f63c0da3ae442b2687ad7b2b7f95
3
+ metadata.gz: e4917de6263422b35cc5d2c04dd466d10e1c0f50f214d0c54753fcef4df826d6
4
+ data.tar.gz: 8c26d6c94f2ab39735cc1011bd155af5dc74b01d714abe7050d55eeac4edebfd
5
5
  SHA512:
6
- metadata.gz: 83007b138c9c86561350991289d7007d42b7aa24859f8039c961c7e2434f1f1b381d3e4f85f897bc3c5c1b1f4d22cb4ddf7257bb9f136a0c465695995ba72690
7
- data.tar.gz: 6b019a7ed611f78e28c0e62473b4e8ee0780568de8b304fed12f9957fde6aebc7f88f30c4656ddd6500f7ef298462616d5fba6fd6d2e9fc3b03f24be1ef8fde4
6
+ metadata.gz: 2e23d92d441333bee877fe164bcfd3405311a78c8e310bfbed17eaca66bcfefaa1020201b8f89c13064c7b0c32bcaec146c0667479e4b45ddedc30e93ac97055
7
+ data.tar.gz: ecd0a5db9719cabf0bd3256776b9874aa7c25092105430eb3fe84aff79e6b18a849ab4e41265fcfcb08eee08352886536936dc92552373068edf569baf3d3548
@@ -2,44 +2,70 @@
2
2
 
3
3
  module Plurimath
4
4
  module Formatter
5
- class NumberFormatter < TwitterCldr::Formatters::NumberFormatter
6
- def format(tokens, number, options = {})
7
- options[:precision] ||= precision_from(number)
8
- options[:type] ||= :decimal
5
+ class NumberFormatter
6
+ attr_reader :number, :data_reader
9
7
 
10
- prefix, suffix, integer_format, fraction_format, signif_format = *partition_tokens(tokens)
11
- number = truncate_number(number, integer_format.format.length)
8
+ STRING_SYMBOLS = {
9
+ dot: ".".freeze,
10
+ f: "F".freeze,
11
+ }.freeze
12
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
13
+ def initialize(number, data_reader = {})
14
+ @number = number
15
+ @data_reader = data_reader
16
+ end
17
+
18
+ def format(precision: nil)
19
+ data_reader[:precision] = precision || precision_from(number)
20
+ int, frac, integer_format, fraction_format, signif_format = *partition_tokens(number)
21
+ result = integer_format.apply(int, data_reader)
22
+ result << fraction_format.apply(frac, data_reader, int) if frac
16
23
 
17
24
  result = signif_format.apply(result, integer_format, fraction_format)
18
25
 
19
- number_system.transliterate(
20
- "#{prefix.to_s}#{result}#{suffix.to_s}"
21
- )
26
+ result
22
27
  end
23
28
 
24
29
  private
25
30
 
26
- def partition_tokens(tokens)
31
+ def partition_tokens(number)
32
+ int, fraction = parse_number(number, data_reader)
27
33
  [
28
- token_val_from(tokens[0]),
29
- token_val_from(tokens[2]),
30
- Numbers::Integer.new(
31
- tokens[1],
32
- data_reader.symbols
33
- ),
34
- Numbers::Fraction.new(
35
- tokens[1],
36
- data_reader.symbols
37
- ),
38
- Numbers::Significant.new(
39
- data_reader.symbols,
40
- )
34
+ int,
35
+ fraction,
36
+ Numbers::Integer.new(data_reader),
37
+ Numbers::Fraction.new(data_reader),
38
+ Numbers::Significant.new(data_reader),
41
39
  ]
42
40
  end
41
+
42
+ def precision_from(number)
43
+ return 0 if number.fix == number
44
+
45
+ parts = number.to_s(STRING_SYMBOLS[:f]).split(STRING_SYMBOLS[:dot])
46
+ parts.size == 2 ? parts[1].size : 0
47
+ end
48
+
49
+ def parse_number(number, options = {})
50
+ precision = options[:precision] || precision_from(number)
51
+
52
+ num = if precision == 0
53
+ round_to(number, precision).abs.fix.to_s(STRING_SYMBOLS[:f])
54
+ else
55
+ round_to(number, precision).abs.round(precision).to_s(STRING_SYMBOLS[:f])
56
+ end
57
+ num.split(STRING_SYMBOLS[:dot])
58
+ end
59
+
60
+ def round_to(number, precision)
61
+ factor = 10 ** precision
62
+ result = if number.is_a?(BigDecimal)
63
+ ((number * factor).fix / factor)
64
+ else
65
+ ((number * factor).round.to_f / factor)
66
+ end
67
+ result
68
+ end
43
69
  end
44
70
  end
45
71
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plurimath
4
+ module Formatter
5
+ module Numbers
6
+ class Base
7
+ def interpolate(string, value, orientation = :right)
8
+ value = value.to_s
9
+ length = value.length
10
+ start = orientation == :left ? 0 : -length
11
+
12
+ string = string.dup
13
+ string = string.ljust(length, '#') if string.length < length
14
+ string[start, length] = value
15
+ string.gsub('#', '')
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -3,20 +3,19 @@
3
3
  module Plurimath
4
4
  module Formatter
5
5
  module Numbers
6
- class Fraction < TwitterCldr::Formatters::Numbers::Fraction
7
- attr_reader :format, :decimal, :precision, :separator, :group
6
+ class Fraction < Base
7
+ attr_reader :decimal, :precision, :separator, :group
8
8
 
9
- def initialize(token, symbols = {})
10
- @format = token ? token.value.split('.').pop : ''
9
+ def initialize(symbols = {})
10
+ @precision = 3
11
11
  @decimal = symbols[:decimal] || '.'
12
12
  @separator = symbols[:fraction_group].to_s
13
13
  @group = symbols[:fraction_group_digits]
14
14
  @digit_count = symbols[:digit_count] || nil
15
- @precision = @format.length
16
15
  end
17
16
 
18
17
  def apply(fraction, options = {}, int = "")
19
- precision = options[:precision] || self.precision
18
+ precision = options[:precision] || @precision
20
19
  return "" unless precision > 0
21
20
 
22
21
  number = interpolate(format(options), fraction, :left)
@@ -26,7 +25,7 @@ module Plurimath
26
25
  end
27
26
 
28
27
  def format(options)
29
- precision = options[:precision] || self.precision
28
+ precision = options[:precision] || @precision
30
29
  precision ? '0' * precision : @format
31
30
  end
32
31
 
@@ -66,13 +65,13 @@ module Plurimath
66
65
  end
67
66
 
68
67
  def update_digit_count(number)
69
- return @digit_count unless all_zeros?(number) == @precision
68
+ return @digit_count unless zeros_count_in(number) == @precision
70
69
 
71
70
  @digit_count - @precision + 1
72
71
  end
73
72
 
74
- def all_zeros?(number)
75
- return unless number.split('').all? { |dig| dig == "0" }
73
+ def zeros_count_in(number)
74
+ return unless number.split('').all? { |digit| digit == "0" }
76
75
 
77
76
  number.length
78
77
  end
@@ -3,13 +3,32 @@
3
3
  module Plurimath
4
4
  module Formatter
5
5
  module Numbers
6
- class Integer < TwitterCldr::Formatters::Numbers::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))
6
+ class Integer < Base
7
+ attr_reader :format, :separator, :groups
8
+
9
+ def initialize(symbols = {})
10
+ @groups = Array(symbols[:group_digits] || 3)
11
11
  @separator = symbols[:group] || ','
12
12
  end
13
+
14
+ def apply(number, options = {})
15
+ format_groups(interpolate(number, number.to_i))
16
+ end
17
+
18
+ def format_groups(string)
19
+ return string if groups.empty?
20
+
21
+ tokens = []
22
+
23
+ tokens << chop_group(string, groups.first)
24
+ tokens << chop_group(string, groups.last) until string.empty?
25
+
26
+ tokens.compact.reverse.join(separator)
27
+ end
28
+
29
+ def chop_group(string, size)
30
+ string.slice!([string.size - size, 0].max, size)
31
+ end
13
32
  end
14
33
  end
15
34
  end
@@ -1,10 +1,9 @@
1
- require "twitter_cldr"
1
+ require_relative "supported_locales"
2
+ require_relative "numbers/base"
2
3
  require_relative "numbers/integer"
3
4
  require_relative "numbers/fraction"
4
5
  require_relative "numbers/significant"
5
6
  require_relative "number_formatter"
6
- require_relative "number_data_reader"
7
- require_relative "localized_number"
8
7
 
9
8
  module Plurimath
10
9
  module Formatter
@@ -32,8 +31,8 @@ module Plurimath
32
31
  private
33
32
 
34
33
  def twitter_cldr_reader_lookup
35
- num = TwitterCldr::DataReaders::NumberDataReader.new(locale)
36
- num.symbols
34
+ symbols = Formatter::SupportedLocales::LOCALES[locale.to_sym]
35
+ symbols
37
36
  .merge!(@localizer_symbols)
38
37
  .merge!(parse_localize_number)
39
38
  end
@@ -51,10 +50,12 @@ module Plurimath
51
50
  end
52
51
 
53
52
  def localize_number(num)
54
- localized = localize(BigDecimal(num.to_s))
55
- return localized.to_s if @precision.zero?
56
-
57
- localized.to_decimal.to_s(precision: @precision)
53
+ Formatter::NumberFormatter.new(
54
+ BigDecimal(num),
55
+ @twitter_cldr_reader,
56
+ ).format(
57
+ precision: @precision
58
+ )
58
59
  end
59
60
 
60
61
  def e_format(num_str)
@@ -122,10 +123,6 @@ module Plurimath
122
123
  chars.first.insert(index + 1, ".") unless chars.first[index + 2].nil?
123
124
  chars[-1] = (chars[-1].to_i - index).to_s
124
125
  end
125
-
126
- def localize(value)
127
- LocalizedNumber.new(value, @locale, type: :decimal)
128
- end
129
126
  end
130
127
  end
131
128
  end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plurimath
4
+ module Formatter
5
+ class SupportedLocales
6
+ LOCALES = {
7
+ "sr-Cyrl-ME": { decimal: ",", group: "." },
8
+ "sr-Latn-ME": { decimal: ",", group: "." },
9
+ "zh-Hant": { decimal: ".", group: "," },
10
+ "en-001": { decimal: ".", group: "," },
11
+ "en-150": { decimal: ".", group: "," },
12
+ "pt-PT": { decimal: ",", group: " " },
13
+ "nl-BE": { decimal: ",", group: "." },
14
+ "it-CH": { decimal: ".", group: "’" },
15
+ "fr-BE": { decimal: ",", group: " " },
16
+ "fr-CA": { decimal: ",", group: " " },
17
+ "fr-CH": { decimal: ",", group: " " },
18
+ "de-AT": { decimal: ",", group: " " },
19
+ "de-CH": { decimal: ".", group: "’" },
20
+ "en-AU": { decimal: ".", group: "," },
21
+ "en-CA": { decimal: ".", group: "," },
22
+ "en-GB": { decimal: ".", group: "," },
23
+ "en-IE": { decimal: ".", group: "," },
24
+ "en-IN": { decimal: ".", group: "," },
25
+ "en-NZ": { decimal: ".", group: "," },
26
+ "en-SG": { decimal: ".", group: "," },
27
+ "en-US": { decimal: ".", group: "," },
28
+ "en-ZA": { decimal: ".", group: "," },
29
+ "es-419": { decimal: ".", group: "," },
30
+ "es-AR": { decimal: ",", group: "." },
31
+ "es-CO": { decimal: ",", group: "." },
32
+ "es-MX": { decimal: ".", group: "," },
33
+ "es-US": { decimal: ".", group: "," },
34
+ fil: { decimal: ".", group: "," },
35
+ af: { decimal: ",", group: " " },
36
+ ar: { decimal: "٫", group: "٬" },
37
+ az: { decimal: ",", group: "." },
38
+ be: { decimal: ",", group: " " },
39
+ bg: { decimal: ",", group: " " },
40
+ bn: { decimal: ".", group: "," },
41
+ bo: { decimal: ".", group: "," },
42
+ bs: { decimal: ",", group: "." },
43
+ ca: { decimal: ",", group: "." },
44
+ cs: { decimal: ",", group: " " },
45
+ cy: { decimal: ".", group: "," },
46
+ da: { decimal: ",", group: "." },
47
+ de: { decimal: ",", group: "." },
48
+ el: { decimal: ",", group: "." },
49
+ en: { decimal: ".", group: "," },
50
+ eo: { decimal: ",", group: " " },
51
+ es: { decimal: ",", group: "." },
52
+ et: { decimal: ",", group: " " },
53
+ eu: { decimal: ",", group: "." },
54
+ fa: { decimal: "٫", group: "٬" },
55
+ fi: { decimal: ",", group: " " },
56
+ fr: { decimal: ",", group: " " },
57
+ ga: { decimal: ".", group: "," },
58
+ gl: { decimal: ",", group: "." },
59
+ gu: { decimal: ".", group: "," },
60
+ he: { decimal: ".", group: "," },
61
+ hi: { decimal: ".", group: "," },
62
+ hr: { decimal: ",", group: "." },
63
+ hu: { decimal: ",", group: " " },
64
+ hy: { decimal: ",", group: " " },
65
+ id: { decimal: ",", group: "." },
66
+ is: { decimal: ",", group: "." },
67
+ it: { decimal: ",", group: "." },
68
+ ja: { decimal: ".", group: "," },
69
+ ka: { decimal: ",", group: " " },
70
+ kk: { decimal: ",", group: " " },
71
+ km: { decimal: ",", group: "." },
72
+ kn: { decimal: ".", group: "," },
73
+ ko: { decimal: ".", group: "," },
74
+ lo: { decimal: ",", group: "." },
75
+ lt: { decimal: ",", group: " " },
76
+ lv: { decimal: ",", group: " " },
77
+ mk: { decimal: ",", group: "." },
78
+ mr: { decimal: ".", group: "," },
79
+ ms: { decimal: ".", group: "," },
80
+ mt: { decimal: ".", group: "," },
81
+ my: { decimal: ".", group: "," },
82
+ nb: { decimal: ",", group: " " },
83
+ nl: { decimal: ",", group: "." },
84
+ pl: { decimal: ",", group: " " },
85
+ pt: { decimal: ",", group: "." },
86
+ ro: { decimal: ",", group: "." },
87
+ ru: { decimal: ",", group: " " },
88
+ sk: { decimal: ",", group: " " },
89
+ sl: { decimal: ",", group: "." },
90
+ sq: { decimal: ",", group: " " },
91
+ sr: { decimal: ",", group: "." },
92
+ sv: { decimal: ",", group: " " },
93
+ sw: { decimal: ".", group: "," },
94
+ ta: { decimal: ".", group: "," },
95
+ th: { decimal: ".", group: "," },
96
+ tr: { decimal: ",", group: "." },
97
+ uk: { decimal: ",", group: " " },
98
+ ur: { decimal: ".", group: "," },
99
+ vi: { decimal: ",", group: "." },
100
+ xh: { decimal: ".", group: " " },
101
+ zh: { decimal: ".", group: "," },
102
+ zu: { decimal: ".", group: "," },
103
+ }
104
+ end
105
+ end
106
+ end
@@ -8,7 +8,7 @@ module Plurimath
8
8
  class Parser
9
9
  attr_accessor :text
10
10
 
11
- TEXT_REGEX = %r(\\(?:mbox|text){[^}]+})
11
+ TEXT_REGEX = %r(\\(?:mbox|text)\{[^\}]+\})
12
12
 
13
13
  def initialize(text)
14
14
  @text = pre_processing(text)
@@ -1,4 +1,5 @@
1
- require "plurimath/formatter/numeric_formatter"
1
+ require_relative "formatter/numeric_formatter"
2
+ require_relative "formatter/supported_locales"
2
3
 
3
4
  module Plurimath
4
5
  class NumberFormatter
@@ -37,11 +38,11 @@ module Plurimath
37
38
  private
38
39
 
39
40
  def supported_locale(locale)
40
- TwitterCldr.supported_locale?(locale.to_sym) ? locale.to_sym : :en
41
+ Formatter::SupportedLocales::LOCALES.key?(locale.to_sym) ? locale.to_sym : :en
41
42
  end
42
43
 
43
44
  def symbols(locale)
44
- TwitterCldr::DataReaders::NumberDataReader.new(locale).symbols
45
+ Formatter::SupportedLocales::LOCALES[locale]
45
46
  end
46
47
  end
47
48
  end
@@ -226,6 +226,7 @@ module Plurimath
226
226
  element_exp_script_validation? >> space? >> exp_script |
227
227
  unary_arg_functions |
228
228
  combined_symbols |
229
+ wrapper_symbols |
229
230
  operand |
230
231
  char |
231
232
  alphanumeric |
@@ -80,6 +80,7 @@ module Plurimath
80
80
  accents |
81
81
  negatable_symbols |
82
82
  fonts.as(:fonts) |
83
+ wrapper_symbols |
83
84
  ((parsing_text | factor.as(:factor)) >> operand.as(:operand).maybe)
84
85
  end
85
86
 
@@ -184,6 +184,7 @@ module Plurimath
184
184
  an_math |
185
185
  other |
186
186
  exp_bracket |
187
+ wrapper_symbols |
187
188
  parsing_text |
188
189
  negatable_symbols |
189
190
  soperand |
@@ -82,6 +82,7 @@ module Plurimath
82
82
  rule(sup_recursion: simple(:recursion)) { recursion }
83
83
  rule(nary_sub_sup: simple(:subsup_exp)) { subsup_exp }
84
84
  rule(open_paren: sequence(:open_paren)) { open_paren }
85
+ rule(subsup_exp: sequence(:subsup_exp)) { Utility.filter_values(subsup_exp) }
85
86
 
86
87
  rule(diacritics_accents: simple(:accent)) { accent }
87
88
  rule(mini_sub_sup: simple(:mini_sub_sup)) { mini_sub_sup }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.8.13"
4
+ VERSION = "0.8.14"
5
5
  end
data/plurimath.gemspec CHANGED
@@ -24,7 +24,6 @@ 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'
28
27
  spec.add_dependency 'parslet'
29
28
  spec.add_dependency 'thor'
30
29
  spec.add_dependency 'ox'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plurimath
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.13
4
+ version: 0.8.14
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-08-23 00:00:00.000000000 Z
11
+ date: 2024-08-30 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'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: parslet
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -116,13 +102,13 @@ files:
116
102
  - lib/plurimath/asciimath/parser.rb
117
103
  - lib/plurimath/asciimath/transform.rb
118
104
  - lib/plurimath/cli.rb
119
- - lib/plurimath/formatter/localized_number.rb
120
- - lib/plurimath/formatter/number_data_reader.rb
121
105
  - lib/plurimath/formatter/number_formatter.rb
106
+ - lib/plurimath/formatter/numbers/base.rb
122
107
  - lib/plurimath/formatter/numbers/fraction.rb
123
108
  - lib/plurimath/formatter/numbers/integer.rb
124
109
  - lib/plurimath/formatter/numbers/significant.rb
125
110
  - lib/plurimath/formatter/numeric_formatter.rb
111
+ - lib/plurimath/formatter/supported_locales.rb
126
112
  - lib/plurimath/html.rb
127
113
  - lib/plurimath/html/constants.rb
128
114
  - lib/plurimath/html/parse.rb
@@ -1,13 +0,0 @@
1
- module Plurimath
2
- module Formatter
3
- class LocalizedNumber < TwitterCldr::Localized::LocalizedNumber
4
- def to_s(options = {})
5
- opts = { type: @type, format: @format }.merge(options)
6
-
7
- NumberDataReader
8
- .new(locale, opts)
9
- .format_number(base_obj, opts)
10
- end
11
- end
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Plurimath
4
- module Formatter
5
- class NumberDataReader < TwitterCldr::DataReaders::NumberDataReader
6
- def formatter
7
- NumberFormatter.new(self)
8
- end
9
- end
10
- end
11
- end