plurimath 0.8.17 → 0.8.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/lib/plurimath/asciimath/parse.rb +1 -0
  4. data/lib/plurimath/asciimath/transform.rb +12 -0
  5. data/lib/plurimath/math/core.rb +63 -4
  6. data/lib/plurimath/math/formula/mrow.rb +193 -0
  7. data/lib/plurimath/math/formula/mstyle.rb +17 -0
  8. data/lib/plurimath/math/formula.rb +307 -4
  9. data/lib/plurimath/math/function/base.rb +4 -0
  10. data/lib/plurimath/math/function/color.rb +17 -4
  11. data/lib/plurimath/math/function/fenced.rb +219 -0
  12. data/lib/plurimath/math/function/frac.rb +4 -0
  13. data/lib/plurimath/math/function/linebreak.rb +2 -2
  14. data/lib/plurimath/math/function/longdiv.rb +3 -0
  15. data/lib/plurimath/math/function/menclose.rb +3 -0
  16. data/lib/plurimath/math/function/merror.rb +5 -2
  17. data/lib/plurimath/math/function/mglyph.rb +27 -0
  18. data/lib/plurimath/math/function/mlabeledtr.rb +19 -0
  19. data/lib/plurimath/math/function/mpadded.rb +28 -1
  20. data/lib/plurimath/math/function/ms.rb +80 -0
  21. data/lib/plurimath/math/function/msgroup.rb +15 -0
  22. data/lib/plurimath/math/function/msline.rb +5 -2
  23. data/lib/plurimath/math/function/multiscript.rb +14 -0
  24. data/lib/plurimath/math/function/over.rb +3 -0
  25. data/lib/plurimath/math/function/overset.rb +11 -0
  26. data/lib/plurimath/math/function/phantom.rb +3 -0
  27. data/lib/plurimath/math/function/power.rb +3 -0
  28. data/lib/plurimath/math/function/power_base.rb +3 -0
  29. data/lib/plurimath/math/function/root.rb +3 -0
  30. data/lib/plurimath/math/function/scarries.rb +3 -0
  31. data/lib/plurimath/math/function/semantics.rb +14 -0
  32. data/lib/plurimath/math/function/sqrt.rb +3 -0
  33. data/lib/plurimath/math/function/stackrel.rb +3 -0
  34. data/lib/plurimath/math/function/table.rb +53 -0
  35. data/lib/plurimath/math/function/td.rb +4 -1
  36. data/lib/plurimath/math/function/text.rb +22 -2
  37. data/lib/plurimath/math/function/tr.rb +13 -0
  38. data/lib/plurimath/math/function/underover.rb +3 -0
  39. data/lib/plurimath/math/function/underset.rb +44 -0
  40. data/lib/plurimath/math/number.rb +10 -1
  41. data/lib/plurimath/math/symbols/gg.rb +4 -4
  42. data/lib/plurimath/math/symbols/ll.rb +4 -4
  43. data/lib/plurimath/math/symbols/minus.rb +1 -1
  44. data/lib/plurimath/math/symbols/symbol.rb +12 -4
  45. data/lib/plurimath/math.rb +2 -0
  46. data/lib/plurimath/mathml/parser.rb +45 -86
  47. data/lib/plurimath/mathml/utility/empty_defined_methods.rb +477 -0
  48. data/lib/plurimath/mathml/utility/formula_transformation.rb +472 -0
  49. data/lib/plurimath/mathml/utility.rb +363 -0
  50. data/lib/plurimath/mathml.rb +1 -0
  51. data/lib/plurimath/unicode_math/transform.rb +2 -2
  52. data/lib/plurimath/utility.rb +5 -23
  53. data/lib/plurimath/version.rb +1 -1
  54. data/lib/plurimath.rb +9 -0
  55. data/plurimath.gemspec +4 -2
  56. metadata +37 -5
  57. data/lib/plurimath/mathml/transform.rb +0 -413
@@ -1,413 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Plurimath
4
- class Mathml
5
- class Transform < Parslet::Transform
6
- rule(mi: simple(:mi)) { mi }
7
- rule(mo: simple(:mo)) { mo }
8
- rule(mo: sequence(:mo)) { Utility.mathml_unary_classes(mo, lang: :mathml) }
9
- rule(mtd: sequence(:mtd)) { Math::Function::Td.new(mtd) }
10
- rule(mtr: sequence(:mtr)) { Math::Function::Tr.new(mtr) }
11
- rule(math: subtree(:math)) { math.flatten.compact }
12
- rule(mfrac: simple(:mfrac)) { mfrac }
13
- rule(none: sequence(:none)) { nil }
14
- rule(mspace: simple(:space)) { space.is_a?(Math::Function::Mpadded) ? nil : space }
15
- rule(mtable: simple(:table)) { table }
16
- rule(mglyph: simple(:glyph)) { glyph }
17
- rule(mstyle: simple(:mstyle)) { mstyle }
18
- rule(msline: sequence(:line)) { Math::Function::Msline.new }
19
- rule(value: sequence(:value)) { Utility.filter_values(value) }
20
-
21
- rule(mpadded: simple(:padded)) { padded }
22
- rule(mspace: sequence(:space)) { nil }
23
- rule(mfenced: simple(:mfenced)) { mfenced }
24
- rule(mtable: sequence(:mtable)) { Math::Function::Table.new(mtable) }
25
- rule(mscarry: sequence(:scarry)) { nil }
26
- rule(menclose: simple(:enclose)) { enclose }
27
- rule(mlabeledtr: sequence(:mtr)) { Math::Function::Tr.new(mtr) }
28
- rule(malignmark: sequence(:mark)) { nil }
29
- rule(maligngroup: sequence(:att)) { nil }
30
- rule(mprescripts: sequence(:att)) { "mprescripts" }
31
- rule(columnlines: simple(:lines)) { lines }
32
-
33
- rule(mphantom: sequence(:phantom)) do
34
- Math::Function::Phantom.new(
35
- Utility.filter_values(phantom),
36
- )
37
- end
38
-
39
- rule(mn: sequence(:mn)) do
40
- Math::Number.new(
41
- Utility.string_to_html_entity(
42
- mn.join,
43
- ),
44
- )
45
- end
46
-
47
- rule(mathvariant: simple(:variant)) do
48
- Utility::FONT_STYLES[variant.to_sym]&.new(nil, variant)
49
- end
50
-
51
- rule(mi: sequence(:mi)) do
52
- mi.any?(String) ? Utility.mathml_unary_classes(mi, lang: :mathml) : mi
53
- end
54
-
55
- rule(open: simple(:lparen)) do
56
- Math::Function::Fenced.new(
57
- Utility.symbols_class(lparen, lang: :mathml),
58
- )
59
- end
60
-
61
- rule(msgroup: sequence(:group)) do
62
- if group.any?(String)
63
- group.each_with_index do |object, ind|
64
- group[ind] = Utility.text_classes(object, lang: :mathml) if object.is_a?(String)
65
- end
66
- end
67
- Math::Function::Msgroup.new(group.flatten.compact)
68
- end
69
-
70
- rule(mlongdiv: sequence(:long)) do
71
- Math::Function::Longdiv.new(long.flatten.compact)
72
- end
73
-
74
- rule(menclose: subtree(:close)) do
75
- options = close.find { |obj| obj.is_a?(Hash) and close.delete(obj) }
76
- Math::Function::Menclose.new(
77
- (options[:notation] if options),
78
- Utility.filter_values(close),
79
- )
80
- end
81
-
82
- rule(mroot: sequence(:mroot)) do
83
- Math::Function::Root.new(
84
- mroot[1],
85
- mroot[0],
86
- )
87
- end
88
-
89
- rule(merror: sequence(:merror)) do
90
- Math::Function::Merror.new(
91
- Utility.filter_values(merror),
92
- )
93
- end
94
-
95
- rule(msqrt: subtree(:sqrt)) do
96
- options = sqrt.find { |sqr| sqr.is_a?(Hash) and sqrt.delete(sqr) }
97
- sqrt_obj = Math::Function::Sqrt.new(
98
- Utility.filter_values(sqrt),
99
- )
100
- sqrt_obj.options = options
101
- sqrt_obj
102
- end
103
-
104
- rule(mfrac: sequence(:mfrac)) do
105
- Math::Function::Frac.new(
106
- mfrac[0],
107
- mfrac[1],
108
- )
109
- end
110
-
111
- rule(mfraction: sequence(:mfrac)) do
112
- Math::Function::Frac.new(
113
- mfrac[0],
114
- mfrac[1],
115
- )
116
- end
117
-
118
- rule(msub: sequence(:msub)) do
119
- Math::Function::Base.new(
120
- msub[0],
121
- msub[1],
122
- )
123
- end
124
-
125
- rule(msub: subtree(:msub)) do
126
- Math::Function::Base.new(
127
- Utility.filter_values(msub[0]),
128
- Utility.filter_values(msub[1]),
129
- )
130
- end
131
-
132
- rule(msup: subtree(:msup)) do
133
- Math::Function::Power.new(
134
- Utility.filter_values(msup[0]),
135
- Utility.filter_values(msup[1]),
136
- )
137
- end
138
-
139
- rule(msup: sequence(:msup)) do
140
- Math::Function::Power.new(
141
- msup[0],
142
- msup[1],
143
- )
144
- end
145
-
146
- rule(msubsup: sequence(:function)) do
147
- base = function[0].is_a?(Math::Formula) ? function[0].value : function
148
- base_object = base.first
149
- if base_object.is_a?(Math::Function::BinaryFunction) && !base_object.any_value_exist?
150
- base_object.parameter_one = function[1]
151
- base_object.parameter_two = function[2]
152
- base_object
153
- elsif base_object.is_a?(Math::Function::TernaryFunction) && !base_object.any_value_exist?
154
- base_object.parameter_one = function[1]
155
- base_object.parameter_two = function[2]
156
- base_object.parameter_three = function[3]
157
- base_object
158
- else
159
- Math::Function::PowerBase.new(
160
- function[0],
161
- function[1],
162
- function[2],
163
- )
164
- end
165
- end
166
-
167
- rule(munderover: sequence(:function)) do
168
- base = function[0].is_a?(Math::Formula) ? function[0].value : function
169
- base_object = base.first
170
- if base_object.is_a?(Math::Function::BinaryFunction) && !base_object.any_value_exist?
171
- base_object.parameter_one = function[1]
172
- base_object.parameter_two = function[2]
173
- base_object
174
- elsif base_object.is_a?(Math::Function::TernaryFunction) && !base_object.any_value_exist?
175
- base_object.parameter_one = function[1]
176
- base_object.parameter_two = function[2]
177
- base_object.parameter_three = function[3]
178
- base_object
179
- else
180
- Math::Function::Underover.new(
181
- function[0],
182
- function[1],
183
- function[2],
184
- )
185
- end
186
- end
187
-
188
- rule(mrow: subtree(:mrow)) do
189
- flatten_mrow = Utility.populate_function_classes(mrow, lang: :mathml)
190
- Utility.fenceable_classes(flatten_mrow)
191
- if flatten_mrow.length == 1
192
- flatten_mrow.first
193
- elsif flatten_mrow&.first&.is_nary_function? && flatten_mrow.length == 2
194
- nary_function = flatten_mrow.first
195
- if nary_function.is_ternary_function? && nary_function.all_values_exist?
196
- if nary_function.respond_to?(:new_nary_function)
197
- flatten_mrow[0] = nary_function.new_nary_function(flatten_mrow.delete_at(1))
198
- flatten_mrow
199
- else
200
- Utility.filter_values(flatten_mrow)
201
- end
202
- elsif nary_function.is_binary_function? && nary_function.any_value_exist?
203
- flatten_mrow[0] = nary_function.new_nary_function(flatten_mrow.delete_at(1))
204
- flatten_mrow
205
- else
206
- Math::Formula.new(
207
- flatten_mrow,
208
- Utility.mrow_left_right(flatten_mrow),
209
- )
210
- end
211
- else
212
- Math::Formula.new(
213
- flatten_mrow,
214
- Utility.mrow_left_right(flatten_mrow),
215
- )
216
- end
217
- end
218
-
219
- rule(mstyle: sequence(:mstyle)) do
220
- nary_function = mstyle.first
221
- if nary_function&.is_nary_function?
222
- if nary_function.is_ternary_function? && nary_function.parameter_three.nil?
223
- nary_function.parameter_three = mstyle.delete_at(1)
224
- elsif nary_function.is_binary_function?
225
- mstyle[0] = nary_function.new_nary_function(mstyle.delete_at(1))
226
- end
227
- end
228
- Utility.filter_values(mstyle)
229
- end
230
-
231
- rule(msrow: sequence(:msrow)) do
232
- Math::Formula.new(msrow.flatten.compact)
233
- end
234
-
235
- rule(mstack: sequence(:stack)) do
236
- Math::Function::Stackrel.new(
237
- Utility.filter_values(stack),
238
- )
239
- end
240
-
241
- rule(mover: subtree(:mover)) do
242
- if mover&.length == 1
243
- base_object = mover.first
244
- base_object.class_name == "underline" ? base_object.swap_class : base_object
245
- elsif Constants::CLASSES.any?(mover&.last&.class_name)
246
- mover.last.parameter_one = mover.shift if mover.length > 1
247
- mover.last
248
- elsif mover&.last&.class_name == "period" && mover.length == 2
249
- Math::Function::Dot.new(mover[0])
250
- else
251
- Math::Function::Overset.new(mover[1], mover[0])
252
- end
253
- end
254
-
255
- rule(munder: sequence(:munder)) do
256
- if munder.any?(String)
257
- munder.each_with_index do |object, ind|
258
- next unless object.is_a?(String)
259
-
260
- munder[ind] = Utility.mathml_unary_classes([object], lang: :mathml)
261
- end
262
- end
263
- if munder.length == 1
264
- munder.first.class_name == "bar" ? munder.first.swap_class : munder.last
265
- elsif ["ubrace", "obrace", "underline"].any?(munder.last.class_name)
266
- munder.last.parameter_one = munder.shift if munder.length > 1
267
- munder.last
268
- elsif Constants::CLASSES.include?(munder.first.class_name)
269
- munder.first.parameter_one = munder.delete_at(1)
270
- munder.first
271
- else
272
- Math::Function::Underset.new(
273
- munder[1],
274
- munder[0],
275
- )
276
- end
277
- end
278
-
279
- rule(mscarries: sequence(:scarries)) do
280
- Math::Function::Scarries.new(
281
- Utility.filter_values(scarries),
282
- )
283
- end
284
-
285
- rule(mpadded: sequence(:padded)) do
286
- Math::Function::Mpadded.new(
287
- Utility.filter_values(padded),
288
- )
289
- end
290
-
291
- rule(mtext: subtree(:mtext)) do
292
- entities = HTMLEntities.new
293
- symbols = Constants::UNICODE_SYMBOLS.transform_keys(&:to_s)
294
- text = entities.encode(mtext.flatten.join, :hexadecimal)
295
- symbols.each do |code, string|
296
- text = text.gsub(code.downcase, "unicode[:#{string}]")
297
- end
298
- Math::Function::Text.new(text)
299
- end
300
-
301
- rule(ms: sequence(:ms)) do
302
- Math::Function::Ms.new(
303
- ms.flatten.compact.join(" "),
304
- )
305
- end
306
-
307
- rule(mfenced: sequence(:fenced)) do
308
- Math::Function::Fenced.new(
309
- Math::Symbols::Paren::Lround.new,
310
- fenced.compact,
311
- Math::Symbols::Paren::Rround.new,
312
- )
313
- end
314
-
315
- rule(mmultiscripts: subtree(:script)) do
316
- multi = Utility.multiscript(script)
317
- prescripts = multi[1]
318
- Math::Function::Multiscript.new(
319
- multi[0],
320
- (prescripts[0] if prescripts),
321
- (prescripts[1] if prescripts),
322
- )
323
- end
324
-
325
- rule(mathcolor: simple(:color)) do
326
- Math::Function::Color.new(
327
- Math::Function::Text.new(color),
328
- )
329
- end
330
-
331
- rule(open: simple(:lparen),
332
- close: simple(:rparen)) do
333
- Math::Function::Fenced.new(
334
- Utility.symbols_class(lparen, lang: :mathml),
335
- nil,
336
- Utility.symbols_class(rparen, lang: :mathml),
337
- )
338
- end
339
-
340
- rule(mathcolor: simple(:color),
341
- mathvariant: simple(:variant)) do
342
- variant_class = Utility::FONT_STYLES[variant.to_sym]
343
- if variant_class
344
- Math::Function::Color.new(
345
- Math::Function::Text.new(
346
- color,
347
- ),
348
- variant_class.new(
349
- nil,
350
- variant,
351
- ),
352
- )
353
- else
354
- Math::Function::Color.new(
355
- Math::Function::Text.new(
356
- color,
357
- ),
358
- )
359
- end
360
- end
361
-
362
- rule(semantics: subtree(:value)) do
363
- Math::Function::Semantics.new(
364
- value.shift,
365
- value,
366
- )
367
- end
368
-
369
- rule(attributes: simple(:attrs),
370
- value: subtree(:value)) do
371
- Utility.join_attr_value(attrs, value&.flatten&.compact)
372
- end
373
-
374
- rule(attributes: subtree(:attrs),
375
- value: sequence(:value)) do
376
- approved = if attrs.is_a?(Hash)
377
- supported_attrs = %w[
378
- linethickness
379
- accentunder
380
- columnlines
381
- separators
382
- rowlines
383
- bevelled
384
- notation
385
- height
386
- accent
387
- height
388
- intent
389
- width
390
- index
391
- depth
392
- width
393
- frame
394
- alt
395
- src
396
- ]
397
- attrs if attrs.keys.any? do |k|
398
- supported_attrs.include?(k.to_s)
399
- end
400
- unicode_only = true if attrs.key?(:linebreak)
401
- attrs
402
- else
403
- attrs
404
- end
405
- Utility.join_attr_value(
406
- approved,
407
- value&.flatten&.compact,
408
- unicode_only: unicode_only,
409
- )
410
- end
411
- end
412
- end
413
- end