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.
- checksums.yaml +4 -4
- data/lib/plurimath/asciimath/parse.rb +1 -0
- data/lib/plurimath/asciimath/transform.rb +12 -0
- data/lib/plurimath/math/core.rb +63 -4
- data/lib/plurimath/math/formula/mrow.rb +193 -0
- data/lib/plurimath/math/formula/mstyle.rb +17 -0
- data/lib/plurimath/math/formula.rb +311 -32
- data/lib/plurimath/math/function/base.rb +4 -0
- data/lib/plurimath/math/function/color.rb +17 -4
- data/lib/plurimath/math/function/fenced.rb +219 -0
- data/lib/plurimath/math/function/frac.rb +4 -0
- data/lib/plurimath/math/function/linebreak.rb +2 -2
- data/lib/plurimath/math/function/longdiv.rb +3 -0
- data/lib/plurimath/math/function/menclose.rb +3 -0
- data/lib/plurimath/math/function/merror.rb +5 -2
- data/lib/plurimath/math/function/mglyph.rb +27 -0
- data/lib/plurimath/math/function/mlabeledtr.rb +19 -0
- data/lib/plurimath/math/function/mpadded.rb +28 -1
- data/lib/plurimath/math/function/ms.rb +80 -0
- data/lib/plurimath/math/function/msgroup.rb +15 -0
- data/lib/plurimath/math/function/msline.rb +5 -2
- data/lib/plurimath/math/function/multiscript.rb +14 -0
- data/lib/plurimath/math/function/over.rb +3 -0
- data/lib/plurimath/math/function/overset.rb +11 -0
- data/lib/plurimath/math/function/phantom.rb +3 -0
- data/lib/plurimath/math/function/power.rb +3 -0
- data/lib/plurimath/math/function/power_base.rb +3 -0
- data/lib/plurimath/math/function/root.rb +3 -0
- data/lib/plurimath/math/function/scarries.rb +3 -0
- data/lib/plurimath/math/function/semantics.rb +14 -0
- data/lib/plurimath/math/function/sqrt.rb +3 -0
- data/lib/plurimath/math/function/stackrel.rb +3 -0
- data/lib/plurimath/math/function/table.rb +53 -0
- data/lib/plurimath/math/function/td.rb +4 -1
- data/lib/plurimath/math/function/text.rb +22 -2
- data/lib/plurimath/math/function/tr.rb +13 -0
- data/lib/plurimath/math/function/underover.rb +3 -0
- data/lib/plurimath/math/function/underset.rb +44 -0
- data/lib/plurimath/math/number.rb +10 -1
- data/lib/plurimath/math/symbols/gg.rb +4 -4
- data/lib/plurimath/math/symbols/ll.rb +4 -4
- data/lib/plurimath/math/symbols/minus.rb +1 -1
- data/lib/plurimath/math/symbols/symbol.rb +12 -4
- data/lib/plurimath/math.rb +2 -0
- data/lib/plurimath/mathml/parser.rb +45 -86
- data/lib/plurimath/mathml/utility/empty_defined_methods.rb +477 -0
- data/lib/plurimath/mathml/utility/formula_transformation.rb +472 -0
- data/lib/plurimath/mathml/utility.rb +363 -0
- data/lib/plurimath/mathml.rb +1 -0
- data/lib/plurimath/unicode_math/transform.rb +2 -2
- data/lib/plurimath/utility.rb +5 -23
- data/lib/plurimath/version.rb +1 -1
- data/lib/plurimath.rb +9 -0
- data/plurimath.gemspec +4 -2
- metadata +37 -5
- data/lib/plurimath/mathml/transform.rb +0 -413
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "../mathml/utility"
|
4
|
+
|
3
5
|
module Plurimath
|
4
6
|
module Math
|
5
7
|
class Formula < Core
|
8
|
+
include Mathml::Utility
|
9
|
+
|
6
10
|
attr_accessor :value, :left_right_wrapper, :displaystyle, :input_string, :unitsml, :unitsml_xml
|
7
11
|
|
8
12
|
MATH_ZONE_TYPES = %i[
|
@@ -168,7 +172,7 @@ module Plurimath
|
|
168
172
|
|
169
173
|
def to_display(type = nil, formatter: nil)
|
170
174
|
options = { formatter: formatter }
|
171
|
-
return type_error! unless MATH_ZONE_TYPES.include?(type.downcase.to_sym)
|
175
|
+
return type_error!(type) unless MATH_ZONE_TYPES.include?(type.downcase.to_sym)
|
172
176
|
|
173
177
|
math_zone = case type
|
174
178
|
when :asciimath
|
@@ -246,7 +250,7 @@ module Plurimath
|
|
246
250
|
end
|
247
251
|
|
248
252
|
def update(object)
|
249
|
-
|
253
|
+
@value = Array(object).flatten.compact
|
250
254
|
end
|
251
255
|
|
252
256
|
def cloned_objects
|
@@ -292,7 +296,6 @@ module Plurimath
|
|
292
296
|
update(Array(value) + values)
|
293
297
|
end
|
294
298
|
|
295
|
-
|
296
299
|
def mini_sized?
|
297
300
|
true if value&.first&.mini_sized?
|
298
301
|
end
|
@@ -304,8 +307,302 @@ module Plurimath
|
|
304
307
|
}
|
305
308
|
end
|
306
309
|
|
310
|
+
def element_order=(value)
|
311
|
+
@value = validated_order(value)
|
312
|
+
end
|
313
|
+
|
314
|
+
# Attributes start
|
315
|
+
def mathcolor=(value)
|
316
|
+
return if value.nil? || value.empty?
|
317
|
+
|
318
|
+
update(
|
319
|
+
[
|
320
|
+
Math::Function::Color.new(
|
321
|
+
Math::Function::Text.new(value),
|
322
|
+
filter_values(@value, array_to_instance: true),
|
323
|
+
)
|
324
|
+
]
|
325
|
+
)
|
326
|
+
end
|
327
|
+
|
328
|
+
def mathvariant=(value)
|
329
|
+
return if value.nil? || value.empty?
|
330
|
+
return unless Plurimath::Utility::FONT_STYLES.key?(value.to_sym)
|
331
|
+
|
332
|
+
update(
|
333
|
+
[
|
334
|
+
Plurimath::Utility::FONT_STYLES[value.to_sym].new(
|
335
|
+
filter_values(@value, array_to_instance: true),
|
336
|
+
value,
|
337
|
+
)
|
338
|
+
]
|
339
|
+
)
|
340
|
+
end
|
341
|
+
|
342
|
+
def intent=(value)
|
343
|
+
return unless value
|
344
|
+
|
345
|
+
self.content = nil
|
346
|
+
update(
|
347
|
+
[
|
348
|
+
Function::Intent.new(
|
349
|
+
filter_values(@value, array_to_instance: true),
|
350
|
+
Function::Text.new(value),
|
351
|
+
)
|
352
|
+
]
|
353
|
+
)
|
354
|
+
end
|
355
|
+
# Attributes end
|
356
|
+
|
357
|
+
def ms_value=(value)
|
358
|
+
return if value.nil? || value.empty?
|
359
|
+
|
360
|
+
update(
|
361
|
+
replace_order_with_value(
|
362
|
+
@value,
|
363
|
+
Array(validate_symbols(value)),
|
364
|
+
"ms"
|
365
|
+
)
|
366
|
+
)
|
367
|
+
end
|
368
|
+
|
369
|
+
def mi_value=(value)
|
370
|
+
return if value.nil? || value.empty?
|
371
|
+
|
372
|
+
value = update_temp_mathml_values(value) if value.any? do |val|
|
373
|
+
val.is_a?(Math::Core) && val.temp_mathml_order.any?
|
374
|
+
end
|
375
|
+
update(
|
376
|
+
replace_order_with_value(
|
377
|
+
@value,
|
378
|
+
Array(validate_symbols(value)).flatten,
|
379
|
+
"mi"
|
380
|
+
)
|
381
|
+
)
|
382
|
+
end
|
383
|
+
|
384
|
+
def mn_value=(value)
|
385
|
+
return if value.nil? || value.empty?
|
386
|
+
|
387
|
+
update(
|
388
|
+
replace_order_with_value(
|
389
|
+
@value,
|
390
|
+
Array(validate_symbols(value)),
|
391
|
+
"mn"
|
392
|
+
)
|
393
|
+
)
|
394
|
+
end
|
395
|
+
|
396
|
+
def mtext_value=(value)
|
397
|
+
return if value.nil? || value.empty?
|
398
|
+
|
399
|
+
update(
|
400
|
+
replace_order_with_value(
|
401
|
+
@value,
|
402
|
+
Array(validate_symbols(value)),
|
403
|
+
"mtext"
|
404
|
+
)
|
405
|
+
)
|
406
|
+
end
|
407
|
+
|
408
|
+
def mo_value=(value)
|
409
|
+
return if value.nil? || value.empty?
|
410
|
+
|
411
|
+
value = update_temp_mathml_values(value)
|
412
|
+
update(
|
413
|
+
replace_order_with_value(
|
414
|
+
@value,
|
415
|
+
Array(value),
|
416
|
+
"mo"
|
417
|
+
)
|
418
|
+
)
|
419
|
+
end
|
420
|
+
|
421
|
+
def mstyle_value=(value)
|
422
|
+
return if value.empty?
|
423
|
+
|
424
|
+
update(
|
425
|
+
filter_values(
|
426
|
+
replace_order_with_value(
|
427
|
+
@value,
|
428
|
+
Array(filter_values(value, array_to_instance: true)),
|
429
|
+
"mstyle"
|
430
|
+
)
|
431
|
+
)
|
432
|
+
)
|
433
|
+
end
|
434
|
+
|
435
|
+
def mrow_value=(value)
|
436
|
+
return if value.nil? || value.empty?
|
437
|
+
|
438
|
+
replacing_order = value.length > 1 && value.any?(String)
|
439
|
+
update(
|
440
|
+
replace_order_with_value(
|
441
|
+
@value,
|
442
|
+
filter_values(
|
443
|
+
value,
|
444
|
+
array_to_instance: true,
|
445
|
+
replacing_order: replacing_order
|
446
|
+
),
|
447
|
+
"mrow"
|
448
|
+
)
|
449
|
+
)
|
450
|
+
end
|
451
|
+
|
452
|
+
def munderover_value=(value)
|
453
|
+
update_temp_order(value, "munderover")
|
454
|
+
end
|
455
|
+
|
456
|
+
def msub_value=(value)
|
457
|
+
update_temp_order(value, "msub")
|
458
|
+
end
|
459
|
+
|
460
|
+
def msup_value=(value)
|
461
|
+
update_temp_order(value, "msup")
|
462
|
+
end
|
463
|
+
|
464
|
+
def mover_value=(value)
|
465
|
+
update_temp_order(value, "mover")
|
466
|
+
end
|
467
|
+
|
468
|
+
def munder_value=(value)
|
469
|
+
update_temp_order(value, "munder")
|
470
|
+
end
|
471
|
+
|
472
|
+
def msubsup_value=(value)
|
473
|
+
update_temp_order(value, "msubsup")
|
474
|
+
end
|
475
|
+
|
476
|
+
def mfrac_value=(value)
|
477
|
+
update_temp_order(value, "mfrac")
|
478
|
+
end
|
479
|
+
|
480
|
+
def msqrt_value=(value)
|
481
|
+
update_temp_order(value, "msqrt")
|
482
|
+
end
|
483
|
+
|
484
|
+
def mfenced_value=(value)
|
485
|
+
update_temp_order(value, "mfenced")
|
486
|
+
end
|
487
|
+
|
488
|
+
def mroot_value=(value)
|
489
|
+
update_temp_order(value, "mroot")
|
490
|
+
end
|
491
|
+
|
492
|
+
def msgroup_value=(value)
|
493
|
+
update_temp_order(value, "msgroup")
|
494
|
+
end
|
495
|
+
|
496
|
+
def mscarries_value=(value)
|
497
|
+
update_temp_order(value, "mscarries")
|
498
|
+
end
|
499
|
+
|
500
|
+
def msline_value=(value)
|
501
|
+
update_temp_order(value, "msline")
|
502
|
+
end
|
503
|
+
|
504
|
+
def msrow_value=(value)
|
505
|
+
update_temp_order(value, "msrow")
|
506
|
+
end
|
507
|
+
|
508
|
+
def semantics_value=(value)
|
509
|
+
update_temp_order(value, "semantics")
|
510
|
+
end
|
511
|
+
|
512
|
+
def mstack_value=(value)
|
513
|
+
update_temp_order(value, "mstack")
|
514
|
+
end
|
515
|
+
|
516
|
+
def merror_value=(value)
|
517
|
+
return if value.nil? || value.empty?
|
518
|
+
|
519
|
+
update(
|
520
|
+
replace_order_with_value(
|
521
|
+
@value,
|
522
|
+
filter_values(update_temp_mathml_values(value)),
|
523
|
+
"merror"
|
524
|
+
)
|
525
|
+
)
|
526
|
+
end
|
527
|
+
|
528
|
+
def mlongdiv_value=(value)
|
529
|
+
update_temp_order(value, "mlongdiv")
|
530
|
+
end
|
531
|
+
|
532
|
+
def none_value=(_)
|
533
|
+
@value&.delete("none")
|
534
|
+
end
|
535
|
+
|
536
|
+
def maligngroup_value=(value)
|
537
|
+
@value&.delete("maligngroup")
|
538
|
+
end
|
539
|
+
|
540
|
+
def menclose_value=(value)
|
541
|
+
update_temp_order(value, "menclose")
|
542
|
+
end
|
543
|
+
|
544
|
+
def mspace_value=(value)
|
545
|
+
return if value.nil? || value.empty?
|
546
|
+
|
547
|
+
if value.first.linebreak
|
548
|
+
linebreak = Math::Function::Linebreak.new(
|
549
|
+
nil,
|
550
|
+
{ linebreak: value.first.linebreak }
|
551
|
+
)
|
552
|
+
update(
|
553
|
+
replace_order_with_value(
|
554
|
+
@value,
|
555
|
+
[linebreak],
|
556
|
+
"mspace"
|
557
|
+
)
|
558
|
+
)
|
559
|
+
else
|
560
|
+
@value&.delete("mspace")
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
def malignmark_value=(value)
|
565
|
+
@value&.delete("malignmark")
|
566
|
+
end
|
567
|
+
|
568
|
+
def mpadded_value=(value)
|
569
|
+
update_temp_order(value, "mpadded")
|
570
|
+
end
|
571
|
+
|
572
|
+
def mfraction_value=(value)
|
573
|
+
update_temp_order(value, "mfraction")
|
574
|
+
end
|
575
|
+
|
576
|
+
def mmultiscripts_value=(value)
|
577
|
+
update_temp_order(value, "mmultiscripts")
|
578
|
+
end
|
579
|
+
|
580
|
+
def mphantom_value=(value)
|
581
|
+
update_temp_order(value, "mphantom")
|
582
|
+
end
|
583
|
+
|
584
|
+
def mglyph_value=(value)
|
585
|
+
update_temp_order(value, "mglyph")
|
586
|
+
end
|
587
|
+
|
307
588
|
protected
|
308
589
|
|
590
|
+
def update_temp_order(value, order_name)
|
591
|
+
return if value.nil? || value.empty?
|
592
|
+
|
593
|
+
update(
|
594
|
+
replace_order_with_value(
|
595
|
+
Array(@value),
|
596
|
+
Array(update_temp_mathml_values(value)),
|
597
|
+
order_name
|
598
|
+
)
|
599
|
+
)
|
600
|
+
end
|
601
|
+
|
602
|
+
def remove_order(order)
|
603
|
+
value.delete_if { |val| val.is_a?(String) && val == order }
|
604
|
+
end
|
605
|
+
|
309
606
|
def boolean_display_style(display_style = displaystyle)
|
310
607
|
YAML.safe_load(display_style.to_s)
|
311
608
|
end
|
@@ -332,11 +629,11 @@ module Plurimath
|
|
332
629
|
end
|
333
630
|
|
334
631
|
def unitsml_post_processing(nodes, prev_node)
|
632
|
+
insert_index = 0
|
335
633
|
nodes.each.with_index do |node, index|
|
336
634
|
if node[:unitsml]
|
337
|
-
|
338
|
-
|
339
|
-
prev_node.insert_in_nodes(index, space_element(node)) if valid_previous?(pre_node)
|
635
|
+
prev_node.insert_in_nodes(index + insert_index, space_element(node))
|
636
|
+
insert_index += 1
|
340
637
|
node.remove_attr("unitsml")
|
341
638
|
end
|
342
639
|
unitsml_post_processing(node.nodes, node) if node.nodes.none?(String)
|
@@ -351,19 +648,10 @@ module Plurimath
|
|
351
648
|
|
352
649
|
def space_element(node)
|
353
650
|
element = (ox_element("mo") << "⁢")
|
354
|
-
element[:rspace] = "thickmathspace"
|
651
|
+
element[:rspace] = "thickmathspace"
|
355
652
|
element
|
356
653
|
end
|
357
654
|
|
358
|
-
def text_in_tag?(nodes)
|
359
|
-
next_nodes = nodes.first.nodes
|
360
|
-
if next_nodes.all?(String)
|
361
|
-
Utility.html_entity_to_unicode(next_nodes.first).match?(/\p{L}|\p{N}/)
|
362
|
-
else
|
363
|
-
text_in_tag?(next_nodes)
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
655
|
def negated_value?
|
368
656
|
value.last.is_a?(Math::Symbols::Symbol) && value.last.value == "̸"
|
369
657
|
end
|
@@ -373,21 +661,6 @@ module Plurimath
|
|
373
661
|
value&.map { |v| v.to_unicodemath(options: options) }&.join(join_str)
|
374
662
|
end
|
375
663
|
|
376
|
-
def valid_previous?(previous)
|
377
|
-
return unless previous
|
378
|
-
|
379
|
-
["mi", "mn"].include?(previous.name) ||
|
380
|
-
inside_tag?(previous)
|
381
|
-
end
|
382
|
-
|
383
|
-
def inside_tag?(previous)
|
384
|
-
previous&.nodes&.any? do |node|
|
385
|
-
next if node.is_a?(String)
|
386
|
-
|
387
|
-
valid_previous?(node) if node.xml_node?
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
664
|
def intent_attribute(mathml)
|
392
665
|
return unless mathml || value.length != 2
|
393
666
|
return unless valid_first_parameter?(value.first)
|
@@ -561,7 +834,7 @@ module Plurimath
|
|
561
834
|
mrow_nodes << nodes.delete_at(1)
|
562
835
|
next
|
563
836
|
when "mrow"
|
564
|
-
second_arg = mrow_nodes.map { |
|
837
|
+
second_arg = mrow_nodes.map { |n| encode(n.nodes.first) }.join
|
565
838
|
third_arg = upcase_dd_intent_name(node.nodes[1..-2])
|
566
839
|
mrow_nodes << nodes.delete_at(1)
|
567
840
|
break
|
@@ -699,6 +972,12 @@ module Plurimath
|
|
699
972
|
encode(str)
|
700
973
|
end
|
701
974
|
# Dd derivative nodes end
|
975
|
+
|
976
|
+
def type_error!(type)
|
977
|
+
raise Math::InvalidTypeError.new(
|
978
|
+
"Invalid type provided: #{type}. Must be one of #{MATH_ZONE_TYPES.join(', ')}.",
|
979
|
+
)
|
980
|
+
end
|
702
981
|
end
|
703
982
|
end
|
704
983
|
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 Base < BinaryFunction
|
10
|
+
include Mathml::Utility
|
11
|
+
|
9
12
|
attr_accessor :options
|
13
|
+
|
10
14
|
FUNCTION = {
|
11
15
|
name: "subscript",
|
12
16
|
first_value: "base",
|
@@ -7,6 +7,7 @@ module Plurimath
|
|
7
7
|
module Function
|
8
8
|
class Color < BinaryFunction
|
9
9
|
attr_accessor :options
|
10
|
+
|
10
11
|
FUNCTION = {
|
11
12
|
name: "color",
|
12
13
|
first_value: "mathcolor",
|
@@ -27,11 +28,10 @@ module Plurimath
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def to_mathml_without_math_tag(intent, options:)
|
30
|
-
color_value = parameter_one&.to_asciimath(options: options)&.gsub(/\s/, "")&.gsub(/"/, "")
|
31
31
|
Utility.update_nodes(
|
32
32
|
Utility.ox_element(
|
33
33
|
"mstyle",
|
34
|
-
attributes:
|
34
|
+
attributes: mathml_options,
|
35
35
|
),
|
36
36
|
[parameter_two&.to_mathml_without_math_tag(intent, options: options)],
|
37
37
|
)
|
@@ -56,13 +56,26 @@ module Plurimath
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def to_unicodemath(options:)
|
59
|
-
"
|
59
|
+
"#{color_symbol}(#{parameter_one.to_unicodemath(options: options)}&#{parameter_two.to_unicodemath(options: options)})"
|
60
60
|
end
|
61
61
|
|
62
62
|
protected
|
63
63
|
|
64
|
+
def color_symbol
|
65
|
+
options&.dig(:backgroundcolor) ? "☁" : "✎"
|
66
|
+
end
|
67
|
+
|
64
68
|
def attr_key
|
65
|
-
(
|
69
|
+
options&.dig(:backgroundcolor) ? :mathbackground : :mathcolor
|
70
|
+
end
|
71
|
+
|
72
|
+
def mathml_options
|
73
|
+
return unless parameter_one
|
74
|
+
|
75
|
+
color_options = {}
|
76
|
+
color_options[attr_key] =
|
77
|
+
parameter_one.to_asciimath(options: options)&.gsub(/\s/, "")&.gsub(/"/, "")
|
78
|
+
color_options
|
66
79
|
end
|
67
80
|
end
|
68
81
|
end
|