plurimath 0.9.11 → 0.10.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 -0
- data/.rspec-opal +1 -1
- data/.rubocop.yml +9 -5
- data/.rubocop_todo.yml +0 -0
- data/Gemfile +7 -5
- data/README.adoc +131 -11
- data/Rakefile +11 -0
- data/lib/plurimath/asciimath/parse.rb +0 -1
- data/lib/plurimath/asciimath/parser.rb +0 -3
- data/lib/plurimath/asciimath.rb +5 -1
- data/lib/plurimath/cli.rb +1 -1
- data/lib/plurimath/errors/formatter/unsupported_base.rb +19 -0
- data/lib/plurimath/errors/invalid_type_error.rb +19 -0
- data/lib/plurimath/errors/parse_error.rb +39 -0
- data/lib/plurimath/errors.rb +1 -0
- data/lib/plurimath/formatter/number_formatter.rb +52 -10
- data/lib/plurimath/formatter/numbers/base.rb +37 -0
- data/lib/plurimath/formatter/numbers/fraction.rb +146 -35
- data/lib/plurimath/formatter/numbers/integer.rb +16 -12
- data/lib/plurimath/formatter/numbers/significant.rb +84 -52
- data/lib/plurimath/formatter/numbers.rb +12 -0
- data/lib/plurimath/formatter/standard.rb +0 -1
- data/lib/plurimath/formatter.rb +6 -7
- data/lib/plurimath/html/parse.rb +0 -1
- data/lib/plurimath/html/parser.rb +0 -3
- data/lib/plurimath/html.rb +5 -0
- data/lib/plurimath/latex/parse.rb +0 -1
- data/lib/plurimath/latex/parser.rb +2 -5
- data/lib/plurimath/latex.rb +5 -0
- data/lib/plurimath/math/core.rb +7 -2
- data/lib/plurimath/math/formula/mrow.rb +2 -41
- data/lib/plurimath/math/formula/mstyle.rb +6 -0
- data/lib/plurimath/math/formula.rb +54 -298
- data/lib/plurimath/math/function/abs.rb +0 -1
- data/lib/plurimath/math/function/arccos.rb +0 -1
- data/lib/plurimath/math/function/arcsin.rb +0 -1
- data/lib/plurimath/math/function/arctan.rb +0 -1
- data/lib/plurimath/math/function/arg.rb +0 -1
- data/lib/plurimath/math/function/bar.rb +0 -1
- data/lib/plurimath/math/function/base.rb +0 -3
- data/lib/plurimath/math/function/binary_function.rb +5 -3
- data/lib/plurimath/math/function/cancel.rb +0 -1
- data/lib/plurimath/math/function/ceil.rb +0 -1
- data/lib/plurimath/math/function/color.rb +0 -1
- data/lib/plurimath/math/function/cos.rb +0 -1
- data/lib/plurimath/math/function/cosh.rb +0 -1
- data/lib/plurimath/math/function/cot.rb +0 -1
- data/lib/plurimath/math/function/coth.rb +0 -1
- data/lib/plurimath/math/function/csc.rb +0 -1
- data/lib/plurimath/math/function/csch.rb +0 -1
- data/lib/plurimath/math/function/ddot.rb +0 -1
- data/lib/plurimath/math/function/deg.rb +0 -1
- data/lib/plurimath/math/function/det.rb +0 -1
- data/lib/plurimath/math/function/dim.rb +0 -1
- data/lib/plurimath/math/function/dot.rb +0 -1
- data/lib/plurimath/math/function/exp.rb +0 -1
- data/lib/plurimath/math/function/fenced.rb +1 -197
- data/lib/plurimath/math/function/floor.rb +0 -1
- data/lib/plurimath/math/function/font_style/bold-fraktur.rb +0 -1
- data/lib/plurimath/math/function/font_style/bold-italic.rb +0 -1
- data/lib/plurimath/math/function/font_style/bold-sans-serif.rb +0 -1
- data/lib/plurimath/math/function/font_style/bold-script.rb +0 -1
- data/lib/plurimath/math/function/font_style/bold.rb +0 -1
- data/lib/plurimath/math/function/font_style/double_struck.rb +0 -1
- data/lib/plurimath/math/function/font_style/fraktur.rb +0 -1
- data/lib/plurimath/math/function/font_style/italic.rb +0 -1
- data/lib/plurimath/math/function/font_style/monospace.rb +0 -1
- data/lib/plurimath/math/function/font_style/normal.rb +0 -1
- data/lib/plurimath/math/function/font_style/sans-serif-bold-italic.rb +0 -1
- data/lib/plurimath/math/function/font_style/sans-serif-italic.rb +0 -1
- data/lib/plurimath/math/function/font_style/sans-serif.rb +0 -1
- data/lib/plurimath/math/function/font_style/script.rb +0 -1
- data/lib/plurimath/math/function/font_style.rb +97 -7
- data/lib/plurimath/math/function/frac.rb +0 -3
- data/lib/plurimath/math/function/gcd.rb +0 -1
- data/lib/plurimath/math/function/glb.rb +0 -1
- data/lib/plurimath/math/function/hat.rb +0 -1
- data/lib/plurimath/math/function/hom.rb +0 -1
- data/lib/plurimath/math/function/inf.rb +1 -2
- data/lib/plurimath/math/function/int.rb +2 -3
- data/lib/plurimath/math/function/intent.rb +0 -1
- data/lib/plurimath/math/function/ker.rb +0 -1
- data/lib/plurimath/math/function/lcm.rb +0 -1
- data/lib/plurimath/math/function/left.rb +0 -1
- data/lib/plurimath/math/function/lg.rb +0 -1
- data/lib/plurimath/math/function/lim.rb +1 -2
- data/lib/plurimath/math/function/liminf.rb +0 -1
- data/lib/plurimath/math/function/limits.rb +0 -1
- data/lib/plurimath/math/function/limsup.rb +0 -1
- data/lib/plurimath/math/function/linebreak.rb +0 -1
- data/lib/plurimath/math/function/ln.rb +0 -1
- data/lib/plurimath/math/function/log.rb +1 -2
- data/lib/plurimath/math/function/longdiv.rb +0 -3
- data/lib/plurimath/math/function/lub.rb +0 -1
- data/lib/plurimath/math/function/max.rb +0 -1
- data/lib/plurimath/math/function/mbox.rb +0 -1
- data/lib/plurimath/math/function/menclose.rb +0 -3
- data/lib/plurimath/math/function/merror.rb +0 -3
- data/lib/plurimath/math/function/mglyph.rb +0 -3
- data/lib/plurimath/math/function/min.rb +0 -1
- data/lib/plurimath/math/function/mlabeledtr.rb +0 -20
- data/lib/plurimath/math/function/mod.rb +0 -1
- data/lib/plurimath/math/function/mpadded.rb +0 -3
- data/lib/plurimath/math/function/ms.rb +1 -77
- data/lib/plurimath/math/function/msgroup.rb +0 -27
- data/lib/plurimath/math/function/msline.rb +0 -3
- data/lib/plurimath/math/function/multiscript.rb +0 -14
- data/lib/plurimath/math/function/nary.rb +4 -0
- data/lib/plurimath/math/function/none.rb +1 -4
- data/lib/plurimath/math/function/norm.rb +0 -1
- data/lib/plurimath/math/function/obrace.rb +0 -1
- data/lib/plurimath/math/function/oint.rb +2 -3
- data/lib/plurimath/math/function/over.rb +0 -3
- data/lib/plurimath/math/function/overset.rb +3 -3
- data/lib/plurimath/math/function/phantom.rb +0 -3
- data/lib/plurimath/math/function/power.rb +0 -3
- data/lib/plurimath/math/function/power_base.rb +0 -3
- data/lib/plurimath/math/function/prod.rb +2 -3
- data/lib/plurimath/math/function/right.rb +0 -1
- data/lib/plurimath/math/function/root.rb +0 -3
- data/lib/plurimath/math/function/rule.rb +0 -1
- data/lib/plurimath/math/function/scarries.rb +0 -3
- data/lib/plurimath/math/function/scarry.rb +22 -0
- data/lib/plurimath/math/function/sec.rb +0 -1
- data/lib/plurimath/math/function/sech.rb +0 -1
- data/lib/plurimath/math/function/semantics.rb +0 -15
- data/lib/plurimath/math/function/sin.rb +0 -1
- data/lib/plurimath/math/function/sinh.rb +0 -1
- data/lib/plurimath/math/function/sqrt.rb +0 -3
- data/lib/plurimath/math/function/stackrel.rb +0 -3
- data/lib/plurimath/math/function/substack.rb +0 -1
- data/lib/plurimath/math/function/sum.rb +2 -3
- data/lib/plurimath/math/function/sup.rb +0 -1
- data/lib/plurimath/math/function/table/align.rb +0 -1
- data/lib/plurimath/math/function/table/array.rb +0 -1
- data/lib/plurimath/math/function/table/bmatrix.rb +0 -1
- data/lib/plurimath/math/function/table/cases.rb +0 -1
- data/lib/plurimath/math/function/table/eqarray.rb +0 -1
- data/lib/plurimath/math/function/table/matrix.rb +0 -1
- data/lib/plurimath/math/function/table/multline.rb +0 -1
- data/lib/plurimath/math/function/table/pmatrix.rb +0 -1
- data/lib/plurimath/math/function/table/split.rb +0 -1
- data/lib/plurimath/math/function/table/vmatrix.rb +0 -1
- data/lib/plurimath/math/function/table.rb +10 -23
- data/lib/plurimath/math/function/tan.rb +0 -1
- data/lib/plurimath/math/function/tanh.rb +0 -1
- data/lib/plurimath/math/function/td.rb +0 -4
- data/lib/plurimath/math/function/ternary_function.rb +6 -2
- data/lib/plurimath/math/function/text.rb +0 -5
- data/lib/plurimath/math/function/tilde.rb +4 -1
- data/lib/plurimath/math/function/tr.rb +0 -13
- data/lib/plurimath/math/function/ubrace.rb +0 -1
- data/lib/plurimath/math/function/ul.rb +4 -1
- data/lib/plurimath/math/function/underover.rb +0 -3
- data/lib/plurimath/math/function/underset.rb +22 -45
- data/lib/plurimath/math/function/unitsml.rb +2 -1
- data/lib/plurimath/math/function/vec.rb +4 -1
- data/lib/plurimath/math/function.rb +107 -10
- data/lib/plurimath/math/number.rb +1 -4
- data/lib/plurimath/math/symbols/comma.rb +1 -1
- data/lib/plurimath/math/symbols/plus.rb +1 -1
- data/lib/plurimath/math/symbols/symbol.rb +17 -4
- data/lib/plurimath/math.rb +13 -49
- data/lib/plurimath/mathml/formula_transformation.rb +442 -0
- data/lib/plurimath/mathml/parser.rb +11 -50
- data/lib/plurimath/mathml/translator.rb +584 -0
- data/lib/plurimath/mathml/utility/formula_transformation.rb +2 -341
- data/lib/plurimath/mathml.rb +5 -2
- data/lib/plurimath/number_formatter.rb +2 -1
- data/lib/plurimath/omml/parser.rb +0 -1
- data/lib/plurimath/omml/transform.rb +2 -1
- data/lib/plurimath/omml.rb +3 -0
- data/lib/plurimath/setup/opal.rb.erb +3 -4
- data/lib/plurimath/unicode_math/parse.rb +0 -5
- data/lib/plurimath/unicode_math/parser.rb +1 -6
- data/lib/plurimath/unicode_math/parsing_rules/absence_rules.rb +0 -1
- data/lib/plurimath/unicode_math/parsing_rules/common_rules.rb +0 -1
- data/lib/plurimath/unicode_math/parsing_rules/constants_rules.rb +0 -1
- data/lib/plurimath/unicode_math/parsing_rules/masked.rb +0 -1
- data/lib/plurimath/unicode_math/parsing_rules/sub_sup.rb +0 -1
- data/lib/plurimath/unicode_math/parsing_rules.rb +14 -0
- data/lib/plurimath/unicode_math.rb +6 -0
- data/lib/plurimath/unitsml.rb +4 -11
- data/lib/plurimath/utility.rb +1 -1
- data/lib/plurimath/version.rb +1 -1
- data/lib/plurimath/xml_engine/oga.rb +6 -6
- data/lib/plurimath/xml_engine/ox_engine.rb +2 -2
- data/lib/plurimath/xml_engine.rb +2 -0
- data/lib/plurimath.rb +43 -18
- data/plurimath.gemspec +6 -4
- metadata +49 -12
- data/lib/plurimath/mathml/utility/empty_defined_methods.rb +0 -483
- data/lib/plurimath/mathml/utility.rb +0 -369
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc005169c3f0268023980ba0d02d40a3e169c73ec1c75541f1ea71d8cadf6de6
|
|
4
|
+
data.tar.gz: 0d9fb467134da2b44ad20d1952d1795f4fa7e233a657b5589ea3b5cf5e99fb26
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c4d59a8681ab5b3b988d3a46ecfadc50661c43cc2d897816d943b3c621a6f8db202a8fca9b59c72fa732384284071aeec20851051b645cb7c29e4126fa0377d3
|
|
7
|
+
data.tar.gz: 54013f676433c00728a7b022b5c16ec3b77d2afd1949573ee56c0d90c936600289647cef2a886978e23da5be20af8d232dabf4e6ff9d3454dca77667f69d0f50
|
data/.rspec-opal
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
# Auto-generated by Cimas: Do not edit it manually!
|
|
2
|
-
# See https://github.com/metanorma/cimas
|
|
3
1
|
inherit_from:
|
|
4
2
|
- https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
|
|
3
|
+
- .rubocop_todo.yml
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
plugins:
|
|
6
|
+
- rubocop-performance
|
|
7
|
+
- rubocop-rake
|
|
8
|
+
- rubocop-rspec
|
|
8
9
|
|
|
9
10
|
AllCops:
|
|
10
|
-
TargetRubyVersion:
|
|
11
|
+
TargetRubyVersion: 3.0
|
|
12
|
+
NewCops: enable
|
|
13
|
+
Exclude:
|
|
14
|
+
- 'vendor/**/*'
|
data/.rubocop_todo.yml
ADDED
|
File without changes
|
data/Gemfile
CHANGED
|
@@ -3,12 +3,14 @@ source "https://rubygems.org"
|
|
|
3
3
|
# Specify your gem's dependencies in plurimath.gemspec
|
|
4
4
|
gemspec
|
|
5
5
|
|
|
6
|
+
gem 'lutaml-model', github: "lutaml/lutaml-model", branch: "main"
|
|
7
|
+
gem 'canon'
|
|
6
8
|
gem "rake", "~> 12.0"
|
|
7
9
|
gem "rspec", "~> 3.0"
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
10
|
-
gem
|
|
11
|
-
gem 'opal-rspec', "~> 1.1.0a"
|
|
10
|
+
gem "rubocop-performance"
|
|
11
|
+
gem "rubocop-rake"
|
|
12
|
+
gem "rubocop-rspec"
|
|
12
13
|
gem 'oga'
|
|
14
|
+
gem 'opal-rspec', "~> 1.1.0a"
|
|
13
15
|
gem 'ox'
|
|
14
|
-
gem
|
|
16
|
+
gem 'simplecov', require: false, group: :test
|
data/README.adoc
CHANGED
|
@@ -129,7 +129,7 @@ plurimath convert -i "equation" -f omml -t mathml -d true
|
|
|
129
129
|
====
|
|
130
130
|
[source,bash]
|
|
131
131
|
----
|
|
132
|
-
plurimath convert -
|
|
132
|
+
plurimath convert -p <file_path> -f asciimath -t unicodemath
|
|
133
133
|
----
|
|
134
134
|
====
|
|
135
135
|
|
|
@@ -524,14 +524,25 @@ Symbol to use for the decimal point. Accepts a character.
|
|
|
524
524
|
====
|
|
525
525
|
|
|
526
526
|
`digit_count`:: (`Numeric` value)
|
|
527
|
-
Total number of digits to render, with the value truncated
|
|
528
|
-
Accepts an integer value.
|
|
527
|
+
Total number of digits to render (integer + fractional), with the value truncated
|
|
528
|
+
or rounded as necessary. Accepts an integer value.
|
|
529
|
+
+
|
|
530
|
+
When `digit_count` is less than or equal to the integer length, the fractional
|
|
531
|
+
part is omitted entirely, and the integer is rounded based on whether the
|
|
532
|
+
fractional value is >= 0.5 (or >= base/2 for non-decimal bases).
|
|
529
533
|
+
|
|
530
534
|
.Specifying a total of 6 digits in rendering the number
|
|
531
535
|
[example]
|
|
532
536
|
====
|
|
533
537
|
"32232.232" => "32232.2"
|
|
534
538
|
====
|
|
539
|
+
+
|
|
540
|
+
.When digit_count is smaller than the integer length
|
|
541
|
+
[example]
|
|
542
|
+
====
|
|
543
|
+
"99999.999" with `digit_count: 3` => "100,000" (fractional part omitted, integer rounded up)
|
|
544
|
+
"12345.123" with `digit_count: 3` => "12,345" (fractional part omitted, no rounding)
|
|
545
|
+
====
|
|
535
546
|
|
|
536
547
|
|
|
537
548
|
`group`:: (`String` value)
|
|
@@ -555,6 +566,116 @@ Accepts an integer value. (default is 3 in most locales.)
|
|
|
555
566
|
"32232.232" => "3 22 32.232"
|
|
556
567
|
====
|
|
557
568
|
|
|
569
|
+
`base`:: (`Numeric` value)
|
|
570
|
+
Sets the numeric base (radix) used to render both the integer and fractional parts of the number.
|
|
571
|
+
Supported values are 2 (binary), 8 (octal), 10 (decimal, default) and 16 (hexadecimal).
|
|
572
|
+
Passing any other value for `base` raises `Plurimath::Formatter::UnsupportedBase`.
|
|
573
|
+
+
|
|
574
|
+
.Rendering numbers in different bases
|
|
575
|
+
[example]
|
|
576
|
+
====
|
|
577
|
+
"10" with `base: 2, group_digits: 2, group: ","` => "0b10,10"
|
|
578
|
+
"9" with `base: 8` => "0o11"
|
|
579
|
+
"255" with `base: 16` => "0xff"
|
|
580
|
+
"10.75" with `base: 2, group_digits: 2, group: ","` => "0b10,10.11" (integer and fractional parts converted, with grouping)
|
|
581
|
+
====
|
|
582
|
+
|
|
583
|
+
`base_prefix`:: (`String` or `nil` value)
|
|
584
|
+
Overrides the default base prefix for non‑decimal bases.
|
|
585
|
+
When omitted, standard prefixes are used (`0b` for base 2, `0o` for base 8, `0x` for base 16).
|
|
586
|
+
`nil` or an empty string can be used to omit the prefix.
|
|
587
|
+
+
|
|
588
|
+
.Custom base prefixes
|
|
589
|
+
[example]
|
|
590
|
+
====
|
|
591
|
+
"255" with `base: 16, base_prefix: "16#"` => "16#ff"
|
|
592
|
+
"255" with `base: 16, base_prefix: nil` => "ff"
|
|
593
|
+
"255" with `base: 16, base_prefix: ""` => "ff"
|
|
594
|
+
====
|
|
595
|
+
|
|
596
|
+
`base_postfix`:: (`String` value)
|
|
597
|
+
If present, a postfix is appended to the converted number instead of using any base prefix.
|
|
598
|
+
This is applied after digit grouping.
|
|
599
|
+
`nil` or an empty string can be used to omit the postfix.
|
|
600
|
+
+
|
|
601
|
+
.Using postfix notation
|
|
602
|
+
[example]
|
|
603
|
+
====
|
|
604
|
+
"255" with `base: 16, base_postfix: "_16"` => "ff_16"
|
|
605
|
+
"255" with `base: 16, base_postfix: nil` => "ff"
|
|
606
|
+
"255" with `base: 16, base_postfix: ""` => "ff"
|
|
607
|
+
====
|
|
608
|
+
|
|
609
|
+
`hex_capital`:: (`Boolean` value)
|
|
610
|
+
When `true` and `base: 16`, all characters in the range `a`-`f` in the converted output
|
|
611
|
+
are rendered using uppercase letters. This includes both hexadecimal digits and any
|
|
612
|
+
separators (such as `decimal`, `group`, `fraction_group`) that happen to be letters
|
|
613
|
+
in the `a`-`f` range. The `base_prefix` and `base_postfix` values are never modified.
|
|
614
|
+
It has no effect for other bases.
|
|
615
|
+
+
|
|
616
|
+
.Uppercase hexadecimal output
|
|
617
|
+
[example]
|
|
618
|
+
====
|
|
619
|
+
"48879" with `base: 16, hex_capital: true` => "0xBE,EF"
|
|
620
|
+
====
|
|
621
|
+
+
|
|
622
|
+
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.
|
|
623
|
+
+
|
|
624
|
+
.Separator uppercasing behavior
|
|
625
|
+
[example]
|
|
626
|
+
====
|
|
627
|
+
"48879" with `base: 16, hex_capital: true, group: "g"` => "0xBEgEF" (g remains lowercase)
|
|
628
|
+
|
|
629
|
+
"48879" with `base: 16, hex_capital: true, group: "f"` => "0xBEFEF" (f separator becomes F)
|
|
630
|
+
====
|
|
631
|
+
|
|
632
|
+
NOTE: When `base` is not 10, both the integer and fractional parts are converted to the specified base.
|
|
633
|
+
The decimal separator is rendered as configured by the `decimal` option.
|
|
634
|
+
+
|
|
635
|
+
NOTE: The fractional-part conversion treats the digits after the decimal point as a fractional value (for example, `"10.75"` is interpreted
|
|
636
|
+
as decimal `0.75` for the fractional part) and converts that real value to the requested base, honoring the configured precision.
|
|
637
|
+
|
|
638
|
+
===== Base conversion with other formatting options
|
|
639
|
+
|
|
640
|
+
Base conversion works seamlessly with other formatting options such as `precision`, `digit_count`,
|
|
641
|
+
`fraction_group`, `fraction_group_digits`, and `significant`.
|
|
642
|
+
|
|
643
|
+
.Base conversion with precision
|
|
644
|
+
[example]
|
|
645
|
+
====
|
|
646
|
+
Controls the maximum number of fractional digits in the converted base (pads with zeros when needed and truncates repeating expansions to the configured precision):
|
|
647
|
+
+
|
|
648
|
+
"10.75" with `base: 2, precision: 4` => "0b10,10.1100" (fractional part padded to 4 digits in base 2)
|
|
649
|
+
"0.5" with `base: 16, precision: 6` => "0x0.800000" (fractional part converted to base 16 and padded to 6 digits)
|
|
650
|
+
====
|
|
651
|
+
|
|
652
|
+
.Base conversion with fraction grouping
|
|
653
|
+
[example]
|
|
654
|
+
====
|
|
655
|
+
Groups fractional digits in the converted base:
|
|
656
|
+
+
|
|
657
|
+
"10.75" with `base: 2, fraction_group_digits: 1, fraction_group: " ", group_digits: 10` => "0b1010.1 1"
|
|
658
|
+
====
|
|
659
|
+
|
|
660
|
+
.Base conversion with digit_count
|
|
661
|
+
[example]
|
|
662
|
+
====
|
|
663
|
+
Limits total digits when using base conversion:
|
|
664
|
+
+
|
|
665
|
+
"14236.39239" with `base: 10, digit_count: 6, group_digits: 3` => "14,236.4"
|
|
666
|
+
"10.75" with `base: 2, digit_count: 7, group_digits: 10` => "0b1010.110"
|
|
667
|
+
"255.9" with `base: 16, digit_count: 2, group_digits: 10` => "0x100" (fractional part omitted, integer rounded)
|
|
668
|
+
====
|
|
669
|
+
|
|
670
|
+
.Base conversion with significant digits
|
|
671
|
+
[example]
|
|
672
|
+
====
|
|
673
|
+
Applies significant digit rounding with base conversion:
|
|
674
|
+
+
|
|
675
|
+
"1234.56" with `base: 10, significant: 4` => "1,235"
|
|
676
|
+
"1999" with `base: 10, significant: 2` => "2,000"
|
|
677
|
+
====
|
|
678
|
+
|
|
558
679
|
`fraction_group`:: (`String` value)
|
|
559
680
|
Delimiter to use between groups of fractional digits specified in
|
|
560
681
|
`fraction_group_digits`. Accepts a character.
|
|
@@ -607,7 +728,7 @@ selected to be divisible by three to match the common metric prefixes.
|
|
|
607
728
|
====
|
|
608
729
|
|
|
609
730
|
`e`:: (`String` value)
|
|
610
|
-
Symbol to use for exponents in E notation (default value `
|
|
731
|
+
Symbol to use for exponents in E notation (default value `e`). (used in the
|
|
611
732
|
mode: `e` only).
|
|
612
733
|
+
|
|
613
734
|
.Using the lowercase 'e' symbol as the exponent symbol
|
|
@@ -743,9 +864,8 @@ formatter.localized_number(
|
|
|
743
864
|
|
|
744
865
|
Where,
|
|
745
866
|
|
|
746
|
-
`<number>`:: (mandatory) The number to be formatted
|
|
747
|
-
|
|
748
|
-
raised.
|
|
867
|
+
`<number>`:: (mandatory) The number to be formatted, as a `String` containing the
|
|
868
|
+
decimal representation of the value (for example, `"1234.56789"`).
|
|
749
869
|
|
|
750
870
|
`locale: <locale-symbol>`:: (optional) The locale to be used for number formatting.
|
|
751
871
|
Value is a symbol.
|
|
@@ -1117,7 +1237,7 @@ locales are listed in the link:/blog/2024-07-09-number-formatter[number formatte
|
|
|
1117
1237
|
`options`:: (default: empty) a hash of options (`localizer_symbols`). The options
|
|
1118
1238
|
are listed in the link:/blog/2024-07-09-number-formatter[number formatter blog post].
|
|
1119
1239
|
|
|
1120
|
-
`
|
|
1240
|
+
`string_format`:: (default: `nil`, disabled) a string value (`localize_number`)
|
|
1121
1241
|
|
|
1122
1242
|
`precision`:: (default: `nil`, disabled) an integer value.
|
|
1123
1243
|
|
|
@@ -1136,7 +1256,7 @@ are listed in the link:/blog/2024-07-09-number-formatter[number formatter blog p
|
|
|
1136
1256
|
}
|
|
1137
1257
|
|
|
1138
1258
|
> formatter = Plurimath::Formatter::Standard.new(locale: :hy, options: options, precision: 2)
|
|
1139
|
-
#
|
|
1259
|
+
# string_format: <string value> if provided
|
|
1140
1260
|
|
|
1141
1261
|
> Plurimath::Math.parse('2121221.3434', :latex).to_latex(formatter: formatter)
|
|
1142
1262
|
# => '2,12,12,21;34'
|
|
@@ -1160,7 +1280,7 @@ The custom formatter is to be subclassed from `Plurimath::Formatter::Standard`.
|
|
|
1160
1280
|
[source,ruby]
|
|
1161
1281
|
----
|
|
1162
1282
|
class MyCustomFormatter < Plurimath::Formatter::Standard <1>
|
|
1163
|
-
def initialize(locale:, precision:, options:,
|
|
1283
|
+
def initialize(locale:, precision:, options:, string_format:) <2>
|
|
1164
1284
|
super
|
|
1165
1285
|
end
|
|
1166
1286
|
end
|
|
@@ -1175,7 +1295,7 @@ The default options of the custom formatter are set using the
|
|
|
1175
1295
|
[source,ruby]
|
|
1176
1296
|
----
|
|
1177
1297
|
class MyCustomFormatter < Plurimath::Formatter::Standard
|
|
1178
|
-
def initialize(locale:, precision:, options:,
|
|
1298
|
+
def initialize(locale:, precision:, options:, string_format:)
|
|
1179
1299
|
super
|
|
1180
1300
|
end
|
|
1181
1301
|
|
data/Rakefile
CHANGED
|
@@ -105,7 +105,18 @@ def write_intent_doc_file(file)
|
|
|
105
105
|
file.write("\nIntent for unary classes like, sin, cos, tan, etc. will be `Function`.\n")
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
+
def require_math_function_files
|
|
109
|
+
(
|
|
110
|
+
Dir.glob(File.join(__dir__, "lib/plurimath/math/function", "*.rb")) +
|
|
111
|
+
Dir.glob(File.join(__dir__, "lib/plurimath/math/function", "*", "*.rb"))
|
|
112
|
+
).each do |file|
|
|
113
|
+
require file
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
108
117
|
def intent_classes
|
|
118
|
+
require_math_function_files
|
|
119
|
+
|
|
109
120
|
intent_classes = [
|
|
110
121
|
Plurimath::Math::Function::TernaryFunction.descendants,
|
|
111
122
|
Plurimath::Math::Function::BinaryFunction.descendants,
|
data/lib/plurimath/asciimath.rb
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "math"
|
|
4
3
|
module Plurimath
|
|
5
4
|
class Asciimath
|
|
5
|
+
autoload :Constants, "#{__dir__}/asciimath/constants"
|
|
6
|
+
autoload :Parse, "#{__dir__}/asciimath/parse"
|
|
7
|
+
autoload :Parser, "#{__dir__}/asciimath/parser"
|
|
8
|
+
autoload :Transform, "#{__dir__}/asciimath/transform"
|
|
9
|
+
|
|
6
10
|
attr_accessor :text
|
|
7
11
|
|
|
8
12
|
def initialize(text)
|
data/lib/plurimath/cli.rb
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plurimath
|
|
4
|
+
module Formatter
|
|
5
|
+
class UnsupportedBase < StandardError
|
|
6
|
+
def initialize(base, supported_bases)
|
|
7
|
+
@base = base
|
|
8
|
+
@supported = supported_bases.keys.map { |key| key.to_s.inspect }.join(", ")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_s
|
|
12
|
+
<<~MESSAGE
|
|
13
|
+
[plurimath] Unsupported base `#{@base}` for number formatting.
|
|
14
|
+
[plurimath] The formatter `:base` option must be one of: #{@supported}.
|
|
15
|
+
MESSAGE
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plurimath
|
|
4
|
+
module Math
|
|
5
|
+
class InvalidTypeError < TypeError
|
|
6
|
+
def initialize(type = nil)
|
|
7
|
+
super(type ? formula_message(type) : parse_message)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def parse_message
|
|
11
|
+
"`type` must be one of: `#{Math::VALID_TYPES.keys.join('`, `')}`"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def formula_message(type)
|
|
15
|
+
"Invalid type provided: #{type}. Must be one of #{Formula::MATH_ZONE_TYPES.join(', ')}."
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plurimath
|
|
4
|
+
module Math
|
|
5
|
+
class ParseError < StandardError
|
|
6
|
+
def initialize(text, type)
|
|
7
|
+
@text = text
|
|
8
|
+
@type = type.to_sym
|
|
9
|
+
super(@type == :invalid_unitsml ? unitsml_message : parsing_message)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def parsing_message
|
|
13
|
+
<<~MESSAGE
|
|
14
|
+
[plurimath] Error: Failed to parse the following formula with type `#{@type}`.
|
|
15
|
+
[plurimath] Please first manually validate the formula.
|
|
16
|
+
#{generic_part}
|
|
17
|
+
---- FORMULA BEGIN ----
|
|
18
|
+
#{@text}
|
|
19
|
+
---- FORMULA END ----
|
|
20
|
+
MESSAGE
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def unitsml_message
|
|
24
|
+
<<~MESSAGE
|
|
25
|
+
[plurimath] Invalid formula `#{@text}`.
|
|
26
|
+
[plurimath] The use of a variable as an exponent is not valid.
|
|
27
|
+
#{generic_part}
|
|
28
|
+
MESSAGE
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def generic_part
|
|
32
|
+
<<~MESSAGE.rstrip
|
|
33
|
+
[plurimath] If this is a bug, please report the formula at our issue tracker at:
|
|
34
|
+
[plurimath] https://github.com/plurimath/plurimath/issues
|
|
35
|
+
MESSAGE
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
@@ -3,17 +3,33 @@
|
|
|
3
3
|
module Plurimath
|
|
4
4
|
module Formatter
|
|
5
5
|
class NumberFormatter
|
|
6
|
-
attr_reader :number, :data_reader
|
|
6
|
+
attr_reader :number, :data_reader
|
|
7
7
|
|
|
8
|
+
DEFAULT_BASE = Numbers::Base::DEFAULT_BASE
|
|
9
|
+
HEX_ALPHABETS = "abcdef".freeze
|
|
8
10
|
STRING_SYMBOLS = {
|
|
9
|
-
dot: "."
|
|
10
|
-
f: "F"
|
|
11
|
+
dot: ".",
|
|
12
|
+
f: "F",
|
|
13
|
+
}.freeze
|
|
14
|
+
DEFAULT_BASE_PREFIXES = {
|
|
15
|
+
2 => "0b",
|
|
16
|
+
8 => "0o",
|
|
17
|
+
10 => "",
|
|
18
|
+
16 => "0x",
|
|
11
19
|
}.freeze
|
|
12
20
|
|
|
13
21
|
def initialize(number, data_reader = {})
|
|
14
22
|
@number = number
|
|
15
23
|
@data_reader = data_reader
|
|
16
|
-
@
|
|
24
|
+
@base = data_reader[:base] || DEFAULT_BASE
|
|
25
|
+
raise UnsupportedBase.new(@base, DEFAULT_BASE_PREFIXES) unless DEFAULT_BASE_PREFIXES.key?(@base)
|
|
26
|
+
|
|
27
|
+
# Handle base_prefix: if explicitly provided (even as nil), use it; otherwise use default
|
|
28
|
+
@base_prefix = if data_reader.key?(:base_prefix)
|
|
29
|
+
data_reader[:base_prefix].to_s
|
|
30
|
+
else
|
|
31
|
+
DEFAULT_BASE_PREFIXES[@base]
|
|
32
|
+
end
|
|
17
33
|
end
|
|
18
34
|
|
|
19
35
|
def format(precision: nil)
|
|
@@ -22,16 +38,37 @@ module Plurimath
|
|
|
22
38
|
# FIX FOR:
|
|
23
39
|
# NotImplementedError: String#<< not supported. Mutable String methods are not supported in Opal.
|
|
24
40
|
result = []
|
|
25
|
-
result << integer_format.apply(int
|
|
26
|
-
result << fraction_format.apply(frac,
|
|
41
|
+
result << integer_format.apply(int)
|
|
42
|
+
result << fraction_format.apply(frac, result, integer_format) # use formatted int for correct fraction formatting
|
|
27
43
|
result = result.join
|
|
28
44
|
result = signif_format.apply(result, integer_format, fraction_format)
|
|
29
|
-
result =
|
|
30
|
-
|
|
45
|
+
result = result.tr(HEX_ALPHABETS, HEX_ALPHABETS.upcase) if upcase_hex?
|
|
46
|
+
result = pre_post_fixed(result) unless base_default?
|
|
47
|
+
"#{prefix_symbol}#{result}"
|
|
31
48
|
end
|
|
32
49
|
|
|
33
50
|
private
|
|
34
51
|
|
|
52
|
+
def upcase_hex?
|
|
53
|
+
@base == 16 && data_reader[:hex_capital]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def prefix_symbol
|
|
57
|
+
if number.negative?
|
|
58
|
+
"-"
|
|
59
|
+
elsif data_reader[:number_sign]&.to_sym == :plus
|
|
60
|
+
"+"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def pre_post_fixed(result)
|
|
65
|
+
if data_reader.key?(:base_postfix)
|
|
66
|
+
"#{result}#{data_reader[:base_postfix]}"
|
|
67
|
+
else
|
|
68
|
+
"#{@base_prefix}#{result}"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
35
72
|
def partition_tokens(number)
|
|
36
73
|
int, fraction = parse_number(number)
|
|
37
74
|
[
|
|
@@ -53,10 +90,11 @@ module Plurimath
|
|
|
53
90
|
def parse_number(number, options = data_reader)
|
|
54
91
|
precision = options[:precision] || precision_from(number)
|
|
55
92
|
|
|
93
|
+
abs = round_to(number, precision).abs
|
|
56
94
|
num = if precision == 0
|
|
57
|
-
|
|
95
|
+
abs.fix.to_s(STRING_SYMBOLS[:f])
|
|
58
96
|
else
|
|
59
|
-
|
|
97
|
+
abs.round(precision).to_s(STRING_SYMBOLS[:f])
|
|
60
98
|
end
|
|
61
99
|
num.split(STRING_SYMBOLS[:dot])
|
|
62
100
|
end
|
|
@@ -65,6 +103,10 @@ module Plurimath
|
|
|
65
103
|
factor = BigDecimal(10).power(precision)
|
|
66
104
|
(number * factor).fix / factor
|
|
67
105
|
end
|
|
106
|
+
|
|
107
|
+
def base_default?
|
|
108
|
+
@base == DEFAULT_BASE
|
|
109
|
+
end
|
|
68
110
|
end
|
|
69
111
|
end
|
|
70
112
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plurimath
|
|
4
|
+
module Formatter
|
|
5
|
+
module Numbers
|
|
6
|
+
class Base
|
|
7
|
+
HEX_ALPHANUMERIC = %w[0 1 2 3 4 5 6 7 8 9 a b c d e f].freeze
|
|
8
|
+
DEFAULT_BASE = 10
|
|
9
|
+
DIGIT_VALUE = HEX_ALPHANUMERIC.each_with_index.to_h
|
|
10
|
+
|
|
11
|
+
attr_accessor :base, :symbols
|
|
12
|
+
|
|
13
|
+
def initialize(symbols = {})
|
|
14
|
+
@symbols = symbols
|
|
15
|
+
@base = symbols[:base] || DEFAULT_BASE
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
protected
|
|
19
|
+
|
|
20
|
+
def threshold
|
|
21
|
+
@threshold ||= base.div(2)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def base_default?
|
|
25
|
+
base == DEFAULT_BASE
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def next_mapping_char(char)
|
|
29
|
+
current_idx = DIGIT_VALUE[char]
|
|
30
|
+
return nil unless current_idx
|
|
31
|
+
|
|
32
|
+
HEX_ALPHANUMERIC[current_idx + 1]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|