plurimath 0.8.16 → 0.8.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/gen_docs.yml +10 -8
  3. data/Gemfile +1 -1
  4. data/README.adoc +4 -0
  5. data/Rakefile +55 -8
  6. data/intent_supported_classes.adoc +82 -0
  7. data/lib/plurimath/asciimath/parse.rb +1 -0
  8. data/lib/plurimath/asciimath/transform.rb +12 -0
  9. data/lib/plurimath/formatter/number_formatter.rb +6 -6
  10. data/lib/plurimath/formatter/numeric_formatter.rb +5 -2
  11. data/lib/plurimath/formatter/standard.rb +2 -0
  12. data/lib/plurimath/math/core.rb +65 -6
  13. data/lib/plurimath/math/formula/mrow.rb +193 -0
  14. data/lib/plurimath/math/formula/mstyle.rb +17 -0
  15. data/lib/plurimath/math/formula.rb +317 -7
  16. data/lib/plurimath/math/function/abs.rb +5 -1
  17. data/lib/plurimath/math/function/base.rb +4 -0
  18. data/lib/plurimath/math/function/color.rb +17 -4
  19. data/lib/plurimath/math/function/fenced.rb +238 -7
  20. data/lib/plurimath/math/function/frac.rb +12 -1
  21. data/lib/plurimath/math/function/inf.rb +5 -1
  22. data/lib/plurimath/math/function/int.rb +5 -1
  23. data/lib/plurimath/math/function/intent.rb +6 -2
  24. data/lib/plurimath/math/function/lim.rb +5 -1
  25. data/lib/plurimath/math/function/linebreak.rb +2 -2
  26. data/lib/plurimath/math/function/longdiv.rb +3 -0
  27. data/lib/plurimath/math/function/menclose.rb +3 -0
  28. data/lib/plurimath/math/function/merror.rb +5 -2
  29. data/lib/plurimath/math/function/mglyph.rb +27 -0
  30. data/lib/plurimath/math/function/mlabeledtr.rb +19 -0
  31. data/lib/plurimath/math/function/mpadded.rb +28 -1
  32. data/lib/plurimath/math/function/ms.rb +80 -0
  33. data/lib/plurimath/math/function/msgroup.rb +15 -0
  34. data/lib/plurimath/math/function/msline.rb +5 -2
  35. data/lib/plurimath/math/function/multiscript.rb +14 -0
  36. data/lib/plurimath/math/function/nary.rb +13 -1
  37. data/lib/plurimath/math/function/oint.rb +5 -1
  38. data/lib/plurimath/math/function/over.rb +3 -0
  39. data/lib/plurimath/math/function/overset.rb +11 -0
  40. data/lib/plurimath/math/function/phantom.rb +3 -0
  41. data/lib/plurimath/math/function/power.rb +3 -0
  42. data/lib/plurimath/math/function/power_base.rb +3 -0
  43. data/lib/plurimath/math/function/prod.rb +5 -1
  44. data/lib/plurimath/math/function/root.rb +3 -0
  45. data/lib/plurimath/math/function/scarries.rb +3 -0
  46. data/lib/plurimath/math/function/semantics.rb +14 -0
  47. data/lib/plurimath/math/function/sqrt.rb +3 -0
  48. data/lib/plurimath/math/function/stackrel.rb +3 -0
  49. data/lib/plurimath/math/function/sum.rb +5 -1
  50. data/lib/plurimath/math/function/table/array.rb +1 -1
  51. data/lib/plurimath/math/function/table/bmatrix.rb +1 -1
  52. data/lib/plurimath/math/function/table/cases.rb +2 -2
  53. data/lib/plurimath/math/function/table/eqarray.rb +2 -2
  54. data/lib/plurimath/math/function/table/pmatrix.rb +1 -1
  55. data/lib/plurimath/math/function/table/vmatrix.rb +1 -1
  56. data/lib/plurimath/math/function/table.rb +65 -0
  57. data/lib/plurimath/math/function/td.rb +4 -1
  58. data/lib/plurimath/math/function/text.rb +22 -2
  59. data/lib/plurimath/math/function/tr.rb +13 -0
  60. data/lib/plurimath/math/function/unary_function.rb +5 -1
  61. data/lib/plurimath/math/function/underover.rb +3 -0
  62. data/lib/plurimath/math/function/underset.rb +44 -0
  63. data/lib/plurimath/math/number.rb +10 -1
  64. data/lib/plurimath/math/symbols/bigwedge.rb +4 -0
  65. data/lib/plurimath/math/symbols/cap.rb +0 -4
  66. data/lib/plurimath/math/symbols/clockoint.rb +1 -1
  67. data/lib/plurimath/math/symbols/cntclockoint.rb +1 -1
  68. data/lib/plurimath/math/symbols/coprod.rb +1 -1
  69. data/lib/plurimath/math/symbols/dd.rb +4 -0
  70. data/lib/plurimath/math/symbols/dint.rb +4 -0
  71. data/lib/plurimath/math/symbols/duni.rb +4 -0
  72. data/lib/plurimath/math/symbols/gg.rb +4 -4
  73. data/lib/plurimath/math/symbols/ii.rb +4 -0
  74. data/lib/plurimath/math/symbols/iiiint.rb +1 -1
  75. data/lib/plurimath/math/symbols/iiint.rb +4 -0
  76. data/lib/plurimath/math/symbols/iint.rb +1 -1
  77. data/lib/plurimath/math/symbols/intclockwise.rb +1 -1
  78. data/lib/plurimath/math/symbols/intercal.rb +4 -0
  79. data/lib/plurimath/math/symbols/jj.rb +4 -0
  80. data/lib/plurimath/math/symbols/ll.rb +4 -4
  81. data/lib/plurimath/math/symbols/minus.rb +1 -1
  82. data/lib/plurimath/math/symbols/oiiint.rb +1 -1
  83. data/lib/plurimath/math/symbols/oiint.rb +1 -1
  84. data/lib/plurimath/math/symbols/oint.rb +1 -1
  85. data/lib/plurimath/math/symbols/symbol.rb +12 -4
  86. data/lib/plurimath/math/symbols/upcase_dd.rb +4 -0
  87. data/lib/plurimath/math.rb +2 -0
  88. data/lib/plurimath/mathml/parser.rb +45 -86
  89. data/lib/plurimath/mathml/utility/empty_defined_methods.rb +477 -0
  90. data/lib/plurimath/mathml/utility/formula_transformation.rb +472 -0
  91. data/lib/plurimath/mathml/utility.rb +363 -0
  92. data/lib/plurimath/mathml.rb +1 -0
  93. data/lib/plurimath/unicode_math/transform.rb +2 -2
  94. data/lib/plurimath/utility/intent_encoding.rb +21 -21
  95. data/lib/plurimath/utility.rb +5 -23
  96. data/lib/plurimath/version.rb +1 -1
  97. data/lib/plurimath.rb +9 -0
  98. data/plurimath.gemspec +4 -2
  99. metadata +38 -5
  100. data/lib/plurimath/mathml/transform.rb +0 -411
@@ -1,411 +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
- else
249
- Math::Function::Overset.new(mover[1], mover[0])
250
- end
251
- end
252
-
253
- rule(munder: sequence(:munder)) do
254
- if munder.any?(String)
255
- munder.each_with_index do |object, ind|
256
- next unless object.is_a?(String)
257
-
258
- munder[ind] = Utility.mathml_unary_classes([object], lang: :mathml)
259
- end
260
- end
261
- if munder.length == 1
262
- munder.first.class_name == "bar" ? munder.first.swap_class : munder.last
263
- elsif ["ubrace", "obrace", "underline"].any?(munder.last.class_name)
264
- munder.last.parameter_one = munder.shift if munder.length > 1
265
- munder.last
266
- elsif Constants::CLASSES.include?(munder.first.class_name)
267
- munder.first.parameter_one = munder.delete_at(1)
268
- munder.first
269
- else
270
- Math::Function::Underset.new(
271
- munder[1],
272
- munder[0],
273
- )
274
- end
275
- end
276
-
277
- rule(mscarries: sequence(:scarries)) do
278
- Math::Function::Scarries.new(
279
- Utility.filter_values(scarries),
280
- )
281
- end
282
-
283
- rule(mpadded: sequence(:padded)) do
284
- Math::Function::Mpadded.new(
285
- Utility.filter_values(padded),
286
- )
287
- end
288
-
289
- rule(mtext: subtree(:mtext)) do
290
- entities = HTMLEntities.new
291
- symbols = Constants::UNICODE_SYMBOLS.transform_keys(&:to_s)
292
- text = entities.encode(mtext.flatten.join, :hexadecimal)
293
- symbols.each do |code, string|
294
- text = text.gsub(code.downcase, "unicode[:#{string}]")
295
- end
296
- Math::Function::Text.new(text)
297
- end
298
-
299
- rule(ms: sequence(:ms)) do
300
- Math::Function::Ms.new(
301
- ms.flatten.compact.join(" "),
302
- )
303
- end
304
-
305
- rule(mfenced: sequence(:fenced)) do
306
- Math::Function::Fenced.new(
307
- Math::Symbols::Paren::Lround.new,
308
- fenced.compact,
309
- Math::Symbols::Paren::Rround.new,
310
- )
311
- end
312
-
313
- rule(mmultiscripts: subtree(:script)) do
314
- multi = Utility.multiscript(script)
315
- prescripts = multi[1]
316
- Math::Function::Multiscript.new(
317
- multi[0],
318
- (prescripts[0] if prescripts),
319
- (prescripts[1] if prescripts),
320
- )
321
- end
322
-
323
- rule(mathcolor: simple(:color)) do
324
- Math::Function::Color.new(
325
- Math::Function::Text.new(color),
326
- )
327
- end
328
-
329
- rule(open: simple(:lparen),
330
- close: simple(:rparen)) do
331
- Math::Function::Fenced.new(
332
- Utility.symbols_class(lparen, lang: :mathml),
333
- nil,
334
- Utility.symbols_class(rparen, lang: :mathml),
335
- )
336
- end
337
-
338
- rule(mathcolor: simple(:color),
339
- mathvariant: simple(:variant)) do
340
- variant_class = Utility::FONT_STYLES[variant.to_sym]
341
- if variant_class
342
- Math::Function::Color.new(
343
- Math::Function::Text.new(
344
- color,
345
- ),
346
- variant_class.new(
347
- nil,
348
- variant,
349
- ),
350
- )
351
- else
352
- Math::Function::Color.new(
353
- Math::Function::Text.new(
354
- color,
355
- ),
356
- )
357
- end
358
- end
359
-
360
- rule(semantics: subtree(:value)) do
361
- Math::Function::Semantics.new(
362
- value.shift,
363
- value,
364
- )
365
- end
366
-
367
- rule(attributes: simple(:attrs),
368
- value: subtree(:value)) do
369
- Utility.join_attr_value(attrs, value&.flatten&.compact)
370
- end
371
-
372
- rule(attributes: subtree(:attrs),
373
- value: sequence(:value)) do
374
- approved = if attrs.is_a?(Hash)
375
- supported_attrs = %w[
376
- linethickness
377
- accentunder
378
- columnlines
379
- separators
380
- rowlines
381
- bevelled
382
- notation
383
- height
384
- accent
385
- height
386
- intent
387
- width
388
- index
389
- depth
390
- width
391
- frame
392
- alt
393
- src
394
- ]
395
- attrs if attrs.keys.any? do |k|
396
- supported_attrs.include?(k.to_s)
397
- end
398
- unicode_only = true if attrs.key?(:linebreak)
399
- attrs
400
- else
401
- attrs
402
- end
403
- Utility.join_attr_value(
404
- approved,
405
- value&.flatten&.compact,
406
- unicode_only: unicode_only,
407
- )
408
- end
409
- end
410
- end
411
- end