plurimath 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +36 -0
  3. data/.rubocop.yml +2 -0
  4. data/lib/plurimath/asciimath/constants.rb +308 -0
  5. data/lib/plurimath/asciimath/parse.rb +87 -0
  6. data/lib/plurimath/asciimath/parser.rb +24 -0
  7. data/lib/plurimath/asciimath/transform.rb +304 -0
  8. data/lib/plurimath/asciimath.rb +16 -0
  9. data/lib/plurimath/html.rb +15 -0
  10. data/lib/plurimath/latex/constants.rb +1963 -0
  11. data/lib/plurimath/latex/parse.rb +105 -0
  12. data/lib/plurimath/latex/parser.rb +24 -0
  13. data/lib/plurimath/latex/transform.rb +298 -0
  14. data/lib/plurimath/latex.rb +15 -0
  15. data/lib/plurimath/math/formula.rb +43 -0
  16. data/lib/plurimath/math/function/abs.rb +12 -0
  17. data/lib/plurimath/math/function/arccos.rb +12 -0
  18. data/lib/plurimath/math/function/arcsin.rb +12 -0
  19. data/lib/plurimath/math/function/arctan.rb +12 -0
  20. data/lib/plurimath/math/function/bar.rb +16 -0
  21. data/lib/plurimath/math/function/base.rb +30 -0
  22. data/lib/plurimath/math/function/binary_function.rb +53 -0
  23. data/lib/plurimath/math/function/cancel.rb +12 -0
  24. data/lib/plurimath/math/function/ceil.rb +12 -0
  25. data/lib/plurimath/math/function/color.rb +23 -0
  26. data/lib/plurimath/math/function/cos.rb +12 -0
  27. data/lib/plurimath/math/function/cosh.rb +12 -0
  28. data/lib/plurimath/math/function/cot.rb +12 -0
  29. data/lib/plurimath/math/function/coth.rb +12 -0
  30. data/lib/plurimath/math/function/csc.rb +12 -0
  31. data/lib/plurimath/math/function/csch.rb +12 -0
  32. data/lib/plurimath/math/function/ddot.rb +12 -0
  33. data/lib/plurimath/math/function/deg.rb +12 -0
  34. data/lib/plurimath/math/function/det.rb +12 -0
  35. data/lib/plurimath/math/function/dim.rb +12 -0
  36. data/lib/plurimath/math/function/dot.rb +12 -0
  37. data/lib/plurimath/math/function/exp.rb +12 -0
  38. data/lib/plurimath/math/function/f.rb +12 -0
  39. data/lib/plurimath/math/function/fenced.rb +22 -0
  40. data/lib/plurimath/math/function/floor.rb +12 -0
  41. data/lib/plurimath/math/function/font_style.rb +45 -0
  42. data/lib/plurimath/math/function/frac.rb +23 -0
  43. data/lib/plurimath/math/function/g.rb +12 -0
  44. data/lib/plurimath/math/function/gcd.rb +12 -0
  45. data/lib/plurimath/math/function/glb.rb +12 -0
  46. data/lib/plurimath/math/function/hat.rb +12 -0
  47. data/lib/plurimath/math/function/hom.rb +12 -0
  48. data/lib/plurimath/math/function/inf.rb +18 -0
  49. data/lib/plurimath/math/function/int.rb +17 -0
  50. data/lib/plurimath/math/function/ker.rb +12 -0
  51. data/lib/plurimath/math/function/lcm.rb +12 -0
  52. data/lib/plurimath/math/function/left.rb +23 -0
  53. data/lib/plurimath/math/function/lg.rb +12 -0
  54. data/lib/plurimath/math/function/lim.rb +23 -0
  55. data/lib/plurimath/math/function/liminf.rb +12 -0
  56. data/lib/plurimath/math/function/limits.rb +19 -0
  57. data/lib/plurimath/math/function/limsup.rb +12 -0
  58. data/lib/plurimath/math/function/ln.rb +12 -0
  59. data/lib/plurimath/math/function/log.rb +23 -0
  60. data/lib/plurimath/math/function/lub.rb +12 -0
  61. data/lib/plurimath/math/function/max.rb +12 -0
  62. data/lib/plurimath/math/function/min.rb +12 -0
  63. data/lib/plurimath/math/function/mod.rb +23 -0
  64. data/lib/plurimath/math/function/norm.rb +15 -0
  65. data/lib/plurimath/math/function/obrace.rb +12 -0
  66. data/lib/plurimath/math/function/oint.rb +17 -0
  67. data/lib/plurimath/math/function/overset.rb +23 -0
  68. data/lib/plurimath/math/function/power.rb +30 -0
  69. data/lib/plurimath/math/function/power_base.rb +26 -0
  70. data/lib/plurimath/math/function/prod.rb +23 -0
  71. data/lib/plurimath/math/function/root.rb +22 -0
  72. data/lib/plurimath/math/function/sec.rb +12 -0
  73. data/lib/plurimath/math/function/sech.rb +12 -0
  74. data/lib/plurimath/math/function/sin.rb +12 -0
  75. data/lib/plurimath/math/function/sinh.rb +12 -0
  76. data/lib/plurimath/math/function/sqrt.rb +16 -0
  77. data/lib/plurimath/math/function/stackrel.rb +12 -0
  78. data/lib/plurimath/math/function/substack.rb +18 -0
  79. data/lib/plurimath/math/function/sum.rb +23 -0
  80. data/lib/plurimath/math/function/sup.rb +12 -0
  81. data/lib/plurimath/math/function/table.rb +42 -0
  82. data/lib/plurimath/math/function/tan.rb +12 -0
  83. data/lib/plurimath/math/function/tanh.rb +12 -0
  84. data/lib/plurimath/math/function/td.rb +27 -0
  85. data/lib/plurimath/math/function/ternary_function.rb +42 -0
  86. data/lib/plurimath/math/function/text.rb +32 -0
  87. data/lib/plurimath/math/function/tilde.rb +12 -0
  88. data/lib/plurimath/math/function/tr.rb +25 -0
  89. data/lib/plurimath/math/function/ubrace.rb +12 -0
  90. data/lib/plurimath/math/function/ul.rb +12 -0
  91. data/lib/plurimath/math/function/unary_function.rb +41 -0
  92. data/lib/plurimath/math/function/underover.rb +12 -0
  93. data/lib/plurimath/math/function/underset.rb +12 -0
  94. data/lib/plurimath/math/function/vec.rb +12 -0
  95. data/lib/plurimath/math/function.rb +3 -0
  96. data/lib/plurimath/math/number.rb +29 -0
  97. data/lib/plurimath/math/symbol.rb +34 -0
  98. data/lib/plurimath/math.rb +51 -0
  99. data/lib/plurimath/mathml/constants.rb +327 -0
  100. data/lib/plurimath/mathml/parse.rb +63 -0
  101. data/lib/plurimath/mathml/parser.rb +25 -0
  102. data/lib/plurimath/mathml/transform.rb +195 -0
  103. data/lib/plurimath/mathml.rb +16 -0
  104. data/lib/plurimath/omml.rb +15 -0
  105. data/lib/plurimath/unicode.rb +15 -0
  106. data/lib/plurimath/unitsml.rb +11 -0
  107. data/lib/plurimath/version.rb +3 -1
  108. data/lib/plurimath.rb +3 -5
  109. data/plurimath.gemspec +3 -3
  110. 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,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plurimath
4
+ class Latex
5
+ attr_accessor :text
6
+
7
+ def initialize(text)
8
+ @text = text
9
+ end
10
+
11
+ def to_formula
12
+ Parser.new(text).parse
13
+ end
14
+ end
15
+ 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,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "unary_function"
4
+
5
+ module Plurimath
6
+ module Math
7
+ module Function
8
+ class Abs < UnaryFunction
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "unary_function"
4
+
5
+ module Plurimath
6
+ module Math
7
+ module Function
8
+ class Arccos < UnaryFunction
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "unary_function"
4
+
5
+ module Plurimath
6
+ module Math
7
+ module Function
8
+ class Arcsin < UnaryFunction
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "unary_function"
4
+
5
+ module Plurimath
6
+ module Math
7
+ module Function
8
+ class Arctan < UnaryFunction
9
+ end
10
+ end
11
+ end
12
+ 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,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "unary_function"
4
+
5
+ module Plurimath
6
+ module Math
7
+ module Function
8
+ class Cancel < UnaryFunction
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "unary_function"
4
+
5
+ module Plurimath
6
+ module Math
7
+ module Function
8
+ class Ceil < UnaryFunction
9
+ end
10
+ end
11
+ end
12
+ 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