plurimath 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +36 -0
- data/.rubocop.yml +2 -0
- data/lib/plurimath/asciimath/constants.rb +308 -0
- data/lib/plurimath/asciimath/parse.rb +87 -0
- data/lib/plurimath/asciimath/parser.rb +24 -0
- data/lib/plurimath/asciimath/transform.rb +304 -0
- data/lib/plurimath/asciimath.rb +16 -0
- data/lib/plurimath/html.rb +15 -0
- data/lib/plurimath/latex/constants.rb +1963 -0
- data/lib/plurimath/latex/parse.rb +105 -0
- data/lib/plurimath/latex/parser.rb +24 -0
- data/lib/plurimath/latex/transform.rb +298 -0
- data/lib/plurimath/latex.rb +15 -0
- data/lib/plurimath/math/formula.rb +43 -0
- data/lib/plurimath/math/function/abs.rb +12 -0
- data/lib/plurimath/math/function/arccos.rb +12 -0
- data/lib/plurimath/math/function/arcsin.rb +12 -0
- data/lib/plurimath/math/function/arctan.rb +12 -0
- data/lib/plurimath/math/function/bar.rb +16 -0
- data/lib/plurimath/math/function/base.rb +30 -0
- data/lib/plurimath/math/function/binary_function.rb +53 -0
- data/lib/plurimath/math/function/cancel.rb +12 -0
- data/lib/plurimath/math/function/ceil.rb +12 -0
- data/lib/plurimath/math/function/color.rb +23 -0
- data/lib/plurimath/math/function/cos.rb +12 -0
- data/lib/plurimath/math/function/cosh.rb +12 -0
- data/lib/plurimath/math/function/cot.rb +12 -0
- data/lib/plurimath/math/function/coth.rb +12 -0
- data/lib/plurimath/math/function/csc.rb +12 -0
- data/lib/plurimath/math/function/csch.rb +12 -0
- data/lib/plurimath/math/function/ddot.rb +12 -0
- data/lib/plurimath/math/function/deg.rb +12 -0
- data/lib/plurimath/math/function/det.rb +12 -0
- data/lib/plurimath/math/function/dim.rb +12 -0
- data/lib/plurimath/math/function/dot.rb +12 -0
- data/lib/plurimath/math/function/exp.rb +12 -0
- data/lib/plurimath/math/function/f.rb +12 -0
- data/lib/plurimath/math/function/fenced.rb +22 -0
- data/lib/plurimath/math/function/floor.rb +12 -0
- data/lib/plurimath/math/function/font_style.rb +45 -0
- data/lib/plurimath/math/function/frac.rb +23 -0
- data/lib/plurimath/math/function/g.rb +12 -0
- data/lib/plurimath/math/function/gcd.rb +12 -0
- data/lib/plurimath/math/function/glb.rb +12 -0
- data/lib/plurimath/math/function/hat.rb +12 -0
- data/lib/plurimath/math/function/hom.rb +12 -0
- data/lib/plurimath/math/function/inf.rb +18 -0
- data/lib/plurimath/math/function/int.rb +17 -0
- data/lib/plurimath/math/function/ker.rb +12 -0
- data/lib/plurimath/math/function/lcm.rb +12 -0
- data/lib/plurimath/math/function/left.rb +23 -0
- data/lib/plurimath/math/function/lg.rb +12 -0
- data/lib/plurimath/math/function/lim.rb +23 -0
- data/lib/plurimath/math/function/liminf.rb +12 -0
- data/lib/plurimath/math/function/limits.rb +19 -0
- data/lib/plurimath/math/function/limsup.rb +12 -0
- data/lib/plurimath/math/function/ln.rb +12 -0
- data/lib/plurimath/math/function/log.rb +23 -0
- data/lib/plurimath/math/function/lub.rb +12 -0
- data/lib/plurimath/math/function/max.rb +12 -0
- data/lib/plurimath/math/function/min.rb +12 -0
- data/lib/plurimath/math/function/mod.rb +23 -0
- data/lib/plurimath/math/function/norm.rb +15 -0
- data/lib/plurimath/math/function/obrace.rb +12 -0
- data/lib/plurimath/math/function/oint.rb +17 -0
- data/lib/plurimath/math/function/overset.rb +23 -0
- data/lib/plurimath/math/function/power.rb +30 -0
- data/lib/plurimath/math/function/power_base.rb +26 -0
- data/lib/plurimath/math/function/prod.rb +23 -0
- data/lib/plurimath/math/function/root.rb +22 -0
- data/lib/plurimath/math/function/sec.rb +12 -0
- data/lib/plurimath/math/function/sech.rb +12 -0
- data/lib/plurimath/math/function/sin.rb +12 -0
- data/lib/plurimath/math/function/sinh.rb +12 -0
- data/lib/plurimath/math/function/sqrt.rb +16 -0
- data/lib/plurimath/math/function/stackrel.rb +12 -0
- data/lib/plurimath/math/function/substack.rb +18 -0
- data/lib/plurimath/math/function/sum.rb +23 -0
- data/lib/plurimath/math/function/sup.rb +12 -0
- data/lib/plurimath/math/function/table.rb +42 -0
- data/lib/plurimath/math/function/tan.rb +12 -0
- data/lib/plurimath/math/function/tanh.rb +12 -0
- data/lib/plurimath/math/function/td.rb +27 -0
- data/lib/plurimath/math/function/ternary_function.rb +42 -0
- data/lib/plurimath/math/function/text.rb +32 -0
- data/lib/plurimath/math/function/tilde.rb +12 -0
- data/lib/plurimath/math/function/tr.rb +25 -0
- data/lib/plurimath/math/function/ubrace.rb +12 -0
- data/lib/plurimath/math/function/ul.rb +12 -0
- data/lib/plurimath/math/function/unary_function.rb +41 -0
- data/lib/plurimath/math/function/underover.rb +12 -0
- data/lib/plurimath/math/function/underset.rb +12 -0
- data/lib/plurimath/math/function/vec.rb +12 -0
- data/lib/plurimath/math/function.rb +3 -0
- data/lib/plurimath/math/number.rb +29 -0
- data/lib/plurimath/math/symbol.rb +34 -0
- data/lib/plurimath/math.rb +51 -0
- data/lib/plurimath/mathml/constants.rb +327 -0
- data/lib/plurimath/mathml/parse.rb +63 -0
- data/lib/plurimath/mathml/parser.rb +25 -0
- data/lib/plurimath/mathml/transform.rb +195 -0
- data/lib/plurimath/mathml.rb +16 -0
- data/lib/plurimath/omml.rb +15 -0
- data/lib/plurimath/unicode.rb +15 -0
- data/lib/plurimath/unitsml.rb +11 -0
- data/lib/plurimath/version.rb +3 -1
- data/lib/plurimath.rb +3 -5
- data/plurimath.gemspec +3 -3
- metadata +129 -11
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "parslet"
|
4
|
+
module Plurimath
|
5
|
+
class Latex
|
6
|
+
class Parse < Parslet::Parser
|
7
|
+
rule(:base) { str("_") }
|
8
|
+
rule(:power) { str("^") }
|
9
|
+
rule(:slash) { str("\\") }
|
10
|
+
rule(:double_slash) { str("\\\\").as("\\\\") }
|
11
|
+
rule(:array_args) { str("{") >> expression >> str("}") }
|
12
|
+
rule(:ending) { slash >> str("end") >> intermediate_exp }
|
13
|
+
rule(:begining) { slash >> str("begin") >> intermediate_exp }
|
14
|
+
rule(:lparen) { arr_to_expression(Constants::PARENTHESIS.keys, :lparen) }
|
15
|
+
rule(:rparen) { arr_to_expression(Constants::PARENTHESIS.values, :rparen) }
|
16
|
+
rule(:subscript) { intermediate_exp >> base >> intermediate_exp.as(:subscript) }
|
17
|
+
rule(:supscript) { intermediate_exp >> power >> intermediate_exp.as(:supscript) }
|
18
|
+
rule(:environment) { arr_to_expression(Constants::ENVIRONMENTS.keys, :environment) }
|
19
|
+
rule(:binary) { slash >> arr_to_expression(Constants::BINARY_CLASSES, :binary) }
|
20
|
+
rule(:under_over) { slash >> arr_to_expression(Constants::UNDEROVER_CLASSES, :binary) }
|
21
|
+
rule(:left_right) { str("\\left") >> lparen >> expression >> str("\\right") >> rparen }
|
22
|
+
rule(:math_operators) { slash >> arr_to_expression(Constants::MATH_OPERATORS, :unary_functions) >> str("\\limits") }
|
23
|
+
rule(:unary) { slash >> arr_to_expression(Constants::UNARY_CLASSES, :unary) >> intermediate_exp.as(:first_value) }
|
24
|
+
|
25
|
+
rule(:limits) do
|
26
|
+
math_operators >> base >> intermediate_exp.as(:base) >> power >> intermediate_exp.as(:power) |
|
27
|
+
math_operators >> power >> intermediate_exp.as(:power) >> base >> intermediate_exp.as(:base)
|
28
|
+
end
|
29
|
+
|
30
|
+
rule(:symbol_class_commands) do
|
31
|
+
(slash >> arr_to_expression(Constants::SYMBOLS, :symbols)) |
|
32
|
+
unary.as(:unary_functions) |
|
33
|
+
binary |
|
34
|
+
under_over |
|
35
|
+
environment |
|
36
|
+
(slash >> arr_to_expression(Constants::FONT_STYLES, :fonts) >> expression.as(:intermediate_exp)) |
|
37
|
+
arr_to_expression(Constants::OPERATORS, :operant) |
|
38
|
+
(slash >> arr_to_expression(Constants::POWER_BASE_CLASSES, :binary)) |
|
39
|
+
arr_to_expression(Constants::NUMERIC_VALUES, :numeric_values)
|
40
|
+
end
|
41
|
+
|
42
|
+
rule(:symbol_text_or_integer) do
|
43
|
+
symbol_class_commands |
|
44
|
+
match["a-zA-Z"].repeat(1).as(:text) |
|
45
|
+
match(/\d+(\.[0-9]+)|\d/).repeat(1).as(:number) |
|
46
|
+
double_slash
|
47
|
+
end
|
48
|
+
|
49
|
+
rule(:intermediate_exp) do
|
50
|
+
(lparen >> expression.as(:expression) >> rparen) |
|
51
|
+
(lparen >> str("") >> rparen) |
|
52
|
+
symbol_text_or_integer
|
53
|
+
end
|
54
|
+
|
55
|
+
rule(:power_base) do
|
56
|
+
(subscript >> power >> intermediate_exp.as(:supscript)).as(:power_base) |
|
57
|
+
(supscript >> base >> intermediate_exp.as(:subscript)).as(:power_base) |
|
58
|
+
supscript.as(:power) |
|
59
|
+
subscript.as(:base)
|
60
|
+
end
|
61
|
+
|
62
|
+
rule(:sqrt_arg) { str("[").as(:lparen) >> (expression | str("")) >> str("]").as(:rparen) }
|
63
|
+
|
64
|
+
rule(:binary_functions) do
|
65
|
+
(slash >> str("sqrt").as(:root) >> sqrt_arg.as(:first_value) >> intermediate_exp.as(:second_value)).as(:binary) |
|
66
|
+
(slash >> str("sqrt").as(:sqrt) >> intermediate_exp.as(:intermediate_exp)).as(:binary) |
|
67
|
+
(intermediate_exp.as(:first_value) >> under_over >> intermediate_exp.as(:second_value)).as(:under_over) |
|
68
|
+
(binary >> intermediate_exp.as(:first_value) >> intermediate_exp.as(:second_value)).as(:binary)
|
69
|
+
end
|
70
|
+
|
71
|
+
rule(:sequence) do
|
72
|
+
limits.as(:limits) |
|
73
|
+
left_right.as(:left_right) |
|
74
|
+
(slash >> str("mbox") >> lparen.capture(:paren) >> read_text >> rparen).as(:unary_functions) |
|
75
|
+
(slash >> str("substack").as(:substack) >> lparen >> expression.as(:substack_value) >> rparen) |
|
76
|
+
(begining.as(:begining) >> array_args.as(:args) >> expression.as(:table_data) >> ending.as(:ending)).as(:environment) |
|
77
|
+
(begining.as(:begining) >> expression.as(:table_data) >> ending.as(:ending)).as(:environment) |
|
78
|
+
(slash >> environment >> intermediate_exp).as(:table_data) |
|
79
|
+
power_base |
|
80
|
+
binary_functions |
|
81
|
+
intermediate_exp
|
82
|
+
end
|
83
|
+
|
84
|
+
rule(:iteration) { (sequence.as(:sequence) >> expression.as(:expression)) | sequence }
|
85
|
+
|
86
|
+
rule(:expression) { (iteration >> expression) | iteration }
|
87
|
+
|
88
|
+
root :expression
|
89
|
+
|
90
|
+
def arr_to_expression(array, name = nil)
|
91
|
+
array.reduce do |expression, expr_string|
|
92
|
+
expression = str(expression).as(name || expression.to_sym) if expression.is_a?(String)
|
93
|
+
expression | str(expr_string).as(name || expr_string.to_sym)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def read_text
|
98
|
+
dynamic do |_sour, context|
|
99
|
+
rparen = Constants::PARENTHESIS[context.captures[:paren][:lparen].to_s]
|
100
|
+
match("[^#{rparen}]").repeat.as(:text)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "parse"
|
4
|
+
require_relative "constants"
|
5
|
+
require_relative "transform"
|
6
|
+
module Plurimath
|
7
|
+
class Latex
|
8
|
+
class Parser
|
9
|
+
attr_accessor :text
|
10
|
+
|
11
|
+
def initialize(text)
|
12
|
+
@text = text.gsub(" ", "").gsub("\n", "")
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse
|
16
|
+
tree_t = Plurimath::Latex::Parse.new.parse(text)
|
17
|
+
formula = Plurimath::Latex::Transform.new.apply(tree_t)
|
18
|
+
formula = [formula] unless formula.is_a?(Array)
|
19
|
+
|
20
|
+
Plurimath::Math::Formula.new(formula)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,298 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plurimath
|
4
|
+
class Latex
|
5
|
+
class Transform < Parslet::Transform
|
6
|
+
rule(base: simple(:base)) { base }
|
7
|
+
rule(text: simple(:text)) { Math::Function::Text.new(text.to_s) }
|
8
|
+
rule(number: simple(:num)) { Math::Number.new(num.to_s) }
|
9
|
+
rule(power: simple(:power)) { power }
|
10
|
+
rule(symbols: simple(:sym)) { Math::Symbol.new(sym.to_s) }
|
11
|
+
rule(operant: simple(:oper)) { Math::Symbol.new(oper.to_s) }
|
12
|
+
rule(ending: simple(:ending)) { nil }
|
13
|
+
rule(limits: simple(:limits)) { limits }
|
14
|
+
rule(binary: simple(:binary)) do
|
15
|
+
binary.is_a?(Slice) ? Transform.get_class(binary == "over" ? "overset" : binary).new : binary
|
16
|
+
end
|
17
|
+
rule("\\\\" => simple(:slash)) { Math::Symbol.new(slash.to_s) }
|
18
|
+
|
19
|
+
rule(unary_functions: simple(:unary)) { unary }
|
20
|
+
rule(under_over: simple(:under_over)) { under_over }
|
21
|
+
rule(power_base: simple(:power_base)) { power_base }
|
22
|
+
rule(table_data: simple(:table_data)) { table_data }
|
23
|
+
rule(environment: simple(:environment)) { environment }
|
24
|
+
rule(intermediate_exp: simple(:int_exp)) { int_exp }
|
25
|
+
rule(lparen: simple(:lparen), rparen: simple(:rparen)) { nil }
|
26
|
+
|
27
|
+
rule(left_right: simple(:left_right)) do
|
28
|
+
Math::Function::Left.new(left_right)
|
29
|
+
end
|
30
|
+
|
31
|
+
rule(fonts: simple(:fonts), intermediate_exp: simple(:int_exp)) do
|
32
|
+
Math::Function::FontStyle.new(int_exp, fonts.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
rule(number: simple(:number), subscript: simple(:subscript)) do
|
36
|
+
number_object = Math::Number.new(number.to_s)
|
37
|
+
Math::Function::Base.new(number_object, subscript)
|
38
|
+
end
|
39
|
+
|
40
|
+
rule(symbols: simple(:symbol), subscript: simple(:subscript)) do
|
41
|
+
symbol_object = Math::Symbol.new(symbol.to_s)
|
42
|
+
Math::Function::Base.new(symbol_object, subscript)
|
43
|
+
end
|
44
|
+
|
45
|
+
rule(text: simple(:text), subscript: simple(:subscript)) do
|
46
|
+
text_object = Math::Function::Text.new(text.to_s)
|
47
|
+
Math::Function::Base.new(text_object, subscript)
|
48
|
+
end
|
49
|
+
|
50
|
+
rule(text: simple(:text), supscript: simple(:supscript)) do
|
51
|
+
text_object = Math::Function::Text.new(text.to_s)
|
52
|
+
Math::Function::Power.new(text_object, supscript)
|
53
|
+
end
|
54
|
+
|
55
|
+
rule(unary: simple(:unary), first_value: simple(:first_value)) do
|
56
|
+
class_name = unary == "overline" ? "bar" : unary
|
57
|
+
Transform.get_class(class_name).new(first_value)
|
58
|
+
end
|
59
|
+
|
60
|
+
rule(sqrt: simple(:sqrt), intermediate_exp: simple(:int_exp)) do
|
61
|
+
Math::Function::Sqrt.new(int_exp)
|
62
|
+
end
|
63
|
+
|
64
|
+
rule(root: simple(:root),
|
65
|
+
first_value: simple(:first_value),
|
66
|
+
second_value: simple(:second_value)) do
|
67
|
+
Math::Function::Root.new(first_value, second_value)
|
68
|
+
end
|
69
|
+
|
70
|
+
rule(sequence: simple(:sequence), expression: simple(:expr)) do
|
71
|
+
[sequence, expr]
|
72
|
+
end
|
73
|
+
|
74
|
+
rule(sequence: simple(:sequence), expression: sequence(:expr)) do
|
75
|
+
[sequence] + expr
|
76
|
+
end
|
77
|
+
|
78
|
+
rule(unary_functions: simple(:unary),
|
79
|
+
base: simple(:base),
|
80
|
+
power: simple(:power)) do
|
81
|
+
Plurimath::Math::Function::Limits.new(
|
82
|
+
Transform.get_class(unary).new,
|
83
|
+
base,
|
84
|
+
power,
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
rule(lparen: simple(:lparen),
|
89
|
+
text: simple(:text),
|
90
|
+
rparen: simple(:rparen)) do
|
91
|
+
Math::Function::Text.new(text.to_s)
|
92
|
+
end
|
93
|
+
|
94
|
+
rule(lparen: simple(:lparen),
|
95
|
+
symbols: simple(:symbol),
|
96
|
+
rparen: simple(:rparen)) do
|
97
|
+
Math::Symbol.new(symbol.to_s)
|
98
|
+
end
|
99
|
+
|
100
|
+
rule(substack: simple(:substack),
|
101
|
+
lparen: simple(:lparen),
|
102
|
+
substack_value: sequence(:value),
|
103
|
+
rparen: simple(:rparen)) do
|
104
|
+
first_value = []
|
105
|
+
until value.nil?
|
106
|
+
if value.first.is_a?(Plurimath::Math::Symbol) &&
|
107
|
+
value.first.value == "\\\\"
|
108
|
+
value.delete_at(0)
|
109
|
+
break;
|
110
|
+
else
|
111
|
+
first_value << value.delete_at(0)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
Transform.get_class(substack).new(
|
115
|
+
Math::Formula.new(first_value),
|
116
|
+
Math::Formula.new(value)
|
117
|
+
)
|
118
|
+
end
|
119
|
+
|
120
|
+
rule(lparen: simple(:lparen),
|
121
|
+
sequence: simple(:sequence),
|
122
|
+
expression: sequence(:expr),
|
123
|
+
rparen: simple(:rparen)) do
|
124
|
+
Math::Formula.new([sequence] + expr)
|
125
|
+
end
|
126
|
+
|
127
|
+
rule(lparen: simple(:lparen),
|
128
|
+
sequence: simple(:sequence),
|
129
|
+
expression: simple(:expr),
|
130
|
+
rparen: simple(:rparen)) do
|
131
|
+
Math::Formula.new([sequence, expr])
|
132
|
+
end
|
133
|
+
|
134
|
+
rule(lparen: simple(:lparen),
|
135
|
+
expression: simple(:expr),
|
136
|
+
rparen: simple(:rparen)) do
|
137
|
+
if expr.is_a?(Slice) && Constants::ENVIRONMENTS.key?(expr.to_s)
|
138
|
+
open_paren = Constants::ENVIRONMENTS[expr.to_s]
|
139
|
+
close_paren = if Constants::PARENTHESIS[open_paren]
|
140
|
+
Constants::PARENTHESIS[open_paren]
|
141
|
+
elsif open_paren == "|"
|
142
|
+
"|"
|
143
|
+
end
|
144
|
+
Math::Function::Table.new(
|
145
|
+
nil,
|
146
|
+
open_paren,
|
147
|
+
close_paren,
|
148
|
+
)
|
149
|
+
else
|
150
|
+
expr
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
rule(lparen: simple(:lparen),
|
155
|
+
expression: sequence(:expr),
|
156
|
+
rparen: simple(:rparen)) do
|
157
|
+
Math::Formula.new(expr)
|
158
|
+
end
|
159
|
+
|
160
|
+
rule(binary: simple(:binary),
|
161
|
+
subscript: simple(:subscript),
|
162
|
+
supscript: simple(:supscript)) do
|
163
|
+
Transform.get_class(binary).new(subscript, supscript)
|
164
|
+
end
|
165
|
+
|
166
|
+
rule(binary: simple(:binary),
|
167
|
+
subscript: simple(:subscript)) do
|
168
|
+
Transform.get_class(binary).new(subscript)
|
169
|
+
end
|
170
|
+
|
171
|
+
rule(text: simple(:text),
|
172
|
+
subscript: simple(:subscript),
|
173
|
+
supscript: simple(:supscript)) do
|
174
|
+
text_object = Math::Function::Text.new(text.to_s)
|
175
|
+
Math::Function::PowerBase.new(text_object, subscript, supscript)
|
176
|
+
end
|
177
|
+
|
178
|
+
rule(binary: simple(:binary),
|
179
|
+
first_value: simple(:first_value),
|
180
|
+
second_value: simple(:second_value)) do
|
181
|
+
if binary == "binom"
|
182
|
+
Math::Function::Table.new(
|
183
|
+
[Math::Function::Tr.new([first_value]),
|
184
|
+
Math::Function::Tr.new([second_value])],
|
185
|
+
"(",
|
186
|
+
")",
|
187
|
+
)
|
188
|
+
else
|
189
|
+
binary_class = if ["pmod", "bmod"].include?(binary)
|
190
|
+
"mod"
|
191
|
+
elsif binary == "over"
|
192
|
+
"frac"
|
193
|
+
else
|
194
|
+
binary
|
195
|
+
end
|
196
|
+
Transform.get_class(binary_class).new(first_value, second_value)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
rule(begining: simple(:begining),
|
201
|
+
table_data: sequence(:table_data),
|
202
|
+
ending: simple(:ending)) do
|
203
|
+
begining.parameter_one = Transform.organize_table(table_data)
|
204
|
+
begining
|
205
|
+
end
|
206
|
+
|
207
|
+
rule(lparen: simple(:lparen),
|
208
|
+
environment: simple(:env),
|
209
|
+
rparen: simple(:rparen)) do
|
210
|
+
env
|
211
|
+
end
|
212
|
+
|
213
|
+
rule(begining: simple(:begining),
|
214
|
+
args: simple(:args),
|
215
|
+
table_data: simple(:table_data),
|
216
|
+
ending: simple(:ending)) do
|
217
|
+
table_value = Transform.organize_table([table_data])
|
218
|
+
begining.parameter_one = table_value
|
219
|
+
begining.parameter_three = [args]
|
220
|
+
begining
|
221
|
+
end
|
222
|
+
|
223
|
+
rule(begining: simple(:begining),
|
224
|
+
args: sequence(:args),
|
225
|
+
table_data: sequence(:table_data),
|
226
|
+
ending: simple(:ending)) do
|
227
|
+
table_value = Transform.organize_table(table_data)
|
228
|
+
begining.parameter_one = table_value
|
229
|
+
begining.parameter_three = args
|
230
|
+
begining
|
231
|
+
end
|
232
|
+
|
233
|
+
rule(begining: simple(:begining),
|
234
|
+
args: simple(:args),
|
235
|
+
table_data: sequence(:table_data),
|
236
|
+
ending: simple(:ending)) do
|
237
|
+
table_value = Transform.organize_table(table_data)
|
238
|
+
begining.parameter_one = table_value
|
239
|
+
begining.parameter_three = [args]
|
240
|
+
begining
|
241
|
+
end
|
242
|
+
|
243
|
+
rule(environment: simple(:env),
|
244
|
+
lparen: simple(:lparen),
|
245
|
+
expression: sequence(:expr),
|
246
|
+
rparen: simple(:rparen)) do
|
247
|
+
table_value = Transform.organize_table(expr)
|
248
|
+
left_paren = Constants::ENVIRONMENTS[env.to_s]
|
249
|
+
Math::Function::Table.new(
|
250
|
+
table_value,
|
251
|
+
left_paren,
|
252
|
+
Constants::PARENTHESIS[left_paren],
|
253
|
+
)
|
254
|
+
end
|
255
|
+
|
256
|
+
rule(lparen: simple(:lparen),
|
257
|
+
expression: sequence(:expr),
|
258
|
+
rparen: simple(:rparen),
|
259
|
+
supscript: simple(:supscript)) do
|
260
|
+
formula = Math::Formula.new(expr)
|
261
|
+
Math::Function::Power.new(formula, supscript)
|
262
|
+
end
|
263
|
+
|
264
|
+
rule(lparen: simple(:lparen),
|
265
|
+
expression: simple(:expr),
|
266
|
+
rparen: simple(:rparen),
|
267
|
+
subscript: simple(:subscript)) do
|
268
|
+
formula = Math::Formula.new(expr)
|
269
|
+
Math::Function::Base.new(formula, subscript)
|
270
|
+
end
|
271
|
+
|
272
|
+
class << self
|
273
|
+
def organize_table(array, table = [], table_data = [], table_row = [])
|
274
|
+
array.each do |data|
|
275
|
+
if data.is_a?(Math::Symbol) && data.value == "&"
|
276
|
+
table_row << Math::Function::Td.new(table_data)
|
277
|
+
table_data = []
|
278
|
+
elsif data.is_a?(Math::Symbol) && data.value == "\\\\"
|
279
|
+
table_row << Math::Function::Td.new(table_data)
|
280
|
+
table << Math::Function::Tr.new(table_row.flatten)
|
281
|
+
table_row = []
|
282
|
+
table_data = []
|
283
|
+
else
|
284
|
+
table_data << data
|
285
|
+
end
|
286
|
+
end
|
287
|
+
table_row << Math::Function::Td.new(table_data) if table_data
|
288
|
+
table << Math::Function::Tr.new(table_row) unless table_row.empty?
|
289
|
+
table
|
290
|
+
end
|
291
|
+
|
292
|
+
def get_class(text)
|
293
|
+
Object.const_get("Plurimath::Math::Function::#{text.to_s.capitalize}")
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plurimath
|
4
|
+
module Math
|
5
|
+
class Formula
|
6
|
+
attr_accessor :value
|
7
|
+
|
8
|
+
def initialize(value = [])
|
9
|
+
@value = value.is_a?(Array) ? value : [value]
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(object)
|
13
|
+
object.value == value
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_asciimath
|
17
|
+
value.map(&:to_asciimath).join
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_mathml
|
21
|
+
<<~MATHML
|
22
|
+
<math xmlns='http://www.w3.org/1998/Math/MathML'>
|
23
|
+
<mstyle displaystyle='true'>
|
24
|
+
#{mathml_content}
|
25
|
+
</mstyle>
|
26
|
+
</math>
|
27
|
+
MATHML
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_mathml_without_math_tag
|
31
|
+
"<mrow>#{mathml_content}</mrow>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def mathml_content
|
35
|
+
value.map(&:to_mathml_without_math_tag).join
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_latex
|
39
|
+
value.map(&:to_latex).join
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "unary_function"
|
4
|
+
|
5
|
+
module Plurimath
|
6
|
+
module Math
|
7
|
+
module Function
|
8
|
+
class Bar < UnaryFunction
|
9
|
+
def to_latex
|
10
|
+
first_value = "{#{parameter_one.to_latex}}" if parameter_one
|
11
|
+
"\\overline#{first_value}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "binary_function"
|
4
|
+
|
5
|
+
module Plurimath
|
6
|
+
module Math
|
7
|
+
module Function
|
8
|
+
class Base < BinaryFunction
|
9
|
+
def to_asciimath
|
10
|
+
first_value = parameter_one.to_asciimath if parameter_one
|
11
|
+
second_value = "_#{parameter_two.to_asciimath}" if parameter_two
|
12
|
+
"#{first_value}#{second_value}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_mathml_without_math_tag
|
16
|
+
first_value = parameter_one.to_mathml_without_math_tag
|
17
|
+
second_value = parameter_two.to_mathml_without_math_tag
|
18
|
+
"<msub>#{first_value}#{second_value}</msub>"
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_latex
|
22
|
+
first_value = parameter_one.to_latex if parameter_one
|
23
|
+
first_value = "{#{first_value}}" if parameter_one.is_a?(Math::Formula)
|
24
|
+
second_value = parameter_two.to_latex if parameter_two
|
25
|
+
"#{first_value}_{#{second_value}}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plurimath
|
4
|
+
module Math
|
5
|
+
module Function
|
6
|
+
class BinaryFunction
|
7
|
+
attr_accessor :parameter_one, :parameter_two
|
8
|
+
|
9
|
+
def initialize(parameter_one = nil, parameter_two = nil)
|
10
|
+
@parameter_one = parameter_one
|
11
|
+
@parameter_two = parameter_two
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_asciimath
|
15
|
+
"#{class_name}#{value_to_asciimath}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def value_to_asciimath
|
19
|
+
first_value = "(#{parameter_one.to_asciimath})" if parameter_one
|
20
|
+
second_value = "(#{parameter_two.to_asciimath})" if parameter_two
|
21
|
+
"#{first_value}#{second_value}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def ==(object)
|
25
|
+
object.class == self.class &&
|
26
|
+
object.parameter_one == parameter_one &&
|
27
|
+
object.parameter_two == parameter_two
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_mathml_without_math_tag
|
31
|
+
first_value = parameter_one.to_mathml_without_math_tag if parameter_one
|
32
|
+
second_value = parameter_two.to_mathml_without_math_tag if parameter_two
|
33
|
+
third_value = invert_unicode_symbols.empty? ? class_name : invert_unicode_symbols
|
34
|
+
"<mo>#{third_value}</mo>#{first_value}#{second_value}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def invert_unicode_symbols
|
38
|
+
Mathml::Constants::UNICODE_SYMBOLS.invert[class_name].to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_latex
|
42
|
+
first_value = "{#{parameter_one.to_latex}}" if parameter_one
|
43
|
+
second_value = "{#{parameter_two.to_latex}}" if parameter_two
|
44
|
+
"\\#{class_name}#{first_value}#{second_value}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def class_name
|
48
|
+
self.class.name.split("::").last.downcase
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "binary_function"
|
4
|
+
|
5
|
+
module Plurimath
|
6
|
+
module Math
|
7
|
+
module Function
|
8
|
+
class Color < BinaryFunction
|
9
|
+
def to_mathml_without_math_tag
|
10
|
+
first_value = parameter_one.value if parameter_one
|
11
|
+
second_value = parameter_two.to_mathml_without_math_tag if parameter_two
|
12
|
+
"<mstyle mathcolor='#{first_value}'>#{second_value}</mstyle>"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_latex
|
16
|
+
first_value = parameter_one.to_latex if parameter_one
|
17
|
+
second_value = parameter_two.to_latex if parameter_two
|
18
|
+
"\\#{class_name}{#{first_value}}#{second_value}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|