plurimath 0.3.8 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/lib/plurimath/asciimath/transform.rb +17 -0
  3. data/lib/plurimath/math/core.rb +20 -4
  4. data/lib/plurimath/math/formula.rb +42 -25
  5. data/lib/plurimath/math/function/abs.rb +2 -2
  6. data/lib/plurimath/math/function/bar.rb +43 -12
  7. data/lib/plurimath/math/function/base.rb +3 -3
  8. data/lib/plurimath/math/function/binary_function.rb +21 -5
  9. data/lib/plurimath/math/function/cancel.rb +2 -2
  10. data/lib/plurimath/math/function/ceil.rb +7 -2
  11. data/lib/plurimath/math/function/color.rb +2 -2
  12. data/lib/plurimath/math/function/ddot.rb +10 -12
  13. data/lib/plurimath/math/function/deg.rb +2 -2
  14. data/lib/plurimath/math/function/det.rb +2 -2
  15. data/lib/plurimath/math/function/dim.rb +2 -2
  16. data/lib/plurimath/math/function/dot.rb +21 -4
  17. data/lib/plurimath/math/function/exp.rb +2 -2
  18. data/lib/plurimath/math/function/fenced.rb +2 -1
  19. data/lib/plurimath/math/function/floor.rb +2 -2
  20. data/lib/plurimath/math/function/font_style/bold-fraktur.rb +17 -0
  21. data/lib/plurimath/math/function/font_style/bold-italic.rb +17 -0
  22. data/lib/plurimath/math/function/font_style/bold-sans-serif.rb +17 -0
  23. data/lib/plurimath/math/function/font_style/bold-script.rb +17 -0
  24. data/lib/plurimath/math/function/font_style/bold.rb +4 -0
  25. data/lib/plurimath/math/function/font_style/double_struck.rb +4 -0
  26. data/lib/plurimath/math/function/font_style/fraktur.rb +4 -0
  27. data/lib/plurimath/math/function/font_style/italic.rb +4 -0
  28. data/lib/plurimath/math/function/font_style/monospace.rb +4 -0
  29. data/lib/plurimath/math/function/font_style/normal.rb +4 -0
  30. data/lib/plurimath/math/function/font_style/sans-serif-bold-italic.rb +17 -0
  31. data/lib/plurimath/math/function/font_style/sans-serif-italic.rb +17 -0
  32. data/lib/plurimath/math/function/font_style/sans-serif.rb +4 -0
  33. data/lib/plurimath/math/function/font_style/script.rb +4 -0
  34. data/lib/plurimath/math/function/font_style.rb +22 -4
  35. data/lib/plurimath/math/function/frac.rb +3 -3
  36. data/lib/plurimath/math/function/gcd.rb +2 -2
  37. data/lib/plurimath/math/function/glb.rb +2 -2
  38. data/lib/plurimath/math/function/hat.rb +37 -11
  39. data/lib/plurimath/math/function/hom.rb +2 -2
  40. data/lib/plurimath/math/function/inf.rb +3 -9
  41. data/lib/plurimath/math/function/int.rb +4 -4
  42. data/lib/plurimath/math/function/ker.rb +2 -2
  43. data/lib/plurimath/math/function/lcm.rb +2 -2
  44. data/lib/plurimath/math/function/left.rb +1 -1
  45. data/lib/plurimath/math/function/lg.rb +2 -2
  46. data/lib/plurimath/math/function/lim.rb +2 -8
  47. data/lib/plurimath/math/function/liminf.rb +2 -2
  48. data/lib/plurimath/math/function/limits.rb +4 -4
  49. data/lib/plurimath/math/function/limsup.rb +2 -2
  50. data/lib/plurimath/math/function/ln.rb +2 -2
  51. data/lib/plurimath/math/function/log.rb +5 -3
  52. data/lib/plurimath/math/function/longdiv.rb +2 -2
  53. data/lib/plurimath/math/function/lub.rb +2 -2
  54. data/lib/plurimath/math/function/max.rb +2 -2
  55. data/lib/plurimath/math/function/mbox.rb +2 -2
  56. data/lib/plurimath/math/function/menclose.rb +2 -2
  57. data/lib/plurimath/math/function/merror.rb +1 -1
  58. data/lib/plurimath/math/function/min.rb +2 -2
  59. data/lib/plurimath/math/function/mod.rb +3 -3
  60. data/lib/plurimath/math/function/msgroup.rb +2 -2
  61. data/lib/plurimath/math/function/msline.rb +2 -2
  62. data/lib/plurimath/math/function/multiscript.rb +4 -4
  63. data/lib/plurimath/math/function/norm.rb +2 -2
  64. data/lib/plurimath/math/function/obrace.rb +35 -28
  65. data/lib/plurimath/math/function/oint.rb +15 -16
  66. data/lib/plurimath/math/function/over.rb +3 -3
  67. data/lib/plurimath/math/function/overset.rb +8 -3
  68. data/lib/plurimath/math/function/power.rb +3 -3
  69. data/lib/plurimath/math/function/power_base.rb +10 -8
  70. data/lib/plurimath/math/function/prod.rb +8 -4
  71. data/lib/plurimath/math/function/right.rb +1 -1
  72. data/lib/plurimath/math/function/root.rb +3 -3
  73. data/lib/plurimath/math/function/rule.rb +1 -1
  74. data/lib/plurimath/math/function/scarries.rb +2 -2
  75. data/lib/plurimath/math/function/semantics.rb +2 -2
  76. data/lib/plurimath/math/function/sqrt.rb +2 -2
  77. data/lib/plurimath/math/function/stackrel.rb +3 -3
  78. data/lib/plurimath/math/function/substack.rb +3 -3
  79. data/lib/plurimath/math/function/sum.rb +22 -19
  80. data/lib/plurimath/math/function/sup.rb +2 -2
  81. data/lib/plurimath/math/function/table.rb +7 -11
  82. data/lib/plurimath/math/function/td.rb +2 -2
  83. data/lib/plurimath/math/function/ternary_function.rb +11 -0
  84. data/lib/plurimath/math/function/text.rb +6 -5
  85. data/lib/plurimath/math/function/tilde.rb +22 -4
  86. data/lib/plurimath/math/function/tr.rb +2 -2
  87. data/lib/plurimath/math/function/ubrace.rb +27 -23
  88. data/lib/plurimath/math/function/ul.rb +50 -20
  89. data/lib/plurimath/math/function/unary_function.rb +7 -5
  90. data/lib/plurimath/math/function/underover.rb +10 -8
  91. data/lib/plurimath/math/function/underset.rb +8 -3
  92. data/lib/plurimath/math/function/vec.rb +20 -5
  93. data/lib/plurimath/math/number.rb +6 -2
  94. data/lib/plurimath/math/symbol.rb +14 -2
  95. data/lib/plurimath/math.rb +4 -1
  96. data/lib/plurimath/mathml/constants.rb +9 -1
  97. data/lib/plurimath/mathml/parser.rb +4 -2
  98. data/lib/plurimath/mathml/transform.rb +51 -22
  99. data/lib/plurimath/omml/parser.rb +24 -1
  100. data/lib/plurimath/omml/transform.rb +43 -36
  101. data/lib/plurimath/utility.rb +114 -9
  102. data/lib/plurimath/version.rb +1 -1
  103. metadata +8 -2
@@ -1,19 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "unary_function"
3
+ require_relative "binary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Tilde < UnaryFunction
8
+ class Tilde < BinaryFunction
9
9
  def to_mathml_without_math_tag
10
10
  mover = Utility.ox_element("mover")
11
+ mover.attributes.merge!({ accent: parameter_two[:accent]}) if parameter_two
11
12
  first_value = (Utility.ox_element("mo") << "~")
12
13
  second_value = parameter_one.to_mathml_without_math_tag if parameter_one
13
14
  Utility.update_nodes(mover, [second_value, first_value])
14
15
  end
15
16
 
16
- def to_omml_without_math_tag
17
+ def to_omml_without_math_tag(display_style)
18
+ return r_element("~", rpr_tag: false) unless all_values_exist?
19
+
20
+ if parameter_two && parameter_two[:accent]
21
+ acc_tag(display_style)
22
+ else
23
+ symbol = Symbol.new("~")
24
+ Overset.new(parameter_one, symbol).to_omml_without_math_tag(true)
25
+ end
26
+ end
27
+
28
+ def validate_function_formula
29
+ false
30
+ end
31
+
32
+ protected
33
+
34
+ def acc_tag(display_style)
17
35
  acc_tag = Utility.ox_element("acc", namespace: "m")
18
36
  acc_pr_tag = Utility.ox_element("accPr", namespace: "m")
19
37
  acc_pr_tag << (Utility.ox_element("chr", namespace: "m", attributes: { "m:val": "˜" }))
@@ -21,7 +39,7 @@ module Plurimath
21
39
  acc_tag,
22
40
  [
23
41
  acc_pr_tag,
24
- omml_parameter(parameter_one, tag_name: "e"),
42
+ omml_parameter(parameter_one, display_style, tag_name: "e"),
25
43
  ],
26
44
  )
27
45
  [acc_tag]
@@ -31,8 +31,8 @@ module Plurimath
31
31
  "<tr>#{first_value}</tr>"
32
32
  end
33
33
 
34
- def to_omml_without_math_tag
35
- omml_content = parameter_one&.map(&:to_omml_without_math_tag)
34
+ def to_omml_without_math_tag(display_style)
35
+ omml_content = parameter_one&.map { |obj| obj.to_omml_without_math_tag(display_style) }
36
36
  if parameter_one.count.eql?(1)
37
37
  omml_content
38
38
  else
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "unary_function"
3
+ require_relative "binary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Ubrace < UnaryFunction
8
+ class Ubrace < BinaryFunction
9
+ def to_asciimath
10
+ first_value = "(#{parameter_one.to_asciimath})" if parameter_one
11
+ "ubrace#{first_value}"
12
+ end
13
+
9
14
  def to_latex
10
15
  first_value = "{#{parameter_one.to_latex}}" if parameter_one
11
16
  "\\underbrace#{first_value}"
@@ -13,37 +18,36 @@ module Plurimath
13
18
 
14
19
  def to_mathml_without_math_tag
15
20
  mo_tag = (Utility.ox_element("mo") << "&#x23df;")
16
- if parameter_one
17
- over_tag = Utility.ox_element("munder")
18
- arr_value = mathml_value
19
- Utility.update_nodes(over_tag, (arr_value << mo_tag))
20
- else
21
- mo_tag
22
- end
21
+ return mo_tag unless parameter_one
22
+
23
+ over_tag = Utility.ox_element("munder")
24
+ over_tag.attributes.merge!(parameter_two) if parameter_two && !parameter_two.empty?
25
+ Utility.update_nodes(
26
+ over_tag,
27
+ [
28
+ parameter_one.to_mathml_without_math_tag,
29
+ mo_tag,
30
+ ],
31
+ )
23
32
  end
24
33
 
25
34
  def tag_name
26
35
  "underover"
27
36
  end
28
37
 
38
+ def omml_tag_name
39
+ "undOvr"
40
+ end
41
+
29
42
  def validate_function_formula
30
43
  false
31
44
  end
32
45
 
33
- def to_omml_without_math_tag
34
- limlow = Utility.ox_element("limLow", namespace: "m")
35
- limlowpr = Utility.ox_element("limLowPr", namespace: "m")
36
- limlowpr << Utility.pr_element("ctrl", true, namespace: "m")
37
- lim = Utility.ox_element("lim", namespace: "m")
38
- Utility.update_nodes(
39
- limlow,
40
- [
41
- limlowpr,
42
- omml_parameter(parameter_one, tag_name: "e"),
43
- Utility.update_nodes(lim, r_element("⏟")),
44
- ],
45
- )
46
- [limlow]
46
+ def to_omml_without_math_tag(display_style)
47
+ return r_element("", rpr_tag: false) unless all_values_exist?
48
+
49
+ symbol = Symbol.new("")
50
+ Underset.new(parameter_one, symbol).to_omml_without_math_tag(true)
47
51
  end
48
52
  end
49
53
 
@@ -1,41 +1,71 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "unary_function"
3
+ require_relative "binary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Ul < UnaryFunction
8
+ class Ul < BinaryFunction
9
+ def to_asciimath
10
+ first_value = "(#{parameter_one.to_asciimath})" if parameter_one
11
+ "underline#{first_value}"
12
+ end
13
+
14
+ def to_latex
15
+ first_value = "{#{parameter_one.to_latex}}" if parameter_one
16
+ "\\underline#{first_value}"
17
+ end
18
+
9
19
  def to_mathml_without_math_tag
10
- first_value = parameter_one&.to_mathml_without_math_tag
20
+ mo_tag = Utility.ox_element("mo") << "&#x332;"
21
+ return mo_tag unless parameter_one
22
+
23
+ munder_tag = Utility.ox_element("munder")
24
+ munder_tag.attributes.merge!(parameter_two) if parameter_two && !parameter_two.empty?
11
25
  Utility.update_nodes(
12
- Utility.ox_element("munder"),
26
+ munder_tag,
13
27
  [
14
- first_value,
15
- Utility.ox_element("mo") << "&#xaf;",
28
+ parameter_one&.to_mathml_without_math_tag,
29
+ mo_tag,
16
30
  ],
17
31
  )
18
32
  end
19
33
 
20
- def to_omml_without_math_tag
21
- bar = Utility.ox_element("bar", namespace: "m")
22
- barpr = Utility.ox_element("barPr", namespace: "m")
23
- barpr << Utility.pr_element("ctrl", true, namespace: "m")
24
- me = Utility.ox_element("e", namespace: "m")
25
- Utility.update_nodes(me, omml_value)
26
- Utility.update_nodes(
27
- bar,
28
- [
29
- barpr,
30
- me,
31
- ],
32
- )
33
- [bar]
34
+ def to_omml_without_math_tag(display_style)
35
+ return r_element("&#x332;", rpr_tag: false) unless all_values_exist?
36
+
37
+ if parameter_two && parameter_two[:accentunder]
38
+ groupchr_tag(display_style)
39
+ else
40
+ symbol = Symbol.new("&#x332;")
41
+ Underset.new(parameter_one, symbol).to_omml_without_math_tag(true)
42
+ end
34
43
  end
35
44
 
36
45
  def class_name
37
46
  "underline"
38
47
  end
48
+
49
+ def swap_class
50
+ Bar.new(parameter_one, parameter_two)
51
+ end
52
+
53
+ protected
54
+
55
+ def groupchr_tag(display_style)
56
+ groupchr = Utility.ox_element("groupChr", namespace: "m")
57
+ groupchrpr = Utility.ox_element("groupChrPR", namespace: "m")
58
+ chr = Utility.ox_element("chr", namespace: "m", attributes: { "m:val": "_" })
59
+ pos = Utility.ox_element("pos", namespace: "m", attributes: { "m:val": "bot" })
60
+ Utility.update_nodes(groupchrpr, [chr, pos])
61
+ Utility.update_nodes(
62
+ groupchr,
63
+ [
64
+ groupchrpr,
65
+ omml_parameter(parameter_one, display_style, tag_name: "e", namespace: "m"),
66
+ ],
67
+ )
68
+ end
39
69
  end
40
70
 
41
71
  Underline = Ul
@@ -52,7 +52,9 @@ module Plurimath
52
52
  "<i>#{class_name}</i>#{first_value}"
53
53
  end
54
54
 
55
- def to_omml_without_math_tag
55
+ def to_omml_without_math_tag(display_style)
56
+ return r_element(class_name, rpr_tag: false) unless parameter_one
57
+
56
58
  func = Utility.ox_element("func", namespace: "m")
57
59
  funcpr = Utility.ox_element("funcPr", namespace: "m")
58
60
  funcpr << Utility.pr_element("ctrl", true, namespace: "m")
@@ -62,7 +64,7 @@ module Plurimath
62
64
  mt = Utility.ox_element("t", namespace: "m") << class_name
63
65
  fname << Utility.update_nodes(mr, [rpr, mt])
64
66
  me = Utility.ox_element("e", namespace: "m")
65
- Utility.update_nodes(me, omml_value) if parameter_one
67
+ Utility.update_nodes(me, omml_value(display_style)) if parameter_one
66
68
  Utility.update_nodes(
67
69
  func,
68
70
  [
@@ -104,12 +106,12 @@ module Plurimath
104
106
  parameter_one&.to_latex
105
107
  end
106
108
 
107
- def omml_value
109
+ def omml_value(display_style)
108
110
  if parameter_one.is_a?(Array)
109
- return parameter_one&.compact&.map(&:insert_t_tag)
111
+ return parameter_one&.compact&.map { |obj| obj.insert_t_tag(display_style) }
110
112
  end
111
113
 
112
- Array(parameter_one&.insert_t_tag)
114
+ Array(parameter_one&.insert_t_tag(display_style))
113
115
  end
114
116
  end
115
117
  end
@@ -35,19 +35,21 @@ module Plurimath
35
35
  )
36
36
  end
37
37
 
38
- def to_omml_without_math_tag
39
- overset = Overset.new(parameter_one, parameter_three)
40
- return overset unless parameter_two
38
+ def to_omml_without_math_tag(display_style)
39
+ if !display_style
40
+ power_base = PowerBase.new(parameter_one, parameter_two, parameter_three)
41
+ return power_base.to_omml_without_math_tag(display_style)
42
+ end
41
43
 
42
- Underset.new(overset, parameter_two)&.to_omml_without_math_tag
44
+ underover(display_style)
43
45
  end
44
46
 
45
- def omml_nary_tag
47
+ def omml_nary_tag(display_style)
46
48
  pr = Utility.ox_element("naryPr", namespace: "m")
47
49
  [
48
50
  pr_element_value(pr),
49
- omml_parameter(parameter_two, tag_name: "sub"),
50
- omml_parameter(parameter_three, tag_name: "sup"),
51
+ omml_parameter(parameter_two, display_style, tag_name: "sub"),
52
+ omml_parameter(parameter_three, display_style, tag_name: "sup"),
51
53
  ]
52
54
  end
53
55
 
@@ -86,7 +88,7 @@ module Plurimath
86
88
  end
87
89
 
88
90
  def first_value(pr_element)
89
- first_value = parameter_one.is_a?(Number) ? parameter_one.value : parameter_one.to_omml_without_math_tag
91
+ first_value = parameter_one.nary_attr_value
90
92
  first_value = Utility.html_entity_to_unicode(first_value)
91
93
  unless first_value == "∫"
92
94
  pr_element << Utility.ox_element(
@@ -18,7 +18,12 @@ module Plurimath
18
18
  )
19
19
  end
20
20
 
21
- def to_omml_without_math_tag
21
+ def to_omml_without_math_tag(display_style)
22
+ if !display_style
23
+ base = Base.new(parameter_one, parameter_two)
24
+ return base.to_omml_without_math_tag(display_style)
25
+ end
26
+
22
27
  limlow = Utility.ox_element("limLow", namespace: "m")
23
28
  limlowpr = Utility.ox_element("limLowPr", namespace: "m")
24
29
  limlowpr << Utility.pr_element("ctrl", true, namespace: "m")
@@ -26,8 +31,8 @@ module Plurimath
26
31
  limlow,
27
32
  [
28
33
  limlowpr,
29
- omml_parameter(parameter_one, tag_name: "e"),
30
- omml_parameter(parameter_two, tag_name: "lim"),
34
+ omml_parameter(parameter_one, display_style, tag_name: "e"),
35
+ omml_parameter(parameter_two, display_style, tag_name: "lim"),
31
36
  ],
32
37
  )
33
38
  [limlow]
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "unary_function"
3
+ require_relative "binary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Vec < UnaryFunction
8
+ class Vec < BinaryFunction
9
9
  def to_mathml_without_math_tag
10
+ mover = Utility.ox_element("mover")
10
11
  first_value = parameter_one&.to_mathml_without_math_tag
12
+ mover.attributes.merge!({ accent: parameter_two[:accent] }) if parameter_two
11
13
  Utility.update_nodes(
12
- Utility.ox_element("mover"),
14
+ mover,
13
15
  [
14
16
  first_value,
15
17
  Utility.ox_element("mo") << "&#x2192;",
@@ -17,7 +19,20 @@ module Plurimath
17
19
  )
18
20
  end
19
21
 
20
- def to_omml_without_math_tag
22
+ def to_omml_without_math_tag(display_style)
23
+ return r_element("&#x2192;", rpr_tag: false) unless all_values_exist?
24
+
25
+ if parameter_two && parameter_two[:accent]
26
+ acc_tag(display_style)
27
+ else
28
+ symbol = Symbol.new("→")
29
+ Overset.new(parameter_one, symbol).to_omml_without_math_tag(true)
30
+ end
31
+ end
32
+
33
+ protected
34
+
35
+ def acc_tag(display_style)
21
36
  acc_tag = Utility.ox_element("acc", namespace: "m")
22
37
  acc_pr_tag = Utility.ox_element("accPr", namespace: "m")
23
38
  acc_pr_tag << (Utility.ox_element("chr", namespace: "m", attributes: { "m:val": "→" }))
@@ -25,7 +40,7 @@ module Plurimath
25
40
  acc_tag,
26
41
  [
27
42
  acc_pr_tag,
28
- omml_parameter(parameter_one, tag_name: "e"),
43
+ omml_parameter(parameter_one, display_style, tag_name: "e"),
29
44
  ],
30
45
  )
31
46
  [acc_tag]
@@ -29,16 +29,20 @@ module Plurimath
29
29
  value
30
30
  end
31
31
 
32
- def to_omml_without_math_tag
32
+ def to_omml_without_math_tag(_display_style)
33
33
  [(Utility.ox_element("t", namespace: "m") << value)]
34
34
  end
35
35
 
36
- def insert_t_tag
36
+ def insert_t_tag(_display_style)
37
37
  r_tag = Utility.ox_element("r", namespace: "m")
38
38
  r_tag << (Utility.ox_element("t", namespace: "m") << value)
39
39
  [r_tag]
40
40
  end
41
41
 
42
+ def font_style_t_tag(_display_style)
43
+ Utility.ox_element("t", namespace: "m") << value
44
+ end
45
+
42
46
  def nary_attr_value
43
47
  value
44
48
  end
@@ -58,11 +58,11 @@ module Plurimath
58
58
  value
59
59
  end
60
60
 
61
- def to_omml_without_math_tag
61
+ def to_omml_without_math_tag(_display_style)
62
62
  value
63
63
  end
64
64
 
65
- def insert_t_tag
65
+ def insert_t_tag(_display_style)
66
66
  r_tag = Utility.ox_element("r", namespace: "m")
67
67
  r_tag << (Utility.ox_element("t", namespace: "m") << value)
68
68
  [r_tag]
@@ -72,6 +72,18 @@ module Plurimath
72
72
  ["&#x22c0;", "&#x22c1;", "&#x22c2;", "&#x22c3;"].include?(value) ? "underover" : "subsup"
73
73
  end
74
74
 
75
+ def omml_tag_name
76
+ if ["&#x22c0;", "&#x22c1;", "&#x22c2;", "&#x22c3;", "&#x22c3;", "&#x2211;", "&#x220f;"].include?(value)
77
+ return "undOvr"
78
+ end
79
+
80
+ "subSup"
81
+ end
82
+
83
+ def font_style_t_tag(_display_style)
84
+ Utility.ox_element("t", namespace: "m") << value
85
+ end
86
+
75
87
  def nary_attr_value
76
88
  value
77
89
  end
@@ -20,6 +20,7 @@ require_relative "html/parser"
20
20
  require_relative "omml/parser"
21
21
  require_relative "utility"
22
22
  require "ox"
23
+ require "yaml"
23
24
  Ox.default_options = { encoding: "UTF-8" }
24
25
 
25
26
  module Plurimath
@@ -42,7 +43,9 @@ module Plurimath
42
43
 
43
44
  begin
44
45
  klass = klass_from_type(type)
45
- klass.new(text).to_formula
46
+ formula = klass.new(text).to_formula
47
+ formula.input_string = text
48
+ formula
46
49
  rescue => ee
47
50
  parse_error!(text, type.to_sym)
48
51
  end
@@ -130,7 +130,6 @@ module Plurimath
130
130
  "&#x21d2;": "rArr",
131
131
  "&#x21d0;": "lArr",
132
132
  "&#x21d4;": "hArr",
133
- "&#x2192;": "->",
134
133
  "&#x21a3;": ">->",
135
134
  "&#x21a0;": "->>",
136
135
  "&#x2916;": ">->>",
@@ -139,10 +138,19 @@ module Plurimath
139
138
  "&#x2212;": "-",
140
139
  "&#x23de;": "obrace",
141
140
  "&#x23df;": "ubrace",
141
+ "&#x2192;": "vec",
142
+ "&#x302;": "hat",
143
+ "&#x332;": "ul",
144
+ "&#xaf;": "bar",
142
145
  "&#x26;": "&",
143
146
  "&#x3e;": ">",
144
147
  "&#x3c;": "<",
145
148
  "&amp;": "&",
149
+ "~": "tilde",
150
+ "..": "ddot",
151
+ "^": "hat",
152
+ "¯": "bar",
153
+ "_": "ul",
146
154
  }.freeze
147
155
  SYMBOLS = {
148
156
  "|": "|",
@@ -10,8 +10,10 @@ module Plurimath
10
10
  SUPPORTED_ATTRIBUTES = %w[
11
11
  columnlines
12
12
  mathvariant
13
+ accentunder
13
14
  mathcolor
14
15
  notation
16
+ accent
15
17
  close
16
18
  open
17
19
  ].freeze
@@ -22,11 +24,11 @@ module Plurimath
22
24
 
23
25
  def parse
24
26
  ox_nodes = Ox.load(text, strip_namespace: true)
25
- display_style = ox_nodes&.locate("*/mstyle/@displaystyle")&.first
27
+ display_style = ox_nodes&.locate("*/mstyle/@displaystyle")&.first || true
26
28
  nodes = parse_nodes(ox_nodes.nodes)
27
29
  Math::Formula.new(
28
30
  Transform.new.apply(nodes).flatten.compact,
29
- displaystyle: display_style
31
+ display_style: display_style,
30
32
  )
31
33
  end
32
34
 
@@ -135,23 +135,33 @@ module Plurimath
135
135
  )
136
136
  end
137
137
 
138
- rule(msubsup: sequence(:msubsup)) do
139
- Math::Function::PowerBase.new(
140
- msubsup[0],
141
- msubsup[1],
142
- msubsup[2],
143
- )
138
+ rule(msubsup: sequence(:function)) do
139
+ base_class = function[0].is_a?(Math::Formula) ? function[0]&.value&.first : function[0]
140
+ if base_class.is_a?(Math::Function::BinaryFunction)
141
+ base_class.parameter_one = function[1]
142
+ base_class.parameter_two = function[2]
143
+ base_class
144
+ elsif base_class.is_a?(Math::Function::TernaryFunction)
145
+ base_class.parameter_one = function[1]
146
+ base_class.parameter_two = function[2]
147
+ base_class.parameter_three = function[3]
148
+ base_class
149
+ else
150
+ Math::Function::PowerBase.new(
151
+ function[0],
152
+ function[1],
153
+ function[2],
154
+ )
155
+ end
144
156
  end
145
157
 
146
158
  rule(munderover: sequence(:function)) do
147
- binary_function = Plurimath::Math::Function::BinaryFunction
148
- ternary_function = Plurimath::Math::Function::TernaryFunction
149
- base_class = function[0]&.value&.first if function[0].is_a?(Math::Formula)
150
- if base_class&.class&.ancestors&.include?(binary_function)
159
+ base_class = function[0].is_a?(Math::Formula) ? function[0]&.value&.first : function[0]
160
+ if base_class.is_a?(Math::Function::BinaryFunction)
151
161
  base_class.parameter_one = function[1]
152
162
  base_class.parameter_two = function[2]
153
163
  base_class
154
- elsif base_class&.class&.ancestors&.include?(ternary_function)
164
+ elsif base_class.is_a?(Math::Function::TernaryFunction)
155
165
  base_class.parameter_one = function[1]
156
166
  base_class.parameter_two = function[2]
157
167
  base_class.parameter_three = function[3]
@@ -166,12 +176,15 @@ module Plurimath
166
176
  end
167
177
 
168
178
  rule(mrow: subtree(:mrow)) do
169
- if mrow.any?(String)
170
- mrow.each_with_index do |object, ind|
171
- mrow[ind] = Utility.mathml_unary_classes([object]) if object.is_a?(String)
172
- end
179
+ flatten_mrow = Utility.populate_function_classes(mrow)
180
+ if flatten_mrow.length == 1
181
+ flatten_mrow.first
182
+ else
183
+ Math::Formula.new(
184
+ flatten_mrow,
185
+ Utility.mrow_left_right(flatten_mrow),
186
+ )
173
187
  end
174
- Math::Formula.new(mrow.flatten.compact)
175
188
  end
176
189
 
177
190
  rule(msrow: sequence(:msrow)) do
@@ -184,8 +197,15 @@ module Plurimath
184
197
  )
185
198
  end
186
199
 
187
- rule(mover: sequence(:mover)) do
188
- if ["ubrace", "obrace"].any?(mover.last.class_name)
200
+ rule(mover: subtree(:mover)) do
201
+ Utility.binary_function_classes(mover, under: true)
202
+ if mover&.length == 1
203
+ if mover.first.class_name == "underline"
204
+ mover.first.swap_class
205
+ else
206
+ mover.first
207
+ end
208
+ elsif Constants::CLASSES.any?(mover&.last&.class_name)
189
209
  mover.last.parameter_one = mover.shift if mover.length > 1
190
210
  mover.last
191
211
  else
@@ -202,9 +222,16 @@ module Plurimath
202
222
  munder[ind] = Utility.mathml_unary_classes([object]) if object.is_a?(String)
203
223
  end
204
224
  end
225
+ Utility.binary_function_classes(munder, under: true)
205
226
  if ["ubrace", "obrace"].any?(munder.last.class_name)
206
227
  munder.last.parameter_one = munder.shift if munder.length > 1
207
228
  munder.last
229
+ elsif munder.length == 1
230
+ if munder.first.class_name == "bar"
231
+ munder.first.swap_class
232
+ else
233
+ munder.last
234
+ end
208
235
  else
209
236
  Math::Function::Underset.new(
210
237
  munder[1],
@@ -308,10 +335,12 @@ module Plurimath
308
335
 
309
336
  rule(attributes: subtree(:attrs),
310
337
  value: sequence(:value)) do
311
- Utility.join_attr_value(
312
- attrs.is_a?(Hash) ? nil : attrs,
313
- value&.flatten&.compact,
314
- )
338
+ approved_attrs = if attrs.is_a?(Hash)
339
+ attrs.keys.any? { |k| ["accentunder", "accent"].include?(k.to_s) } ? attrs : nil
340
+ else
341
+ attrs
342
+ end
343
+ Utility.join_attr_value(approved_attrs, value&.flatten&.compact)
315
344
  end
316
345
  end
317
346
  end