plurimath 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/Latex-Supported-Data.adoc +1 -0
  4. data/lib/plurimath/asciimath/parse.rb +1 -1
  5. data/lib/plurimath/asciimath/transform.rb +2 -6
  6. data/lib/plurimath/latex/constants.rb +2 -0
  7. data/lib/plurimath/math/core.rb +38 -6
  8. data/lib/plurimath/math/formula.rb +60 -6
  9. data/lib/plurimath/math/function/abs.rb +4 -0
  10. data/lib/plurimath/math/function/arg.rb +22 -0
  11. data/lib/plurimath/math/function/bar.rb +4 -0
  12. data/lib/plurimath/math/function/base.rb +49 -0
  13. data/lib/plurimath/math/function/binary_function.rb +6 -0
  14. data/lib/plurimath/math/function/cancel.rb +5 -0
  15. data/lib/plurimath/math/function/ceil.rb +6 -0
  16. data/lib/plurimath/math/function/color.rb +20 -1
  17. data/lib/plurimath/math/function/ddot.rb +4 -0
  18. data/lib/plurimath/math/function/dot.rb +5 -0
  19. data/lib/plurimath/math/function/fenced.rb +98 -7
  20. data/lib/plurimath/math/function/floor.rb +6 -0
  21. data/lib/plurimath/math/function/font_style/monospace.rb +4 -0
  22. data/lib/plurimath/math/function/font_style.rb +31 -6
  23. data/lib/plurimath/math/function/frac.rb +69 -15
  24. data/lib/plurimath/math/function/hat.rb +4 -0
  25. data/lib/plurimath/math/function/inf.rb +30 -0
  26. data/lib/plurimath/math/function/int.rb +47 -1
  27. data/lib/plurimath/math/function/intent.rb +22 -0
  28. data/lib/plurimath/math/function/left.rb +4 -0
  29. data/lib/plurimath/math/function/lim.rb +6 -0
  30. data/lib/plurimath/math/function/limits.rb +28 -0
  31. data/lib/plurimath/math/function/linebreak.rb +5 -0
  32. data/lib/plurimath/math/function/log.rb +27 -20
  33. data/lib/plurimath/math/function/longdiv.rb +4 -0
  34. data/lib/plurimath/math/function/mbox.rb +4 -0
  35. data/lib/plurimath/math/function/menclose.rb +74 -5
  36. data/lib/plurimath/math/function/merror.rb +2 -0
  37. data/lib/plurimath/math/function/mglyph.rb +64 -0
  38. data/lib/plurimath/math/function/mlabeledtr.rb +29 -0
  39. data/lib/plurimath/math/function/mod.rb +4 -0
  40. data/lib/plurimath/math/function/mpadded.rb +84 -0
  41. data/lib/plurimath/math/function/ms.rb +33 -0
  42. data/lib/plurimath/math/function/msgroup.rb +4 -0
  43. data/lib/plurimath/math/function/msline.rb +2 -4
  44. data/lib/plurimath/math/function/multiscript.rb +70 -6
  45. data/lib/plurimath/math/function/nary.rb +69 -10
  46. data/lib/plurimath/math/function/none.rb +25 -0
  47. data/lib/plurimath/math/function/norm.rb +6 -0
  48. data/lib/plurimath/math/function/obrace.rb +4 -0
  49. data/lib/plurimath/math/function/oint.rb +25 -1
  50. data/lib/plurimath/math/function/over.rb +6 -0
  51. data/lib/plurimath/math/function/overset.rb +46 -1
  52. data/lib/plurimath/math/function/phantom.rb +18 -2
  53. data/lib/plurimath/math/function/power.rb +37 -0
  54. data/lib/plurimath/math/function/power_base.rb +45 -18
  55. data/lib/plurimath/math/function/prod.rb +46 -0
  56. data/lib/plurimath/math/function/right.rb +4 -0
  57. data/lib/plurimath/math/function/root.rb +9 -1
  58. data/lib/plurimath/math/function/rule.rb +4 -0
  59. data/lib/plurimath/math/function/sqrt.rb +7 -1
  60. data/lib/plurimath/math/function/stackrel.rb +6 -0
  61. data/lib/plurimath/math/function/substack.rb +4 -0
  62. data/lib/plurimath/math/function/sum.rb +45 -24
  63. data/lib/plurimath/math/function/table/bmatrix.rb +18 -5
  64. data/lib/plurimath/math/function/table/cases.rb +24 -0
  65. data/lib/plurimath/math/function/table/eqarray.rb +24 -0
  66. data/lib/plurimath/math/function/table/matrix.rb +23 -3
  67. data/lib/plurimath/math/function/table/pmatrix.rb +4 -0
  68. data/lib/plurimath/math/function/table/vmatrix.rb +10 -0
  69. data/lib/plurimath/math/function/table.rb +58 -7
  70. data/lib/plurimath/math/function/td.rb +9 -0
  71. data/lib/plurimath/math/function/ternary_function.rb +14 -1
  72. data/lib/plurimath/math/function/text.rb +6 -0
  73. data/lib/plurimath/math/function/tilde.rb +4 -0
  74. data/lib/plurimath/math/function/tr.rb +9 -0
  75. data/lib/plurimath/math/function/ubrace.rb +5 -0
  76. data/lib/plurimath/math/function/ul.rb +4 -0
  77. data/lib/plurimath/math/function/unary_function.rb +4 -0
  78. data/lib/plurimath/math/function/underover.rb +14 -0
  79. data/lib/plurimath/math/function/underset.rb +49 -1
  80. data/lib/plurimath/math/function/vec.rb +4 -0
  81. data/lib/plurimath/math/number.rb +33 -3
  82. data/lib/plurimath/math/symbol.rb +68 -3
  83. data/lib/plurimath/math.rb +3 -2
  84. data/lib/plurimath/mathml/constants.rb +16 -0
  85. data/lib/plurimath/mathml/parser.rb +42 -2
  86. data/lib/plurimath/mathml/transform.rb +80 -29
  87. data/lib/plurimath/omml/parser.rb +8 -0
  88. data/lib/plurimath/omml/transform.rb +29 -26
  89. data/lib/plurimath/unicode_math/constants.rb +1015 -0
  90. data/lib/plurimath/unicode_math/parse.rb +233 -0
  91. data/lib/plurimath/unicode_math/parser.rb +58 -0
  92. data/lib/plurimath/unicode_math/parsing_rules/absence_rules.rb +138 -0
  93. data/lib/plurimath/unicode_math/parsing_rules/common_rules.rb +114 -0
  94. data/lib/plurimath/unicode_math/parsing_rules/constants_rules.rb +102 -0
  95. data/lib/plurimath/unicode_math/parsing_rules/helper.rb +19 -0
  96. data/lib/plurimath/unicode_math/parsing_rules/masked.rb +62 -0
  97. data/lib/plurimath/unicode_math/parsing_rules/sub_sup.rb +254 -0
  98. data/lib/plurimath/unicode_math/transform.rb +3831 -0
  99. data/lib/plurimath/{unicode.rb → unicode_math.rb} +2 -2
  100. data/lib/plurimath/unitsml.rb +14 -1
  101. data/lib/plurimath/utility.rb +346 -11
  102. data/lib/plurimath/version.rb +1 -1
  103. data/lib/plurimath/xml_engine/oga.rb +5 -0
  104. data/lib/plurimath/xml_engine/ox.rb +5 -0
  105. metadata +23 -3
@@ -8,34 +8,28 @@ module Plurimath
8
8
  rule(mo: sequence(:mo)) { Utility.mathml_unary_classes(mo) }
9
9
  rule(mtd: sequence(:mtd)) { Math::Function::Td.new(mtd) }
10
10
  rule(mtr: sequence(:mtr)) { Math::Function::Tr.new(mtr) }
11
+ rule(math: subtree(:math)) { math.flatten.compact }
12
+ rule(mfrac: simple(:mfrac)) { mfrac }
11
13
  rule(none: sequence(:none)) { nil }
12
- rule(mspace: simple(:space)) { nil }
13
- rule(notation: simple(:att)) { Math::Function::Menclose.new(att) }
14
+ rule(mspace: simple(:space)) { space.is_a?(Math::Function::Mpadded) ? nil : space }
14
15
  rule(mtable: simple(:table)) { table }
15
- rule(msqrt: sequence(:sqrt)) { Math::Function::Sqrt.new(sqrt.first) }
16
+ rule(mglyph: simple(:glyph)) { glyph }
16
17
  rule(mstyle: simple(:mstyle)) { mstyle }
17
18
  rule(msline: sequence(:line)) { Math::Function::Msline.new }
18
19
  rule(value: sequence(:value)) { Utility.filter_values(value) }
19
20
 
21
+ rule(mpadded: simple(:padded)) { padded }
20
22
  rule(mspace: sequence(:space)) { nil }
21
- rule(mstyle: sequence(:mstyle)) { Utility.filter_values(mstyle) }
22
23
  rule(mfenced: simple(:mfenced)) { mfenced }
23
24
  rule(mtable: sequence(:mtable)) { Math::Function::Table.new(mtable) }
24
25
  rule(mscarry: sequence(:scarry)) { nil }
25
26
  rule(menclose: simple(:enclose)) { enclose }
26
27
  rule(mlabeledtr: sequence(:mtr)) { Math::Function::Tr.new(mtr) }
27
- rule(mpadded: sequence(:padded)) { Utility.filter_values(padded) }
28
28
  rule(malignmark: sequence(:mark)) { nil }
29
29
  rule(maligngroup: sequence(:att)) { nil }
30
30
  rule(mprescripts: sequence(:att)) { "mprescripts" }
31
31
  rule(columnlines: simple(:lines)) { lines }
32
32
 
33
- rule(math: subtree(:math)) do
34
- Utility.filter_values(
35
- math.flatten.compact,
36
- )
37
- end
38
-
39
33
  rule(mphantom: sequence(:phantom)) do
40
34
  Math::Function::Phantom.new(
41
35
  Utility.filter_values(phantom),
@@ -75,9 +69,10 @@ module Plurimath
75
69
  Math::Function::Longdiv.new(long.flatten.compact)
76
70
  end
77
71
 
78
- rule(menclose: sequence(:close)) do
72
+ rule(menclose: subtree(:close)) do
73
+ options = close.find { |obj| obj.is_a?(Hash) and close.delete(obj) }
79
74
  Math::Function::Menclose.new(
80
- nil,
75
+ (options[:notation] if options),
81
76
  Utility.filter_values(close),
82
77
  )
83
78
  end
@@ -95,6 +90,15 @@ module Plurimath
95
90
  )
96
91
  end
97
92
 
93
+ rule(msqrt: subtree(:sqrt)) do
94
+ options = sqrt.find { |sqr| sqr.is_a?(Hash) and sqrt.delete(sqr) }
95
+ sqrt_obj = Math::Function::Sqrt.new(
96
+ Utility.filter_values(sqrt),
97
+ )
98
+ sqrt_obj.options = options
99
+ sqrt_obj
100
+ end
101
+
98
102
  rule(mfrac: sequence(:mfrac)) do
99
103
  Math::Function::Frac.new(
100
104
  mfrac[0],
@@ -184,6 +188,20 @@ module Plurimath
184
188
  Utility.fenceable_classes(flatten_mrow)
185
189
  if flatten_mrow.length == 1
186
190
  flatten_mrow.first
191
+ elsif flatten_mrow&.first&.is_nary_function? && flatten_mrow.length == 2
192
+ nary_function = flatten_mrow.first
193
+ if nary_function.is_ternary_function? && nary_function.all_values_exist?
194
+ flatten_mrow[0] = nary_function.new_nary_function(flatten_mrow.delete_at(1))
195
+ flatten_mrow
196
+ elsif nary_function.is_binary_function? && nary_function.any_value_exist?
197
+ flatten_mrow[0] = nary_function.new_nary_function(flatten_mrow.delete_at(1))
198
+ flatten_mrow
199
+ else
200
+ Math::Formula.new(
201
+ flatten_mrow,
202
+ Utility.mrow_left_right(flatten_mrow),
203
+ )
204
+ end
187
205
  else
188
206
  Math::Formula.new(
189
207
  flatten_mrow,
@@ -192,6 +210,18 @@ module Plurimath
192
210
  end
193
211
  end
194
212
 
213
+ rule(mstyle: sequence(:mstyle)) do
214
+ nary_function = mstyle.first
215
+ if nary_function&.is_nary_function?
216
+ if nary_function.is_ternary_function? && nary_function.parameter_three.nil?
217
+ nary_function.parameter_three = mstyle.delete_at(1)
218
+ elsif nary_function.is_binary_function?
219
+ mstyle[0] = nary_function.new_nary_function(mstyle.delete_at(1))
220
+ end
221
+ end
222
+ Utility.filter_values(mstyle)
223
+ end
224
+
195
225
  rule(msrow: sequence(:msrow)) do
196
226
  Math::Formula.new(msrow.flatten.compact)
197
227
  end
@@ -210,10 +240,7 @@ module Plurimath
210
240
  mover.last.parameter_one = mover.shift if mover.length > 1
211
241
  mover.last
212
242
  else
213
- Math::Function::Overset.new(
214
- mover[1],
215
- mover[0],
216
- )
243
+ Math::Function::Overset.new(mover[1], mover[0])
217
244
  end
218
245
  end
219
246
 
@@ -230,6 +257,9 @@ module Plurimath
230
257
  elsif ["ubrace", "obrace", "underline"].any?(munder.last.class_name)
231
258
  munder.last.parameter_one = munder.shift if munder.length > 1
232
259
  munder.last
260
+ elsif Constants::CLASSES.include?(munder.first.class_name)
261
+ munder.first.parameter_one = munder.delete_at(1)
262
+ munder.first
233
263
  else
234
264
  Math::Function::Underset.new(
235
265
  munder[1],
@@ -244,6 +274,12 @@ module Plurimath
244
274
  )
245
275
  end
246
276
 
277
+ rule(mpadded: sequence(:padded)) do
278
+ Math::Function::Mpadded.new(
279
+ Utility.filter_values(padded),
280
+ )
281
+ end
282
+
247
283
  rule(mtext: subtree(:mtext)) do
248
284
  entities = HTMLEntities.new
249
285
  symbols = Constants::UNICODE_SYMBOLS.transform_keys(&:to_s)
@@ -255,13 +291,9 @@ module Plurimath
255
291
  end
256
292
 
257
293
  rule(ms: sequence(:ms)) do
258
- entities = HTMLEntities.new
259
- symbols = Constants::UNICODE_SYMBOLS.transform_keys(&:to_s)
260
- text = entities.encode(ms.first, :hexadecimal)
261
- symbols.each do |code, string|
262
- text = text.gsub(code.downcase, "unicode[:#{string}]")
263
- end
264
- Math::Function::Text.new(text)
294
+ Math::Function::Ms.new(
295
+ ms.flatten.compact.join(" "),
296
+ )
265
297
  end
266
298
 
267
299
  rule(mfenced: sequence(:fenced)) do
@@ -273,7 +305,7 @@ module Plurimath
273
305
  end
274
306
 
275
307
  rule(mmultiscripts: subtree(:script)) do
276
- multi = Utility.multiscript(script.compact)
308
+ multi = Utility.multiscript(script)
277
309
  prescripts = multi[1]
278
310
  Math::Function::Multiscript.new(
279
311
  multi[0],
@@ -334,11 +366,30 @@ module Plurimath
334
366
  rule(attributes: subtree(:attrs),
335
367
  value: sequence(:value)) do
336
368
  approved = if attrs.is_a?(Hash)
337
- supported = %w[accentunder accent linebreak]
338
- if attrs.keys.any? { |k| supported.include?(k.to_s) }
339
- unicode_only = true if attrs.key?(:linebreak)
340
- attrs
369
+ supported_attrs = %w[
370
+ linethickness
371
+ accentunder
372
+ columnlines
373
+ separators
374
+ rowlines
375
+ bevelled
376
+ notation
377
+ height
378
+ accent
379
+ height
380
+ width
381
+ index
382
+ depth
383
+ width
384
+ frame
385
+ alt
386
+ src
387
+ ]
388
+ attrs if attrs.keys.any? do |k|
389
+ supported_attrs.include?(k.to_s)
341
390
  end
391
+ unicode_only = true if attrs.key?(:linebreak)
392
+ attrs
342
393
  else
343
394
  attrs
344
395
  end
@@ -8,6 +8,7 @@ module Plurimath
8
8
 
9
9
  CUSTOMIZABLE_TAGS = %w[
10
10
  eqArr
11
+ sPre
11
12
  mr
12
13
  r
13
14
  ].freeze
@@ -67,6 +68,8 @@ module Plurimath
67
68
  organize_fonts(node)
68
69
  when "mr", "eqArr"
69
70
  organize_table_td(node)
71
+ when "sPre"
72
+ organize_spre(node)
70
73
  end
71
74
  end
72
75
 
@@ -83,6 +86,11 @@ module Plurimath
83
86
  end
84
87
  node.attributes.merge! attrs_arr
85
88
  end
89
+
90
+ def organize_spre(node)
91
+ node.locate("sub").first.name = "sPreSub"
92
+ node.locate("sup").first.name = "sPreSup"
93
+ end
86
94
  end
87
95
  end
88
96
  end
@@ -32,10 +32,10 @@ module Plurimath
32
32
  rule(barPr: subtree(:barpr)) { barpr }
33
33
  rule(oMath: subtree(:omath)) { omath.flatten.compact }
34
34
  rule(fName: subtree(:fname)) { fname }
35
+ rule(sPreSub: sequence(:sub)) { { sub: Utility.nil_to_none_object(sub) } }
36
+ rule(sPreSup: sequence(:sup)) { { sup: Utility.nil_to_none_object(sup) } }
35
37
  rule(oMath: sequence(:omath)) { omath }
36
38
  rule(limLoc: simple(:limLoc)) { limLoc }
37
- rule(begChr: simple(:begChr)) { Math::Symbol.new(begChr) }
38
- rule(endChr: simple(:endChr)) { Math::Symbol.new(endChr) }
39
39
 
40
40
  rule(rFonts: subtree(:rFonts)) { nil }
41
41
  rule(sSupPr: subtree(:ssuppr)) { nil }
@@ -95,26 +95,32 @@ module Plurimath
95
95
  end
96
96
 
97
97
  rule(d: subtree(:data)) do
98
- fenced = data.flatten
99
- open_paren = fenced.shift if fenced&.first&.class_name == "symbol"
100
- close_paren = fenced.shift if fenced&.first&.class_name == "symbol"
101
- fenced_value = fenced.compact
102
- if fenced_value.length == 1 && fenced_value.first.is_a?(Math::Function::Table)
103
- fenced_value.first.open_paren = open_paren&.value
104
- fenced_value.first.close_paren = close_paren&.value
105
- fenced_value
98
+ fenced = data.shift
99
+ fenced_value = data.flatten.compact
100
+ if data.length == 1 && data.flatten.compact.first.is_a?(Math::Function::Table)
101
+ fenced_value.first.open_paren = fenced&.parameter_one&.value
102
+ fenced_value.first.close_paren = fenced&.parameter_three&.value
103
+ data
106
104
  else
107
- Math::Function::Fenced.new(
108
- open_paren,
109
- fenced_value,
110
- close_paren,
111
- )
105
+ fenced.parameter_two = data.flatten.compact
106
+ fenced
112
107
  end
113
108
  end
114
109
 
115
110
  rule(dPr: subtree(:dpr)) do
116
- dpr.reject! { |d| d.is_a?(Hash) }
117
- dpr
111
+ flatten_dpr = dpr.flatten.compact
112
+ open_paren = flatten_dpr.find { |hash| hash[:begChr] }&.values&.first
113
+ close_paren = flatten_dpr.find { |hash| hash[:endChr] }&.values&.first
114
+ sep_chr = flatten_dpr.find { |hash| hash[:sepChr] }
115
+ open_paren_object = Utility.symbol_object(open_paren) if open_paren
116
+ close_paren_object = Utility.symbol_object(close_paren) if close_paren
117
+ fenced = Math::Function::Fenced.new(
118
+ open_paren_object,
119
+ nil,
120
+ close_paren_object,
121
+ )
122
+ fenced.options = sep_chr
123
+ fenced
118
124
  end
119
125
 
120
126
  rule(mtd: sequence(:mtd)) do
@@ -149,11 +155,7 @@ module Plurimath
149
155
  end
150
156
 
151
157
  rule(lim: sequence(:lim)) do
152
- if lim.any?(String)
153
- Utility.text_classes(lim)
154
- else
155
- Utility.filter_values(lim)
156
- end
158
+ lim.any?(String) ? Utility.text_classes(lim) : Utility.filter_values(lim)
157
159
  end
158
160
 
159
161
  rule(acc: subtree(:acc)) do
@@ -298,11 +300,12 @@ module Plurimath
298
300
  end
299
301
 
300
302
  rule(sPre: subtree(:spre)) do
301
- pre = spre.flatten.compact
303
+ sub_value = spre.find { |pre| pre.is_a?(Hash) && pre[:sub] }[:sub]
304
+ sup_value = spre.find { |pre| pre.is_a?(Hash) && pre[:sup] }[:sup]
302
305
  Math::Function::Multiscript.new(
303
- pre[2],
304
- pre[0],
305
- pre[1],
306
+ Utility.filter_values(spre[0]),
307
+ sub_value,
308
+ sup_value,
306
309
  )
307
310
  end
308
311