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
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "ternary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Fenced < TernaryFunction
10
+ include Mathml::Utility
11
+
9
12
  attr_accessor :options
10
13
 
11
14
  def initialize(
@@ -157,8 +160,220 @@ module Plurimath
157
160
  }
158
161
  end
159
162
 
163
+ def separators=(value)
164
+ return if value.nil?
165
+
166
+ @options[:separators] = value
167
+ end
168
+
169
+ def content=(value)
170
+ if parens_nil?
171
+ @parameter_one = Math::Symbols::Paren::Lround.new
172
+ @parameter_three = Math::Symbols::Paren::Rround.new
173
+ end
174
+ end
175
+
176
+ def open=(value)
177
+ return unless value
178
+
179
+ @parameter_one = validate_symbols(value)
180
+ end
181
+
182
+ def close=(value)
183
+ return unless value
184
+
185
+ @parameter_three = validate_symbols(value)
186
+ end
187
+
188
+ def element_order=(value)
189
+ @parameter_two = validated_order(value)
190
+ end
191
+
192
+ def mi_value=(value)
193
+ return if value.nil? || value.empty?
194
+
195
+ update(
196
+ replace_order_with_value(
197
+ @parameter_two,
198
+ Array(validate_symbols(value)),
199
+ "mi"
200
+ )
201
+ )
202
+ end
203
+
204
+ def mn_value=(value)
205
+ return if value.nil? || value.empty?
206
+
207
+ update(
208
+ replace_order_with_value(
209
+ @parameter_two,
210
+ Array(validate_symbols(value)),
211
+ "mn"
212
+ )
213
+ )
214
+ end
215
+
216
+ def mtext_value=(value)
217
+ return if value.nil? || value.empty?
218
+
219
+ update(
220
+ replace_order_with_value(
221
+ @parameter_two,
222
+ Array(validate_symbols(value)),
223
+ "mtext"
224
+ )
225
+ )
226
+ end
227
+
228
+ def mo_value=(value)
229
+ return if value.nil? || value.empty?
230
+
231
+ update(
232
+ replace_order_with_value(
233
+ @parameter_two,
234
+ Array(validate_symbols(value)),
235
+ "mo"
236
+ )
237
+ )
238
+ end
239
+
240
+ def mstyle_value=(value)
241
+ return if value.empty?
242
+
243
+ update(
244
+ replace_order_with_value(
245
+ @parameter_two,
246
+ Array(value),
247
+ "mstyle"
248
+ )
249
+ )
250
+ end
251
+
252
+ def munderover_value=(value)
253
+ update_temp_order(value, "munderover")
254
+ end
255
+
256
+ def msub_value=(value)
257
+ update_temp_order(value, "msub")
258
+ end
259
+
260
+ def msup_value=(value)
261
+ update_temp_order(value, "msup")
262
+ end
263
+
264
+ def mover_value=(value)
265
+ update_temp_order(value, "mover")
266
+ end
267
+
268
+ def munder_value=(value)
269
+ update_temp_order(value, "munder")
270
+ end
271
+
272
+ def msubsup_value=(value)
273
+ update_temp_order(value, "msubsup")
274
+ end
275
+
276
+ def mfrac_value=(value)
277
+ update_temp_order(value, "mfrac")
278
+ end
279
+
280
+ def msqrt_value=(value)
281
+ update_temp_order(value, "msqrt")
282
+ end
283
+
284
+ def mfenced_value=(value)
285
+ update_temp_order(value, "mfenced")
286
+ end
287
+
288
+ def mtable_value=(value)
289
+ return if value.nil? || value.empty?
290
+
291
+ update(
292
+ replace_order_with_value(
293
+ Array(@parameter_two),
294
+ update_temp_mathml_values(value),
295
+ "mtable"
296
+ )
297
+ )
298
+ end
299
+
300
+ def mrow_value=(value)
301
+ return if value.nil? || value.empty?
302
+
303
+ update(
304
+ replace_order_with_value(
305
+ Array(@parameter_two),
306
+ update_temp_mathml_values(
307
+ Array(filter_values(value, array_to_instance: true))
308
+ ),
309
+ "mrow"
310
+ )
311
+ )
312
+ end
313
+
314
+ def mspace_value=(value)
315
+ return if value.nil? || value.empty?
316
+
317
+ if value.first.linebreak
318
+ linebreak = Math::Function::Linebreak.new(
319
+ nil,
320
+ { linebreak: value.first.linebreak }
321
+ )
322
+
323
+ update(
324
+ replace_order_with_value(
325
+ Array(@parameter_two),
326
+ [linebreak],
327
+ "mspace"
328
+ )
329
+ )
330
+ else
331
+ @parameter_two&.delete("mspace")
332
+ end
333
+ end
334
+
335
+ def mpadded_value=(value)
336
+ update_temp_order(value, "mpadded")
337
+ end
338
+
339
+ def mfraction_value=(value)
340
+ update_temp_order(value, "mfraction")
341
+ end
342
+
343
+ def mmultiscripts_value=(value)
344
+ update_temp_order(value, "mmultiscripts")
345
+ end
346
+
347
+ def mphantom_value=(value)
348
+ update_temp_order(value, "mphantom")
349
+ end
350
+
160
351
  protected
161
352
 
353
+ def update_temp_order(value, order_name)
354
+ return if value.nil? || value.empty?
355
+
356
+ update(
357
+ replace_order_with_value(
358
+ Array(@parameter_two),
359
+ update_temp_mathml_values(value),
360
+ order_name
361
+ )
362
+ )
363
+ end
364
+
365
+ def remove_order(order)
366
+ @parameter_two.delete_if { |val| val.is_a?(String) && val == order }
367
+ end
368
+
369
+ def insert(values)
370
+ update(Array(@parameter_two) + values)
371
+ end
372
+
373
+ def update(object)
374
+ @parameter_two = Array(object)
375
+ end
376
+
162
377
  def open_paren(dpr, options:)
163
378
  first_value = symbol_or_paren(parameter_one, lang: :omml, options: options)
164
379
  return dpr if first_value.nil?
@@ -359,6 +574,10 @@ module Plurimath
359
574
  node["intent"]&.start_with?(":partial-derivative") &&
360
575
  !node.locate("*/@arg").include?("f")
361
576
  end
577
+
578
+ def parens_nil?
579
+ @parameter_one.nil? && @parameter_three.nil?
580
+ end
362
581
  end
363
582
  end
364
583
  end
@@ -1,12 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "binary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Frac < BinaryFunction
10
+ include Mathml::Utility
11
+
9
12
  attr_accessor :options
13
+
10
14
  FUNCTION = {
11
15
  name: "fraction",
12
16
  first_value: "numerator",
@@ -17,7 +17,7 @@ module Plurimath
17
17
  def ==(object)
18
18
  object.class == self.class &&
19
19
  object.parameter_one == parameter_one &&
20
- object.linebreak == linebreak
20
+ object.linebreak? == linebreak?
21
21
  end
22
22
 
23
23
  def to_asciimath(options:)
@@ -91,7 +91,7 @@ module Plurimath
91
91
  true
92
92
  end
93
93
 
94
- def linebreak
94
+ def linebreak?
95
95
  true
96
96
  end
97
97
  end
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "unary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Longdiv < UnaryFunction
10
+ include Mathml::Utility
11
+
9
12
  def to_asciimath(options:)
10
13
  asciimath_value(options: options)
11
14
  end
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "binary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Menclose < BinaryFunction
10
+ include Mathml::Utility
11
+
9
12
  FUNCTION = {
10
13
  name: "enclosure",
11
14
  first_value: "enclosure type",
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "unary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Merror < UnaryFunction
9
- def to_asciimath(**);end
10
+ include Mathml::Utility
10
11
 
11
- def to_latex(**);end
12
+ def to_asciimath(**); end
13
+
14
+ def to_latex(**); end
12
15
 
13
16
  def to_mathml_without_math_tag(intent, options:)
14
17
  merror = Utility.ox_element("merror")
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "unary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Mglyph < UnaryFunction
10
+ include Mathml::Utility
11
+
9
12
  def initialize(parameter_one = {})
10
13
  super(parameter_one)
11
14
  end
@@ -34,8 +37,32 @@ module Plurimath
34
37
  parameter_one[:alt] if parameter_one
35
38
  end
36
39
 
40
+ def alt; end
41
+
42
+ def src; end
43
+
44
+ def index; end
45
+
46
+ def src=(value)
47
+ set_option(:src, value)
48
+ end
49
+
50
+ def alt=(value)
51
+ set_option(:alt, value)
52
+ end
53
+
54
+ def index=(value)
55
+ set_option(:index, value)
56
+ end
57
+
37
58
  protected
38
59
 
60
+ def set_option(option, value)
61
+ return if value.nil?
62
+
63
+ parameter_one[option] = value
64
+ end
65
+
39
66
  def glyph_user_index(index)
40
67
  return "" unless index > 0
41
68
 
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "binary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Mlabeledtr < BinaryFunction
10
+ include Mathml::Utility
11
+
9
12
  def to_mathml_without_math_tag(intent, options:)
10
13
  table = ox_element("mtable")
11
14
  mlabeledtr = ox_element(class_name)
@@ -18,6 +21,22 @@ module Plurimath
18
21
  "#{parameter_one&.to_unicodemath(options: options)}##{parameter_two&.value}"
19
22
  end
20
23
 
24
+ def id=(value)
25
+ return if value.nil?
26
+
27
+ @parameter_two = Text.new(value)
28
+ end
29
+
30
+ def mtd_value=(value)
31
+ return if value.nil? || value.empty?
32
+
33
+ self.parameter_one = replace_order_with_value(
34
+ clear_temp_order,
35
+ update_temp_mathml_values(value),
36
+ "mtd"
37
+ )
38
+ end
39
+
21
40
  protected
22
41
 
23
42
  def labeledtr_td(tr, value)
@@ -1,12 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "unary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Mpadded < UnaryFunction
10
+ include Mathml::Utility
11
+
9
12
  attr_accessor :options
13
+
10
14
  ZERO_TAGS = {
11
15
  height: "zeroAsc",
12
16
  depth: "zeroDesc",
@@ -58,11 +62,34 @@ module Plurimath
58
62
  end
59
63
  end
60
64
 
65
+ def voffset; end
66
+
67
+ def voffset=(value); end
68
+
69
+ def height=(value)
70
+ set_option(:height, value)
71
+ end
72
+
73
+ def depth=(value)
74
+ set_option(:depth, value)
75
+ end
76
+
77
+ def width=(value)
78
+ set_option(:width, value)
79
+ end
80
+
61
81
  protected
62
82
 
83
+ def set_option(option, value)
84
+ return if value.nil?
85
+
86
+ @options ||= {}
87
+ @options[option] = value
88
+ end
89
+
63
90
  def phant_pr
64
91
  attributes = { "m:val": "on" }
65
- options.map do |atr, value|
92
+ options&.map do |atr, value|
66
93
  ox_element(ZERO_TAGS[atr], attributes: attributes) if attr_value_zero?(value)
67
94
  end
68
95
  end
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "unary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Ms < UnaryFunction
10
+ include Mathml::Utility
11
+
9
12
  def to_mathml_without_math_tag(intent, **)
10
13
  Utility.ox_element("ms") << parameter_one
11
14
  end
@@ -27,6 +30,83 @@ module Plurimath
27
30
  def to_unicodemath(options:)
28
31
  Text.new(parameter_one).to_unicodemath(options: options)
29
32
  end
33
+
34
+ def value
35
+ parameter_one
36
+ end
37
+
38
+ def value=(content)
39
+ internal_content = updated_temp_mathml_values.flatten.map(&:to_ms_value)
40
+ @parameter_one = [internal_content, content.is_a?(String) ? content : content].flatten.compact.join(" ")
41
+ end
42
+
43
+ def mi_value=(value)
44
+ return if value.nil?
45
+
46
+ @temp_mathml_order = replace_order_with_value(
47
+ @temp_mathml_order,
48
+ value,
49
+ "mi"
50
+ )
51
+ end
52
+
53
+ def mn_value=(value)
54
+ return if value.nil?
55
+
56
+ @temp_mathml_order = replace_order_with_value(
57
+ @temp_mathml_order,
58
+ value,
59
+ "mn"
60
+ )
61
+ end
62
+
63
+ def mo_value=(value)
64
+ return if value.nil?
65
+
66
+ @temp_mathml_order = replace_order_with_value(
67
+ @temp_mathml_order,
68
+ value,
69
+ "mo"
70
+ )
71
+ end
72
+
73
+ def msub_value=(value)
74
+ return if value.nil?
75
+
76
+ @temp_mathml_order = replace_order_with_value(
77
+ @temp_mathml_order,
78
+ value,
79
+ "msub"
80
+ )
81
+ end
82
+
83
+ def msup_value=(value)
84
+ return if value.nil?
85
+
86
+ @temp_mathml_order = replace_order_with_value(
87
+ @temp_mathml_order,
88
+ value,
89
+ "msup"
90
+ )
91
+ end
92
+
93
+ def msubsup_value=(value)
94
+ return if value.nil?
95
+
96
+ @temp_mathml_order = replace_order_with_value(
97
+ @temp_mathml_order,
98
+ value,
99
+ "msubsup"
100
+ )
101
+ end
102
+
103
+ def updated_temp_mathml_values
104
+ @temp_mathml_order.map do |element|
105
+ next element if element.is_a?(Math::Symbols::Symbol)
106
+
107
+ update_temp_mathml_values([element])
108
+ end
109
+ end
30
110
  end
31
111
  end
32
112
  end
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "unary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Msgroup < UnaryFunction
10
+ include Mathml::Utility
11
+
9
12
  def to_asciimath(options:)
10
13
  parameter_one.map { |param| param.to_asciimath(options: options) }.join
11
14
  end
@@ -71,6 +74,18 @@ module Plurimath
71
74
  def line_breaking(obj)
72
75
  custom_array_line_breaking(obj)
73
76
  end
77
+
78
+ def msgroup_text; end
79
+
80
+ def msgroup_text=(value)
81
+ return unless value
82
+
83
+ if value.is_a?(Array) && value.none? { |element| element.match?(/[^\s]/) }
84
+ @temp_mathml_order << Text.new(value.pop)
85
+ else
86
+ @temp_mathml_order << Text.new(value)
87
+ end
88
+ end
74
89
  end
75
90
  end
76
91
  end
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "unary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Msline < UnaryFunction
9
- def to_asciimath(**);end
10
+ include Mathml::Utility
10
11
 
11
- def to_latex(**);end
12
+ def to_asciimath(**); end
13
+
14
+ def to_latex(**); end
12
15
 
13
16
  def to_mathml_without_math_tag(intent, **)
14
17
  ox_element("msline")
@@ -1,10 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "ternary_function"
4
+ require_relative "../../mathml/utility"
5
+
4
6
  module Plurimath
5
7
  module Math
6
8
  module Function
7
9
  class Multiscript < TernaryFunction
10
+ include Mathml::Utility
11
+
8
12
  FUNCTION = {
9
13
  name: "multiscript",
10
14
  first_value: "base",
@@ -79,6 +83,16 @@ module Plurimath
79
83
  end
80
84
  end
81
85
 
86
+ def none_value=(value)
87
+ return if value.nil? || value.empty?
88
+
89
+ @temp_mathml_order = replace_order_with_value(
90
+ @temp_mathml_order,
91
+ value,
92
+ "none"
93
+ )
94
+ end
95
+
82
96
  private
83
97
 
84
98
  def prescripts
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "binary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Over < BinaryFunction
10
+ include Mathml::Utility
11
+
9
12
  FUNCTION = {
10
13
  name: "over",
11
14
  first_value: "numerator",
@@ -1,12 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "binary_function"
4
+ require_relative "../../mathml/utility"
4
5
 
5
6
  module Plurimath
6
7
  module Math
7
8
  module Function
8
9
  class Overset < BinaryFunction
10
+ include Mathml::Utility
11
+
9
12
  attr_accessor :options
13
+
10
14
  FUNCTION = {
11
15
  name: "overset",
12
16
  first_value: "base",
@@ -77,6 +81,13 @@ module Plurimath
77
81
  parameter_two.is_nary_function? || parameter_two.is_nary_symbol?
78
82
  end
79
83
 
84
+ def accent=(value)
85
+ return unless value
86
+
87
+ @options ||= {}
88
+ @options[:accent] = value
89
+ end
90
+
80
91
  protected
81
92
 
82
93
  def unicode_accent?(field)