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,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "unicode"
4
+ require_relative "asciimath"
5
+ require_relative "omml"
6
+ require_relative "mathml"
7
+ require_relative "html"
8
+ require_relative "latex"
9
+ require_relative "unitsml"
10
+ require_relative "math/formula"
11
+ require_relative "math/function"
12
+ require_relative "math/number"
13
+ require_relative "math/symbol"
14
+ require_relative "asciimath/parser"
15
+ require_relative "mathml/parser"
16
+ require_relative "latex/parser"
17
+ module Plurimath
18
+ module Math
19
+ class Error < StandardError; end
20
+
21
+ VALID_TYPES = {
22
+ unicode: Unicode,
23
+ asciimath: Asciimath,
24
+ omml: Omml,
25
+ mathml: Mathml,
26
+ html: Html,
27
+ latex: Latex,
28
+ }.freeze
29
+
30
+ def parse(text, type)
31
+ raise_error! unless valid_type?(type)
32
+
33
+ klass = VALID_TYPES[type.to_sym]
34
+ klass.new(text).to_formula
35
+ end
36
+
37
+ private
38
+
39
+ def raise_error!
40
+ raise Plurimath::Math::Error, Error.new("Type is not valid, "\
41
+ "please enter string or symbol")
42
+ end
43
+
44
+ def valid_type?(type)
45
+ (type.is_a?(Symbol) || type.is_a?(String)) &&
46
+ VALID_TYPES.key?(type.to_sym)
47
+ end
48
+
49
+ module_function :parse, :raise_error!, :valid_type?
50
+ end
51
+ end
@@ -0,0 +1,327 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plurimath
4
+ class Mathml
5
+ class Constants
6
+ UNICODE_SYMBOLS = {
7
+ "&#x3B1;": "alpha",
8
+ "&#x3B2;": "beta",
9
+ "&#x3B3;": "gamma",
10
+ "&#x393;": "Gamma",
11
+ "&#x3B4;": "delta",
12
+ "&#x394;": "Delta",
13
+ "&#x2206;": "Delta",
14
+ "&#x3B5;": "epsilon",
15
+ "&#x25b;": "varepsilon",
16
+ "&#x3B6;": "zeta",
17
+ "&#x3B7;": "eta",
18
+ "&#x3B8;": "theta",
19
+ "&#x398;": "Theta",
20
+ "&#x3D1;": "vartheta",
21
+ "&#x3B9;": "iota",
22
+ "&#x3BA;": "kappa",
23
+ "&#x3BB;": "lambda",
24
+ "&#x39B;": "Lambda",
25
+ "&#x3BC;": "mu",
26
+ "&#x3BD;": "nu",
27
+ "&#x3BE;": "xi",
28
+ "&#x39E;": "Xi",
29
+ "&#x3C0;": "pi",
30
+ "&#x3A0;": "Pi",
31
+ "&#x3C1;": "rho",
32
+ "&#x3C2;": "beta",
33
+ "&#x3C3;": "sigma",
34
+ "&#x3A3;": "Sigma",
35
+ "&#x3C4;": "tau",
36
+ "&#x3C5;": "upsilon",
37
+ "&#x3C6;": "phi",
38
+ "&#x3A6;": "Phi",
39
+ "&#x3D5;": "varphi",
40
+ "&#x3C7;": "chi",
41
+ "&#x3C8;": "psi",
42
+ "&#x3A8;": "Psi",
43
+ "&#x3C9;": "omega",
44
+ "&#x3A9;": "omega",
45
+ "&#x22C5;": "dot",
46
+ "&#x2219;": "*",
47
+ "&#xB7;": ".",
48
+ "&#x2217;": "**",
49
+ "&#x22C6;": "***",
50
+ "&#xD7;": "xx",
51
+ "&#x22C9;": "|><",
52
+ "&#x22CA;": "><|",
53
+ "&#x22C8;": "|><|",
54
+ "&#xF7;": "-:",
55
+ "&#x2218;": "@",
56
+ "&#x2295;": "o+",
57
+ "&#x2A01;": "o+",
58
+ "&#x2297;": "ox",
59
+ "&#x2299;": " ",
60
+ "&#x2211;": "sum",
61
+ "&#x220F;": "prod",
62
+ "&#x220f;": "prod",
63
+ "&#x2227;": "^^",
64
+ "&#x22C0;": "^^^",
65
+ "&#x2228;": "vv",
66
+ "&#x22c1;": "vvv",
67
+ "&#x2229;": "nn",
68
+ "&#x22C2;": "nnn",
69
+ "&#x222A;": "cup",
70
+ "&#x22C3;": "uuu",
71
+ "&#x2260;": "!=",
72
+ "&#x2264;": "<=",
73
+ "&#x2265;": ">=",
74
+ "&#x227A;": "-<",
75
+ "&#x227B;": ">-",
76
+ "&#x2AAF;": "-<=",
77
+ "&#x2AB0;": " >-=",
78
+ "&#x2208;": "in",
79
+ "&#x2209;": "!in",
80
+ "&#x2282;": "sub",
81
+ "&#x2283;": "sup",
82
+ "&#x2286;": "sube",
83
+ "&#x2287;": "supe",
84
+ "&#x2261;": "-=",
85
+ "&#x2245;": "~=",
86
+ "&#x2248;": "~~",
87
+ "&#x221D;": "prop",
88
+ "&#xAC;": "not",
89
+ "&#x2200;": "AA",
90
+ "&#x2203;": "EE",
91
+ "&#x22A5;": "_|_",
92
+ "&#x22A4;": "TT",
93
+ "&#x22A2;": "|--",
94
+ "&#x22A8;": "|==",
95
+ "&#x2329;": "(:",
96
+ "&#x232A;": ":)",
97
+ "&#x27E8;": "<<",
98
+ "&#x27E9;": ">>",
99
+ "&#x222B;": "int",
100
+ "&#x222E;": "oint",
101
+ "&#x2202;": "del",
102
+ "&#x2207;": "grad",
103
+ "&#xB1;": "+-",
104
+ "&#x2205;": "O/",
105
+ "&#x221E;": "oo",
106
+ "&#x2135;": "aleph",
107
+ "&#x2234;": ":.",
108
+ "&#x2235;": ":'",
109
+ "&#x2220;": "/_",
110
+ "&#x25B3;": "/_\\",
111
+ "&#x2032;": "'",
112
+ "&#xA0;&#xA0;": "quad",
113
+ "&#xA0;&#xA0;&#xA0;&#xA0;": "qquad",
114
+ "&#x2322;": "frown",
115
+ "&#x22EF;": "cdots",
116
+ "&#x22EE;": "vdots",
117
+ "&#x22F1;": "ddots",
118
+ "&#x22C4;": "diamond",
119
+ "&#x25A1;": "square",
120
+ "&#x230A;": "|__",
121
+ "&#x230B;": "__|",
122
+ "&#x2308;": "|~",
123
+ "&#x2309;": "~|",
124
+ "&#x2102;": "CC",
125
+ "&#x2115;": "NN",
126
+ "&#x211A;": "QQ",
127
+ "&#x211D;": "RR",
128
+ "&#x2124;": "ZZ",
129
+ "&#x2191;": "uarr",
130
+ "&#x2193;": "darr",
131
+ "&#x2190;": "larr",
132
+ "&#x2194;": "harr",
133
+ "&#x21D2;": "rArr",
134
+ "&#x21D0;": "lArr",
135
+ "&#x21D4;": "hArr",
136
+ "&#x2192;": "->",
137
+ "&#x21A3;": ">->",
138
+ "&#x21A0;": "->>",
139
+ "&#x2916;": ">->>",
140
+ "&#x21A6;": "|->",
141
+ "&#x2026;": "...",
142
+ "&#x2212;": "-",
143
+ "&#x2061;": "",
144
+ "&#x23DE;": "obrace",
145
+ "&#x23DF;": "ubrace",
146
+ }.freeze
147
+ SYMBOLS = {
148
+ "|": "|",
149
+ "/": "//",
150
+ "\\": "\\\\",
151
+ "~": "tilde",
152
+ "(": "(",
153
+ ")": ")",
154
+ "(:": "(:",
155
+ ":)": ":)",
156
+ "{": "{",
157
+ "}": "}",
158
+ "{:": "{:",
159
+ ":}": ":}",
160
+ "]": "]",
161
+ "[": "[",
162
+ "=": "=",
163
+ "+": "+",
164
+ "-": "-",
165
+ }.freeze
166
+ CLASSES = %w[
167
+ mathfrak
168
+ underset
169
+ stackrel
170
+ overset
171
+ mathcal
172
+ arccos
173
+ arcsin
174
+ arctan
175
+ mathsf
176
+ mathbb
177
+ mathbf
178
+ mathtt
179
+ ubrace
180
+ obrace
181
+ cancel
182
+ tilde
183
+ floor
184
+ color
185
+ frac
186
+ root
187
+ oint
188
+ ceil
189
+ ddot
190
+ coth
191
+ csch
192
+ sech
193
+ sinh
194
+ tanh
195
+ cosh
196
+ sqrt
197
+ norm
198
+ text
199
+ prod
200
+ sec
201
+ int
202
+ sin
203
+ tan
204
+ cos
205
+ sum
206
+ exp
207
+ gcd
208
+ glb
209
+ lcm
210
+ lub
211
+ cot
212
+ csc
213
+ det
214
+ dim
215
+ max
216
+ min
217
+ abs
218
+ bar
219
+ dot
220
+ hat
221
+ vec
222
+ mod
223
+ log
224
+ ul
225
+ ln
226
+ f
227
+ g
228
+ ].freeze
229
+ TAGS = %i[
230
+ annotation-xml
231
+ annotation_xml
232
+ mmultiscripts
233
+ maligngroup
234
+ malignmark
235
+ annotation
236
+ munderover
237
+ mscarries
238
+ semantics
239
+ mphantom
240
+ mlongdiv
241
+ menclose
242
+ mscarry
243
+ msubsup
244
+ mpadded
245
+ maction
246
+ msgroup
247
+ mfenced
248
+ merror
249
+ munder
250
+ mtable
251
+ mstyle
252
+ mstack
253
+ mspace
254
+ msline
255
+ mfrac
256
+ mover
257
+ msrow
258
+ mroot
259
+ msqrt
260
+ msup
261
+ msub
262
+ mrow
263
+ math
264
+ mtr
265
+ mtd
266
+ ms
267
+ mi
268
+ mo
269
+ mn
270
+ ].freeze
271
+ BINARY_CLASSES = %i[
272
+ underset
273
+ stackrel
274
+ overset
275
+ color
276
+ prod
277
+ frac
278
+ root
279
+ oint
280
+ int
281
+ sum
282
+ mod
283
+ log
284
+ ].freeze
285
+ FONT_CLASSES = %i[
286
+ fraktur
287
+ sans-serif
288
+ monospace
289
+ script
290
+ double-struck
291
+ bold
292
+ ].freeze
293
+ FONT_TYPES = {
294
+ :bb=>"bold",
295
+ :fr=>"fraktur",
296
+ :cc=>"script",
297
+ :sf=>"sans-serif",
298
+ :tt=>"monospace",
299
+ :mbf=>"bold",
300
+ :mit=>"italic",
301
+ :mtt=>"monospace",
302
+ :Bbb=>"double-struck",
303
+ :bbb=>"double-struck",
304
+ :mscr=>"mathbb",
305
+ :mfrak=>"fraktur",
306
+ :msans=>"sans-serif",
307
+ :mbfit=>"bold italic",
308
+ :mathbf=>"bold",
309
+ :mathit=>"italic",
310
+ :mathds=>"mathbb",
311
+ :mathrm=>"mathrm",
312
+ :mathtt=>"monospace",
313
+ :mathsf=>"sans-serif",
314
+ :mathbb=>"double-struck",
315
+ :mbfsans=>"bold sans-serif",
316
+ :mathcal=>"script",
317
+ :mathbold=>"bold",
318
+ :mathfrak=>"fraktur",
319
+ :mathbfit=>"bold italic",
320
+ :mathsfbf=>"sans-serif bold",
321
+ :mathsfit=>"sans-serif italic",
322
+ :mbfitsans=>"bold italic sans-serif",
323
+ :mathsfbfit=>"sans-serif bold italic",
324
+ }.freeze
325
+ end
326
+ end
327
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+ module Plurimath
5
+ class Mathml
6
+ class Parse < Parslet::Parser
7
+ rule(:parse_record) do
8
+ array_to_expression(Constants::CLASSES).as(:class) |
9
+ array_to_expression(Constants::UNICODE_SYMBOLS.keys).as(:symbol) |
10
+ array_to_expression(Constants::SYMBOLS.keys).as(:symbol) |
11
+ match["a-zA-Z"].repeat(1).as(:text) |
12
+ match(/[0-9]/).repeat(1).as(:number) |
13
+ str("")
14
+ end
15
+
16
+ rule(:tag) { (parse_tag(:open) >> iteration.as(:iteration) >> parse_tag(:close)).as(:tag) | parse_text_tag.as(:tag) }
17
+
18
+ rule(:sequence) { (tag >> sequence.as(:sequence)) | tag }
19
+
20
+ rule(:iteration) { (sequence >> iteration.as(:iteration)) | parse_record }
21
+
22
+ rule(:expression) { parse_tag(:open) >> iteration.as(:iteration) >> parse_tag(:close) }
23
+
24
+ root :expression
25
+
26
+ def array_to_expression(array, name = nil)
27
+ initial_type = array.first.class
28
+ array.reduce do |expr, tag|
29
+ expr = str_to_expression(expr, name) if expr.is_a?(initial_type)
30
+ expr | str_to_expression(tag, name)
31
+ end
32
+ end
33
+
34
+ def str_to_expression(string, name)
35
+ return str(string) if name.nil?
36
+
37
+ str(string).as(name)
38
+ end
39
+
40
+ def parse_tag(opts)
41
+ tag = str("<")
42
+ tag = tag >> str("/") if opts == :close
43
+ tag = tag >> array_to_expression(Constants::TAGS, opts)
44
+ tag = tag >> attributes.as(:attributes) if opts == :open
45
+ tag >> str(">")
46
+ end
47
+
48
+ def attributes
49
+ (match["a-zA-Z"].repeat.as(:name) >>
50
+ str("=") >> quoted_string).repeat
51
+ end
52
+
53
+ def quoted_string
54
+ (str('"') >> match("[^\"]").repeat.as(:value) >> str('"')) |
55
+ (str("'") >> match("[^\']").repeat.as(:value) >> str("'"))
56
+ end
57
+
58
+ def parse_text_tag
59
+ str("<mtext>") >> match("[^<]").repeat.as(:quoted_text) >> str("</mtext>")
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "parse"
4
+ require_relative "constants"
5
+ require_relative "transform"
6
+ module Plurimath
7
+ class Mathml
8
+ class Parser
9
+ attr_accessor :text
10
+
11
+ def initialize(text)
12
+ @text = text.gsub("\n", "").gsub(" ", "")
13
+ end
14
+
15
+ def parse
16
+ tree_t = Plurimath::Mathml::Parse.new.parse(text)
17
+ formula = Plurimath::Mathml::Transform.new.apply(tree_t)
18
+ formula = [formula] unless formula.is_a?(Array) || formula.nil?
19
+ return if formula.nil?
20
+
21
+ Plurimath::Math::Formula.new(formula)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plurimath
4
+ class Mathml
5
+ class Transform < Parslet::Transform
6
+ rule(tag: simple(:tag)) { tag }
7
+ rule(tag: sequence(:tag)) { tag }
8
+ rule(text: simple(:text)) { Plurimath::Math::Symbol.new(text.to_s) }
9
+ rule(class: simple(:string)) { Transform.get_class(string).new }
10
+ rule(number: simple(:number)) { Plurimath::Math::Number.new(number.to_s) }
11
+ rule(tag: sequence(:tag), sequence: simple(:sequence)) { tag + [sequence] }
12
+ rule(tag: simple(:tag), sequence: sequence(:sequence)) { [tag] + sequence }
13
+ rule(tag: sequence(:tag), sequence: sequence(:sequence)) { tag + sequence }
14
+
15
+ rule(quoted_text: simple(:quoted_text)) do
16
+ text = quoted_text.to_s
17
+ Constants::UNICODE_SYMBOLS.each do |code, string|
18
+ text.gsub!(code.to_s, "unicode[:#{string}]")
19
+ end
20
+ Plurimath::Math::Function::Text.new(text)
21
+ end
22
+
23
+ rule(
24
+ tag: sequence(:tag),
25
+ sequence: sequence(:sequence),
26
+ iteration: simple(:iteration),
27
+ ) do
28
+ new_arr = []
29
+ new_arr = new_arr + tag unless tag.compact.empty?
30
+ new_arr = new_arr + sequence unless sequence.compact.empty?
31
+ new_arr << iteration unless iteration.to_s.empty?
32
+ new_arr
33
+ end
34
+
35
+ rule(
36
+ tag: sequence(:tag),
37
+ sequence: simple(:sequence),
38
+ iteration: simple(:iteration),
39
+ ) do
40
+ Plurimath::Math::Formula.new(tag + [sequence])
41
+ end
42
+
43
+ rule(
44
+ tag: simple(:tag),
45
+ sequence: simple(:sequence),
46
+ iteration: simple(:iteration),
47
+ ) do
48
+ [tag, sequence]
49
+ end
50
+
51
+ rule(tag: sequence(:tag), iteration: simple(:iteration)) do
52
+ new_arr = []
53
+ new_arr = tag unless tag.compact.empty?
54
+ new_arr << iteration unless iteration.to_s.empty?
55
+ new_arr
56
+ end
57
+
58
+ rule(tag: simple(:tag), sequence: simple(:sequence)) do
59
+ new_arr = []
60
+ new_arr << tag unless tag.nil?
61
+ new_arr << sequence unless sequence.nil?
62
+ new_arr
63
+ end
64
+
65
+ rule(tag: simple(:tag), iteration: simple(:iteration)) do
66
+ new_arr = []
67
+ new_arr << tag unless tag.to_s.empty?
68
+ new_arr << iteration unless iteration.to_s.empty?
69
+ new_arr
70
+ end
71
+
72
+ rule(symbol: simple(:symbol)) do
73
+ decoded_symbol = Constants::UNICODE_SYMBOLS[symbol.to_sym]
74
+ if Constants::CLASSES.include?(decoded_symbol)
75
+ [Transform.get_class(decoded_symbol).new]
76
+ elsif decoded_symbol.nil? && Constants::SYMBOLS[symbol.to_sym]
77
+ Plurimath::Math::Symbol.new(Constants::SYMBOLS[symbol.to_sym])
78
+ else
79
+ Plurimath::Math::Symbol.new(decoded_symbol)
80
+ end
81
+ end
82
+
83
+ rule(name: simple(:name), value: simple(:value)) do
84
+ if ["open", "close"].include?(name.to_s)
85
+ Plurimath::Math::Symbol.new(value.to_s)
86
+ elsif name.to_s == "mathcolor"
87
+ Plurimath::Math::Function::Color.new(value.to_s)
88
+ elsif name.to_s == "mathvariant"
89
+ value.to_s
90
+ end
91
+ end
92
+
93
+ rule(
94
+ tag: simple(:tag),
95
+ sequence: sequence(:sequence),
96
+ iteration: simple(:iteration),
97
+ ) do
98
+ tag_str = tag.to_s.split("::").last.downcase.to_sym
99
+ if Constants::BINARY_CLASSES.include?(tag_str)
100
+ tag.new(sequence.first, sequence.last)
101
+ else
102
+ new_arr = sequence.compact
103
+ new_arr = [tag] + new_arr unless tag.nil?
104
+ new_arr << iteration unless iteration.to_s.empty?
105
+ new_arr
106
+ end
107
+ end
108
+
109
+ rule(
110
+ open: simple(:open_tag),
111
+ attributes: sequence(:attributes),
112
+ iteration: sequence(:iteration),
113
+ close: simple(:close_tag),
114
+ ) do
115
+ Transform.raise_error!(open_tag, close_tag) unless open_tag == close_tag
116
+
117
+ if open_tag == "mrow"
118
+ Plurimath::Math::Formula.new(iteration)
119
+ elsif open_tag == "munder"
120
+ if Transform.get_class("obrace") == iteration.last.class
121
+ iteration.last.parameter_one = iteration.first
122
+ iteration.last
123
+ else
124
+ Plurimath::Math::Function::Underset.new(iteration[1], iteration[0])
125
+ end
126
+ elsif open_tag == "munderover"
127
+ Plurimath::Math::Function::Underover.new(iteration[0], iteration[1], iteration[2])
128
+ elsif open_tag == "mover"
129
+ if Transform.get_class("ubrace") == iteration.last.class
130
+ iteration.last.parameter_one = iteration.first
131
+ iteration.last
132
+ else
133
+ Plurimath::Math::Function::Overset.new(iteration[1], iteration[0])
134
+ end
135
+ elsif open_tag == "msup"
136
+ Plurimath::Math::Function::Power.new(iteration[0], iteration[1])
137
+ elsif open_tag == "msub"
138
+ Plurimath::Math::Function::Base.new(iteration[0], iteration[1])
139
+ elsif open_tag == "msubsup"
140
+ Plurimath::Math::Function::PowerBase.new(iteration[0], iteration[1], iteration[2])
141
+ elsif open_tag == "mfrac"
142
+ Plurimath::Math::Function::Frac.new(iteration.first, iteration.last)
143
+ elsif open_tag == "msqrt"
144
+ Plurimath::Math::Function::Sqrt.new(iteration.first)
145
+ elsif open_tag == "mroot"
146
+ Plurimath::Math::Function::Root.new(iteration[0], iteration[1])
147
+ elsif open_tag == "mfenced"
148
+ Plurimath::Math::Function::Fenced.new(attributes[0], iteration, attributes[1])
149
+ elsif open_tag == "mtable"
150
+ Plurimath::Math::Function::Table.new(iteration)
151
+ elsif open_tag == "mtr"
152
+ Plurimath::Math::Function::Tr.new(iteration)
153
+ elsif open_tag == "mtd"
154
+ Plurimath::Math::Function::Td.new(iteration)
155
+ elsif attributes.first.is_a?(Plurimath::Math::Function::Color)
156
+ attributes.first.parameter_two = iteration.first
157
+ attributes.first
158
+ elsif open_tag == "mstyle" && !attributes.compact.empty?
159
+ font_type = attributes.compact.last.to_sym
160
+ if Constants::FONT_CLASSES.include?(font_type)
161
+ Math::Function::FontStyle.new(iteration.last, font_type.to_s)
162
+ end
163
+ else
164
+ iteration
165
+ end
166
+ end
167
+
168
+ rule(
169
+ open: simple(:open_tag),
170
+ attributes: sequence(:attributes),
171
+ iteration: simple(:iteration),
172
+ close: simple(:close_tag),
173
+ ) do
174
+ Transform.raise_error!(open_tag, close_tag) unless open_tag == close_tag
175
+
176
+ if iteration.to_s.include?("Function")
177
+ iteration
178
+ else
179
+ [iteration.to_s.empty? ? nil : iteration]
180
+ end
181
+ end
182
+
183
+ def self.get_class(text)
184
+ Object.const_get("Plurimath::Math::Function::#{text.to_s.capitalize}")
185
+ end
186
+
187
+ def self.raise_error!(open_tag, close_tag)
188
+ message = "Please check your input."\
189
+ " Opening tag is \"#{open_tag}\""\
190
+ " and closing tag is \"#{close_tag}\""
191
+ raise Plurimath::Math::Error.new(message)
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "math"
4
+ module Plurimath
5
+ class Mathml
6
+ attr_accessor :text
7
+
8
+ def initialize(text)
9
+ @text = text
10
+ end
11
+
12
+ def to_formula
13
+ Plurimath::Mathml::Parser.new(text).parse
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plurimath
4
+ class Omml
5
+ attr_accessor :text
6
+
7
+ def initialize(text)
8
+ @text = text
9
+ end
10
+
11
+ def to_formula
12
+ # TODO: Will be implemented soon
13
+ end
14
+ end
15
+ end