plurimath 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/plurimath/latex/constants.rb +1 -0
- data/lib/plurimath/latex/parse.rb +11 -3
- data/lib/plurimath/latex/transform.rb +93 -7
- data/lib/plurimath/math/function/bar.rb +13 -6
- data/lib/plurimath/math/function/binary_function.rb +4 -0
- data/lib/plurimath/math/function/ddot.rb +7 -0
- data/lib/plurimath/math/function/dot.rb +13 -6
- data/lib/plurimath/math/function/fenced.rb +4 -6
- data/lib/plurimath/math/function/font_style.rb +4 -0
- data/lib/plurimath/math/function/hat.rb +12 -5
- data/lib/plurimath/math/function/obrace.rb +12 -5
- data/lib/plurimath/math/function/ternary_function.rb +6 -6
- data/lib/plurimath/math/function/text.rb +1 -1
- data/lib/plurimath/math/function/tilde.rb +12 -5
- data/lib/plurimath/math/function/ubrace.rb +11 -4
- data/lib/plurimath/math/function/ul.rb +13 -6
- data/lib/plurimath/math/function/unary_function.rb +6 -3
- data/lib/plurimath/math/function/vec.rb +12 -5
- data/lib/plurimath/mathml/parser.rb +14 -10
- data/lib/plurimath/mathml/transform.rb +38 -39
- data/lib/plurimath/omml/transform.rb +18 -10
- data/lib/plurimath/utility.rb +53 -13
- data/lib/plurimath/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ec251305cefca33f4a6d66180a797595d43ef370d55f7b67bdeac63b37e3111
|
4
|
+
data.tar.gz: 2c041edf5748e938813a20e0d397080d2f8cedcf96b19e9e39e98edae6b47ef8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37065161c1a09768bbec28f0d98e5438be18a5a0affa9e6024f7027ad002324c1e66e63c22f921f43fd32fa2bf1b723ace3f08b99464a8af3b7e6d265e092df6
|
7
|
+
data.tar.gz: 596e9cb2ce7f7d41ab8f93b4c0f330ffcdfec6adba518b49086dc4792c12f7eafed799ee087ea2ea82a3753389c179fab8883445c1b804a52fe779314941280c
|
@@ -95,11 +95,18 @@ module Plurimath
|
|
95
95
|
end
|
96
96
|
|
97
97
|
rule(:intermediate_exp) do
|
98
|
-
(lparen.as(:left_paren) >> expression.maybe.as(:expression) >> rparen.as(:right_paren)).as(:intermediate_exp) |
|
98
|
+
(lparen.as(:left_paren) >> expression.maybe.as(:expression) >> (rparen | (str("\\") >> (match("\s") >> str(".")).maybe).as(:rparen)).maybe.as(:right_paren)).as(:intermediate_exp) |
|
99
99
|
(str("{") >> expression.maybe.as(:expression) >> str("}")) |
|
100
100
|
symbol_text_or_integer
|
101
101
|
end
|
102
102
|
|
103
|
+
rule(:parsing_text_values) do
|
104
|
+
(str("{") >> parsing_text_values >> str("}")) >> parsing_text_values |
|
105
|
+
(str("{") >> parsing_text_values >> str("}")) |
|
106
|
+
(match("[^}]") >> parsing_text_values) |
|
107
|
+
match("[^}]").repeat
|
108
|
+
end
|
109
|
+
|
103
110
|
rule(:power_base) do
|
104
111
|
(subscript >> power >> intermediate_exp.as(:supscript)).as(:power_base) |
|
105
112
|
(supscript >> base >> intermediate_exp.as(:subscript)).as(:power_base) |
|
@@ -130,7 +137,8 @@ module Plurimath
|
|
130
137
|
(begining >> expression.as(:table_data) >> ending).as(:environment) |
|
131
138
|
(slash >> environment >> intermediate_exp).as(:table_data) |
|
132
139
|
power_base |
|
133
|
-
intermediate_exp
|
140
|
+
intermediate_exp |
|
141
|
+
intermediate_exp.as(:intermediate_exp) >> rparen.as(:symbol)
|
134
142
|
end
|
135
143
|
|
136
144
|
rule(:left_right) do
|
@@ -204,7 +212,7 @@ module Plurimath
|
|
204
212
|
when :binary
|
205
213
|
(slashed_value(first_value, :binary) >> intermediate_exp.as(:first_value) >> intermediate_exp.as(:second_value)).as(:binary)
|
206
214
|
when :text
|
207
|
-
(slashed_value(first_value, :text) >> (str("{") >>
|
215
|
+
(slashed_value(first_value, :text) >> (str("{") >> parsing_text_values.as(:first_value) >> str("}")))
|
208
216
|
when :ternary
|
209
217
|
(slashed_value(first_value, :ternary_functions) >> dynamic_power_base >> sequence.as(:third_value).maybe).as(:ternary_class) |
|
210
218
|
slashed_value(first_value, :ternary)
|
@@ -45,13 +45,9 @@ module Plurimath
|
|
45
45
|
end
|
46
46
|
|
47
47
|
rule(symbols: simple(:sym)) do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
)
|
52
|
-
else
|
53
|
-
sym
|
54
|
-
end
|
48
|
+
Math::Symbol.new(
|
49
|
+
Constants::UNICODE_SYMBOLS[sym.to_sym] || sym,
|
50
|
+
)
|
55
51
|
end
|
56
52
|
|
57
53
|
rule(lparen: simple(:lparen),
|
@@ -404,6 +400,16 @@ module Plurimath
|
|
404
400
|
)
|
405
401
|
end
|
406
402
|
|
403
|
+
rule(number: simple(:number),
|
404
|
+
subscript: simple(:subscript),
|
405
|
+
supscript: simple(:supscript)) do
|
406
|
+
Math::Function::PowerBase.new(
|
407
|
+
Math::Number.new(number),
|
408
|
+
subscript,
|
409
|
+
supscript,
|
410
|
+
)
|
411
|
+
end
|
412
|
+
|
407
413
|
rule(symbols: simple(:sym),
|
408
414
|
subscript: simple(:subscript)) do
|
409
415
|
Math::Function::Base.new(
|
@@ -469,6 +475,47 @@ module Plurimath
|
|
469
475
|
Math::Function::Text.new(first_value)
|
470
476
|
end
|
471
477
|
|
478
|
+
rule(text: simple(:text),
|
479
|
+
first_value: sequence(:first_value)) do
|
480
|
+
Math::Function::Text.new(first_value.join)
|
481
|
+
end
|
482
|
+
|
483
|
+
rule(text: simple(:text),
|
484
|
+
first_value: simple(:first_value),
|
485
|
+
supscript: simple(:supscript),) do
|
486
|
+
Math::Function::Power.new(
|
487
|
+
Math::Function::Text.new(first_value),
|
488
|
+
supscript,
|
489
|
+
)
|
490
|
+
end
|
491
|
+
|
492
|
+
rule(text: simple(:text),
|
493
|
+
first_value: sequence(:first_value),
|
494
|
+
supscript: simple(:supscript),) do
|
495
|
+
Math::Function::Power.new(
|
496
|
+
Math::Function::Text.new(first_value.join),
|
497
|
+
supscript,
|
498
|
+
)
|
499
|
+
end
|
500
|
+
|
501
|
+
rule(text: simple(:text),
|
502
|
+
first_value: sequence(:first_value),
|
503
|
+
subscript: simple(:subscript),) do
|
504
|
+
Math::Function::Base.new(
|
505
|
+
Math::Function::Text.new(first_value.join),
|
506
|
+
subscript,
|
507
|
+
)
|
508
|
+
end
|
509
|
+
|
510
|
+
rule(text: simple(:text),
|
511
|
+
first_value: simple(:first_value),
|
512
|
+
subscript: simple(:subscript),) do
|
513
|
+
Math::Function::Base.new(
|
514
|
+
Math::Function::Text.new(first_value),
|
515
|
+
subscript,
|
516
|
+
)
|
517
|
+
end
|
518
|
+
|
472
519
|
rule(unary: simple(:unary),
|
473
520
|
first_value: simple(:first_value)) do
|
474
521
|
Utility.get_class(
|
@@ -521,6 +568,28 @@ module Plurimath
|
|
521
568
|
)
|
522
569
|
end
|
523
570
|
|
571
|
+
rule(fonts: simple(:fonts),
|
572
|
+
intermediate_exp: simple(:int_exp),
|
573
|
+
subscript: simple(:subscript),
|
574
|
+
supscript: simple(:supscript)) do
|
575
|
+
font_style = if Utility::FONT_STYLES[fonts.to_sym].nil?
|
576
|
+
Math::Function::FontStyle.new(
|
577
|
+
int_exp,
|
578
|
+
fonts.to_s,
|
579
|
+
)
|
580
|
+
else
|
581
|
+
Utility::FONT_STYLES[fonts.to_sym].new(
|
582
|
+
int_exp,
|
583
|
+
fonts.to_s,
|
584
|
+
)
|
585
|
+
end
|
586
|
+
Math::Function::PowerBase.new(
|
587
|
+
font_style,
|
588
|
+
subscript,
|
589
|
+
supscript,
|
590
|
+
)
|
591
|
+
end
|
592
|
+
|
524
593
|
rule(root: simple(:root),
|
525
594
|
first_value: simple(:first_value),
|
526
595
|
second_value: simple(:second_value)) do
|
@@ -626,6 +695,23 @@ module Plurimath
|
|
626
695
|
)
|
627
696
|
end
|
628
697
|
|
698
|
+
rule(binary: simple(:binary),
|
699
|
+
subscript: simple(:subscript),
|
700
|
+
supscript: simple(:supscript)) do
|
701
|
+
if binary.is_a?(Parslet::Slice)
|
702
|
+
Utility.get_class(binary).new(
|
703
|
+
subscript,
|
704
|
+
supscript,
|
705
|
+
)
|
706
|
+
else
|
707
|
+
Math::Function::PowerBase.new(
|
708
|
+
binary,
|
709
|
+
subscript,
|
710
|
+
subscript,
|
711
|
+
)
|
712
|
+
end
|
713
|
+
end
|
714
|
+
|
629
715
|
rule(binary: simple(:binary),
|
630
716
|
subscript: simple(:subscript)) do
|
631
717
|
if binary.is_a?(Parslet::Slice)
|
@@ -1,11 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Bar <
|
8
|
+
class Bar < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_asciimath
|
10
17
|
first_value = "(#{parameter_one.to_asciimath})" if parameter_one
|
11
18
|
"bar#{first_value}"
|
@@ -21,7 +28,7 @@ module Plurimath
|
|
21
28
|
return mo_tag unless parameter_one
|
22
29
|
|
23
30
|
mover_tag = Utility.ox_element("mover")
|
24
|
-
mover_tag.attributes.merge!(
|
31
|
+
mover_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
|
25
32
|
Utility.update_nodes(
|
26
33
|
mover_tag,
|
27
34
|
[
|
@@ -32,13 +39,13 @@ module Plurimath
|
|
32
39
|
end
|
33
40
|
|
34
41
|
def to_omml_without_math_tag(display_style)
|
35
|
-
return r_element("¯", rpr_tag: false) unless
|
42
|
+
return r_element("¯", rpr_tag: false) unless parameter_one
|
36
43
|
|
37
|
-
|
44
|
+
attributes && attributes[:accent] ? acc_tag(display_style) : bar_tag(display_style)
|
38
45
|
end
|
39
46
|
|
40
47
|
def swap_class
|
41
|
-
Ul.new(parameter_one,
|
48
|
+
Ul.new(parameter_one, attributes)
|
42
49
|
end
|
43
50
|
|
44
51
|
protected
|
@@ -6,6 +6,13 @@ module Plurimath
|
|
6
6
|
module Math
|
7
7
|
module Function
|
8
8
|
class Ddot < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_mathml_without_math_tag
|
10
17
|
second_value = Utility.ox_element("mo") << ".."
|
11
18
|
Utility.update_nodes(
|
@@ -1,19 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Dot <
|
8
|
+
class Dot < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_mathml_without_math_tag
|
10
17
|
dot_tag = (Utility.ox_element("mo") << ".")
|
11
|
-
return dot_tag unless
|
18
|
+
return dot_tag unless parameter_one
|
12
19
|
|
13
20
|
first_value = parameter_one&.to_mathml_without_math_tag
|
14
21
|
dot_tag = (Utility.ox_element("mo") << ".")
|
15
22
|
over_tag = Utility.ox_element("mover")
|
16
|
-
over_tag.attributes.merge!({ accent:
|
23
|
+
over_tag.attributes.merge!({ accent: attributes[:accent] }) if attributes && attributes[:accent]
|
17
24
|
Utility.update_nodes(
|
18
25
|
over_tag,
|
19
26
|
[
|
@@ -24,9 +31,9 @@ module Plurimath
|
|
24
31
|
end
|
25
32
|
|
26
33
|
def to_omml_without_math_tag(display_style)
|
27
|
-
return r_element(".", rpr_tag: false) unless
|
34
|
+
return r_element(".", rpr_tag: false) unless parameter_one
|
28
35
|
|
29
|
-
if
|
36
|
+
if attributes && attributes[:accent]
|
30
37
|
acc_tag(display_style)
|
31
38
|
else
|
32
39
|
symbol = Symbol.new(".")
|
@@ -30,11 +30,9 @@ module Plurimath
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def to_latex
|
33
|
-
open_paren = parameter_one ? parameter_one.value : "("
|
34
33
|
fenced_value = parameter_two&.map(&:to_latex)&.join(" ")
|
35
|
-
|
36
|
-
|
37
|
-
second_value = latex_paren(close_paren)
|
34
|
+
first_value = latex_paren(parameter_one&.value)
|
35
|
+
second_value = latex_paren(parameter_three&.value)
|
38
36
|
"#{first_value} #{fenced_value} #{second_value}"
|
39
37
|
end
|
40
38
|
|
@@ -88,8 +86,8 @@ module Plurimath
|
|
88
86
|
return "" if paren.nil? || paren.empty?
|
89
87
|
|
90
88
|
paren = %w[{ }].include?(paren) ? "\\#{paren}" : paren
|
91
|
-
paren = "\\#{Latex::Constants::UNICODE_SYMBOLS.invert[paren]}" if paren
|
92
|
-
paren
|
89
|
+
paren = "\\#{Latex::Constants::UNICODE_SYMBOLS.invert[paren]}" if paren&.to_s&.match?(/&#x.{0,4};/)
|
90
|
+
paren&.to_s
|
93
91
|
end
|
94
92
|
|
95
93
|
def mathml_paren(field)
|
@@ -1,11 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Hat <
|
8
|
+
class Hat < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_asciimath
|
10
17
|
first_value = "(#{parameter_one.to_asciimath})" if parameter_one
|
11
18
|
"hat#{first_value}"
|
@@ -21,7 +28,7 @@ module Plurimath
|
|
21
28
|
return mo_tag unless parameter_one
|
22
29
|
|
23
30
|
mover_tag = Utility.ox_element("mover")
|
24
|
-
mover_tag.attributes.merge!(
|
31
|
+
mover_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
|
25
32
|
Utility.update_nodes(
|
26
33
|
mover_tag,
|
27
34
|
[
|
@@ -36,9 +43,9 @@ module Plurimath
|
|
36
43
|
end
|
37
44
|
|
38
45
|
def to_omml_without_math_tag(display_style)
|
39
|
-
return r_element("^", rpr_tag: false)
|
46
|
+
return r_element("^", rpr_tag: false) unless parameter_one
|
40
47
|
|
41
|
-
if
|
48
|
+
if attributes && attributes[:accent]
|
42
49
|
accent_tag(display_style)
|
43
50
|
else
|
44
51
|
symbol = Symbol.new("̂")
|
@@ -1,11 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Obrace <
|
8
|
+
class Obrace < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_asciimath
|
10
17
|
first_value = "(#{parameter_one.to_asciimath})" if parameter_one
|
11
18
|
"obrace#{first_value}"
|
@@ -21,7 +28,7 @@ module Plurimath
|
|
21
28
|
return mo_tag unless parameter_one
|
22
29
|
|
23
30
|
over_tag = Utility.ox_element("mover")
|
24
|
-
over_tag.attributes.merge!(
|
31
|
+
over_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
|
25
32
|
Utility.update_nodes(
|
26
33
|
over_tag,
|
27
34
|
[
|
@@ -36,9 +43,9 @@ module Plurimath
|
|
36
43
|
end
|
37
44
|
|
38
45
|
def to_omml_without_math_tag(display_style)
|
39
|
-
return r_element("⏞", rpr_tag: false) unless
|
46
|
+
return r_element("⏞", rpr_tag: false) unless parameter_one
|
40
47
|
|
41
|
-
if
|
48
|
+
if attributes && attributes[:accent]
|
42
49
|
acc_tag(display_style)
|
43
50
|
else
|
44
51
|
symbol = Symbol.new("⏞")
|
@@ -55,6 +55,10 @@ module Plurimath
|
|
55
55
|
!(parameter_one.nil? || parameter_two.nil? || parameter_three.nil?)
|
56
56
|
end
|
57
57
|
|
58
|
+
def all_values_exist?
|
59
|
+
!(parameter_one.nil? && parameter_two.nil? && parameter_three.nil?)
|
60
|
+
end
|
61
|
+
|
58
62
|
protected
|
59
63
|
|
60
64
|
def latex_wrapped(field)
|
@@ -108,8 +112,8 @@ module Plurimath
|
|
108
112
|
def narypr(function_symbol, function_type: "undOvr")
|
109
113
|
chr_arg = { "m:val": function_symbol }
|
110
114
|
limloc_arg = { "m:val": function_type }
|
111
|
-
subhide_arg = { "m:val": "0" }
|
112
|
-
suphide_arg = { "m:val": "0" }
|
115
|
+
subhide_arg = { "m:val": parameter_one ? "0" : "1" }
|
116
|
+
suphide_arg = { "m:val": parameter_two ? "0" : "1" }
|
113
117
|
chr_tag = Utility.ox_element("chr", attributes: chr_arg, namespace: "m")
|
114
118
|
limloc_tag = Utility.ox_element("limLoc", attributes: limloc_arg, namespace: "m")
|
115
119
|
subhide_tag = Utility.ox_element("subHide", attributes: subhide_arg, namespace: "m")
|
@@ -126,10 +130,6 @@ module Plurimath
|
|
126
130
|
)
|
127
131
|
end
|
128
132
|
|
129
|
-
def all_values_exist?
|
130
|
-
!(parameter_one.nil? && parameter_two.nil? && parameter_three.nil?)
|
131
|
-
end
|
132
|
-
|
133
133
|
def validate_mathml_tag(parameter)
|
134
134
|
return Array(Utility.ox_element("mrow")) unless parameter
|
135
135
|
|
@@ -1,23 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Tilde <
|
8
|
+
class Tilde < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_mathml_without_math_tag
|
10
17
|
mover = Utility.ox_element("mover")
|
11
|
-
mover.attributes.merge!({ accent:
|
18
|
+
mover.attributes.merge!({ accent: attributes[:accent]}) if attributes && attributes[:accent]
|
12
19
|
first_value = (Utility.ox_element("mo") << "~")
|
13
20
|
second_value = parameter_one.to_mathml_without_math_tag if parameter_one
|
14
21
|
Utility.update_nodes(mover, [second_value, first_value])
|
15
22
|
end
|
16
23
|
|
17
24
|
def to_omml_without_math_tag(display_style)
|
18
|
-
return r_element("~", rpr_tag: false) unless
|
25
|
+
return r_element("~", rpr_tag: false) unless parameter_one
|
19
26
|
|
20
|
-
if
|
27
|
+
if attributes && attributes[:accent]
|
21
28
|
acc_tag(display_style)
|
22
29
|
else
|
23
30
|
symbol = Symbol.new("~")
|
@@ -1,11 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Ubrace <
|
8
|
+
class Ubrace < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_asciimath
|
10
17
|
first_value = "(#{parameter_one.to_asciimath})" if parameter_one
|
11
18
|
"ubrace#{first_value}"
|
@@ -21,7 +28,7 @@ module Plurimath
|
|
21
28
|
return mo_tag unless parameter_one
|
22
29
|
|
23
30
|
over_tag = Utility.ox_element("munder")
|
24
|
-
over_tag.attributes.merge!(
|
31
|
+
over_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
|
25
32
|
Utility.update_nodes(
|
26
33
|
over_tag,
|
27
34
|
[
|
@@ -44,7 +51,7 @@ module Plurimath
|
|
44
51
|
end
|
45
52
|
|
46
53
|
def to_omml_without_math_tag(display_style)
|
47
|
-
return r_element("⏟", rpr_tag: false) unless
|
54
|
+
return r_element("⏟", rpr_tag: false) unless parameter_one
|
48
55
|
|
49
56
|
symbol = Symbol.new("⏟")
|
50
57
|
Underset.new(parameter_one, symbol).to_omml_without_math_tag(true)
|
@@ -1,11 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Ul <
|
8
|
+
class Ul < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_asciimath
|
10
17
|
first_value = "(#{parameter_one.to_asciimath})" if parameter_one
|
11
18
|
"underline#{first_value}"
|
@@ -21,7 +28,7 @@ module Plurimath
|
|
21
28
|
return mo_tag unless parameter_one
|
22
29
|
|
23
30
|
munder_tag = Utility.ox_element("munder")
|
24
|
-
munder_tag.attributes.merge!(
|
31
|
+
munder_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
|
25
32
|
Utility.update_nodes(
|
26
33
|
munder_tag,
|
27
34
|
[
|
@@ -32,9 +39,9 @@ module Plurimath
|
|
32
39
|
end
|
33
40
|
|
34
41
|
def to_omml_without_math_tag(display_style)
|
35
|
-
return r_element("̲", rpr_tag: false) unless
|
42
|
+
return r_element("̲", rpr_tag: false) unless parameter_one
|
36
43
|
|
37
|
-
if
|
44
|
+
if attributes && attributes[:accentunder]
|
38
45
|
groupchr_tag(display_style)
|
39
46
|
else
|
40
47
|
symbol = Symbol.new("̲")
|
@@ -47,7 +54,7 @@ module Plurimath
|
|
47
54
|
end
|
48
55
|
|
49
56
|
def swap_class
|
50
|
-
Bar.new(parameter_one,
|
57
|
+
Bar.new(parameter_one, attributes)
|
51
58
|
end
|
52
59
|
|
53
60
|
protected
|
@@ -39,8 +39,7 @@ module Plurimath
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def to_latex
|
42
|
-
|
43
|
-
"\\#{class_name}#{first_value}"
|
42
|
+
"\\#{class_name}{#{latex_value}}"
|
44
43
|
end
|
45
44
|
|
46
45
|
def to_html
|
@@ -49,7 +48,7 @@ module Plurimath
|
|
49
48
|
elsif parameter_one
|
50
49
|
"<i>#{parameter_one.to_html}</i>"
|
51
50
|
end
|
52
|
-
|
51
|
+
"<i>#{invert_unicode_symbols}</i>#{first_value}"
|
53
52
|
end
|
54
53
|
|
55
54
|
def to_omml_without_math_tag(display_style)
|
@@ -78,6 +77,10 @@ module Plurimath
|
|
78
77
|
|
79
78
|
protected
|
80
79
|
|
80
|
+
def invert_unicode_symbols
|
81
|
+
Mathml::Constants::UNICODE_SYMBOLS.invert[class_name] || class_name
|
82
|
+
end
|
83
|
+
|
81
84
|
def asciimath_value
|
82
85
|
return "" unless parameter_one
|
83
86
|
|
@@ -1,15 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "unary_function"
|
4
4
|
|
5
5
|
module Plurimath
|
6
6
|
module Math
|
7
7
|
module Function
|
8
|
-
class Vec <
|
8
|
+
class Vec < UnaryFunction
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(parameter_one = nil, attributes = {})
|
12
|
+
super(parameter_one)
|
13
|
+
@attributes = attributes
|
14
|
+
end
|
15
|
+
|
9
16
|
def to_mathml_without_math_tag
|
10
17
|
mover = Utility.ox_element("mover")
|
11
18
|
first_value = parameter_one&.to_mathml_without_math_tag
|
12
|
-
mover.attributes.merge!({ accent:
|
19
|
+
mover.attributes.merge!({ accent: attributes[:accent] }) if attributes && attributes[:accent]
|
13
20
|
Utility.update_nodes(
|
14
21
|
mover,
|
15
22
|
[
|
@@ -20,9 +27,9 @@ module Plurimath
|
|
20
27
|
end
|
21
28
|
|
22
29
|
def to_omml_without_math_tag(display_style)
|
23
|
-
return r_element("→", rpr_tag: false) unless
|
30
|
+
return r_element("→", rpr_tag: false) unless parameter_one
|
24
31
|
|
25
|
-
if
|
32
|
+
if attributes && attributes[:accent]
|
26
33
|
acc_tag(display_style)
|
27
34
|
else
|
28
35
|
symbol = Symbol.new("→")
|
@@ -7,7 +7,7 @@ module Plurimath
|
|
7
7
|
class Parser
|
8
8
|
attr_accessor :text
|
9
9
|
|
10
|
-
|
10
|
+
SUPPORTED_ATTRS = %w[
|
11
11
|
columnlines
|
12
12
|
mathvariant
|
13
13
|
accentunder
|
@@ -24,11 +24,11 @@ module Plurimath
|
|
24
24
|
|
25
25
|
def parse
|
26
26
|
ox_nodes = Ox.load(text, strip_namespace: true)
|
27
|
-
display_style = ox_nodes&.locate("*/mstyle/@displaystyle")&.first
|
27
|
+
display_style = ox_nodes&.locate("*/mstyle/@displaystyle")&.first
|
28
28
|
nodes = parse_nodes(ox_nodes.nodes)
|
29
29
|
Math::Formula.new(
|
30
30
|
Transform.new.apply(nodes).flatten.compact,
|
31
|
-
display_style: display_style,
|
31
|
+
display_style: (display_style || true),
|
32
32
|
)
|
33
33
|
end
|
34
34
|
|
@@ -39,12 +39,7 @@ module Plurimath
|
|
39
39
|
if node.is_a?(String)
|
40
40
|
node
|
41
41
|
elsif !node.attributes.empty?
|
42
|
-
|
43
|
-
node.name.to_sym => {
|
44
|
-
attributes: validate_attributes(node.attributes),
|
45
|
-
value: parse_nodes(node.nodes),
|
46
|
-
},
|
47
|
-
}
|
42
|
+
attrs_hash(node)
|
48
43
|
else
|
49
44
|
{ node.name.to_sym => parse_nodes(node.nodes) }
|
50
45
|
end
|
@@ -52,9 +47,18 @@ module Plurimath
|
|
52
47
|
end
|
53
48
|
|
54
49
|
def validate_attributes(attributes)
|
55
|
-
attributes&.select! { |key, _|
|
50
|
+
attributes&.select! { |key, _| SUPPORTED_ATTRS.include?(key&.to_s) }
|
56
51
|
attributes&.transform_keys(&:to_sym) if attributes&.any?
|
57
52
|
end
|
53
|
+
|
54
|
+
def attrs_hash(node)
|
55
|
+
{
|
56
|
+
node.name.to_sym => {
|
57
|
+
attributes: validate_attributes(node.attributes),
|
58
|
+
value: parse_nodes(node.nodes),
|
59
|
+
},
|
60
|
+
}
|
61
|
+
end
|
58
62
|
end
|
59
63
|
end
|
60
64
|
end
|
@@ -136,16 +136,17 @@ module Plurimath
|
|
136
136
|
end
|
137
137
|
|
138
138
|
rule(msubsup: sequence(:function)) do
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
139
|
+
base = function[0].is_a?(Math::Formula) ? function[0].value : function
|
140
|
+
base_object = base.first
|
141
|
+
if base_object.is_a?(Math::Function::BinaryFunction) && !base_object.any_value_exist?
|
142
|
+
base_object.parameter_one = function[1]
|
143
|
+
base_object.parameter_two = function[2]
|
144
|
+
base_object
|
145
|
+
elsif base_object.is_a?(Math::Function::TernaryFunction) && !base_object.any_value_exist?
|
146
|
+
base_object.parameter_one = function[1]
|
147
|
+
base_object.parameter_two = function[2]
|
148
|
+
base_object.parameter_three = function[3]
|
149
|
+
base_object
|
149
150
|
else
|
150
151
|
Math::Function::PowerBase.new(
|
151
152
|
function[0],
|
@@ -156,16 +157,17 @@ module Plurimath
|
|
156
157
|
end
|
157
158
|
|
158
159
|
rule(munderover: sequence(:function)) do
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
160
|
+
base = function[0].is_a?(Math::Formula) ? function[0].value : function
|
161
|
+
base_object = base.first
|
162
|
+
if base_object.is_a?(Math::Function::BinaryFunction) && !base_object.any_value_exist?
|
163
|
+
base_object.parameter_one = function[1]
|
164
|
+
base_object.parameter_two = function[2]
|
165
|
+
base_object
|
166
|
+
elsif base_object.is_a?(Math::Function::TernaryFunction) && !base_object.any_value_exist?
|
167
|
+
base_object.parameter_one = function[1]
|
168
|
+
base_object.parameter_two = function[2]
|
169
|
+
base_object.parameter_three = function[3]
|
170
|
+
base_object
|
169
171
|
else
|
170
172
|
Math::Function::Underover.new(
|
171
173
|
function[0],
|
@@ -177,6 +179,7 @@ module Plurimath
|
|
177
179
|
|
178
180
|
rule(mrow: subtree(:mrow)) do
|
179
181
|
flatten_mrow = Utility.populate_function_classes(mrow)
|
182
|
+
Utility.fenceable_classes(flatten_mrow)
|
180
183
|
if flatten_mrow.length == 1
|
181
184
|
flatten_mrow.first
|
182
185
|
else
|
@@ -198,13 +201,9 @@ module Plurimath
|
|
198
201
|
end
|
199
202
|
|
200
203
|
rule(mover: subtree(:mover)) do
|
201
|
-
Utility.binary_function_classes(mover, under: true)
|
202
204
|
if mover&.length == 1
|
203
|
-
|
204
|
-
|
205
|
-
else
|
206
|
-
mover.first
|
207
|
-
end
|
205
|
+
base_object = mover.first
|
206
|
+
base_object.class_name == "underline" ? base_object.swap_class : base_object
|
208
207
|
elsif Constants::CLASSES.any?(mover&.last&.class_name)
|
209
208
|
mover.last.parameter_one = mover.shift if mover.length > 1
|
210
209
|
mover.last
|
@@ -219,19 +218,16 @@ module Plurimath
|
|
219
218
|
rule(munder: sequence(:munder)) do
|
220
219
|
if munder.any?(String)
|
221
220
|
munder.each_with_index do |object, ind|
|
222
|
-
|
221
|
+
next unless object.is_a?(String)
|
222
|
+
|
223
|
+
munder[ind] = Utility.mathml_unary_classes([object])
|
223
224
|
end
|
224
225
|
end
|
225
|
-
|
226
|
-
|
226
|
+
if munder.length == 1
|
227
|
+
munder.first.class_name == "bar" ? munder.first.swap_class : munder.last
|
228
|
+
elsif ["ubrace", "obrace", "underline"].any?(munder.last.class_name)
|
227
229
|
munder.last.parameter_one = munder.shift if munder.length > 1
|
228
230
|
munder.last
|
229
|
-
elsif munder.length == 1
|
230
|
-
if munder.first.class_name == "bar"
|
231
|
-
munder.first.swap_class
|
232
|
-
else
|
233
|
-
munder.last
|
234
|
-
end
|
235
231
|
else
|
236
232
|
Math::Function::Underset.new(
|
237
233
|
munder[1],
|
@@ -336,10 +332,13 @@ module Plurimath
|
|
336
332
|
rule(attributes: subtree(:attrs),
|
337
333
|
value: sequence(:value)) do
|
338
334
|
approved_attrs = if attrs.is_a?(Hash)
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
335
|
+
supported_attrs = %w[accentunder accent]
|
336
|
+
attrs if attrs.keys.any? do |k|
|
337
|
+
supported_attrs.include?(k.to_s)
|
338
|
+
end
|
339
|
+
else
|
340
|
+
attrs
|
341
|
+
end
|
343
342
|
Utility.join_attr_value(approved_attrs, value&.flatten&.compact)
|
344
343
|
end
|
345
344
|
end
|
@@ -137,8 +137,8 @@ module Plurimath
|
|
137
137
|
chr_value = chr ? chr[:chr] : Math::Function::Hat.new
|
138
138
|
index = acc_value.index { |d| d[:chr] }
|
139
139
|
acc_value[index] = chr_value
|
140
|
-
Utility.
|
141
|
-
acc_value.first.
|
140
|
+
Utility.unary_function_classes(acc_value)
|
141
|
+
acc_value.first.attributes = { accent: true }
|
142
142
|
acc_value.first
|
143
143
|
end
|
144
144
|
|
@@ -149,12 +149,22 @@ module Plurimath
|
|
149
149
|
end
|
150
150
|
|
151
151
|
rule(nary: subtree(:nary)) do
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
]
|
157
|
-
|
152
|
+
flatten_nary = nary.flatten.compact
|
153
|
+
chr = Utility.find_pos_chr(flatten_nary, :chr)
|
154
|
+
ternary_class = Utility.mathml_unary_classes(chr.values) if chr
|
155
|
+
if ternary_class.is_a?(Math::Function::TernaryFunction)
|
156
|
+
ternary_class.parameter_one = Utility.filter_values(nary[1])
|
157
|
+
ternary_class.parameter_two = Utility.filter_values(nary[2])
|
158
|
+
ternary_class.parameter_three = Utility.filter_values(nary[3])
|
159
|
+
ternary_class
|
160
|
+
else
|
161
|
+
Math::Formula.new(
|
162
|
+
[
|
163
|
+
Utility.nary_fonts(nary),
|
164
|
+
Utility.filter_values(nary[3]),
|
165
|
+
],
|
166
|
+
)
|
167
|
+
end
|
158
168
|
end
|
159
169
|
|
160
170
|
rule(groupChr: subtree(:groupchr)) do
|
@@ -175,7 +185,6 @@ module Plurimath
|
|
175
185
|
end
|
176
186
|
|
177
187
|
rule(sSubSup: subtree(:sSubSup)) do
|
178
|
-
function_classes = [Math::Formula, Math::Function::FontStyle]
|
179
188
|
subsup = sSubSup.flatten.compact
|
180
189
|
subsup.each_with_index do |object, ind|
|
181
190
|
subsup[ind] = Utility.mathml_unary_classes([object]) if object.is_a?(String)
|
@@ -235,7 +244,6 @@ module Plurimath
|
|
235
244
|
end
|
236
245
|
|
237
246
|
rule(limLow: subtree(:lim)) do
|
238
|
-
flatten_lim = lim.flatten.compact
|
239
247
|
second_value = Utility.filter_values(lim[2])
|
240
248
|
unicode = Mathml::Constants::UNICODE_SYMBOLS.invert[second_value.class_name]
|
241
249
|
second_value = unicode ? Math::Symbol.new(unicode.to_s) : second_value
|
data/lib/plurimath/utility.rb
CHANGED
@@ -72,7 +72,7 @@ module Plurimath
|
|
72
72
|
max
|
73
73
|
min
|
74
74
|
].freeze
|
75
|
-
OMML_FONTS
|
75
|
+
OMML_FONTS = {
|
76
76
|
"sans-serif-bi": Math::Function::FontStyle::SansSerifBoldItalic,
|
77
77
|
"sans-serif-i": Math::Function::FontStyle::SansSerifItalic,
|
78
78
|
"sans-serif-b": Math::Function::FontStyle::BoldSansSerif,
|
@@ -81,12 +81,24 @@ module Plurimath
|
|
81
81
|
"fraktur-p": Math::Function::FontStyle::Fraktur,
|
82
82
|
"fraktur-b": Math::Function::FontStyle::BoldFraktur,
|
83
83
|
"script-b": Math::Function::FontStyle::BoldScript,
|
84
|
-
"monospace": Math::Function::FontStyle::Monospace,
|
85
84
|
"script-p": Math::Function::FontStyle::Script,
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
monospace: Math::Function::FontStyle::Monospace,
|
86
|
+
bi: Math::Function::FontStyle::BoldItalic,
|
87
|
+
p: Math::Function::FontStyle::Normal,
|
88
|
+
i: Math::Function::FontStyle::Italic,
|
89
|
+
b: Math::Function::FontStyle::Bold,
|
90
|
+
}.freeze
|
91
|
+
PARENTHESIS = {
|
92
|
+
"〈": "〉",
|
93
|
+
"⌊": "⌋",
|
94
|
+
"⌈": "⌉",
|
95
|
+
"‖": "‖",
|
96
|
+
"{": "}",
|
97
|
+
"[": "]",
|
98
|
+
"|": "|",
|
99
|
+
"(": ")",
|
100
|
+
"{": "}",
|
101
|
+
"[": "]",
|
90
102
|
}.freeze
|
91
103
|
|
92
104
|
class << self
|
@@ -344,7 +356,7 @@ module Plurimath
|
|
344
356
|
value
|
345
357
|
elsif attrs.is_a?(String) && ["solid", "none"].include?(attrs.split.first.downcase)
|
346
358
|
table_separator(attrs.split, value)
|
347
|
-
elsif attrs.is_a?(Hash) && (attrs.key?(:accent) ||
|
359
|
+
elsif attrs.is_a?(Hash) && (attrs.key?(:accent) || attrs.key?(:accentunder))
|
348
360
|
attr_is_accent(attrs, value)
|
349
361
|
elsif attrs.is_a?(Math::Core)
|
350
362
|
attr_is_function(attrs, value)
|
@@ -352,9 +364,9 @@ module Plurimath
|
|
352
364
|
end
|
353
365
|
|
354
366
|
def attr_is_accent(attrs, value)
|
355
|
-
value.last.
|
356
|
-
|
357
|
-
value.last.
|
367
|
+
if value.last.is_a?(Math::Function::UnaryFunction)
|
368
|
+
value.last.parameter_one = value.shift if value.length > 1
|
369
|
+
value.last.attributes = attrs.transform_values { |v| YAML.safe_load(v) }
|
358
370
|
end
|
359
371
|
value
|
360
372
|
end
|
@@ -470,9 +482,9 @@ module Plurimath
|
|
470
482
|
(
|
471
483
|
object.is_a?(Math::Function::TernaryFunction) && object.any_value_exist?
|
472
484
|
) &&
|
473
|
-
mrow.length <= 2
|
485
|
+
(mrow.length <= 2)
|
474
486
|
) ||
|
475
|
-
object.is_a?(Math::Function::UnaryFunction) && mrow.length == 1
|
487
|
+
(object.is_a?(Math::Function::UnaryFunction) && mrow.length == 1)
|
476
488
|
)
|
477
489
|
end
|
478
490
|
|
@@ -494,7 +506,7 @@ module Plurimath
|
|
494
506
|
if object.is_a?(Math::Function::Mod)
|
495
507
|
next unless mrow.length >= 1
|
496
508
|
|
497
|
-
object.parameter_one = mrow.delete_at(ind - 1) unless ind
|
509
|
+
object.parameter_one = mrow.delete_at(ind - 1) unless ind.zero?
|
498
510
|
object.parameter_two = mrow.delete_at(ind)
|
499
511
|
elsif Mathml::Constants::UNICODE_SYMBOLS.invert[object.class_name] && mrow.length > 1
|
500
512
|
next if object.parameter_one || mrow.length > 2
|
@@ -510,9 +522,11 @@ module Plurimath
|
|
510
522
|
if mrow.any?(String) || mrow.any?(unary_class)
|
511
523
|
mrow.each_with_index do |object, ind|
|
512
524
|
mrow[ind] = mathml_unary_classes([object]) if object.is_a?(String)
|
525
|
+
object = mrow[ind] if object.is_a?(String)
|
513
526
|
next unless object.is_a?(unary_class)
|
514
527
|
next if object.is_a?(Math::Function::Text)
|
515
528
|
next if object.parameter_one || mrow[ind + 1].nil?
|
529
|
+
next unless ind.zero?
|
516
530
|
|
517
531
|
object.parameter_one = mrow.delete_at(ind + 1)
|
518
532
|
end
|
@@ -533,6 +547,32 @@ module Plurimath
|
|
533
547
|
end
|
534
548
|
end
|
535
549
|
end
|
550
|
+
|
551
|
+
def paren_able?(arr = [], mrow = [])
|
552
|
+
arr.any? do |opening, closing|
|
553
|
+
symbol_value(mrow.first, opening.to_s) && symbol_value(mrow.last, closing.to_s)
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
def fenceable_classes(mrow = [])
|
558
|
+
return false unless mrow.length > 1
|
559
|
+
|
560
|
+
if paren_able?(PARENTHESIS, mrow)
|
561
|
+
open_paren = mrow.shift
|
562
|
+
close_paren = mrow.pop
|
563
|
+
if mrow.length == 1 && mrow.first.is_a?(Math::Function::Table)
|
564
|
+
table = mrow.first
|
565
|
+
table.open_paren = open_paren
|
566
|
+
table.close_paren = close_paren
|
567
|
+
else
|
568
|
+
mrow.replace(
|
569
|
+
[
|
570
|
+
Math::Function::Fenced.new(open_paren, mrow.dup, close_paren),
|
571
|
+
],
|
572
|
+
)
|
573
|
+
end
|
574
|
+
end
|
575
|
+
end
|
536
576
|
end
|
537
577
|
end
|
538
578
|
end
|
data/lib/plurimath/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plurimath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parslet
|