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
@@ -0,0 +1,363 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "utility/empty_defined_methods"
4
+ require_relative "utility/formula_transformation"
5
+
6
+ module Plurimath
7
+ class Mathml
8
+ module Utility
9
+ include EmptyDefinedMethods
10
+ include FormulaTransformation
11
+
12
+ attr_accessor :temp_mathml_order
13
+
14
+ def element_order=(value)
15
+ @temp_mathml_order = Array(validated_order(value))
16
+ end
17
+
18
+ def clear_temp_order
19
+ @temp_mathml_order.shift(@temp_mathml_order.count)
20
+ end
21
+
22
+ def mathvariant=(value)
23
+ return if value.nil? || value.empty?
24
+ return unless Plurimath::Utility::FONT_STYLES.key?(value.to_sym)
25
+
26
+ @temp_mathml_order = [
27
+ Plurimath::Utility::FONT_STYLES[value.to_sym].new(
28
+ nil,
29
+ value,
30
+ ),
31
+ ]
32
+ end
33
+
34
+ def accent=(value)
35
+ return if value.nil? || value.empty?
36
+
37
+ @options = Hash(@options).merge(accent: true)
38
+ end
39
+
40
+ def accentunder=(value)
41
+ return if value.nil? || value.empty?
42
+
43
+ @options = Hash(@options).merge(accentunder: true)
44
+ end
45
+
46
+ def bevelled=(value)
47
+ return if value.nil? || value.empty?
48
+
49
+ @options = (@options || {}).merge(bevelled: value)
50
+ end
51
+
52
+ def linebreak=(value)
53
+ return if value.nil? || value.empty?
54
+
55
+ @temp_mathml_order << Plurimath::Math::Function::Linebreak.new(
56
+ nil,
57
+ { linebreak: value },
58
+ )
59
+ end
60
+
61
+ def linebreakstyle=(value)
62
+ return if value.nil? || value.empty?
63
+
64
+ linebreak_object = @temp_mathml_order.find do |object|
65
+ object.is_a?(Math::Function::Linebreak)
66
+ end
67
+ linebreak_object.attributes[:linebreakstyle] = value if linebreak_object
68
+ end
69
+
70
+ def linethickness=(value)
71
+ return if value.nil? || value.empty?
72
+
73
+ @options = (@options || {}).merge(linethickness: value)
74
+ end
75
+
76
+ def notation=(value)
77
+ return if value.nil? || value.empty?
78
+
79
+ @parameter_one = value
80
+ end
81
+
82
+ def mi_value=(value)
83
+ return if value.nil? || value.empty?
84
+
85
+ update_temp(
86
+ replace_order_with_value(
87
+ @temp_mathml_order,
88
+ validate_symbols(value),
89
+ "mi",
90
+ ),
91
+ )
92
+ end
93
+
94
+ def mo_value=(value)
95
+ return if value.nil? || value.empty?
96
+
97
+ update_temp(
98
+ replace_order_with_value(
99
+ @temp_mathml_order,
100
+ validate_symbols(value),
101
+ "mo",
102
+ ),
103
+ )
104
+ end
105
+
106
+ def mn_value=(value)
107
+ return if value.nil? || value.empty?
108
+
109
+ update_temp(
110
+ replace_order_with_value(
111
+ @temp_mathml_order,
112
+ value,
113
+ "mn",
114
+ ),
115
+ )
116
+ end
117
+
118
+ def ms_value=(value)
119
+ return if value.nil? || value.empty?
120
+
121
+ update_temp(
122
+ replace_order_with_value(
123
+ @temp_mathml_order,
124
+ Array(value),
125
+ "ms",
126
+ ),
127
+ )
128
+ end
129
+
130
+ def mtext_value=(value)
131
+ return if value.nil? || value.empty?
132
+
133
+ update_temp(
134
+ replace_order_with_value(
135
+ @temp_mathml_order,
136
+ Array(value),
137
+ "mtext",
138
+ ),
139
+ )
140
+ end
141
+
142
+ def mrow_value=(value)
143
+ return if value.nil? || value.empty?
144
+
145
+ update_temp(
146
+ replace_order_with_value(
147
+ @temp_mathml_order,
148
+ filter_values(value, array_to_instance: true),
149
+ "mrow",
150
+ ),
151
+ )
152
+ end
153
+
154
+ def mstyle_value=(value)
155
+ return if value.nil? || value.empty?
156
+
157
+ update_temp(
158
+ replace_order_with_value(
159
+ @temp_mathml_order,
160
+ Array(value),
161
+ "mstyle",
162
+ ),
163
+ )
164
+ end
165
+
166
+ def mfrac_value=(value)
167
+ return if value.nil? || value.empty?
168
+
169
+ update_temp_order(value, "mfrac")
170
+ end
171
+
172
+ def munderover_value=(value)
173
+ return if value.nil? || value.empty?
174
+
175
+ update_temp_order(value, "munderover")
176
+ end
177
+
178
+ def msubsup_value=(value)
179
+ return if value.nil? || value.empty?
180
+
181
+ update_temp_order(value, "msubsup")
182
+ end
183
+
184
+ def munder_value=(value)
185
+ return if value.nil? || value.empty?
186
+
187
+ update_temp_order(value, "munder")
188
+ end
189
+
190
+ def mover_value=(value)
191
+ return if value.nil? || value.empty?
192
+
193
+ update_temp_order(value, "mover")
194
+ end
195
+
196
+ def msup_value=(value)
197
+ return if value.nil? || value.empty?
198
+
199
+ update_temp_order(value, "msup")
200
+ end
201
+
202
+ def msub_value=(value)
203
+ return if value.nil? || value.empty?
204
+
205
+ update_temp_order(value, "msub")
206
+ end
207
+
208
+ def mtable_value=(value)
209
+ return if value.nil? || value.empty?
210
+
211
+ if respond_to?(:value)
212
+ self.value = replace_order_with_value(
213
+ self.value,
214
+ update_temp_mathml_values(value),
215
+ "mtable",
216
+ )
217
+ else
218
+ update_temp_order(value, "mtable")
219
+ end
220
+ end
221
+
222
+ def msqrt_value=(value)
223
+ return if value.nil? || value.empty?
224
+
225
+ update_temp_order(value, "msqrt")
226
+ end
227
+
228
+ def mfenced_value=(value)
229
+ return if value.nil? || value.empty?
230
+
231
+ update_temp_order(value, "mfenced")
232
+ end
233
+
234
+ def mroot_value=(value)
235
+ return if value.nil? || value.empty?
236
+
237
+ update_temp_order(value, "mroot")
238
+ end
239
+
240
+ def msgroup_value=(value)
241
+ return if value.nil? || value.empty?
242
+
243
+ update_temp_order(value, "msgroup")
244
+ end
245
+
246
+ def mscarries_value=(value)
247
+ return if value.nil? || value.empty?
248
+
249
+ update_temp_order(value, "mscarries")
250
+ end
251
+
252
+ def msline_value=(value)
253
+ return if value.nil? || value.empty?
254
+
255
+ update_temp_order(value, "msline")
256
+ end
257
+
258
+ def msrow_value=(value)
259
+ return if value.nil? || value.empty?
260
+
261
+ update_temp_order(value, "msrow")
262
+ end
263
+
264
+ def mspace_value=(value)
265
+ return if value.nil? || value.empty?
266
+
267
+ if value.first.linebreak
268
+ linebreak = Math::Function::Linebreak.new(
269
+ nil,
270
+ { linebreak: value.first.linebreak },
271
+ )
272
+ update_temp_order([linebreak], "mspace")
273
+ else
274
+ @temp_mathml_order&.delete("mspace")
275
+ end
276
+ end
277
+
278
+ def semantics_value=(value)
279
+ return if value.nil? || value.empty?
280
+
281
+ update_temp_order(value, "semantics")
282
+ end
283
+
284
+ def mstack_value=(value)
285
+ return if value.nil? || value.empty?
286
+
287
+ update_temp_order(value, "mstack")
288
+ end
289
+
290
+ def merror_value=(value)
291
+ return if value.nil? || value.empty?
292
+
293
+ update_temp_order(value, "merror")
294
+ end
295
+
296
+ def mlongdiv_value=(value)
297
+ return if value.nil? || value.empty?
298
+
299
+ update_temp_order(value, "mlongdiv")
300
+ end
301
+
302
+ def none_value=(_)
303
+ @temp_mathml_order&.delete("none")
304
+ end
305
+
306
+ def mscarry_value=(value)
307
+ return if value.nil? || value.empty?
308
+
309
+ @temp_mathml_order&.delete("mscarry")
310
+ end
311
+
312
+ def menclose_value=(value)
313
+ return if value.nil? || value.empty?
314
+
315
+ update_temp_order(value, "menclose")
316
+ end
317
+
318
+ def maligngroup_value=(_)
319
+ @temp_mathml_order&.delete("maligngroup")
320
+ end
321
+
322
+ def malignmark_value=(_)
323
+ @temp_mathml_order&.delete("malignmark")
324
+ end
325
+
326
+ def mpadded_value=(value)
327
+ return if value.nil? || value.empty?
328
+
329
+ update_temp_order(value, "mpadded")
330
+ end
331
+
332
+ def mfraction_value=(value)
333
+ return if value.nil? || value.empty?
334
+
335
+ update_temp_order(value, "mfraction")
336
+ end
337
+
338
+ def mlabeledtr_value=(value)
339
+ return if value.nil? || value.empty?
340
+
341
+ update_temp_order(value, "mlabeledtr")
342
+ end
343
+
344
+ def mmultiscripts_value=(value)
345
+ return if value.nil? || value.empty?
346
+
347
+ update_temp_order(value, "mmultiscripts")
348
+ end
349
+
350
+ def mphantom_value=(value)
351
+ return if value.nil? || value.empty?
352
+
353
+ update_temp_order(value, "mphantom")
354
+ end
355
+
356
+ def mglyph_value=(value)
357
+ return if value.nil? || value.empty?
358
+
359
+ update_temp_order(value, "mglyph")
360
+ end
361
+ end
362
+ end
363
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "math"
4
+
4
5
  module Plurimath
5
6
  class Mathml
6
7
  attr_accessor :text
@@ -1249,7 +1249,7 @@ module Plurimath
1249
1249
  color_obj = Math::Function::Color.new(
1250
1250
  Math::Symbols::Symbol.new(color),
1251
1251
  first_value,
1252
- { backcolor: true }
1252
+ { backgroundcolor: true }
1253
1253
  )
1254
1254
  end
1255
1255
 
@@ -1258,7 +1258,7 @@ module Plurimath
1258
1258
  color_obj = Math::Function::Color.new(
1259
1259
  Math::Symbols::Symbol.new(color),
1260
1260
  Utility.filter_values(first_value),
1261
- { backcolor: true }
1261
+ { backgroundcolor: true }
1262
1262
  )
1263
1263
  end
1264
1264
 
@@ -171,7 +171,7 @@ module Plurimath
171
171
  if data&.separate_table
172
172
  table_row << Math::Function::Td.new(filter_table_data(table_data).compact)
173
173
  table_data = []
174
- if data.linebreak
174
+ if data.linebreak?
175
175
  organize_tds(table_row.flatten, string_columns.dup, options)
176
176
  table << Math::Function::Tr.new(table_row)
177
177
  table_row = []
@@ -264,7 +264,7 @@ module Plurimath
264
264
  Math::Symbols::Paren.descendants
265
265
  end
266
266
 
267
- def symbols_files
267
+ def symbols_files
268
268
  Math::Symbols::Symbol.descendants
269
269
  end
270
270
 
@@ -342,11 +342,12 @@ module Plurimath
342
342
  ) << rpr_element(wi_tag: wi_tag)
343
343
  end
344
344
 
345
- def filter_values(array)
345
+ def filter_values(array, new_formula: true)
346
346
  return array unless array.is_a?(Array) || array.is_a?(Math::Formula)
347
347
 
348
348
  array = array.is_a?(Math::Formula) ? array.value : array.flatten.compact
349
- return Math::Formula.new(array) if array.length > 1
349
+ return Math::Formula.new(array) if array.length > 1 && new_formula
350
+ return array if array.length > 1 && !new_formula
350
351
 
351
352
  array.first
352
353
  end
@@ -552,25 +553,6 @@ module Plurimath
552
553
  end
553
554
  end
554
555
 
555
- def multiscript(values)
556
- values.slice_before("mprescripts").map do |value|
557
- base_value = value.shift
558
- value = nil_to_none_object(value)
559
- part_val = value.partition.with_index { |_, i| i.even? }
560
- first_value = part_val[0].empty? ? nil : part_val[0]
561
- second_value = part_val[1].empty? ? nil : part_val[1]
562
- if base_value.to_s.include?("mprescripts")
563
- [first_value, second_value]
564
- else
565
- Math::Function::PowerBase.new(
566
- filter_values(base_value),
567
- filter_values(first_value),
568
- filter_values(second_value),
569
- )
570
- end
571
- end
572
- end
573
-
574
556
  def nil_to_none_object(value)
575
557
  return value unless value.any?(NilClass) || value.any? { |val| val.is_a?(Array) && val.empty? }
576
558
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.8.17"
4
+ VERSION = "0.8.18"
5
5
  end
data/lib/plurimath.rb CHANGED
@@ -1,14 +1,23 @@
1
1
 
2
2
  require_relative "plurimath/version"
3
+ require "lutaml/model"
4
+ require "mml/configuration"
5
+
6
+ def mml_adapter(adapter)
7
+ Mml::Configuration.adapter = adapter unless Mml::Configuration.adapter
8
+ end
3
9
 
4
10
  # Select an XML engine
5
11
  if RUBY_ENGINE == 'opal'
6
12
  require "plurimath/setup/oga"
7
13
  require "plurimath/setup/opal"
14
+ mml_adapter(:oga)
8
15
  elsif ENV['PLURIMATH_OGA']
9
16
  require "plurimath/setup/oga"
17
+ mml_adapter(:oga)
10
18
  else
11
19
  require "plurimath/setup/ox"
20
+ mml_adapter(:ox)
12
21
  end
13
22
 
14
23
  require "plurimath/math"
data/plurimath.gemspec CHANGED
@@ -24,8 +24,10 @@ Gem::Specification.new do |spec|
24
24
  spec.bindir = "exe"
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
- spec.add_dependency 'parslet'
28
- spec.add_dependency 'thor'
29
27
  spec.add_dependency 'ox'
28
+ spec.add_dependency 'mml'
29
+ spec.add_dependency 'thor'
30
+ spec.add_dependency 'parslet'
30
31
  spec.add_dependency 'bigdecimal'
32
+ spec.add_dependency 'lutaml-model'
31
33
  end
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plurimath
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.17
4
+ version: 0.8.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-07 00:00:00.000000000 Z
11
+ date: 2024-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: parslet
14
+ name: ox
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mml
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
@@ -39,7 +53,7 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: ox
56
+ name: parslet
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - ">="
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: lutaml-model
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description: Converts LaTeX math into MathML.
70
98
  email:
71
99
  - open.source@ribose.com
@@ -125,6 +153,8 @@ files:
125
153
  - lib/plurimath/math.rb
126
154
  - lib/plurimath/math/core.rb
127
155
  - lib/plurimath/math/formula.rb
156
+ - lib/plurimath/math/formula/mrow.rb
157
+ - lib/plurimath/math/formula/mstyle.rb
128
158
  - lib/plurimath/math/function.rb
129
159
  - lib/plurimath/math/function/abs.rb
130
160
  - lib/plurimath/math/function/arccos.rb
@@ -1714,7 +1744,9 @@ files:
1714
1744
  - lib/plurimath/mathml.rb
1715
1745
  - lib/plurimath/mathml/constants.rb
1716
1746
  - lib/plurimath/mathml/parser.rb
1717
- - lib/plurimath/mathml/transform.rb
1747
+ - lib/plurimath/mathml/utility.rb
1748
+ - lib/plurimath/mathml/utility/empty_defined_methods.rb
1749
+ - lib/plurimath/mathml/utility/formula_transformation.rb
1718
1750
  - lib/plurimath/number_formatter.rb
1719
1751
  - lib/plurimath/omml.rb
1720
1752
  - lib/plurimath/omml/parser.rb