plurimath 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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