plurimath 0.8.16 → 0.8.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/gen_docs.yml +10 -8
- data/Gemfile +1 -1
- data/README.adoc +4 -0
- data/Rakefile +55 -8
- data/intent_supported_classes.adoc +82 -0
- data/lib/plurimath/asciimath/parse.rb +1 -0
- data/lib/plurimath/asciimath/transform.rb +12 -0
- data/lib/plurimath/formatter/number_formatter.rb +6 -6
- data/lib/plurimath/formatter/numeric_formatter.rb +5 -2
- data/lib/plurimath/formatter/standard.rb +2 -0
- data/lib/plurimath/math/core.rb +65 -6
- data/lib/plurimath/math/formula/mrow.rb +193 -0
- data/lib/plurimath/math/formula/mstyle.rb +17 -0
- data/lib/plurimath/math/formula.rb +317 -7
- data/lib/plurimath/math/function/abs.rb +5 -1
- data/lib/plurimath/math/function/base.rb +4 -0
- data/lib/plurimath/math/function/color.rb +17 -4
- data/lib/plurimath/math/function/fenced.rb +238 -7
- data/lib/plurimath/math/function/frac.rb +12 -1
- data/lib/plurimath/math/function/inf.rb +5 -1
- data/lib/plurimath/math/function/int.rb +5 -1
- data/lib/plurimath/math/function/intent.rb +6 -2
- data/lib/plurimath/math/function/lim.rb +5 -1
- data/lib/plurimath/math/function/linebreak.rb +2 -2
- data/lib/plurimath/math/function/longdiv.rb +3 -0
- data/lib/plurimath/math/function/menclose.rb +3 -0
- data/lib/plurimath/math/function/merror.rb +5 -2
- data/lib/plurimath/math/function/mglyph.rb +27 -0
- data/lib/plurimath/math/function/mlabeledtr.rb +19 -0
- data/lib/plurimath/math/function/mpadded.rb +28 -1
- data/lib/plurimath/math/function/ms.rb +80 -0
- data/lib/plurimath/math/function/msgroup.rb +15 -0
- data/lib/plurimath/math/function/msline.rb +5 -2
- data/lib/plurimath/math/function/multiscript.rb +14 -0
- data/lib/plurimath/math/function/nary.rb +13 -1
- data/lib/plurimath/math/function/oint.rb +5 -1
- data/lib/plurimath/math/function/over.rb +3 -0
- data/lib/plurimath/math/function/overset.rb +11 -0
- data/lib/plurimath/math/function/phantom.rb +3 -0
- data/lib/plurimath/math/function/power.rb +3 -0
- data/lib/plurimath/math/function/power_base.rb +3 -0
- data/lib/plurimath/math/function/prod.rb +5 -1
- data/lib/plurimath/math/function/root.rb +3 -0
- data/lib/plurimath/math/function/scarries.rb +3 -0
- data/lib/plurimath/math/function/semantics.rb +14 -0
- data/lib/plurimath/math/function/sqrt.rb +3 -0
- data/lib/plurimath/math/function/stackrel.rb +3 -0
- data/lib/plurimath/math/function/sum.rb +5 -1
- data/lib/plurimath/math/function/table/array.rb +1 -1
- data/lib/plurimath/math/function/table/bmatrix.rb +1 -1
- data/lib/plurimath/math/function/table/cases.rb +2 -2
- data/lib/plurimath/math/function/table/eqarray.rb +2 -2
- data/lib/plurimath/math/function/table/pmatrix.rb +1 -1
- data/lib/plurimath/math/function/table/vmatrix.rb +1 -1
- data/lib/plurimath/math/function/table.rb +65 -0
- data/lib/plurimath/math/function/td.rb +4 -1
- data/lib/plurimath/math/function/text.rb +22 -2
- data/lib/plurimath/math/function/tr.rb +13 -0
- data/lib/plurimath/math/function/unary_function.rb +5 -1
- data/lib/plurimath/math/function/underover.rb +3 -0
- data/lib/plurimath/math/function/underset.rb +44 -0
- data/lib/plurimath/math/number.rb +10 -1
- data/lib/plurimath/math/symbols/bigwedge.rb +4 -0
- data/lib/plurimath/math/symbols/cap.rb +0 -4
- data/lib/plurimath/math/symbols/clockoint.rb +1 -1
- data/lib/plurimath/math/symbols/cntclockoint.rb +1 -1
- data/lib/plurimath/math/symbols/coprod.rb +1 -1
- data/lib/plurimath/math/symbols/dd.rb +4 -0
- data/lib/plurimath/math/symbols/dint.rb +4 -0
- data/lib/plurimath/math/symbols/duni.rb +4 -0
- data/lib/plurimath/math/symbols/gg.rb +4 -4
- data/lib/plurimath/math/symbols/ii.rb +4 -0
- data/lib/plurimath/math/symbols/iiiint.rb +1 -1
- data/lib/plurimath/math/symbols/iiint.rb +4 -0
- data/lib/plurimath/math/symbols/iint.rb +1 -1
- data/lib/plurimath/math/symbols/intclockwise.rb +1 -1
- data/lib/plurimath/math/symbols/intercal.rb +4 -0
- data/lib/plurimath/math/symbols/jj.rb +4 -0
- data/lib/plurimath/math/symbols/ll.rb +4 -4
- data/lib/plurimath/math/symbols/minus.rb +1 -1
- data/lib/plurimath/math/symbols/oiiint.rb +1 -1
- data/lib/plurimath/math/symbols/oiint.rb +1 -1
- data/lib/plurimath/math/symbols/oint.rb +1 -1
- data/lib/plurimath/math/symbols/symbol.rb +12 -4
- data/lib/plurimath/math/symbols/upcase_dd.rb +4 -0
- data/lib/plurimath/math.rb +2 -0
- data/lib/plurimath/mathml/parser.rb +45 -86
- data/lib/plurimath/mathml/utility/empty_defined_methods.rb +477 -0
- data/lib/plurimath/mathml/utility/formula_transformation.rb +472 -0
- data/lib/plurimath/mathml/utility.rb +363 -0
- data/lib/plurimath/mathml.rb +1 -0
- data/lib/plurimath/unicode_math/transform.rb +2 -2
- data/lib/plurimath/utility/intent_encoding.rb +21 -21
- data/lib/plurimath/utility.rb +5 -23
- data/lib/plurimath/version.rb +1 -1
- data/lib/plurimath.rb +9 -0
- data/plurimath.gemspec +4 -2
- metadata +38 -5
- data/lib/plurimath/mathml/transform.rb +0 -411
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 766097c1faa26dc82f8664fca18a302b52920df2fce4ec8395cf2f65d8a7d687
|
4
|
+
data.tar.gz: 35cf1a6b6a0e87fa5404b3eea87927cd69da535deeebfcd49f8db5ce1aaba8e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7307ab95dc0d60e6fe65c939665e08ec59902527a454427956ee17e6d2c7bc207921e529ae107d51ec0f2a2a0909cd7da260943d277a03755efc34aa01edd2d0
|
7
|
+
data.tar.gz: 6f050eb9cae6730e911ccae66afe0a4384ab0fade68810fa4fa176e15d5f37eef225f0b11c1409fcd10ed05e75cbf7aa6fdd10a4e18d85ab335dbb947c22d350
|
@@ -9,6 +9,13 @@ on:
|
|
9
9
|
jobs:
|
10
10
|
generate_docs:
|
11
11
|
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
filename:
|
15
|
+
- supported_parens_list.adoc
|
16
|
+
- supported_symbols_list.adoc
|
17
|
+
- intent_supported_classes.adoc
|
18
|
+
|
12
19
|
steps:
|
13
20
|
- uses: actions/checkout@v4
|
14
21
|
|
@@ -17,12 +24,7 @@ jobs:
|
|
17
24
|
ruby-version: '3.3'
|
18
25
|
bundler-cache: true
|
19
26
|
|
20
|
-
- name: Generate
|
21
|
-
run: |
|
22
|
-
rm -f supported_parens_list.adoc
|
23
|
-
bundle exec rake supported_parens_list.adoc
|
24
|
-
|
25
|
-
- name: Generate supported_symbols_list.adoc
|
27
|
+
- name: Generate documentation
|
26
28
|
run: |
|
27
|
-
rm -f
|
28
|
-
bundle exec rake
|
29
|
+
rm -f ${{ matrix.filename }}
|
30
|
+
bundle exec rake ${{ matrix.filename }}
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
@@ -583,6 +583,10 @@ Consult the following tables for details on supported symbols and parentheses:
|
|
583
583
|
* link:supported_symbols_list.adoc[Symbols]
|
584
584
|
* link:supported_parens_list.adoc[Parentheses]
|
585
585
|
|
586
|
+
The following table shows the classes that support MathML "intent" encoding:
|
587
|
+
|
588
|
+
* link:intent_supported_classes.adoc[Classes that support MathML Intent]
|
589
|
+
|
586
590
|
NOTE: To regenerate these files, delete them and run:
|
587
591
|
`bundle exec rake supported_symbols_list.adoc`.
|
588
592
|
|
data/Rakefile
CHANGED
@@ -18,6 +18,7 @@ end
|
|
18
18
|
DOC_FILES = {
|
19
19
|
"supported_parens_list.adoc" => :paren,
|
20
20
|
"supported_symbols_list.adoc" => :symbols,
|
21
|
+
"intent_supported_classes.adoc" => :intent,
|
21
22
|
}.freeze
|
22
23
|
|
23
24
|
DOC_FILES.each do |file_name, type|
|
@@ -28,17 +29,26 @@ end
|
|
28
29
|
|
29
30
|
def write_doc_file(doc_file, type:)
|
30
31
|
File.open(doc_file, "a") do |file|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
file_name = File.basename(klass.const_source_location(:INPUT).first, ".rb")
|
37
|
-
file.write(documentation_content(file_name, klass))
|
32
|
+
case type
|
33
|
+
when :intent
|
34
|
+
write_intent_doc_file(file)
|
35
|
+
else
|
36
|
+
paren_symbols_doc(file, type)
|
38
37
|
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def paren_symbols_doc(file, type)
|
42
|
+
file.write(file_header)
|
39
43
|
|
40
|
-
|
44
|
+
Plurimath::Utility.send(:"#{type}_files").each do |klass|
|
45
|
+
next if klass::INPUT.empty?
|
46
|
+
|
47
|
+
file_name = File.basename(klass.const_source_location(:INPUT).first, ".rb")
|
48
|
+
file.write(documentation_content(file_name, klass))
|
41
49
|
end
|
50
|
+
|
51
|
+
file.write("|===")
|
42
52
|
end
|
43
53
|
|
44
54
|
def documentation_content(file_name, klass)
|
@@ -75,4 +85,41 @@ def format_input(format, klass)
|
|
75
85
|
end.join(", ").gsub(/\|/, "\\|")
|
76
86
|
end
|
77
87
|
|
88
|
+
def write_intent_doc_file(file)
|
89
|
+
file.write("= List of classes supporting `intent` encoding with relevant values\n")
|
90
|
+
|
91
|
+
intent_classes.each do |klass|
|
92
|
+
intents = klass.new.intent_names.values.map do |intent|
|
93
|
+
"`#{intent}`"
|
94
|
+
end
|
95
|
+
|
96
|
+
file.write(
|
97
|
+
<<~INTENT
|
98
|
+
|
99
|
+
* `#{klass.name.gsub("Plurimath::Math::", "")}`
|
100
|
+
** #{intents.join("\n** ")}
|
101
|
+
INTENT
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
file.write("\nIntent for unary classes like, sin, cos, tan, etc. will be `Function`.\n")
|
106
|
+
end
|
107
|
+
|
108
|
+
def intent_classes
|
109
|
+
intent_classes = [
|
110
|
+
Plurimath::Math::Function::TernaryFunction.descendants,
|
111
|
+
Plurimath::Math::Function::BinaryFunction.descendants,
|
112
|
+
Plurimath::Math::Function::UnaryFunction.descendants,
|
113
|
+
Plurimath::Math::Function::Table.descendants,
|
114
|
+
Plurimath::Math::Symbols::Symbol.descendants,
|
115
|
+
Plurimath::Math::Function::UnaryFunction,
|
116
|
+
Plurimath::Math::Function::Table,
|
117
|
+
Plurimath::Math::Function::Nary,
|
118
|
+
Plurimath::Math::Formula,
|
119
|
+
].flatten
|
120
|
+
intent_classes.select do |klass|
|
121
|
+
klass.instance_methods(false).include?(:intent_names)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
78
125
|
task :default => :spec
|
@@ -0,0 +1,82 @@
|
|
1
|
+
= List of classes supporting `intent` encoding with relevant values
|
2
|
+
|
3
|
+
* `Function::Fenced`
|
4
|
+
** `open-closed-interval`
|
5
|
+
** `closed-open-interval`
|
6
|
+
** `binomial-coefficient`
|
7
|
+
** `closed-interval`
|
8
|
+
** `open-interval`
|
9
|
+
** `:fenced`
|
10
|
+
|
11
|
+
* `Function::Int`
|
12
|
+
** `:integral`
|
13
|
+
|
14
|
+
* `Function::Oint`
|
15
|
+
** `:contour integral`
|
16
|
+
|
17
|
+
* `Function::Prod`
|
18
|
+
** `:product`
|
19
|
+
|
20
|
+
* `Function::Sum`
|
21
|
+
** `:sum`
|
22
|
+
|
23
|
+
* `Function::Frac`
|
24
|
+
** `:derivative`
|
25
|
+
** `:partial-derivative`
|
26
|
+
|
27
|
+
* `Function::Inf`
|
28
|
+
** `:function`
|
29
|
+
|
30
|
+
* `Function::Intent`
|
31
|
+
** `:derivative`
|
32
|
+
|
33
|
+
* `Function::Lim`
|
34
|
+
** `:function`
|
35
|
+
|
36
|
+
* `Function::Abs`
|
37
|
+
** `absolute-value`
|
38
|
+
|
39
|
+
* `Symbols::Dd`
|
40
|
+
** `ⅆ`
|
41
|
+
|
42
|
+
* `Symbols::Ii`
|
43
|
+
** `ⅈ`
|
44
|
+
|
45
|
+
* `Symbols::Intercal`
|
46
|
+
** `transpose`
|
47
|
+
|
48
|
+
* `Symbols::Jj`
|
49
|
+
** `ⅉ`
|
50
|
+
|
51
|
+
* `Symbols::UpcaseDd`
|
52
|
+
** `ⅅ`
|
53
|
+
|
54
|
+
* `Function::UnaryFunction`
|
55
|
+
** `:function`
|
56
|
+
|
57
|
+
* `Function::Table`
|
58
|
+
** `:curly-braced-matrix`
|
59
|
+
** `:parenthesized-matrix`
|
60
|
+
** `:bracketed-matrix`
|
61
|
+
** `:normed-matrix`
|
62
|
+
** `:determinant`
|
63
|
+
** `:equations`
|
64
|
+
** `:cases`
|
65
|
+
|
66
|
+
* `Function::Nary`
|
67
|
+
** `:n-ary`
|
68
|
+
** `:anticlockwise contour integral`
|
69
|
+
** `:coproduct`
|
70
|
+
** `:quadruple integral`
|
71
|
+
** `:triple integral`
|
72
|
+
** `:double integral`
|
73
|
+
** `:clockwise contour integral`
|
74
|
+
** `:volume integral`
|
75
|
+
** `:surface integral`
|
76
|
+
** `:contour integral`
|
77
|
+
|
78
|
+
* `Formula`
|
79
|
+
** `:partial-derivative`
|
80
|
+
** `:derivative`
|
81
|
+
|
82
|
+
Intent for unary classes like, sin, cos, tan, etc. will be `Function`.
|
@@ -158,6 +158,7 @@ module Plurimath
|
|
158
158
|
str("") |
|
159
159
|
(rparen.as(:rparen) >> space? >> controversial_symbols >> comma.as(:comma).maybe >> expression).repeat(1).as(:expr) |
|
160
160
|
(power.as(:symbol) >> space? >> expression).as(:expr) |
|
161
|
+
table.as(:table) >> space? >> rparen.as(:rparen) >> space? >> expression.as(:expr).maybe |
|
161
162
|
comma.as(:comma).maybe
|
162
163
|
end
|
163
164
|
|
@@ -900,6 +900,18 @@ module Plurimath
|
|
900
900
|
Math::Formula.new(formula_array)
|
901
901
|
end
|
902
902
|
|
903
|
+
rule(table: simple(:table),
|
904
|
+
rparen: simple(:rparen),
|
905
|
+
expr: sequence(:expr)) do
|
906
|
+
[
|
907
|
+
Math::Function::Fenced.new(
|
908
|
+
Math::Symbols::Paren::OpenParen.new,
|
909
|
+
[table],
|
910
|
+
Utility.asciimath_symbol_object(rparen),
|
911
|
+
),
|
912
|
+
] + expr.flatten.compact
|
913
|
+
end
|
914
|
+
|
903
915
|
rule(left: simple(:left),
|
904
916
|
left_right_value: simple(:left_right),
|
905
917
|
right: simple(:right)) do
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Plurimath
|
4
4
|
module Formatter
|
5
5
|
class NumberFormatter
|
6
|
-
attr_reader :number, :data_reader
|
6
|
+
attr_reader :number, :data_reader, :prefix
|
7
7
|
|
8
8
|
STRING_SYMBOLS = {
|
9
9
|
dot: ".".freeze,
|
@@ -13,6 +13,7 @@ module Plurimath
|
|
13
13
|
def initialize(number, data_reader = {})
|
14
14
|
@number = number
|
15
15
|
@data_reader = data_reader
|
16
|
+
@prefix = "-" if number.negative?
|
16
17
|
end
|
17
18
|
|
18
19
|
def format(precision: nil)
|
@@ -20,16 +21,15 @@ module Plurimath
|
|
20
21
|
int, frac, integer_format, fraction_format, signif_format = *partition_tokens(number)
|
21
22
|
result = integer_format.apply(int, data_reader)
|
22
23
|
result << fraction_format.apply(frac, data_reader, int) if frac
|
23
|
-
|
24
24
|
result = signif_format.apply(result, integer_format, fraction_format)
|
25
|
-
|
26
|
-
result
|
25
|
+
result = "+#{result}" if number.positive? && data_reader[:number_sign] == :plus
|
26
|
+
"#{prefix}#{result}"
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def partition_tokens(number)
|
32
|
-
int, fraction = parse_number(number
|
32
|
+
int, fraction = parse_number(number)
|
33
33
|
[
|
34
34
|
int,
|
35
35
|
fraction,
|
@@ -46,7 +46,7 @@ module Plurimath
|
|
46
46
|
parts.size == 2 ? parts[1].size : 0
|
47
47
|
end
|
48
48
|
|
49
|
-
def parse_number(number, options =
|
49
|
+
def parse_number(number, options = data_reader)
|
50
50
|
precision = options[:precision] || precision_from(number)
|
51
51
|
|
52
52
|
num = if precision == 0
|
@@ -72,7 +72,9 @@ module Plurimath
|
|
72
72
|
|
73
73
|
def update_exponent_value(number_str)
|
74
74
|
exponent_number = BigDecimal(number_str) - 1
|
75
|
-
|
75
|
+
return exponent_number.to_i if exponent_number.negative? || @exponent_sign != :plus
|
76
|
+
|
77
|
+
"+#{exponent_number.to_i}"
|
76
78
|
end
|
77
79
|
|
78
80
|
def notation_chars(num_str)
|
@@ -112,7 +114,8 @@ module Plurimath
|
|
112
114
|
|
113
115
|
chars.first.delete!(".")
|
114
116
|
chars.first.insert(index + 1, ".") unless chars.first[index + 2].nil?
|
115
|
-
|
117
|
+
exponent = chars[-1]
|
118
|
+
chars[-1] = "#{"+" if exponent.to_s.start_with?("+")}#{exponent.to_i - index}"
|
116
119
|
end
|
117
120
|
end
|
118
121
|
end
|
@@ -10,6 +10,7 @@ module Plurimath
|
|
10
10
|
fraction_group_digits: 3,
|
11
11
|
exponent_sign: "plus",
|
12
12
|
fraction_group: "'",
|
13
|
+
number_sign: "plus",
|
13
14
|
notation: :basic,
|
14
15
|
group_digits: 3,
|
15
16
|
significant: 0,
|
@@ -38,6 +39,7 @@ module Plurimath
|
|
38
39
|
options[:fraction_group] ||= default_options[:fraction_group]
|
39
40
|
options[:exponent_sign] ||= default_options[:exponent_sign]
|
40
41
|
options[:group_digits] ||= default_options[:group_digits]
|
42
|
+
options[:number_sign] ||= default_options[:number_sign]
|
41
43
|
options[:significant] ||= default_options[:significant]
|
42
44
|
options[:notation] ||= default_options[:notation]
|
43
45
|
options[:decimal] ||= default_options[:decimal]
|
data/lib/plurimath/math/core.rb
CHANGED
@@ -8,6 +8,13 @@ module Plurimath
|
|
8
8
|
/^\n/ => "",
|
9
9
|
}.freeze
|
10
10
|
|
11
|
+
ALL_PARAMETERS = %i[
|
12
|
+
parameter_one
|
13
|
+
parameter_two
|
14
|
+
parameter_three
|
15
|
+
parameter_four
|
16
|
+
].freeze
|
17
|
+
|
11
18
|
def self.inherited(subclass)
|
12
19
|
@descendants ||= []
|
13
20
|
@descendants << subclass
|
@@ -201,7 +208,7 @@ module Plurimath
|
|
201
208
|
false
|
202
209
|
end
|
203
210
|
|
204
|
-
def linebreak
|
211
|
+
def linebreak?
|
205
212
|
false
|
206
213
|
end
|
207
214
|
|
@@ -291,11 +298,15 @@ module Plurimath
|
|
291
298
|
is_a?(Math::Function::UnaryFunction)
|
292
299
|
end
|
293
300
|
|
294
|
-
def is_nary_function?;end
|
301
|
+
def is_nary_function?; end
|
302
|
+
|
303
|
+
def is_nary_symbol?; end
|
295
304
|
|
296
|
-
def
|
305
|
+
def nary_intent_name; end
|
297
306
|
|
298
|
-
def
|
307
|
+
def symbol?
|
308
|
+
is_a?(Math::Symbols::Symbol)
|
309
|
+
end
|
299
310
|
|
300
311
|
def is_binary_function?
|
301
312
|
is_a?(Function::BinaryFunction)
|
@@ -323,8 +334,56 @@ module Plurimath
|
|
323
334
|
Utility.primes_constants.any? { |prefix, prime| unicodemath_field_value(field).include?(prime) }
|
324
335
|
end
|
325
336
|
|
337
|
+
def paren?
|
338
|
+
false
|
339
|
+
end
|
340
|
+
|
341
|
+
def pretty_print_instance_variables
|
342
|
+
excluded_vars = [
|
343
|
+
:@left_right_wrapper,
|
344
|
+
:@temp_mathml_order,
|
345
|
+
:@using_default,
|
346
|
+
:@displaystyle,
|
347
|
+
:@__ordered,
|
348
|
+
:@__mixed,
|
349
|
+
:@is_mrow,
|
350
|
+
:@values,
|
351
|
+
]
|
352
|
+
instance_variables.sort - excluded_vars
|
353
|
+
end
|
354
|
+
|
355
|
+
def to_ms_value
|
356
|
+
new_arr = []
|
357
|
+
case self
|
358
|
+
when Math::Symbols::Symbol
|
359
|
+
new_arr << (value ? value.to_s : to_unicodemath(options: {}))
|
360
|
+
when Math::Number, Math::Function::Text
|
361
|
+
new_arr << value
|
362
|
+
else
|
363
|
+
parameters_to_ms_value(new_arr)
|
364
|
+
if respond_to?(:value) && value.is_a?(Array)
|
365
|
+
new_arr << value&.map { |element| element.to_ms_value }.join(" ")
|
366
|
+
end
|
367
|
+
end
|
368
|
+
new_arr
|
369
|
+
end
|
370
|
+
|
371
|
+
def is_mstyle?
|
372
|
+
false
|
373
|
+
end
|
374
|
+
|
375
|
+
def is_mrow?
|
376
|
+
false
|
377
|
+
end
|
378
|
+
|
326
379
|
private
|
327
380
|
|
381
|
+
def parameters_to_ms_value(array)
|
382
|
+
ALL_PARAMETERS.each do |field|
|
383
|
+
array << get("@#{field}")&.to_ms_value if respond_to?(field)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
328
387
|
def array_line_break_field(field, variable, obj)
|
329
388
|
if result(field).length > 1
|
330
389
|
updated_object_values(variable, obj: obj)
|
@@ -344,10 +403,10 @@ module Plurimath
|
|
344
403
|
ox_element("mrow") << xml_engine_node
|
345
404
|
end
|
346
405
|
|
347
|
-
def intentify(tag, intent, func_name:, intent_name: nil)
|
406
|
+
def intentify(tag, intent, func_name:, intent_name: nil, options: {})
|
348
407
|
return tag unless intent
|
349
408
|
|
350
|
-
Utility::IntentEncoding.send("#{func_name}_intent", tag, intent_name)
|
409
|
+
Utility::IntentEncoding.send("#{func_name}_intent", tag, intent_name, options)
|
351
410
|
end
|
352
411
|
|
353
412
|
def masked_tag(tag)
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plurimath
|
4
|
+
module Math
|
5
|
+
class Formula
|
6
|
+
class Mrow < Formula
|
7
|
+
attr_accessor :is_mrow
|
8
|
+
|
9
|
+
def initialize(
|
10
|
+
value = [],
|
11
|
+
left_right_wrapper = true,
|
12
|
+
display_style: true,
|
13
|
+
input_string: nil,
|
14
|
+
unitsml: false
|
15
|
+
)
|
16
|
+
super
|
17
|
+
@is_mrow = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def element_order=(value)
|
21
|
+
@value = validated_order(value, rejectable_array: ["comment"])
|
22
|
+
end
|
23
|
+
|
24
|
+
def content; end
|
25
|
+
|
26
|
+
def content=(value)
|
27
|
+
arr_value = Array(value)
|
28
|
+
if no_content_in?(arr_value)
|
29
|
+
delete_all_text
|
30
|
+
else
|
31
|
+
validate_text_order(
|
32
|
+
arr_value.map { |val| validate_symbols(val) unless val.strip.empty? }
|
33
|
+
)
|
34
|
+
end
|
35
|
+
organize_value
|
36
|
+
end
|
37
|
+
|
38
|
+
def is_mrow?
|
39
|
+
@is_mrow
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def organize_value
|
45
|
+
return if value.any?(String)
|
46
|
+
return unless is_mrow
|
47
|
+
|
48
|
+
value.each_with_index do |element, index|
|
49
|
+
update_current_element(element, value, index)
|
50
|
+
if value[index + 1].is_a?(Math::Function::Mod)
|
51
|
+
update_mod_function(value, index)
|
52
|
+
elsif unary_function_updatable?(value, element, index)
|
53
|
+
unary_function_update(value, index)
|
54
|
+
elsif value.first.paren? && value.last.paren?
|
55
|
+
organize_fencing(value)
|
56
|
+
elsif valid_underset_function?(element)
|
57
|
+
value[index] = new_nary_element(element, value)
|
58
|
+
elsif valid_underover_function?(element)
|
59
|
+
replace_with_nary_function(element, value, index)
|
60
|
+
elsif ternary_function_third_value_present?(element)
|
61
|
+
element.parameter_three = value.delete_at(index + 1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def update_current_element(element, value, index)
|
67
|
+
if first_and_last_values_nil?(value)
|
68
|
+
replace_symbols_with_parens(value)
|
69
|
+
elsif element.class_name == "symbol" && element.value.nil?
|
70
|
+
element.value = ""
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def validate_text_order(value)
|
75
|
+
@value.each_with_index do |item, index|
|
76
|
+
next unless item == "text"
|
77
|
+
|
78
|
+
if value.first
|
79
|
+
@value[index] = value.shift
|
80
|
+
else
|
81
|
+
value.shift
|
82
|
+
@value.delete_at(index)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete_all_text
|
88
|
+
@value.delete("text")
|
89
|
+
end
|
90
|
+
|
91
|
+
def no_content_in?(value)
|
92
|
+
value.nil? || value.empty? || value&.all? { |val| val.strip.empty? }
|
93
|
+
end
|
94
|
+
|
95
|
+
def first_and_last_values_nil?(value)
|
96
|
+
value.first.class_name == "symbol" &&
|
97
|
+
value.first.value.nil? &&
|
98
|
+
value.last.class_name == "symbol" &&
|
99
|
+
value.last.value.nil?
|
100
|
+
end
|
101
|
+
|
102
|
+
def replace_symbols_with_parens(value)
|
103
|
+
value[0] = Math::Symbols::Paren::OpenParen.new
|
104
|
+
value[-1] = Math::Symbols::Paren::CloseParen.new
|
105
|
+
end
|
106
|
+
|
107
|
+
def nary_function_or_symbol?(element)
|
108
|
+
element.is_nary_function? || element.is_nary_symbol?
|
109
|
+
end
|
110
|
+
|
111
|
+
def valid_underover_function?(element)
|
112
|
+
element.is_a?(Math::Function::Underover) &&
|
113
|
+
nary_function_or_symbol?(element.parameter_one)
|
114
|
+
end
|
115
|
+
|
116
|
+
def valid_underset_function?(element)
|
117
|
+
element.is_a?(Math::Function::Underset) &&
|
118
|
+
nary_function_or_symbol?(element.parameter_two)
|
119
|
+
end
|
120
|
+
|
121
|
+
def unary_function_updatable?(value, element, index)
|
122
|
+
value.length > 1 &&
|
123
|
+
element.is_unary? &&
|
124
|
+
value[index + 1] &&
|
125
|
+
Plurimath::Utility::UNARY_CLASSES.include?(element.class_name)
|
126
|
+
end
|
127
|
+
|
128
|
+
def ternary_function_third_value_present?(element)
|
129
|
+
element.is_ternary_function? &&
|
130
|
+
element.any_value_exist? &&
|
131
|
+
element.parameter_three.nil?
|
132
|
+
end
|
133
|
+
|
134
|
+
def update_mod_function(value, index)
|
135
|
+
mod_obj = value[index + 1]
|
136
|
+
mod_obj.parameter_one = filter_values(
|
137
|
+
value.delete_at(index),
|
138
|
+
array_to_instance: true
|
139
|
+
)
|
140
|
+
mod_obj.parameter_two = filter_values(
|
141
|
+
value.delete_at(index + 1),
|
142
|
+
array_to_instance: true
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
def unary_function_update(value, index)
|
147
|
+
element = value.delete_at(index)
|
148
|
+
element.parameter_one = filter_values(
|
149
|
+
value.delete_at(index),
|
150
|
+
array_to_instance: true
|
151
|
+
)
|
152
|
+
value.insert(index, element)
|
153
|
+
end
|
154
|
+
|
155
|
+
def organize_fencing(value)
|
156
|
+
if value[1].is_a?(Math::Function::Table) && value.length == 3
|
157
|
+
table = value[1]
|
158
|
+
table.open_paren = value.shift
|
159
|
+
table.close_paren = value.pop
|
160
|
+
else
|
161
|
+
@value = [
|
162
|
+
Function::Fenced.new(value.shift, value, value.pop)
|
163
|
+
]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def new_nary_element(element, value)
|
168
|
+
value.shift
|
169
|
+
nary = Plurimath::Math::Function::Nary.new(
|
170
|
+
element.parameter_two,
|
171
|
+
element.parameter_one,
|
172
|
+
nil,
|
173
|
+
filter_values(value.shift(value.length), array_to_instance: true),
|
174
|
+
{ type: "undOvr" }
|
175
|
+
)
|
176
|
+
nary
|
177
|
+
end
|
178
|
+
|
179
|
+
def replace_with_nary_function(element, value, index)
|
180
|
+
fourth_value = value.delete_at(index + 1)
|
181
|
+
organize_value(fourth_value) if fourth_value.is_mrow?
|
182
|
+
value[index] = Math::Function::Nary.new(
|
183
|
+
element.parameter_one,
|
184
|
+
element.parameter_two,
|
185
|
+
element.parameter_three,
|
186
|
+
filter_values(fourth_value, array_to_instance: true),
|
187
|
+
{ type: "undOvr" }
|
188
|
+
)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plurimath
|
4
|
+
module Math
|
5
|
+
class Formula
|
6
|
+
class Mstyle < Formula
|
7
|
+
def displaystyle=(value)
|
8
|
+
@displaystyle = boolean_display_style(value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_mstyle?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|