plurimath 0.3.4 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/lib/plurimath/asciimath/constants.rb +5 -3
  3. data/lib/plurimath/asciimath/parse.rb +41 -28
  4. data/lib/plurimath/asciimath/transform.rb +111 -0
  5. data/lib/plurimath/latex/constants.rb +2 -2
  6. data/lib/plurimath/latex/parse.rb +3 -0
  7. data/lib/plurimath/latex/transform.rb +37 -0
  8. data/lib/plurimath/math/core.rb +43 -0
  9. data/lib/plurimath/math/formula.rb +33 -25
  10. data/lib/plurimath/math/function/abs.rb +19 -0
  11. data/lib/plurimath/math/function/arccos.rb +3 -0
  12. data/lib/plurimath/math/function/arcsin.rb +3 -0
  13. data/lib/plurimath/math/function/arctan.rb +3 -0
  14. data/lib/plurimath/math/function/bar.rb +2 -1
  15. data/lib/plurimath/math/function/base.rb +5 -7
  16. data/lib/plurimath/math/function/binary_function.rb +11 -61
  17. data/lib/plurimath/math/function/cos.rb +3 -0
  18. data/lib/plurimath/math/function/cosh.rb +3 -0
  19. data/lib/plurimath/math/function/cot.rb +3 -0
  20. data/lib/plurimath/math/function/coth.rb +3 -0
  21. data/lib/plurimath/math/function/csc.rb +3 -0
  22. data/lib/plurimath/math/function/csch.rb +3 -0
  23. data/lib/plurimath/math/function/ddot.rb +13 -0
  24. data/lib/plurimath/math/function/deg.rb +3 -0
  25. data/lib/plurimath/math/function/det.rb +3 -0
  26. data/lib/plurimath/math/function/dim.rb +3 -0
  27. data/lib/plurimath/math/function/exp.rb +3 -0
  28. data/lib/plurimath/math/function/fenced.rb +9 -31
  29. data/lib/plurimath/math/function/font_style.rb +7 -1
  30. data/lib/plurimath/math/function/frac.rb +5 -7
  31. data/lib/plurimath/math/function/gcd.rb +3 -0
  32. data/lib/plurimath/math/function/glb.rb +3 -0
  33. data/lib/plurimath/math/function/hat.rb +4 -0
  34. data/lib/plurimath/math/function/int.rb +36 -6
  35. data/lib/plurimath/math/function/left.rb +10 -3
  36. data/lib/plurimath/math/function/lg.rb +3 -0
  37. data/lib/plurimath/math/function/lim.rb +5 -14
  38. data/lib/plurimath/math/function/limits.rb +8 -0
  39. data/lib/plurimath/math/function/ln.rb +3 -0
  40. data/lib/plurimath/math/function/log.rb +40 -22
  41. data/lib/plurimath/math/function/lub.rb +3 -0
  42. data/lib/plurimath/math/function/max.rb +3 -0
  43. data/lib/plurimath/math/function/mbox.rb +1 -3
  44. data/lib/plurimath/math/function/menclose.rb +2 -1
  45. data/lib/plurimath/math/function/min.rb +3 -0
  46. data/lib/plurimath/math/function/msgroup.rb +1 -4
  47. data/lib/plurimath/math/function/multiscript.rb +4 -9
  48. data/lib/plurimath/math/function/obrace.rb +8 -0
  49. data/lib/plurimath/math/function/overset.rb +3 -16
  50. data/lib/plurimath/math/function/power.rb +5 -8
  51. data/lib/plurimath/math/function/power_base.rb +9 -39
  52. data/lib/plurimath/math/function/prod.rb +34 -4
  53. data/lib/plurimath/math/function/right.rb +10 -3
  54. data/lib/plurimath/math/function/root.rb +6 -4
  55. data/lib/plurimath/math/function/rule.rb +1 -1
  56. data/lib/plurimath/math/function/sec.rb +3 -0
  57. data/lib/plurimath/math/function/sech.rb +3 -0
  58. data/lib/plurimath/math/function/sin.rb +3 -0
  59. data/lib/plurimath/math/function/sinh.rb +3 -0
  60. data/lib/plurimath/math/function/sqrt.rb +4 -3
  61. data/lib/plurimath/math/function/sum.rb +31 -27
  62. data/lib/plurimath/math/function/table.rb +54 -8
  63. data/lib/plurimath/math/function/tan.rb +3 -0
  64. data/lib/plurimath/math/function/tanh.rb +3 -0
  65. data/lib/plurimath/math/function/td.rb +4 -1
  66. data/lib/plurimath/math/function/ternary_function.rb +34 -17
  67. data/lib/plurimath/math/function/text.rb +11 -0
  68. data/lib/plurimath/math/function/tr.rb +1 -0
  69. data/lib/plurimath/math/function/ubrace.rb +8 -0
  70. data/lib/plurimath/math/function/ul.rb +2 -1
  71. data/lib/plurimath/math/function/unary_function.rb +10 -9
  72. data/lib/plurimath/math/function/underover.rb +10 -27
  73. data/lib/plurimath/math/function/underset.rb +3 -16
  74. data/lib/plurimath/math/number.rb +17 -3
  75. data/lib/plurimath/math/symbol.rb +20 -2
  76. data/lib/plurimath/math.rb +1 -1
  77. data/lib/plurimath/mathml/constants.rb +0 -2
  78. data/lib/plurimath/mathml/parser.rb +9 -1
  79. data/lib/plurimath/mathml/transform.rb +21 -1
  80. data/lib/plurimath/omml/parser.rb +8 -1
  81. data/lib/plurimath/omml/transform.rb +27 -13
  82. data/lib/plurimath/utility.rb +20 -8
  83. data/lib/plurimath/version.rb +1 -1
  84. metadata +3 -3
  85. data/lib/plurimath/math/base.rb +0 -15
@@ -34,10 +34,13 @@ module Plurimath
34
34
 
35
35
  def to_omml_without_math_tag
36
36
  me = Utility.ox_element("e", namespace: "m")
37
+ return [me] if parameter_one&.empty?
38
+
37
39
  Utility.update_nodes(
38
40
  me,
39
- parameter_one&.map(&:to_omml_without_math_tag),
41
+ Formula.new(parameter_one).omml_content,
40
42
  )
43
+ [me]
41
44
  end
42
45
  end
43
46
  end
@@ -3,7 +3,7 @@
3
3
  module Plurimath
4
4
  module Math
5
5
  module Function
6
- class TernaryFunction
6
+ class TernaryFunction < Core
7
7
  attr_accessor :parameter_one, :parameter_two, :parameter_three
8
8
 
9
9
  def initialize(parameter_one = nil,
@@ -51,32 +51,24 @@ module Plurimath
51
51
  "#{first_value}#{second_value}#{third_value}"
52
52
  end
53
53
 
54
- def to_omml_without_math_tag
55
- r_tag = Utility.ox_element("r", namespace: "m")
56
- r_tag << omml_value(parameter_one) if parameter_one
57
- r_tag << omml_value(parameter_two) if parameter_two
58
- r_tag << omml_value(parameter_three) if parameter_three
59
- r_tag
60
- end
61
-
62
54
  def class_name
63
55
  self.class.name.split("::").last.downcase
64
56
  end
65
57
 
66
58
  protected
67
59
 
68
- def omml_value(field)
69
- case field
70
- when Array
71
- field.compact.map(&:to_omml_without_math_tag)
60
+ def latex_wrapped(field)
61
+ if field.validate_function_formula
62
+ "{ \\left ( #{field.to_latex} \\right ) }"
72
63
  else
73
- t_tag = Utility.ox_element("t", namespace: "m")
74
- first_value = field.to_omml_without_math_tag
75
- first_value = (t_tag << first_value) if field.is_a?(Symbol)
76
- first_value
64
+ "{#{field.to_latex}}"
77
65
  end
78
66
  end
79
67
 
68
+ def invert_unicode_symbols
69
+ Mathml::Constants::UNICODE_SYMBOLS.invert[class_name] || class_name
70
+ end
71
+
80
72
  def wrapped(field, type: "ascii")
81
73
  return "" unless field
82
74
 
@@ -112,6 +104,31 @@ module Plurimath
112
104
  latex
113
105
  end
114
106
  end
107
+
108
+ def narypr(function_symbol, function_type: "undOvr")
109
+ chr_arg = { "m:val": function_symbol }
110
+ limloc_arg = { "m:val": function_type }
111
+ subhide_arg = { "m:val": "0" }
112
+ suphide_arg = { "m:val": "0" }
113
+ chr_tag = Utility.ox_element("chr", attributes: chr_arg, namespace: "m")
114
+ limloc_tag = Utility.ox_element("limLoc", attributes: limloc_arg, namespace: "m")
115
+ subhide_tag = Utility.ox_element("subHide", attributes: subhide_arg, namespace: "m")
116
+ suphide_tag = Utility.ox_element("supHide", attributes: suphide_arg, namespace: "m")
117
+ nary_pr_tag = Utility.ox_element("naryPr", namespace: "m")
118
+ Utility.update_nodes(
119
+ nary_pr_tag,
120
+ [
121
+ chr_tag,
122
+ limloc_tag,
123
+ subhide_tag,
124
+ suphide_tag,
125
+ ],
126
+ )
127
+ end
128
+
129
+ def all_values_exist?
130
+ !(parameter_one.nil? && parameter_two.nil? && parameter_three.nil?)
131
+ end
115
132
  end
116
133
  end
117
134
  end
@@ -30,6 +30,17 @@ module Plurimath
30
30
  def to_omml_without_math_tag
31
31
  text = Utility.ox_element("t", namespace: "m")
32
32
  text << (parse_text("omml") || parameter_one)
33
+ [text]
34
+ end
35
+
36
+ def insert_t_tag
37
+ r_tag = Utility.ox_element("r", namespace: "m")
38
+ Utility.update_nodes(r_tag, to_omml_without_math_tag)
39
+ [r_tag]
40
+ end
41
+
42
+ def validate_function_formula
43
+ false
33
44
  end
34
45
 
35
46
  protected
@@ -41,6 +41,7 @@ module Plurimath
41
41
  mr,
42
42
  omml_content,
43
43
  )
44
+ [mr]
44
45
  end
45
46
  end
46
47
  end
@@ -21,6 +21,14 @@ module Plurimath
21
21
  mo_tag
22
22
  end
23
23
  end
24
+
25
+ def tag_name
26
+ "underover"
27
+ end
28
+
29
+ def validate_function_formula
30
+ false
31
+ end
24
32
  end
25
33
 
26
34
  Underbrace = Ubrace
@@ -22,7 +22,7 @@ module Plurimath
22
22
  barpr = Utility.ox_element("barPr", namespace: "m")
23
23
  barpr << Utility.pr_element("ctrl", true, namespace: "m")
24
24
  me = Utility.ox_element("e", namespace: "m")
25
- me << parameter_one.to_omml_without_math_tag
25
+ Utility.update_nodes(me, omml_value)
26
26
  Utility.update_nodes(
27
27
  bar,
28
28
  [
@@ -30,6 +30,7 @@ module Plurimath
30
30
  me,
31
31
  ],
32
32
  )
33
+ [bar]
33
34
  end
34
35
 
35
36
  def class_name
@@ -3,7 +3,7 @@
3
3
  module Plurimath
4
4
  module Math
5
5
  module Function
6
- class UnaryFunction
6
+ class UnaryFunction < Core
7
7
  attr_accessor :parameter_one
8
8
 
9
9
  def initialize(parameter_one = nil)
@@ -30,8 +30,12 @@ module Plurimath
30
30
  row_tag = Utility.ox_element("mrow")
31
31
  tag_name = Utility::UNARY_CLASSES.include?(class_name) ? "mi" : "mo"
32
32
  new_arr = [Utility.ox_element(tag_name) << class_name]
33
- new_arr += mathml_value if parameter_one
34
- Utility.update_nodes(row_tag, new_arr)
33
+ if parameter_one
34
+ new_arr += mathml_value
35
+ Utility.update_nodes(row_tag, new_arr)
36
+ else
37
+ new_arr.first
38
+ end
35
39
  end
36
40
 
37
41
  def to_latex
@@ -67,6 +71,7 @@ module Plurimath
67
71
  me,
68
72
  ],
69
73
  )
74
+ [func]
70
75
  end
71
76
 
72
77
  def class_name
@@ -105,14 +110,10 @@ module Plurimath
105
110
 
106
111
  def omml_value
107
112
  if parameter_one.is_a?(Array)
108
- return parameter_one&.compact&.map(&:to_omml_without_math_tag)
113
+ return parameter_one&.compact&.map(&:insert_t_tag)
109
114
  end
110
115
 
111
- first_value = parameter_one&.to_omml_without_math_tag
112
- if parameter_one.is_a?(Symbol)
113
- first_value = Utility.ox_element("t", namespace: "m") << first_value
114
- end
115
- Array(first_value)
116
+ Array(parameter_one&.insert_t_tag)
116
117
  end
117
118
  end
118
119
  end
@@ -36,25 +36,19 @@ module Plurimath
36
36
  end
37
37
 
38
38
  def to_omml_without_math_tag
39
- limupp = Utility.ox_element("limUpp", namespace: "m")
40
- limpr = Utility.ox_element("limUppPr", namespace: "m")
41
- limpr << Utility.pr_element("ctrl", namespace: "m")
42
- e_tag = Utility.ox_element("e", namespace: "m")
43
- e_tag << parameter_one&.to_omml_without_math_tag
44
- lim = Utility.ox_element("lim", namespace: "m")
45
- lim << parameter_two&.to_omml_without_math_tag if parameter_two
46
- Utility.update_nodes(
47
- limupp,
48
- [
49
- e_tag,
50
- lim,
51
- ],
52
- )
39
+ overset = Overset.new(parameter_one, parameter_three)
40
+ return overset unless parameter_two
41
+
42
+ Underset.new(overset, parameter_two)&.to_omml_without_math_tag
53
43
  end
54
44
 
55
45
  def omml_nary_tag
56
46
  pr = Utility.ox_element("naryPr", namespace: "m")
57
- [pr_element_value(pr), sub_value, sup_value]
47
+ [
48
+ pr_element_value(pr),
49
+ omml_parameter(parameter_two, tag_name: "sub"),
50
+ omml_parameter(parameter_three, tag_name: "sup"),
51
+ ]
58
52
  end
59
53
 
60
54
  protected
@@ -91,20 +85,9 @@ module Plurimath
91
85
  pr_element << Utility.pr_element("ctrl", true, namespace: "m")
92
86
  end
93
87
 
94
- def sub_value
95
- sub = Utility.ox_element("sub", namespace: "m")
96
- sub << omml_value(parameter_two) if parameter_two
97
- sub
98
- end
99
-
100
- def sup_value
101
- sup = Utility.ox_element("sup", namespace: "m")
102
- sup << omml_value(parameter_three) if parameter_three
103
- sup
104
- end
105
-
106
88
  def first_value(pr_element)
107
89
  first_value = parameter_one.is_a?(Number) ? parameter_one.value : parameter_one.to_omml_without_math_tag
90
+ first_value = Utility.html_entity_to_unicode(first_value)
108
91
  unless first_value == "∫"
109
92
  pr_element << Utility.ox_element(
110
93
  "chr",
@@ -19,31 +19,18 @@ module Plurimath
19
19
  end
20
20
 
21
21
  def to_omml_without_math_tag
22
- first_value = if parameter_one.is_a?(Math::Symbol)
23
- mt = Utility.ox_element("t", namespace: "m")
24
- mt << parameter_one.to_omml_without_math_tag
25
- else
26
- parameter_one.to_omml_without_math_tag
27
- end
28
- second_value = if parameter_two.is_a?(Math::Symbol)
29
- mt = Utility.ox_element("t", namespace: "m")
30
- mt << parameter_two.to_omml_without_math_tag
31
- else
32
- parameter_two.to_omml_without_math_tag
33
- end
34
22
  limlow = Utility.ox_element("limLow", namespace: "m")
35
23
  limlowpr = Utility.ox_element("limLowPr", namespace: "m")
36
24
  limlowpr << Utility.pr_element("ctrl", true, namespace: "m")
37
- me = Utility.ox_element("e", namespace: "m") << first_value
38
- lim = Utility.ox_element("lim", namespace: "m") << second_value if second_value
39
25
  Utility.update_nodes(
40
26
  limlow,
41
27
  [
42
28
  limlowpr,
43
- me,
44
- lim,
29
+ omml_parameter(parameter_one, tag_name: "e"),
30
+ omml_parameter(parameter_two, tag_name: "lim"),
45
31
  ],
46
32
  )
33
+ [limlow]
47
34
  end
48
35
  end
49
36
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Plurimath
4
4
  module Math
5
- class Number < Base
5
+ class Number < Core
6
6
  attr_accessor :value
7
7
 
8
8
  def initialize(value)
9
- @value = super
9
+ @value = value.is_a?(Parslet::Slice) ? value.to_s : value
10
10
  end
11
11
 
12
12
  def ==(object)
@@ -30,7 +30,21 @@ module Plurimath
30
30
  end
31
31
 
32
32
  def to_omml_without_math_tag
33
- Utility.ox_element("t", namespace: "m") << value
33
+ [(Utility.ox_element("t", namespace: "m") << value)]
34
+ end
35
+
36
+ def insert_t_tag
37
+ r_tag = Utility.ox_element("r", namespace: "m")
38
+ r_tag << (Utility.ox_element("t", namespace: "m") << value)
39
+ [r_tag]
40
+ end
41
+
42
+ def nary_attr_value
43
+ value
44
+ end
45
+
46
+ def validate_function_formula
47
+ false
34
48
  end
35
49
  end
36
50
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Plurimath
4
4
  module Math
5
- class Symbol < Base
5
+ class Symbol < Core
6
6
  attr_accessor :value
7
7
 
8
8
  def initialize(sym)
9
- @value = super
9
+ @value = sym.is_a?(Parslet::Slice) ? sym.to_s : sym
10
10
  end
11
11
 
12
12
  def ==(object)
@@ -62,6 +62,24 @@ module Plurimath
62
62
  value
63
63
  end
64
64
 
65
+ def insert_t_tag
66
+ r_tag = Utility.ox_element("r", namespace: "m")
67
+ r_tag << (Utility.ox_element("t", namespace: "m") << value)
68
+ [r_tag]
69
+ end
70
+
71
+ def tag_name
72
+ ["&#x22c0;", "&#x22c1;", "&#x22c2;", "&#x22c3;"].include?(value) ? "underover" : "subsup"
73
+ end
74
+
75
+ def nary_attr_value
76
+ value
77
+ end
78
+
79
+ def validate_function_formula
80
+ false
81
+ end
82
+
65
83
  private
66
84
 
67
85
  def operator?(unicode)
@@ -7,7 +7,7 @@ require_relative "mathml"
7
7
  require_relative "html"
8
8
  require_relative "latex"
9
9
  require_relative "unitsml"
10
- require_relative "math/base"
10
+ require_relative "math/core"
11
11
  require_relative "math/number"
12
12
  require_relative "math/symbol"
13
13
  require_relative "math/unicode"
@@ -91,8 +91,6 @@ module Plurimath
91
91
  "&#x22a4;": "TT",
92
92
  "&#x22a2;": "|--",
93
93
  "&#x22a8;": "|==",
94
- "&#x2329;": "(:",
95
- "&#x232a;": ":)",
96
94
  "&#x2329;": "<<",
97
95
  "&#x232a;": ">>",
98
96
  "&#x222b;": "int",
@@ -6,7 +6,15 @@ module Plurimath
6
6
  class Mathml
7
7
  class Parser
8
8
  attr_accessor :text
9
- SUPPORTED_ATTRIBUTES = %w[columnlines mathvariant mathcolor notation close open].freeze
9
+
10
+ SUPPORTED_ATTRIBUTES = %w[
11
+ columnlines
12
+ mathvariant
13
+ mathcolor
14
+ notation
15
+ close
16
+ open
17
+ ].freeze
10
18
 
11
19
  def initialize(text)
12
20
  @text = text
@@ -114,6 +114,20 @@ module Plurimath
114
114
  )
115
115
  end
116
116
 
117
+ rule(msub: subtree(:msub)) do
118
+ Math::Function::Base.new(
119
+ Utility.filter_values(msub[0]),
120
+ Utility.filter_values(msub[1]),
121
+ )
122
+ end
123
+
124
+ rule(msup: subtree(:msup)) do
125
+ Math::Function::Power.new(
126
+ Utility.filter_values(msup[0]),
127
+ Utility.filter_values(msup[1]),
128
+ )
129
+ end
130
+
117
131
  rule(msup: sequence(:msup)) do
118
132
  Math::Function::Power.new(
119
133
  msup[0],
@@ -131,11 +145,17 @@ module Plurimath
131
145
 
132
146
  rule(munderover: sequence(:function)) do
133
147
  binary_function = Plurimath::Math::Function::BinaryFunction
148
+ ternary_function = Plurimath::Math::Function::TernaryFunction
134
149
  base_class = function[0]&.value&.first if function[0].is_a?(Math::Formula)
135
150
  if base_class&.class&.ancestors&.include?(binary_function)
136
151
  base_class.parameter_one = function[1]
137
152
  base_class.parameter_two = function[2]
138
153
  base_class
154
+ elsif base_class&.class&.ancestors&.include?(ternary_function)
155
+ base_class.parameter_one = function[1]
156
+ base_class.parameter_two = function[2]
157
+ base_class.parameter_three = function[3]
158
+ base_class
139
159
  else
140
160
  Math::Function::Underover.new(
141
161
  function[0],
@@ -290,7 +310,7 @@ module Plurimath
290
310
  value: sequence(:value)) do
291
311
  Utility.join_attr_value(
292
312
  attrs.is_a?(Hash) ? nil : attrs,
293
- value&.flatten.compact,
313
+ value&.flatten&.compact,
294
314
  )
295
315
  end
296
316
  end
@@ -24,7 +24,7 @@ module Plurimath
24
24
  def parse_nodes(nodes)
25
25
  nodes.map do |node|
26
26
  if node.is_a?(String)
27
- node
27
+ node == "​" ? nil : node
28
28
  elsif !node.attributes.empty?
29
29
  {
30
30
  node.name => {
@@ -33,10 +33,17 @@ module Plurimath
33
33
  },
34
34
  }
35
35
  else
36
+ organize_table_td(node) if %w[mr eqArr].include?(node.name)
36
37
  { node.name => parse_nodes(node.nodes) }
37
38
  end
38
39
  end
39
40
  end
41
+
42
+ def organize_table_td(node)
43
+ node.locate("e/?").each do |child_node|
44
+ child_node.name = "mtd" if child_node.name == "r"
45
+ end
46
+ end
40
47
  end
41
48
  end
42
49
  end
@@ -21,6 +21,7 @@ module Plurimath
21
21
  rule(deg: sequence(:deg)) { Utility.filter_values(deg) }
22
22
  rule(sub: sequence(:sub)) { Utility.filter_values(sub) }
23
23
  rule(sup: sequence(:sup)) { Utility.filter_values(sup) }
24
+ rule(mtd: sequence(:mtd)) { mtd.flatten.compact }
24
25
  rule(boxPr: subtree(:box)) { nil }
25
26
  rule(argPr: subtree(:arg)) { nil }
26
27
  rule(accPr: subtree(:acc)) { acc.flatten.compact }
@@ -64,10 +65,14 @@ module Plurimath
64
65
  )
65
66
  end
66
67
 
67
- rule(r: sequence(:r)) do
68
- Math::Formula.new(
69
- r.flatten.compact,
70
- )
68
+ rule(r: subtree(:r)) do
69
+ if r.flatten.compact.empty?
70
+ nil
71
+ else
72
+ Math::Formula.new(
73
+ r.flatten.compact,
74
+ )
75
+ end
71
76
  end
72
77
 
73
78
  rule(m: sequence(:m)) do
@@ -80,7 +85,7 @@ module Plurimath
80
85
  if t.empty?
81
86
  Math::Function::Text.new
82
87
  else
83
- Utility.text_classes(t)
88
+ t&.compact&.empty? ? [nil] : Utility.text_classes(t)
84
89
  end
85
90
  end
86
91
 
@@ -100,7 +105,7 @@ module Plurimath
100
105
  row = []
101
106
  mr.each do |td|
102
107
  row << Math::Function::Td.new(
103
- td.is_a?(Array) ? td : [td],
108
+ Array(td),
104
109
  )
105
110
  end
106
111
  Math::Function::Tr.new(row)
@@ -167,11 +172,20 @@ module Plurimath
167
172
  subsup.each_with_index do |object, ind|
168
173
  subsup[ind] = Utility.mathml_unary_classes([object]) if object.is_a?(String)
169
174
  end
170
- Math::Function::PowerBase.new(
171
- subsup[0],
172
- subsup[1],
173
- subsup[2],
174
- )
175
+ if subsup[0].is_a?(Math::Formula) && Utility.valid_class(subsup[0])
176
+ Utility.get_class(
177
+ subsup[0].extract_class_from_text,
178
+ ).new(
179
+ subsup[1],
180
+ subsup[2],
181
+ )
182
+ else
183
+ Math::Function::PowerBase.new(
184
+ subsup[0],
185
+ subsup[1],
186
+ subsup[2],
187
+ )
188
+ end
175
189
  end
176
190
 
177
191
  rule(sSup: subtree(:ssup)) do
@@ -197,7 +211,7 @@ module Plurimath
197
211
 
198
212
  rule(sSub: subtree(:ssub)) do
199
213
  sub = ssub.flatten.compact
200
- Plurimath::Math::Function::Base.new(
214
+ Math::Function::Base.new(
201
215
  sub[0],
202
216
  sub[1],
203
217
  )
@@ -253,7 +267,7 @@ module Plurimath
253
267
  table_value << Math::Function::Tr.new(
254
268
  [
255
269
  Math::Function::Td.new(
256
- value.is_a?(Array) ? value : [value],
270
+ Array(value),
257
271
  ),
258
272
  ],
259
273
  )
@@ -64,8 +64,6 @@ module Plurimath
64
64
  csc
65
65
  ln
66
66
  lg
67
- f
68
- g
69
67
  ].freeze
70
68
  MUNDER_CLASSES = %w[
71
69
  ubrace
@@ -192,6 +190,7 @@ module Plurimath
192
190
  def update_nodes(element, nodes)
193
191
  nodes&.each do |node|
194
192
  next update_nodes(element, node) if node.is_a?(Array)
193
+
195
194
  element << node unless node.nil?
196
195
  end
197
196
  element
@@ -217,12 +216,12 @@ module Plurimath
217
216
  end
218
217
 
219
218
  def text_classes(text)
220
- return nil if text.empty?
219
+ return nil if text&.empty?
221
220
 
222
221
  text = filter_values(text) unless text.is_a?(String)
223
- if text.scan(/[[:digit:]]/).length == text.length
222
+ if text&.scan(/[[:digit:]]/)&.length == text&.length
224
223
  Math::Number.new(text)
225
- elsif text.match?(/[a-zA-Z]/)
224
+ elsif text&.match?(/[a-zA-Z]/)
226
225
  Math::Function::Text.new(text)
227
226
  else
228
227
  Math::Symbol.new(text)
@@ -230,10 +229,11 @@ module Plurimath
230
229
  end
231
230
 
232
231
  def nary_fonts(nary)
233
- narypr = nary.first.flatten.compact
234
- subsup = narypr.any?("undOvr") ? "underover" : "power_base"
232
+ narypr = nary.first.flatten.compact
233
+ subsup = narypr.any?("undOvr") ? "underover" : "power_base"
234
+ unicode = narypr.any?(Hash) ? narypr.first[:chr] : "∫"
235
235
  get_class(subsup).new(
236
- Math::Symbol.new(narypr.any?(Hash) ? narypr.first[:chr] : "∫"),
236
+ Math::Symbol.new(string_to_html_entity(unicode)),
237
237
  nary[1],
238
238
  nary[2],
239
239
  )
@@ -299,6 +299,11 @@ module Plurimath
299
299
  entities.encode(string, :hexadecimal)
300
300
  end
301
301
 
302
+ def html_entity_to_unicode(string)
303
+ entities = HTMLEntities.new
304
+ entities.decode(string)
305
+ end
306
+
302
307
  def table_separator(separator, value, symbol: "solid")
303
308
  sep_symbol = Math::Function::Td.new([Math::Symbol.new("|")])
304
309
  separator&.each_with_index do |sep, ind|
@@ -395,6 +400,8 @@ module Plurimath
395
400
  value = case value
396
401
  when "ℒ" then "{:"
397
402
  when "ℛ" then ":}"
403
+ when "ᑕ" then "&#x2329;"
404
+ when "ᑐ" then "&#x232a;"
398
405
  else value
399
406
  end
400
407
  Math::Symbol.new(value)
@@ -416,6 +423,11 @@ module Plurimath
416
423
  end
417
424
  get_class(function).new(paren)
418
425
  end
426
+
427
+ def valid_class(object)
428
+ text = object.extract_class_from_text
429
+ Asciimath::Constants::SUB_SUP_CLASSES.include?(text)
430
+ end
419
431
  end
420
432
  end
421
433
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.3.4"
4
+ VERSION = "0.3.6"
5
5
  end