plurimath 0.10.7 → 0.10.9.pre.1
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/.github/workflows/release.yml +3 -2
- data/README.adoc +343 -44
- data/lib/plurimath/asciimath/parse.rb +6 -2
- data/lib/plurimath/configuration.rb +17 -0
- data/lib/plurimath/deprecation.rb +81 -0
- data/lib/plurimath/errors/configuration_error.rb +27 -0
- data/lib/plurimath/errors/deprecation_error.rb +33 -0
- data/lib/plurimath/errors/error.rb +6 -0
- data/lib/plurimath/errors/formatter/unsupported_base.rb +1 -1
- data/lib/plurimath/errors/formatter/unsupported_locale.rb +18 -0
- data/lib/plurimath/errors/omml/unsupported_node_error.rb +1 -1
- data/lib/plurimath/errors/parse_error.rb +1 -1
- data/lib/plurimath/errors/parse_option_error.rb +34 -0
- data/lib/plurimath/formatter/numbers/base.rb +18 -8
- data/lib/plurimath/formatter/numbers/base_notation.rb +67 -0
- data/lib/plurimath/formatter/numbers/digit_sequence.rb +96 -0
- data/lib/plurimath/formatter/numbers/format_options.rb +141 -0
- data/lib/plurimath/formatter/numbers/fraction.rb +50 -93
- data/lib/plurimath/formatter/numbers/integer.rb +30 -6
- data/lib/plurimath/formatter/numbers/notation_renderer.rb +128 -0
- data/lib/plurimath/formatter/numbers/number_renderer.rb +66 -0
- data/lib/plurimath/formatter/numbers/parts.rb +69 -0
- data/lib/plurimath/formatter/numbers/parts_renderer.rb +30 -0
- data/lib/plurimath/formatter/numbers/precision_resolver.rb +54 -0
- data/lib/plurimath/formatter/numbers/sign_renderer.rb +28 -0
- data/lib/plurimath/formatter/numbers/significant.rb +77 -103
- data/lib/plurimath/formatter/numbers/source.rb +120 -0
- data/lib/plurimath/formatter/numbers/symbol_resolver.rb +55 -0
- data/lib/plurimath/formatter/numbers.rb +11 -0
- data/lib/plurimath/formatter/standard.rb +32 -42
- data/lib/plurimath/formatter/supported_locales.rb +27 -0
- data/lib/plurimath/formatter.rb +1 -2
- data/lib/plurimath/html/constants.rb +2 -0
- data/lib/plurimath/html/parse.rb +77 -14
- data/lib/plurimath/html/parser.rb +15 -3
- data/lib/plurimath/html/transform.rb +193 -91
- data/lib/plurimath/html/transform_utility.rb +61 -0
- data/lib/plurimath/html.rb +1 -0
- data/lib/plurimath/latex/parse.rb +7 -1
- data/lib/plurimath/latex/transform.rb +5 -5
- data/lib/plurimath/math/function/lim.rb +6 -0
- data/lib/plurimath/math/number.rb +8 -2
- data/lib/plurimath/math/symbols/cdot.rb +1 -1
- data/lib/plurimath/math/symbols/exclam.rb +1 -1
- data/lib/plurimath/math/symbols/minus.rb +1 -1
- data/lib/plurimath/math/symbols/percent.rb +1 -1
- data/lib/plurimath/math/symbols/pi.rb +1 -1
- data/lib/plurimath/math/symbols/slash.rb +1 -1
- data/lib/plurimath/math.rb +56 -8
- data/lib/plurimath/number_formatter.rb +57 -27
- data/lib/plurimath/unicode_math/parse.rb +7 -1
- data/lib/plurimath/unicode_math/transform.rb +2 -2
- data/lib/plurimath/version.rb +1 -1
- data/lib/plurimath.rb +23 -1
- metadata +21 -4
- data/lib/plurimath/formatter/number_formatter.rb +0 -115
- data/lib/plurimath/formatter/numeric_formatter.rb +0 -187
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e399a104da75213be9f312c84c413650fd5a52c15f159ffa53587ea7edb8da50
|
|
4
|
+
data.tar.gz: d2aeea44e7ebaf4a761337b534a9720a8da261b5e3f552c1ddc8b50edaff7599
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 676a1e8b22a782617673e665b0fa53bdb5fe6e6c348cf893517dcb648984ad58418d43a6cca7a6e7d5bbe1bdaae66339a0995aeff096292fee0f51827dc2bd1f
|
|
7
|
+
data.tar.gz: 8e2e2c44156b845ca0f0e9aa3354586c89cb3d057ef8dd9b7072e4a23232b785a217ef068cc8beb42d4f00d6e376a2ef4022065dfeaa53c6c573b64a9047da2a
|
|
@@ -10,8 +10,8 @@ on:
|
|
|
10
10
|
Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
|
|
11
11
|
required: true
|
|
12
12
|
default: 'skip'
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
repository_dispatch:
|
|
14
|
+
types: [ do-release ]
|
|
15
15
|
|
|
16
16
|
jobs:
|
|
17
17
|
release:
|
|
@@ -23,3 +23,4 @@ jobs:
|
|
|
23
23
|
next_version: ${{ github.event.inputs.next_version }}
|
|
24
24
|
secrets:
|
|
25
25
|
rubygems-api-key: ${{ secrets.PLURIMATH_CI_RUBYGEMS_API_KEY }}
|
|
26
|
+
pat_token: ${{ secrets.PLURIMATH_CI_PAT_TOKEN }}
|
data/README.adoc
CHANGED
|
@@ -160,6 +160,72 @@ asciimath = "sin(1)"
|
|
|
160
160
|
formula = Plurimath::Math.parse(asciimath, :asciimath)
|
|
161
161
|
----
|
|
162
162
|
|
|
163
|
+
==== Localized decimal input
|
|
164
|
+
|
|
165
|
+
AsciiMath, LaTeX, HTML, and UnicodeMath input can use a locale decimal marker
|
|
166
|
+
from `Plurimath::Formatter::SupportedLocales::LOCALES` when parsing numbers.
|
|
167
|
+
Pass `locale:` to `Plurimath::Math.parse` for one parse, or use
|
|
168
|
+
`Plurimath.configure` for persistent defaults.
|
|
169
|
+
|
|
170
|
+
For AsciiMath, LaTeX, and HTML, the configured marker is the decimal marker.
|
|
171
|
+
When a locale uses a non-full-stop marker, `1.2` is parsed as `1`, `.`, and
|
|
172
|
+
`2`, not as one decimal number.
|
|
173
|
+
|
|
174
|
+
[source,ruby]
|
|
175
|
+
----
|
|
176
|
+
formula = Plurimath::Math.parse("1,2", :asciimath, locale: :fr)
|
|
177
|
+
----
|
|
178
|
+
|
|
179
|
+
When the locale decimal marker is a comma, unspaced digit-comma-digit input is
|
|
180
|
+
read as a decimal number.
|
|
181
|
+
|
|
182
|
+
[source,asciimath]
|
|
183
|
+
----
|
|
184
|
+
1,2 # decimal number
|
|
185
|
+
1 , 2 # comma separator
|
|
186
|
+
----
|
|
187
|
+
|
|
188
|
+
AsciiMath uses commas for expression and table separators, so separator commas
|
|
189
|
+
between digit tokens should be written with spaces around them when the
|
|
190
|
+
configured decimal marker is a comma.
|
|
191
|
+
|
|
192
|
+
HTML can use the same configured decimal marker inside plain text or tags.
|
|
193
|
+
|
|
194
|
+
[source,html]
|
|
195
|
+
----
|
|
196
|
+
1,2
|
|
197
|
+
<span>1,2</span>
|
|
198
|
+
----
|
|
199
|
+
|
|
200
|
+
Locales are not limited to full stop and comma markers. For example, Arabic and
|
|
201
|
+
Persian locales use the Arabic decimal separator.
|
|
202
|
+
|
|
203
|
+
[source,ruby]
|
|
204
|
+
----
|
|
205
|
+
formula = Plurimath::Math.parse("1٫2", :unicode, locale: :ar)
|
|
206
|
+
----
|
|
207
|
+
|
|
208
|
+
LaTeX ordinary spaces are removed during parser preprocessing, so `1, 2` is
|
|
209
|
+
equivalent to `1,2` for this parser. With a comma decimal marker, only
|
|
210
|
+
digit-comma-digit is parsed as a decimal number; a leading comma remains a comma
|
|
211
|
+
symbol followed by a number. To write a comma separator between two digits,
|
|
212
|
+
wrap the comma or the following value in a group, such as `1{,}2` or `1,{}2`.
|
|
213
|
+
|
|
214
|
+
[source,latex]
|
|
215
|
+
----
|
|
216
|
+
1,2 % decimal number
|
|
217
|
+
1{,}2 % comma separator
|
|
218
|
+
1,{}2 % comma separator
|
|
219
|
+
----
|
|
220
|
+
|
|
221
|
+
UnicodeMath is different: it keeps its existing full stop and comma decimal
|
|
222
|
+
grammar, including leading markers such as `.2` and `,2`, and also accepts the
|
|
223
|
+
configured locale marker.
|
|
224
|
+
|
|
225
|
+
Localized decimal parsing preserves the parsed number text, such as `1,2` or
|
|
226
|
+
`1٫2`. Number formatter input remains canonical decimal input; locale decimal
|
|
227
|
+
and grouping symbols are applied when formatting output.
|
|
228
|
+
|
|
163
229
|
==== MathML Formula example
|
|
164
230
|
|
|
165
231
|
[source,ruby]
|
|
@@ -403,6 +469,11 @@ priority, ordered from highest to lowest precedence:
|
|
|
403
469
|
. The `localizer_symbols` hash in the creation of a `Plurimath::NumberFormatter`
|
|
404
470
|
. The **default configuration** of the locale of the `Plurimath::NumberFormatter`
|
|
405
471
|
|
|
472
|
+
`precision` is resolved separately: the `precision:` keyword passed to
|
|
473
|
+
`localized_number`, which defaults to the formatter instance's `precision`
|
|
474
|
+
value, takes precedence over any `precision` provided through the formatter
|
|
475
|
+
symbols or `format` hash.
|
|
476
|
+
|
|
406
477
|
|
|
407
478
|
[example]
|
|
408
479
|
.Formatting a number to group every 2 digits
|
|
@@ -488,6 +559,9 @@ formatter = Plurimath::NumberFormatter.new(:en)
|
|
|
488
559
|
The `Plurimath::NumberFormatter` object can be configured using either the
|
|
489
560
|
`localize_number` or `localizer_symbols` options.
|
|
490
561
|
|
|
562
|
+
`Plurimath::Formatter::Standard` exposes the same configuration through the
|
|
563
|
+
`string_format` and `options` initializer arguments.
|
|
564
|
+
|
|
491
565
|
|
|
492
566
|
[[localizer_symbols]]
|
|
493
567
|
===== Via "format options" using `localizer_symbols`
|
|
@@ -499,14 +573,17 @@ This Hash object is called the "format options Hash".
|
|
|
499
573
|
|
|
500
574
|
Available options are explained below.
|
|
501
575
|
|
|
502
|
-
NOTE: Each option takes an input of a certain specified type
|
|
503
|
-
|
|
504
|
-
errors or incorrect output.
|
|
576
|
+
NOTE: Each option takes an input of a certain specified type. Using an input
|
|
577
|
+
type other than the specified type will result in errors or incorrect output.
|
|
505
578
|
|
|
506
579
|
The values passed to `localizer_symbols` persist as long as the initialized
|
|
507
580
|
`NumberFormatter` instance is accessible. It is therefore useful in scenarios
|
|
508
581
|
when configuration will be static or changes are not required very often.
|
|
509
582
|
|
|
583
|
+
The same option keys can be passed through `localizer_symbols`, through the
|
|
584
|
+
per-call `format:` hash, or through `Plurimath::Formatter::Standard`'s
|
|
585
|
+
`options:` argument.
|
|
586
|
+
|
|
510
587
|
|
|
511
588
|
`decimal`:: (`String` value)
|
|
512
589
|
Symbol to use for the decimal point. Accepts a character.
|
|
@@ -566,6 +643,60 @@ Accepts an integer value. (default is 3 in most locales.)
|
|
|
566
643
|
"32232.232" => "3 22 32.232"
|
|
567
644
|
====
|
|
568
645
|
|
|
646
|
+
`number_sign`:: (`Symbol` or `String` value)
|
|
647
|
+
Controls whether positive numbers are rendered with an explicit sign. Use
|
|
648
|
+
`:plus` or `"plus"` to add a leading `+` to positive values. Negative values
|
|
649
|
+
keep their normal `-` sign. The sign is applied before base prefixes and before
|
|
650
|
+
notation rendering.
|
|
651
|
+
+
|
|
652
|
+
.Showing a positive number sign
|
|
653
|
+
[example]
|
|
654
|
+
====
|
|
655
|
+
When `base` is used, the input string is still the source decimal value; `base`
|
|
656
|
+
controls the rendered output base.
|
|
657
|
+
|
|
658
|
+
"14236.39239" with `number_sign: :plus` => "+14,236.39239"
|
|
659
|
+
"10" with `base: 2, number_sign: :plus, group_digits: 2, group: ","` => "+0b10,10"
|
|
660
|
+
====
|
|
661
|
+
|
|
662
|
+
`padding`:: (`String` value)
|
|
663
|
+
Character to use when padding the integer portion. Defaults to `0`.
|
|
664
|
+
+
|
|
665
|
+
.Using spaces as integer padding
|
|
666
|
+
[example]
|
|
667
|
+
====
|
|
668
|
+
"32" with `padding_digits: 6, padding: " ", group: ""` => " 32"
|
|
669
|
+
====
|
|
670
|
+
|
|
671
|
+
`padding_digits`:: (`Numeric` value)
|
|
672
|
+
Minimum number of integer digits to render. Missing integer digits are inserted
|
|
673
|
+
before grouping using the configured `padding` character. Do not use it together
|
|
674
|
+
with `padding_group_digits`.
|
|
675
|
+
+
|
|
676
|
+
Padding is applied before integer grouping, so padding characters are grouped
|
|
677
|
+
with the rest of the integer digits.
|
|
678
|
+
+
|
|
679
|
+
.Padding to a fixed integer width
|
|
680
|
+
[example]
|
|
681
|
+
====
|
|
682
|
+
"32" with `padding_digits: 6, group: ""` => "000032"
|
|
683
|
+
"32123" with `padding_digits: 6, group: ""` => "032123"
|
|
684
|
+
"32" with `padding_digits: 6, group_digits: 3, group: " "` => "000 032"
|
|
685
|
+
====
|
|
686
|
+
|
|
687
|
+
`padding_group_digits`:: (`Numeric` value)
|
|
688
|
+
Pads the integer portion to the lowest multiple of the configured digit count.
|
|
689
|
+
Missing integer digits are inserted before grouping using the configured
|
|
690
|
+
`padding` character. Do not use it together with `padding_digits`.
|
|
691
|
+
+
|
|
692
|
+
.Padding to an integer width multiple
|
|
693
|
+
[example]
|
|
694
|
+
====
|
|
695
|
+
"32" with `padding_group_digits: 4, group: ""` => "0032"
|
|
696
|
+
"32123" with `padding_group_digits: 4, group: ""` => "00032123"
|
|
697
|
+
====
|
|
698
|
+
====
|
|
699
|
+
|
|
569
700
|
`base`:: (`Numeric` value)
|
|
570
701
|
Sets the numeric base (radix) used to render both the integer and fractional parts of the number.
|
|
571
702
|
Supported values are 2 (binary), 8 (octal), 10 (decimal, default) and 16 (hexadecimal).
|
|
@@ -593,30 +724,39 @@ When omitted, standard prefixes are used (`0b` for base 2, `0o` for base 8, `0x`
|
|
|
593
724
|
"255" with `base: 16, base_prefix: ""` => "ff"
|
|
594
725
|
====
|
|
595
726
|
|
|
596
|
-
`base_postfix`:: (`String` value)
|
|
597
|
-
If present
|
|
727
|
+
`base_postfix`:: (`String` or `nil` value)
|
|
728
|
+
If present without `base_prefix`, a postfix is appended to the converted number
|
|
729
|
+
instead of using the default base prefix. When `base_prefix` is also provided,
|
|
730
|
+
the prefix and postfix are both rendered.
|
|
598
731
|
This is applied after digit grouping.
|
|
599
|
-
|
|
732
|
+
Because the formatter checks whether the `base_postfix` key is present, setting
|
|
733
|
+
it to `nil` or an empty string omits both the postfix and the default base
|
|
734
|
+
prefix.
|
|
600
735
|
+
|
|
601
736
|
.Using postfix notation
|
|
602
737
|
[example]
|
|
603
738
|
====
|
|
604
739
|
"255" with `base: 16, base_postfix: "_16"` => "ff_16"
|
|
740
|
+
"255" with `base: 16, base_prefix: "16#", base_postfix: "_16"` => "16#ff_16"
|
|
605
741
|
"255" with `base: 16, base_postfix: nil` => "ff"
|
|
606
742
|
"255" with `base: 16, base_postfix: ""` => "ff"
|
|
607
743
|
====
|
|
608
744
|
|
|
609
|
-
`hex_capital`:: (`Boolean` value)
|
|
610
|
-
When `true` and `base: 16`,
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
745
|
+
`hex_capital`:: (`Boolean` or `:numbers_only` value)
|
|
746
|
+
Controls uppercase rendering for hexadecimal output. When `true` and `base: 16`,
|
|
747
|
+
all characters in the range `a`-`f` in the converted output are rendered using
|
|
748
|
+
uppercase letters. This includes both hexadecimal digits and any separators
|
|
749
|
+
(such as `decimal`, `group`, `fraction_group`) that happen to be letters in the
|
|
750
|
+
`a`-`f` range. The `base_prefix` and `base_postfix` values are never modified.
|
|
751
|
+
+
|
|
752
|
+
Use `:numbers_only` to uppercase generated hexadecimal digits without changing
|
|
753
|
+
separator characters. It has no effect for other bases.
|
|
615
754
|
+
|
|
616
755
|
.Uppercase hexadecimal output
|
|
617
756
|
[example]
|
|
618
757
|
====
|
|
619
|
-
"48879" with `base: 16, hex_capital: true` => "0xBE,EF"
|
|
758
|
+
"48879" with `base: 16, hex_capital: true, group_digits: 2` => "0xBE,EF"
|
|
759
|
+
"48879" with `base: 16, hex_capital: :numbers_only, group_digits: 2, group: "e"` => "0xBEeEF"
|
|
620
760
|
====
|
|
621
761
|
+
|
|
622
762
|
WARNING: If you use separator characters in the range `a`-`f` (such as `decimal: "d"` or `fraction_group: "f"`), those separators will also be uppercased when `hex_capital: true`. Choose separators outside this range (e.g., `".", ",", " ", "_"`) if you need them to remain unchanged.
|
|
@@ -624,9 +764,9 @@ WARNING: If you use separator characters in the range `a`-`f` (such as `decimal:
|
|
|
624
764
|
.Separator uppercasing behavior
|
|
625
765
|
[example]
|
|
626
766
|
====
|
|
627
|
-
"48879" with `base: 16, hex_capital: true, group: "g"` => "0xBEgEF" (g remains lowercase)
|
|
767
|
+
"48879" with `base: 16, hex_capital: true, group_digits: 2, group: "g"` => "0xBEgEF" (g remains lowercase)
|
|
628
768
|
|
|
629
|
-
"48879" with `base: 16, hex_capital: true, group: "f"` => "0xBEFEF" (f separator becomes F)
|
|
769
|
+
"48879" with `base: 16, hex_capital: true, group_digits: 2, group: "f"` => "0xBEFEF" (f separator becomes F)
|
|
630
770
|
====
|
|
631
771
|
|
|
632
772
|
NOTE: When `base` is not 10, both the integer and fractional parts are converted to the specified base.
|
|
@@ -638,7 +778,10 @@ as decimal `0.75` for the fractional part) and converts that real value to the r
|
|
|
638
778
|
===== Base conversion with other formatting options
|
|
639
779
|
|
|
640
780
|
Base conversion works seamlessly with other formatting options such as `precision`, `digit_count`,
|
|
641
|
-
`fraction_group`, `fraction_group_digits`, and
|
|
781
|
+
`fraction_group`, `fraction_group_digits`, `significant`, and integer padding.
|
|
782
|
+
+
|
|
783
|
+
Integer padding is applied after `digit_count` rounding, so padding can add
|
|
784
|
+
integer digits after the total visible-digit budget has been resolved.
|
|
642
785
|
|
|
643
786
|
.Base conversion with precision
|
|
644
787
|
[example]
|
|
@@ -696,8 +839,44 @@ right. Accepts an integer value.
|
|
|
696
839
|
"32232.232131" => "32232.23 21 31"
|
|
697
840
|
====
|
|
698
841
|
|
|
842
|
+
[[format_option_significant]]
|
|
699
843
|
`significant`:: (`Numeric` value)
|
|
700
844
|
Sets the number of significant digits to show, with the value rounded.
|
|
845
|
+
Leading zeros before the first non-zero digit are not counted as significant.
|
|
846
|
+
+
|
|
847
|
+
.Using significant digits
|
|
848
|
+
[example]
|
|
849
|
+
====
|
|
850
|
+
"112" with `significant: 2` => "110"
|
|
851
|
+
"1999" with `significant: 2` => "2,000"
|
|
852
|
+
"0.1999" with `significant: 3` => "0.200"
|
|
853
|
+
====
|
|
854
|
+
+
|
|
855
|
+
Significant-digit rounding is applied before localized rendering. This means
|
|
856
|
+
the formatter does not re-parse an already grouped or localized output string,
|
|
857
|
+
so `decimal` and `group` may use the same symbol without changing which digits
|
|
858
|
+
are rounded.
|
|
859
|
+
+
|
|
860
|
+
.Using significant digits with overlapping decimal and group symbols
|
|
861
|
+
[example]
|
|
862
|
+
====
|
|
863
|
+
"327428.7432878432992" with `decimal: ","`, `group_digits: 3`, `fraction_group_digits: 2`, `fraction_group: "'"`, `significant: 9`
|
|
864
|
+
=> "327,428,74'3"
|
|
865
|
+
====
|
|
866
|
+
+
|
|
867
|
+
When `base` is not 10 and `precision` is omitted, Plurimath infers the
|
|
868
|
+
fractional precision needed in the target base where possible. That inference
|
|
869
|
+
is capped by the source number's significant digits, so finite converted values
|
|
870
|
+
can keep required trailing zeros while repeating fractional conversions are not
|
|
871
|
+
expanded only to fill the requested count.
|
|
872
|
+
+
|
|
873
|
+
.Using significant digits with base conversion
|
|
874
|
+
[example]
|
|
875
|
+
====
|
|
876
|
+
"48879" with `base: 16, significant: 3, group_digits: 2, group: ","` => "0xbe,f0"
|
|
877
|
+
"123.25" with `base: 16, significant: 5, group_digits: 10` => "0x7b.400"
|
|
878
|
+
"0.1" with `base: 16, significant: 5, group_digits: 10` => "0x0.1"
|
|
879
|
+
====
|
|
701
880
|
|
|
702
881
|
`notation`:: (`String` value)
|
|
703
882
|
Specifies the mathematical notation to be used. Accepts the following values.
|
|
@@ -751,12 +930,12 @@ modes: `scientific` and `engineering`). Defaults to `×`.
|
|
|
751
930
|
----
|
|
752
931
|
====
|
|
753
932
|
|
|
754
|
-
`exponent_sign`:: (`String` value)
|
|
933
|
+
`exponent_sign`:: (`Symbol` or `String` value)
|
|
755
934
|
Whether to use a plus sign to indicate positive exponents, in exponent-based
|
|
756
935
|
notation (used in the modes: `e`, `scientific`, `engineering`). Legal values
|
|
757
936
|
are:
|
|
758
937
|
|
|
759
|
-
`plus`::: The `+` symbol is used.
|
|
938
|
+
`:plus`, `"plus"`::: The `+` symbol is used.
|
|
760
939
|
+
|
|
761
940
|
.Using the plus sign to indicate positive exponents
|
|
762
941
|
[example]
|
|
@@ -773,13 +952,27 @@ These options are to be grouped under a single Hash object.
|
|
|
773
952
|
----
|
|
774
953
|
{
|
|
775
954
|
decimal: ",", # replaces the decimal point with the passed string
|
|
776
|
-
group_digits: 2, # groups integer
|
|
777
|
-
group: "'", # places the string between grouped
|
|
778
|
-
fraction_group_digits: 3, # groups fraction
|
|
779
|
-
fraction_group: ",", # places the string between grouped
|
|
955
|
+
group_digits: 2, # groups integer digits into groups of the passed size
|
|
956
|
+
group: "'", # places the string between grouped integer digits
|
|
957
|
+
fraction_group_digits: 3, # groups fraction digits into groups of the passed size
|
|
958
|
+
fraction_group: ",", # places the string between grouped fraction digits
|
|
959
|
+
number_sign: :plus, # adds a plus sign to positive numbers
|
|
960
|
+
digit_count: 6, # limits the total rendered digit count
|
|
961
|
+
significant: 4, # limits the rendered significant digit count
|
|
962
|
+
precision: 2, # controls rendered fractional precision
|
|
963
|
+
notation: :scientific, # renders the number using the selected notation
|
|
964
|
+
e: "E", # sets the exponent marker for E notation
|
|
965
|
+
times: "x", # sets the multiplication symbol for power notation
|
|
966
|
+
exponent_sign: :plus, # adds a plus sign to positive exponents
|
|
967
|
+
base: 16, # renders the number in the selected base
|
|
968
|
+
base_prefix: "0x", # prefixes non-decimal base output when no postfix key is present
|
|
969
|
+
base_postfix: "_16", # appends a postfix and takes precedence over base_prefix
|
|
970
|
+
hex_capital: :numbers_only, # uppercases generated hexadecimal digits only
|
|
780
971
|
}
|
|
781
972
|
----
|
|
782
973
|
|
|
974
|
+
Only include the keys needed for the formatter behavior being configured.
|
|
975
|
+
|
|
783
976
|
|
|
784
977
|
[[localize_number]]
|
|
785
978
|
===== Via the `localize_number` option
|
|
@@ -1131,13 +1324,15 @@ The steps to format numbers within a formula are:
|
|
|
1131
1324
|
. Create a number formatter that can be configured;
|
|
1132
1325
|
|
|
1133
1326
|
. Apply the number formatter to a formula through the `Formula.to_{format}`
|
|
1134
|
-
method using a `formatter` option,
|
|
1135
|
-
|
|
1327
|
+
method using a `formatter` option, or configure a default formatter through
|
|
1328
|
+
`Plurimath.configure`.
|
|
1136
1329
|
|
|
1137
1330
|
The formatter should be an instance of `Plurimath::NumberFormatter` or a custom
|
|
1138
1331
|
formatter derived from `Plurimath::Formatter::Standard`. Custom formatters can
|
|
1139
|
-
define a `
|
|
1140
|
-
decisions based on the surrounding formula (see
|
|
1332
|
+
define a `format_number(formula, number)` method to make context-aware
|
|
1333
|
+
formatting decisions based on the surrounding formula (see
|
|
1334
|
+
<<Contextual number formatting>>). Existing custom formatters that define
|
|
1335
|
+
`format(formula, number)` remain supported.
|
|
1141
1336
|
|
|
1142
1337
|
The quick example below demonstrates how to format a number in a formula.
|
|
1143
1338
|
|
|
@@ -1191,6 +1386,58 @@ print formula.to_mathml(formatter: custom_formatter)
|
|
|
1191
1386
|
----
|
|
1192
1387
|
====
|
|
1193
1388
|
|
|
1389
|
+
[example]
|
|
1390
|
+
.Configuring a default number formatter for formula rendering
|
|
1391
|
+
====
|
|
1392
|
+
[source,ruby]
|
|
1393
|
+
----
|
|
1394
|
+
Plurimath.configure do |config|
|
|
1395
|
+
config.number_formatter = Plurimath::Formatter::Standard.new
|
|
1396
|
+
end
|
|
1397
|
+
|
|
1398
|
+
formula = Plurimath::Math.parse("10000 + 2000", :asciimath)
|
|
1399
|
+
formula.to_latex
|
|
1400
|
+
# => "10,000 + 2,000"
|
|
1401
|
+
----
|
|
1402
|
+
|
|
1403
|
+
Passing `formatter:` to a formula serialization method takes precedence over
|
|
1404
|
+
the configured default formatter.
|
|
1405
|
+
====
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
==== Deprecation notices
|
|
1409
|
+
|
|
1410
|
+
Plurimath exposes deprecation behavior through the shared configuration object.
|
|
1411
|
+
The current number formatter arguments documented above remain supported; this
|
|
1412
|
+
setting controls how Plurimath handles deprecation notices when a deprecated
|
|
1413
|
+
feature is used.
|
|
1414
|
+
|
|
1415
|
+
[source,ruby]
|
|
1416
|
+
----
|
|
1417
|
+
Plurimath.configure do |config|
|
|
1418
|
+
config.deprecation.behavior = :collect
|
|
1419
|
+
end
|
|
1420
|
+
|
|
1421
|
+
# Retrieve collected notices after parsing
|
|
1422
|
+
Plurimath::Deprecation.notices.each do |notice|
|
|
1423
|
+
puts notice.to_s # => "[plurimath][DEPRECATION] ..."
|
|
1424
|
+
puts notice.severity # => :warning
|
|
1425
|
+
puts notice.feature # => "feature_name"
|
|
1426
|
+
end
|
|
1427
|
+
----
|
|
1428
|
+
|
|
1429
|
+
Supported behaviors are:
|
|
1430
|
+
|
|
1431
|
+
`collect`:: Default behavior. Collects deprecation notices in
|
|
1432
|
+
`Plurimath::Deprecation.notices` for the caller to retrieve. Each notice is a
|
|
1433
|
+
`Plurimath::DeprecationError` with `severity`, `feature`, `replacement`,
|
|
1434
|
+
`since`, `remove_in`, and `to_s`.
|
|
1435
|
+
|
|
1436
|
+
`raise`:: Raises `Plurimath::DeprecationError` immediately when a deprecated
|
|
1437
|
+
feature is used.
|
|
1438
|
+
|
|
1439
|
+
`silence`:: Suppresses deprecation notices entirely.
|
|
1440
|
+
|
|
1194
1441
|
|
|
1195
1442
|
==== Defining a number formatter
|
|
1196
1443
|
|
|
@@ -1231,15 +1478,29 @@ There are two types of number formatting configuration to change:
|
|
|
1231
1478
|
|
|
1232
1479
|
. Overriding options through the `options` argument.
|
|
1233
1480
|
|
|
1481
|
+
.Syntax for creating a `Plurimath::Formatter::Standard` object
|
|
1482
|
+
[source,ruby]
|
|
1483
|
+
----
|
|
1484
|
+
formatter = Plurimath::Formatter::Standard.new(
|
|
1485
|
+
locale: :en,
|
|
1486
|
+
string_format: nil,
|
|
1487
|
+
options: {},
|
|
1488
|
+
precision: nil,
|
|
1489
|
+
)
|
|
1490
|
+
----
|
|
1491
|
+
|
|
1234
1492
|
The arguments are:
|
|
1235
1493
|
|
|
1236
1494
|
`locale`:: (default: `:en` for English) a symbol or string value. The supported
|
|
1237
1495
|
locales are listed in the link:/blog/2024-07-09-number-formatter[number formatter blog post].
|
|
1238
1496
|
|
|
1239
|
-
`options`:: (default: empty) a hash of options
|
|
1240
|
-
|
|
1497
|
+
`options`:: (default: empty) a hash of options. This is the
|
|
1498
|
+
`Plurimath::Formatter::Standard` alias for
|
|
1499
|
+
`Plurimath::NumberFormatter`'s `localizer_symbols` argument.
|
|
1241
1500
|
|
|
1242
|
-
`string_format`:: (default: `nil`, disabled) a string value
|
|
1501
|
+
`string_format`:: (default: `nil`, disabled) a string value. This is the
|
|
1502
|
+
`Plurimath::Formatter::Standard` alias for
|
|
1503
|
+
`Plurimath::NumberFormatter`'s `localize_number` argument.
|
|
1243
1504
|
|
|
1244
1505
|
`precision`:: (default: `nil`, disabled) an integer value.
|
|
1245
1506
|
|
|
@@ -1282,7 +1543,7 @@ The custom formatter is to be subclassed from `Plurimath::Formatter::Standard`.
|
|
|
1282
1543
|
[source,ruby]
|
|
1283
1544
|
----
|
|
1284
1545
|
class MyCustomFormatter < Plurimath::Formatter::Standard <1>
|
|
1285
|
-
def initialize(locale
|
|
1546
|
+
def initialize(locale: :en, precision: nil, options: {}, string_format: nil) <2>
|
|
1286
1547
|
super
|
|
1287
1548
|
end
|
|
1288
1549
|
end
|
|
@@ -1297,7 +1558,7 @@ The default options of the custom formatter are set using the
|
|
|
1297
1558
|
[source,ruby]
|
|
1298
1559
|
----
|
|
1299
1560
|
class MyCustomFormatter < Plurimath::Formatter::Standard
|
|
1300
|
-
def initialize(locale
|
|
1561
|
+
def initialize(locale: :en, precision: nil, options: {}, string_format: nil)
|
|
1301
1562
|
super
|
|
1302
1563
|
end
|
|
1303
1564
|
|
|
@@ -1354,24 +1615,30 @@ In some cases, certain numbers within a formula should be formatted differently
|
|
|
1354
1615
|
depending on their context. For example, a year like "2024" should not have digit
|
|
1355
1616
|
grouping applied, while other numbers in the same formula should.
|
|
1356
1617
|
|
|
1357
|
-
The `
|
|
1618
|
+
The `format_number` method on the formatter receives both the root
|
|
1358
1619
|
`Plurimath::Math::Formula` tree and the current `Plurimath::Math::Number` node
|
|
1359
1620
|
being processed, allowing context-aware formatting decisions.
|
|
1360
1621
|
|
|
1361
|
-
.Signature of the `
|
|
1622
|
+
.Signature of the `format_number` method
|
|
1362
1623
|
[source,ruby]
|
|
1363
1624
|
----
|
|
1364
|
-
def
|
|
1625
|
+
def format_number(formula, number)
|
|
1365
1626
|
# formula: the root Plurimath::Math::Formula containing the full equation
|
|
1366
1627
|
# number: the Plurimath::Math::Number node currently being formatted
|
|
1367
1628
|
# returns: a formatted string
|
|
1368
1629
|
end
|
|
1369
1630
|
----
|
|
1370
1631
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1632
|
+
Formula rendering uses the first formatter method available in this order:
|
|
1633
|
+
`format_number(formula, number)`, then `format(formula, number)`, then
|
|
1634
|
+
`localized_number(number.value.to_s)`. This keeps existing custom formatters
|
|
1635
|
+
working while giving new custom formatters a method name specific to formula
|
|
1636
|
+
number formatting.
|
|
1373
1637
|
|
|
1374
|
-
|
|
1638
|
+
New custom formatters should define `format_number`; the `format` fallback
|
|
1639
|
+
exists for compatibility with existing custom formatters.
|
|
1640
|
+
|
|
1641
|
+
To implement contextual formatting, define a `format_number` method in a custom
|
|
1375
1642
|
formatter subclass.
|
|
1376
1643
|
|
|
1377
1644
|
.Creating a year-aware formatter that skips digit grouping for year-like numbers
|
|
@@ -1380,7 +1647,7 @@ formatter subclass.
|
|
|
1380
1647
|
[source,ruby]
|
|
1381
1648
|
----
|
|
1382
1649
|
class YearFormatter < Plurimath::Formatter::Standard
|
|
1383
|
-
def
|
|
1650
|
+
def format_number(formula, number) <1>
|
|
1384
1651
|
int_value = Integer(number.value, exception: false)
|
|
1385
1652
|
if int_value && int_value > 1800 && int_value < 2200 <2>
|
|
1386
1653
|
number.value.to_s
|
|
@@ -1395,7 +1662,7 @@ formula = Plurimath::Math.parse("2024 + 1000000", :asciimath)
|
|
|
1395
1662
|
formula.to_latex(formatter: formatter)
|
|
1396
1663
|
# => "2024 + 1,000,000" <4>
|
|
1397
1664
|
----
|
|
1398
|
-
<1> Define `
|
|
1665
|
+
<1> Define `format_number` to receive the formula tree and number node.
|
|
1399
1666
|
<2> Detect year-like numbers and return them unformatted.
|
|
1400
1667
|
<3> Call `localized_number` to apply locale-based formatting for other numbers.
|
|
1401
1668
|
<4> "2024" is left as-is, while "1000000" is formatted with digit grouping.
|
|
@@ -1405,8 +1672,8 @@ formula.to_latex(formatter: formatter)
|
|
|
1405
1672
|
[[standard_configuration]]
|
|
1406
1673
|
=== Default number formatting configuration
|
|
1407
1674
|
|
|
1408
|
-
The default configuration for
|
|
1409
|
-
|
|
1675
|
+
The effective default configuration for `Plurimath::Formatter::Standard` is as
|
|
1676
|
+
follows.
|
|
1410
1677
|
|
|
1411
1678
|
|===
|
|
1412
1679
|
|Option key |Description |Value
|
|
@@ -1421,7 +1688,11 @@ The default configuration for formatting numbers is as follows, set in the
|
|
|
1421
1688
|
|
|
1422
1689
|
|`exponent_sign`
|
|
1423
1690
|
|The sign used for the exponent part of the number
|
|
1424
|
-
|`
|
|
1691
|
+
|`nil`
|
|
1692
|
+
|
|
1693
|
+
|`number_sign`
|
|
1694
|
+
|The sign used for positive numbers
|
|
1695
|
+
|`nil`
|
|
1425
1696
|
|
|
1426
1697
|
|`fraction_group`
|
|
1427
1698
|
|The character used to separate groups of digits in the fraction part
|
|
@@ -1435,6 +1706,18 @@ The default configuration for formatting numbers is as follows, set in the
|
|
|
1435
1706
|
|The number of digits in each group of the integer part
|
|
1436
1707
|
|`3`
|
|
1437
1708
|
|
|
1709
|
+
|`padding`
|
|
1710
|
+
|The character used to pad the integer part
|
|
1711
|
+
|`"0"`
|
|
1712
|
+
|
|
1713
|
+
|`padding_digits`
|
|
1714
|
+
|The minimum number of integer digits to display
|
|
1715
|
+
|`0`
|
|
1716
|
+
|
|
1717
|
+
|`padding_group_digits`
|
|
1718
|
+
|The multiple of integer digits to pad to
|
|
1719
|
+
|`0`
|
|
1720
|
+
|
|
1438
1721
|
|`significant`
|
|
1439
1722
|
|The number of significant digits to display
|
|
1440
1723
|
|`0`
|
|
@@ -1445,7 +1728,23 @@ The default configuration for formatting numbers is as follows, set in the
|
|
|
1445
1728
|
|
|
1446
1729
|
|`precision`
|
|
1447
1730
|
|The number of decimal places to display
|
|
1448
|
-
|`
|
|
1731
|
+
|`nil`
|
|
1732
|
+
|
|
1733
|
+
|`base`
|
|
1734
|
+
|The numeric base used to render the number
|
|
1735
|
+
|`10`
|
|
1736
|
+
|
|
1737
|
+
|`base_prefix`
|
|
1738
|
+
|The prefix used for non-decimal bases
|
|
1739
|
+
|standard prefix for the selected base
|
|
1740
|
+
|
|
1741
|
+
|`base_postfix`
|
|
1742
|
+
|The postfix used for non-decimal bases
|
|
1743
|
+
|`nil`
|
|
1744
|
+
|
|
1745
|
+
|`hex_capital`
|
|
1746
|
+
|Whether hexadecimal output is capitalized
|
|
1747
|
+
|`nil`
|
|
1449
1748
|
|
|
1450
1749
|
|`decimal`
|
|
1451
1750
|
|The character used as the decimal separator
|
|
@@ -1460,7 +1759,7 @@ The default configuration for formatting numbers is as follows, set in the
|
|
|
1460
1759
|
|`"x"`
|
|
1461
1760
|
|
|
1462
1761
|
|`e`
|
|
1463
|
-
|The character used for
|
|
1762
|
+
|The character used for E notation
|
|
1464
1763
|
|`"e"`
|
|
1465
1764
|
|
|
1466
1765
|
|===
|
|
@@ -10,7 +10,7 @@ module Plurimath
|
|
|
10
10
|
rule(:comma) { str(",") >> space? }
|
|
11
11
|
rule(:space?) { space.maybe }
|
|
12
12
|
rule(:number) do
|
|
13
|
-
(match("[0-9]").repeat(1) >>
|
|
13
|
+
(match("[0-9]").repeat(1) >> decimal_marker >> match("[0-9]").repeat(1)).as(:number) |
|
|
14
14
|
match("[0-9]").repeat(1).as(:number) |
|
|
15
15
|
str(".").as(:symbol)
|
|
16
16
|
end
|
|
@@ -78,7 +78,7 @@ module Plurimath
|
|
|
78
78
|
binary_classes |
|
|
79
79
|
ternary_classes |
|
|
80
80
|
hash_to_expression(Constants.precompile_constants) |
|
|
81
|
-
(match(/[0-9]/).as(:number) >> str(",").as(:comma)).repeat(1).as(:comma_separated) |
|
|
81
|
+
(match(/[0-9]/).as(:number) >> (decimal_marker >> match("[0-9]")).absent? >> str(",").as(:comma)).repeat(1).as(:comma_separated) |
|
|
82
82
|
quoted_text |
|
|
83
83
|
(str("d").as(:d) >> str("x").as(:x)).as(:intermediate_exp) |
|
|
84
84
|
((str("left").absent? >> str("right").absent?) >> match["a-zA-Z"].as(:symbol)) |
|
|
@@ -196,6 +196,10 @@ module Plurimath
|
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
+
def decimal_marker
|
|
200
|
+
str(Plurimath.configuration.decimal)
|
|
201
|
+
end
|
|
202
|
+
|
|
199
203
|
def unary_functions(first_value)
|
|
200
204
|
if ["'underbrace'", "'ubrace'"].include?(first_value.to_s)
|
|
201
205
|
(first_value.as(:unary_class) >> space? >> str("_").as(:symbol)).as(:unary) |
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plurimath
|
|
4
|
+
class Configuration
|
|
5
|
+
DEFAULT_DECIMAL = "."
|
|
6
|
+
|
|
7
|
+
attr_accessor :number_formatter, :locale
|
|
8
|
+
|
|
9
|
+
def deprecation
|
|
10
|
+
Deprecation
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def decimal
|
|
14
|
+
Formatter::SupportedLocales.decimal_for(locale, default: DEFAULT_DECIMAL)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|