plurimath 0.3.5 → 0.3.7

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 (84) 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 +43 -30
  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 -21
  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 +48 -6
  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/parser.rb +13 -3
  78. data/lib/plurimath/mathml/transform.rb +21 -1
  79. data/lib/plurimath/omml/parser.rb +8 -1
  80. data/lib/plurimath/omml/transform.rb +27 -13
  81. data/lib/plurimath/utility.rb +18 -8
  82. data/lib/plurimath/version.rb +1 -1
  83. metadata +3 -3
  84. data/lib/plurimath/math/base.rb +0 -15
@@ -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"
@@ -6,17 +6,27 @@ 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
13
21
  end
14
22
 
15
23
  def parse
16
- ox_nodes = Ox.load(text, strip_namespace: true).nodes
17
- nodes = parse_nodes(ox_nodes)
24
+ ox_nodes = Ox.load(text, strip_namespace: true)
25
+ display_style = ox_nodes&.locate("*/mstyle/@displaystyle")&.first
26
+ nodes = parse_nodes(ox_nodes.nodes)
18
27
  Math::Formula.new(
19
28
  Transform.new.apply(nodes).flatten.compact,
29
+ displaystyle: display_style
20
30
  )
21
31
  end
22
32
 
@@ -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|
@@ -418,6 +423,11 @@ module Plurimath
418
423
  end
419
424
  get_class(function).new(paren)
420
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
421
431
  end
422
432
  end
423
433
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.3.5"
4
+ VERSION = "0.3.7"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plurimath
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-16 00:00:00.000000000 Z
11
+ date: 2023-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -76,7 +76,7 @@ files:
76
76
  - lib/plurimath/latex/parser.rb
77
77
  - lib/plurimath/latex/transform.rb
78
78
  - lib/plurimath/math.rb
79
- - lib/plurimath/math/base.rb
79
+ - lib/plurimath/math/core.rb
80
80
  - lib/plurimath/math/formula.rb
81
81
  - lib/plurimath/math/function.rb
82
82
  - lib/plurimath/math/function/abs.rb
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Plurimath
4
- module Math
5
- class Base
6
- def initialize(field)
7
- field.is_a?(Parslet::Slice) ? field.to_s : field
8
- end
9
-
10
- def class_name
11
- self.class.name.split("::").last.downcase
12
- end
13
- end
14
- end
15
- end