plurimath 0.8.17 → 0.8.19

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/plurimath/asciimath/parse.rb +1 -0
  3. data/lib/plurimath/asciimath/transform.rb +12 -0
  4. data/lib/plurimath/math/core.rb +63 -4
  5. data/lib/plurimath/math/formula/mrow.rb +193 -0
  6. data/lib/plurimath/math/formula/mstyle.rb +17 -0
  7. data/lib/plurimath/math/formula.rb +311 -32
  8. data/lib/plurimath/math/function/base.rb +4 -0
  9. data/lib/plurimath/math/function/color.rb +17 -4
  10. data/lib/plurimath/math/function/fenced.rb +219 -0
  11. data/lib/plurimath/math/function/frac.rb +4 -0
  12. data/lib/plurimath/math/function/linebreak.rb +2 -2
  13. data/lib/plurimath/math/function/longdiv.rb +3 -0
  14. data/lib/plurimath/math/function/menclose.rb +3 -0
  15. data/lib/plurimath/math/function/merror.rb +5 -2
  16. data/lib/plurimath/math/function/mglyph.rb +27 -0
  17. data/lib/plurimath/math/function/mlabeledtr.rb +19 -0
  18. data/lib/plurimath/math/function/mpadded.rb +28 -1
  19. data/lib/plurimath/math/function/ms.rb +80 -0
  20. data/lib/plurimath/math/function/msgroup.rb +15 -0
  21. data/lib/plurimath/math/function/msline.rb +5 -2
  22. data/lib/plurimath/math/function/multiscript.rb +14 -0
  23. data/lib/plurimath/math/function/over.rb +3 -0
  24. data/lib/plurimath/math/function/overset.rb +11 -0
  25. data/lib/plurimath/math/function/phantom.rb +3 -0
  26. data/lib/plurimath/math/function/power.rb +3 -0
  27. data/lib/plurimath/math/function/power_base.rb +3 -0
  28. data/lib/plurimath/math/function/root.rb +3 -0
  29. data/lib/plurimath/math/function/scarries.rb +3 -0
  30. data/lib/plurimath/math/function/semantics.rb +14 -0
  31. data/lib/plurimath/math/function/sqrt.rb +3 -0
  32. data/lib/plurimath/math/function/stackrel.rb +3 -0
  33. data/lib/plurimath/math/function/table.rb +53 -0
  34. data/lib/plurimath/math/function/td.rb +4 -1
  35. data/lib/plurimath/math/function/text.rb +22 -2
  36. data/lib/plurimath/math/function/tr.rb +13 -0
  37. data/lib/plurimath/math/function/underover.rb +3 -0
  38. data/lib/plurimath/math/function/underset.rb +44 -0
  39. data/lib/plurimath/math/number.rb +10 -1
  40. data/lib/plurimath/math/symbols/gg.rb +4 -4
  41. data/lib/plurimath/math/symbols/ll.rb +4 -4
  42. data/lib/plurimath/math/symbols/minus.rb +1 -1
  43. data/lib/plurimath/math/symbols/symbol.rb +12 -4
  44. data/lib/plurimath/math.rb +2 -0
  45. data/lib/plurimath/mathml/parser.rb +45 -86
  46. data/lib/plurimath/mathml/utility/empty_defined_methods.rb +477 -0
  47. data/lib/plurimath/mathml/utility/formula_transformation.rb +472 -0
  48. data/lib/plurimath/mathml/utility.rb +363 -0
  49. data/lib/plurimath/mathml.rb +1 -0
  50. data/lib/plurimath/unicode_math/transform.rb +2 -2
  51. data/lib/plurimath/utility.rb +5 -23
  52. data/lib/plurimath/version.rb +1 -1
  53. data/lib/plurimath.rb +9 -0
  54. data/plurimath.gemspec +4 -2
  55. metadata +37 -5
  56. 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.19"
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.19
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-19 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