plurimath 0.3.9 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/lib/plurimath/latex/constants.rb +1 -0
  3. data/lib/plurimath/latex/parse.rb +11 -3
  4. data/lib/plurimath/latex/transform.rb +93 -7
  5. data/lib/plurimath/math/core.rb +16 -4
  6. data/lib/plurimath/math/formula.rb +24 -20
  7. data/lib/plurimath/math/function/abs.rb +2 -2
  8. data/lib/plurimath/math/function/bar.rb +48 -10
  9. data/lib/plurimath/math/function/base.rb +3 -3
  10. data/lib/plurimath/math/function/binary_function.rb +20 -10
  11. data/lib/plurimath/math/function/cancel.rb +2 -2
  12. data/lib/plurimath/math/function/ceil.rb +7 -2
  13. data/lib/plurimath/math/function/color.rb +2 -2
  14. data/lib/plurimath/math/function/ddot.rb +17 -12
  15. data/lib/plurimath/math/function/deg.rb +2 -2
  16. data/lib/plurimath/math/function/det.rb +2 -2
  17. data/lib/plurimath/math/function/dim.rb +2 -2
  18. data/lib/plurimath/math/function/dot.rb +26 -2
  19. data/lib/plurimath/math/function/exp.rb +2 -2
  20. data/lib/plurimath/math/function/fenced.rb +6 -7
  21. data/lib/plurimath/math/function/floor.rb +2 -2
  22. data/lib/plurimath/math/function/font_style/bold-fraktur.rb +17 -0
  23. data/lib/plurimath/math/function/font_style/bold-italic.rb +17 -0
  24. data/lib/plurimath/math/function/font_style/bold-sans-serif.rb +17 -0
  25. data/lib/plurimath/math/function/font_style/bold-script.rb +17 -0
  26. data/lib/plurimath/math/function/font_style/bold.rb +4 -0
  27. data/lib/plurimath/math/function/font_style/double_struck.rb +4 -0
  28. data/lib/plurimath/math/function/font_style/fraktur.rb +4 -0
  29. data/lib/plurimath/math/function/font_style/italic.rb +4 -0
  30. data/lib/plurimath/math/function/font_style/monospace.rb +4 -0
  31. data/lib/plurimath/math/function/font_style/normal.rb +4 -0
  32. data/lib/plurimath/math/function/font_style/sans-serif-bold-italic.rb +17 -0
  33. data/lib/plurimath/math/function/font_style/sans-serif-italic.rb +17 -0
  34. data/lib/plurimath/math/function/font_style/sans-serif.rb +4 -0
  35. data/lib/plurimath/math/function/font_style/script.rb +4 -0
  36. data/lib/plurimath/math/function/font_style.rb +24 -2
  37. data/lib/plurimath/math/function/frac.rb +3 -3
  38. data/lib/plurimath/math/function/gcd.rb +2 -2
  39. data/lib/plurimath/math/function/glb.rb +2 -2
  40. data/lib/plurimath/math/function/hat.rb +42 -9
  41. data/lib/plurimath/math/function/hom.rb +2 -2
  42. data/lib/plurimath/math/function/inf.rb +2 -2
  43. data/lib/plurimath/math/function/int.rb +4 -4
  44. data/lib/plurimath/math/function/ker.rb +2 -2
  45. data/lib/plurimath/math/function/lcm.rb +2 -2
  46. data/lib/plurimath/math/function/left.rb +1 -1
  47. data/lib/plurimath/math/function/lg.rb +2 -2
  48. data/lib/plurimath/math/function/lim.rb +2 -2
  49. data/lib/plurimath/math/function/liminf.rb +2 -2
  50. data/lib/plurimath/math/function/limits.rb +4 -4
  51. data/lib/plurimath/math/function/limsup.rb +2 -2
  52. data/lib/plurimath/math/function/ln.rb +2 -2
  53. data/lib/plurimath/math/function/log.rb +5 -3
  54. data/lib/plurimath/math/function/longdiv.rb +2 -2
  55. data/lib/plurimath/math/function/lub.rb +2 -2
  56. data/lib/plurimath/math/function/max.rb +2 -2
  57. data/lib/plurimath/math/function/mbox.rb +2 -2
  58. data/lib/plurimath/math/function/menclose.rb +2 -2
  59. data/lib/plurimath/math/function/merror.rb +1 -1
  60. data/lib/plurimath/math/function/min.rb +2 -2
  61. data/lib/plurimath/math/function/mod.rb +3 -3
  62. data/lib/plurimath/math/function/msgroup.rb +2 -2
  63. data/lib/plurimath/math/function/msline.rb +2 -2
  64. data/lib/plurimath/math/function/multiscript.rb +4 -4
  65. data/lib/plurimath/math/function/norm.rb +2 -2
  66. data/lib/plurimath/math/function/obrace.rb +40 -26
  67. data/lib/plurimath/math/function/oint.rb +4 -4
  68. data/lib/plurimath/math/function/over.rb +3 -3
  69. data/lib/plurimath/math/function/overset.rb +8 -3
  70. data/lib/plurimath/math/function/power.rb +3 -3
  71. data/lib/plurimath/math/function/power_base.rb +8 -8
  72. data/lib/plurimath/math/function/prod.rb +4 -4
  73. data/lib/plurimath/math/function/right.rb +1 -1
  74. data/lib/plurimath/math/function/root.rb +3 -3
  75. data/lib/plurimath/math/function/rule.rb +1 -1
  76. data/lib/plurimath/math/function/scarries.rb +2 -2
  77. data/lib/plurimath/math/function/semantics.rb +2 -2
  78. data/lib/plurimath/math/function/sqrt.rb +2 -2
  79. data/lib/plurimath/math/function/stackrel.rb +3 -3
  80. data/lib/plurimath/math/function/substack.rb +3 -3
  81. data/lib/plurimath/math/function/sum.rb +14 -19
  82. data/lib/plurimath/math/function/sup.rb +2 -2
  83. data/lib/plurimath/math/function/table.rb +7 -7
  84. data/lib/plurimath/math/function/td.rb +2 -2
  85. data/lib/plurimath/math/function/ternary_function.rb +13 -9
  86. data/lib/plurimath/math/function/text.rb +6 -5
  87. data/lib/plurimath/math/function/tilde.rb +27 -2
  88. data/lib/plurimath/math/function/tr.rb +2 -2
  89. data/lib/plurimath/math/function/ubrace.rb +28 -21
  90. data/lib/plurimath/math/function/ul.rb +55 -18
  91. data/lib/plurimath/math/function/unary_function.rb +13 -8
  92. data/lib/plurimath/math/function/underover.rb +10 -5
  93. data/lib/plurimath/math/function/underset.rb +8 -3
  94. data/lib/plurimath/math/function/vec.rb +25 -3
  95. data/lib/plurimath/math/number.rb +6 -2
  96. data/lib/plurimath/math/symbol.rb +6 -2
  97. data/lib/plurimath/math.rb +1 -0
  98. data/lib/plurimath/mathml/constants.rb +9 -1
  99. data/lib/plurimath/mathml/parser.rb +16 -10
  100. data/lib/plurimath/mathml/transform.rb +59 -31
  101. data/lib/plurimath/omml/parser.rb +24 -1
  102. data/lib/plurimath/omml/transform.rb +56 -41
  103. data/lib/plurimath/utility.rb +154 -9
  104. data/lib/plurimath/version.rb +1 -1
  105. metadata +8 -2
@@ -135,27 +135,39 @@ 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 = function[0].is_a?(Math::Formula) ? function[0].value : function
140
+ base_object = base.first
141
+ if base_object.is_a?(Math::Function::BinaryFunction) && !base_object.any_value_exist?
142
+ base_object.parameter_one = function[1]
143
+ base_object.parameter_two = function[2]
144
+ base_object
145
+ elsif base_object.is_a?(Math::Function::TernaryFunction) && !base_object.any_value_exist?
146
+ base_object.parameter_one = function[1]
147
+ base_object.parameter_two = function[2]
148
+ base_object.parameter_three = function[3]
149
+ base_object
150
+ else
151
+ Math::Function::PowerBase.new(
152
+ function[0],
153
+ function[1],
154
+ function[2],
155
+ )
156
+ end
144
157
  end
145
158
 
146
159
  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)
151
- base_class.parameter_one = function[1]
152
- base_class.parameter_two = function[2]
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
160
+ base = function[0].is_a?(Math::Formula) ? function[0].value : function
161
+ base_object = base.first
162
+ if base_object.is_a?(Math::Function::BinaryFunction) && !base_object.any_value_exist?
163
+ base_object.parameter_one = function[1]
164
+ base_object.parameter_two = function[2]
165
+ base_object
166
+ elsif base_object.is_a?(Math::Function::TernaryFunction) && !base_object.any_value_exist?
167
+ base_object.parameter_one = function[1]
168
+ base_object.parameter_two = function[2]
169
+ base_object.parameter_three = function[3]
170
+ base_object
159
171
  else
160
172
  Math::Function::Underover.new(
161
173
  function[0],
@@ -166,12 +178,16 @@ module Plurimath
166
178
  end
167
179
 
168
180
  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
181
+ flatten_mrow = Utility.populate_function_classes(mrow)
182
+ Utility.fenceable_classes(flatten_mrow)
183
+ if flatten_mrow.length == 1
184
+ flatten_mrow.first
185
+ else
186
+ Math::Formula.new(
187
+ flatten_mrow,
188
+ Utility.mrow_left_right(flatten_mrow),
189
+ )
173
190
  end
174
- Math::Formula.new(mrow.flatten.compact)
175
191
  end
176
192
 
177
193
  rule(msrow: sequence(:msrow)) do
@@ -184,8 +200,11 @@ module Plurimath
184
200
  )
185
201
  end
186
202
 
187
- rule(mover: sequence(:mover)) do
188
- if ["ubrace", "obrace"].any?(mover.last.class_name)
203
+ rule(mover: subtree(:mover)) do
204
+ if mover&.length == 1
205
+ base_object = mover.first
206
+ base_object.class_name == "underline" ? base_object.swap_class : base_object
207
+ elsif Constants::CLASSES.any?(mover&.last&.class_name)
189
208
  mover.last.parameter_one = mover.shift if mover.length > 1
190
209
  mover.last
191
210
  else
@@ -199,10 +218,14 @@ module Plurimath
199
218
  rule(munder: sequence(:munder)) do
200
219
  if munder.any?(String)
201
220
  munder.each_with_index do |object, ind|
202
- munder[ind] = Utility.mathml_unary_classes([object]) if object.is_a?(String)
221
+ next unless object.is_a?(String)
222
+
223
+ munder[ind] = Utility.mathml_unary_classes([object])
203
224
  end
204
225
  end
205
- if ["ubrace", "obrace"].any?(munder.last.class_name)
226
+ if munder.length == 1
227
+ munder.first.class_name == "bar" ? munder.first.swap_class : munder.last
228
+ elsif ["ubrace", "obrace", "underline"].any?(munder.last.class_name)
206
229
  munder.last.parameter_one = munder.shift if munder.length > 1
207
230
  munder.last
208
231
  else
@@ -308,10 +331,15 @@ module Plurimath
308
331
 
309
332
  rule(attributes: subtree(:attrs),
310
333
  value: sequence(:value)) do
311
- Utility.join_attr_value(
312
- attrs.is_a?(Hash) ? nil : attrs,
313
- value&.flatten&.compact,
314
- )
334
+ approved_attrs = if attrs.is_a?(Hash)
335
+ supported_attrs = %w[accentunder accent]
336
+ attrs if attrs.keys.any? do |k|
337
+ supported_attrs.include?(k.to_s)
338
+ end
339
+ else
340
+ attrs
341
+ end
342
+ Utility.join_attr_value(approved_attrs, value&.flatten&.compact)
315
343
  end
316
344
  end
317
345
  end
@@ -6,6 +6,12 @@ module Plurimath
6
6
  class Parser
7
7
  attr_accessor :text
8
8
 
9
+ CUSTOMIZABLE_TAGS = %w[
10
+ eqArr
11
+ mr
12
+ r
13
+ ].freeze
14
+
9
15
  def initialize(text)
10
16
  @text = text
11
17
  end
@@ -33,17 +39,34 @@ module Plurimath
33
39
  },
34
40
  }
35
41
  else
36
- organize_table_td(node) if %w[mr eqArr].include?(node.name)
42
+ customize_tags(node) if CUSTOMIZABLE_TAGS.include?(node.name)
37
43
  { node.name => parse_nodes(node.nodes) }
38
44
  end
39
45
  end
40
46
  end
41
47
 
48
+ def customize_tags(node)
49
+ case node.name
50
+ when "r"
51
+ organize_fonts(node)
52
+ when "mr", "eqArr"
53
+ organize_table_td(node)
54
+ end
55
+ end
56
+
42
57
  def organize_table_td(node)
43
58
  node.locate("e/?").each do |child_node|
44
59
  child_node.name = "mtd" if child_node.name == "r"
45
60
  end
46
61
  end
62
+
63
+ def organize_fonts(node)
64
+ attrs_arr = { val: [] }
65
+ node.locate("rPr/?").each do |child|
66
+ attrs_arr[:val] << child.attributes["val"]
67
+ end
68
+ node.attributes.merge! attrs_arr
69
+ end
47
70
  end
48
71
  end
49
72
  end
@@ -10,10 +10,11 @@ module Plurimath
10
10
  rule(e: sequence(:e)) { e.flatten.compact }
11
11
 
12
12
  rule(val: simple(:val)) { val }
13
+ rule(scr: simple(:scr)) { scr }
14
+ rule(sty: simple(:sty)) { sty }
13
15
  rule(dPr: subtree(:dpr)) { dpr }
14
16
  rule(num: subtree(:num)) { num }
15
17
  rule(den: subtree(:den)) { den }
16
- rule(rPr: subtree(:rPr)) { nil }
17
18
  rule(fPr: subtree(:fPr)) { nil }
18
19
  rule(mpr: subtree(:mpr)) { nil }
19
20
  rule(mPr: subtree(:mPr)) { nil }
@@ -66,12 +67,17 @@ module Plurimath
66
67
  end
67
68
 
68
69
  rule(r: subtree(:r)) do
69
- if r.flatten.compact.empty?
70
+ flatten_row = r&.flatten&.compact
71
+ if flatten_row.empty?
70
72
  nil
71
- else
72
- Math::Formula.new(
73
- r.flatten.compact,
73
+ elsif flatten_row.length > 1 && !flatten_row.first.is_a?(Math::Core)
74
+ font = flatten_row.shift
75
+ font.new(
76
+ Utility.filter_values(flatten_row),
77
+ Utility::OMML_FONTS.invert[font].to_s,
74
78
  )
79
+ else
80
+ Utility.filter_values(flatten_row)
75
81
  end
76
82
  end
77
83
 
@@ -85,15 +91,15 @@ module Plurimath
85
91
  if t.empty?
86
92
  Math::Function::Text.new
87
93
  else
88
- t&.compact&.empty? ? [nil] : Utility.text_classes(t)
94
+ t&.compact&.empty? ? [nil] : Utility.mathml_unary_classes(t, omml: true)
89
95
  end
90
96
  end
91
97
 
92
98
  rule(d: subtree(:data)) do
93
- fenced = data.flatten.compact
94
- open_paren = fenced.shift if fenced.first.class_name == "symbol"
95
- close_paren = fenced.shift if fenced.first.class_name == "symbol"
96
- fenced_value = fenced
99
+ fenced = data.flatten
100
+ open_paren = fenced.shift if fenced&.first&.class_name == "symbol"
101
+ close_paren = fenced.shift if fenced&.first&.class_name == "symbol"
102
+ fenced_value = fenced.compact
97
103
  Math::Function::Fenced.new(
98
104
  open_paren,
99
105
  fenced_value,
@@ -111,6 +117,12 @@ module Plurimath
111
117
  Math::Function::Tr.new(row)
112
118
  end
113
119
 
120
+ rule(rPr: subtree(:rpr)) do
121
+ if rpr.is_a?(Array)
122
+ Utility::OMML_FONTS[rpr.join("-").to_sym]
123
+ end
124
+ end
125
+
114
126
  rule(lim: sequence(:lim)) do
115
127
  if lim.any?(String)
116
128
  Utility.text_classes(lim)
@@ -122,34 +134,39 @@ module Plurimath
122
134
  rule(acc: subtree(:acc)) do
123
135
  acc_value = acc.flatten.compact
124
136
  chr = Utility.find_pos_chr(acc_value, :chr)
125
- chr_value = chr ? chr[:chr] : "^"
126
- Math::Function::Overset.new(
127
- Math::Symbol.new(chr_value),
128
- Utility.filter_values(acc.last),
129
- )
137
+ chr_value = chr ? chr[:chr] : Math::Function::Hat.new
138
+ index = acc_value.index { |d| d[:chr] }
139
+ acc_value[index] = chr_value
140
+ Utility.unary_function_classes(acc_value)
141
+ acc_value.first.attributes = { accent: true }
142
+ acc_value.first
130
143
  end
131
144
 
132
145
  rule(func: subtree(:func)) do
133
- func_name = func.flatten.compact
134
- class_object = Utility.find_class_name(func_name.first)
135
- if class_object
136
- class_object.new(func_name.last)
146
+ Utility.filter_values(
147
+ Utility.populate_function_classes(func),
148
+ )
149
+ end
150
+
151
+ rule(nary: subtree(:nary)) do
152
+ flatten_nary = nary.flatten.compact
153
+ chr = Utility.find_pos_chr(flatten_nary, :chr)
154
+ ternary_class = Utility.mathml_unary_classes(chr.values) if chr
155
+ if ternary_class.is_a?(Math::Function::TernaryFunction)
156
+ ternary_class.parameter_one = Utility.filter_values(nary[1])
157
+ ternary_class.parameter_two = Utility.filter_values(nary[2])
158
+ ternary_class.parameter_three = Utility.filter_values(nary[3])
159
+ ternary_class
137
160
  else
138
161
  Math::Formula.new(
139
- func_name,
162
+ [
163
+ Utility.nary_fonts(nary),
164
+ Utility.filter_values(nary[3]),
165
+ ],
140
166
  )
141
167
  end
142
168
  end
143
169
 
144
- rule(nary: subtree(:nary)) do
145
- Math::Formula.new(
146
- [
147
- Utility.nary_fonts(nary),
148
- Utility.filter_values(nary[3]),
149
- ],
150
- )
151
- end
152
-
153
170
  rule(groupChr: subtree(:groupchr)) do
154
171
  chr_pos = groupchr.first
155
172
  pos = Utility.find_pos_chr(chr_pos, :pos)
@@ -172,7 +189,7 @@ module Plurimath
172
189
  subsup.each_with_index do |object, ind|
173
190
  subsup[ind] = Utility.mathml_unary_classes([object]) if object.is_a?(String)
174
191
  end
175
- if subsup[0].is_a?(Math::Formula) && Utility.valid_class(subsup[0])
192
+ if Utility.valid_class(subsup[0])
176
193
  Utility.get_class(
177
194
  subsup[0].extract_class_from_text,
178
195
  ).new(
@@ -217,8 +234,8 @@ module Plurimath
217
234
  )
218
235
  end
219
236
 
220
- rule(limUpp: subtree(:limUpp)) do
221
- lim_values = limUpp.flatten.compact
237
+ rule(limUpp: subtree(:lim)) do
238
+ lim_values = lim.flatten.compact
222
239
  first_value = lim_values[0]
223
240
  Math::Function::Overset.new(
224
241
  first_value,
@@ -227,9 +244,12 @@ module Plurimath
227
244
  end
228
245
 
229
246
  rule(limLow: subtree(:lim)) do
247
+ second_value = Utility.filter_values(lim[2])
248
+ unicode = Mathml::Constants::UNICODE_SYMBOLS.invert[second_value.class_name]
249
+ second_value = unicode ? Math::Symbol.new(unicode.to_s) : second_value
230
250
  Math::Function::Underset.new(
231
251
  Utility.filter_values(lim[1]),
232
- Utility.filter_values(lim[2]),
252
+ second_value,
233
253
  )
234
254
  end
235
255
 
@@ -241,14 +261,9 @@ module Plurimath
241
261
  end
242
262
 
243
263
  rule(bar: subtree(:bar)) do
244
- barpr = bar&.flatten&.compact
245
- pospr = Utility.find_pos_chr(bar.first, :pos)
246
- class_name = if pospr&.value?("top")
247
- Math::Function::Bar
248
- else
249
- Math::Function::Ul
250
- end
251
- class_name.new(barpr.last)
264
+ flatten_bar = bar.flatten.compact
265
+ attrs = { accent: false }
266
+ Math::Function::Bar.new(flatten_bar.last, attrs)
252
267
  end
253
268
 
254
269
  rule(sPre: subtree(:spre)) do
@@ -72,6 +72,34 @@ module Plurimath
72
72
  max
73
73
  min
74
74
  ].freeze
75
+ OMML_FONTS = {
76
+ "sans-serif-bi": Math::Function::FontStyle::SansSerifBoldItalic,
77
+ "sans-serif-i": Math::Function::FontStyle::SansSerifItalic,
78
+ "sans-serif-b": Math::Function::FontStyle::BoldSansSerif,
79
+ "double-struck": Math::Function::FontStyle::DoubleStruck,
80
+ "sans-serif-p": Math::Function::FontStyle::SansSerif,
81
+ "fraktur-p": Math::Function::FontStyle::Fraktur,
82
+ "fraktur-b": Math::Function::FontStyle::BoldFraktur,
83
+ "script-b": Math::Function::FontStyle::BoldScript,
84
+ "script-p": Math::Function::FontStyle::Script,
85
+ monospace: Math::Function::FontStyle::Monospace,
86
+ bi: Math::Function::FontStyle::BoldItalic,
87
+ p: Math::Function::FontStyle::Normal,
88
+ i: Math::Function::FontStyle::Italic,
89
+ b: Math::Function::FontStyle::Bold,
90
+ }.freeze
91
+ PARENTHESIS = {
92
+ "&#x2329;": "&#x232a;",
93
+ "&#x230a;": "&#x230b;",
94
+ "&#x2308;": "&#x2309;",
95
+ "&#x2016;": "&#x2016;",
96
+ "&#x7b;": "&#x7d;",
97
+ "&#x5b;": "&#x5d;",
98
+ "&#x7c;": "&#x7c;",
99
+ "(": ")",
100
+ "{": "}",
101
+ "[": "]",
102
+ }.freeze
75
103
 
76
104
  class << self
77
105
  def organize_table(array, column_align: nil, options: nil)
@@ -271,7 +299,7 @@ module Plurimath
271
299
  td_object
272
300
  end
273
301
 
274
- def mathml_unary_classes(text_array)
302
+ def mathml_unary_classes(text_array, omml: false)
275
303
  return [] if text_array.empty?
276
304
 
277
305
  compacted = text_array.compact
@@ -290,7 +318,7 @@ module Plurimath
290
318
  elsif classes.any?(string&.strip)
291
319
  get_class(string.strip).new
292
320
  else
293
- Math::Symbol.new(unicode)
321
+ omml ? text_classes(string) : Math::Symbol.new(unicode)
294
322
  end
295
323
  end
296
324
 
@@ -326,16 +354,35 @@ module Plurimath
326
354
  attrs.nil? ? array_value : join_attr_value(attrs, array_value)
327
355
  elsif attrs.nil?
328
356
  value
329
- elsif attrs.is_a?(Math::Function::Menclose)
357
+ elsif attrs.is_a?(String) && ["solid", "none"].include?(attrs.split.first.downcase)
358
+ table_separator(attrs.split, value)
359
+ elsif attrs.is_a?(Hash) && (attrs.key?(:accent) || attrs.key?(:accentunder))
360
+ attr_is_accent(attrs, value)
361
+ elsif attrs.is_a?(Math::Core)
362
+ attr_is_function(attrs, value)
363
+ end
364
+ end
365
+
366
+ def attr_is_accent(attrs, value)
367
+ if value.last.is_a?(Math::Function::UnaryFunction)
368
+ value.last.parameter_one = value.shift if value.length > 1
369
+ value.last.attributes = attrs.transform_values { |v| YAML.safe_load(v) }
370
+ end
371
+ value
372
+ end
373
+
374
+ def attr_is_function(attrs, value)
375
+ case attrs
376
+ when Math::Function::Menclose
330
377
  attrs.parameter_two = filter_values(value)
331
378
  attrs
332
- elsif attrs.is_a?(Math::Function::Fenced)
379
+ when Math::Function::Fenced
333
380
  attrs.parameter_two = value.compact
334
381
  attrs
335
- elsif attrs.is_a?(Math::Function::FontStyle)
382
+ when Math::Function::FontStyle
336
383
  attrs.parameter_one = filter_values(value)
337
384
  attrs
338
- elsif attrs.is_a?(Math::Function::Color)
385
+ when Math::Function::Color
339
386
  color_value = filter_values(value)
340
387
  if attrs.parameter_two
341
388
  attrs.parameter_two.parameter_one = color_value
@@ -343,8 +390,6 @@ module Plurimath
343
390
  attrs.parameter_two = color_value
344
391
  end
345
392
  attrs
346
- elsif ["solid", "none"].include?(attrs.split.first.downcase)
347
- table_separator(attrs.split, value)
348
393
  end
349
394
  end
350
395
 
@@ -426,7 +471,107 @@ module Plurimath
426
471
 
427
472
  def valid_class(object)
428
473
  text = object.extract_class_from_text
429
- Asciimath::Constants::SUB_SUP_CLASSES.include?(text)
474
+ (object.extractable? && Asciimath::Constants::SUB_SUP_CLASSES.include?(text)) ||
475
+ Latex::Constants::SYMBOLS[text.to_sym] == :power_base
476
+ end
477
+
478
+ def mrow_left_right(mrow = [])
479
+ object = mrow.first
480
+ !(
481
+ (
482
+ (
483
+ object.is_a?(Math::Function::TernaryFunction) && object.any_value_exist?
484
+ ) &&
485
+ (mrow.length <= 2)
486
+ ) ||
487
+ (object.is_a?(Math::Function::UnaryFunction) && mrow.length == 1)
488
+ )
489
+ end
490
+
491
+ def populate_function_classes(mrow = [])
492
+ flatten_mrow = mrow.flatten.compact
493
+ unary_function_classes(flatten_mrow)
494
+ binary_function_classes(flatten_mrow)
495
+ ternary_function_classes(flatten_mrow)
496
+ flatten_mrow
497
+ end
498
+
499
+ def binary_function_classes(mrow, under: false)
500
+ binary_class = Math::Function::BinaryFunction
501
+ mrow.each_with_index do |object, ind|
502
+ mrow[ind] = mathml_unary_classes([object]) if object.is_a?(String)
503
+ object = mrow[ind]
504
+ next unless object.is_a?(binary_class)
505
+
506
+ if object.is_a?(Math::Function::Mod)
507
+ next unless mrow.length >= 1
508
+
509
+ object.parameter_one = mrow.delete_at(ind - 1) unless ind.zero?
510
+ object.parameter_two = mrow.delete_at(ind)
511
+ elsif Mathml::Constants::UNICODE_SYMBOLS.invert[object.class_name] && mrow.length > 1
512
+ next if object.parameter_one || mrow.length > 2
513
+ next object.parameter_one = mrow.delete_at(ind - 1) if under && ind <= 1
514
+
515
+ object.parameter_one = mrow.delete_at(ind + 1)
516
+ end
517
+ end
518
+ end
519
+
520
+ def unary_function_classes(mrow)
521
+ unary_class = Math::Function::UnaryFunction
522
+ if mrow.any?(String) || mrow.any?(unary_class)
523
+ mrow.each_with_index do |object, ind|
524
+ mrow[ind] = mathml_unary_classes([object]) if object.is_a?(String)
525
+ object = mrow[ind] if object.is_a?(String)
526
+ next unless object.is_a?(unary_class)
527
+ next if object.is_a?(Math::Function::Text)
528
+ next if object.parameter_one || mrow[ind + 1].nil?
529
+ next unless ind.zero?
530
+
531
+ object.parameter_one = mrow.delete_at(ind + 1)
532
+ end
533
+ end
534
+ end
535
+
536
+ def ternary_function_classes(mrow)
537
+ ternary_class = Math::Function::TernaryFunction
538
+ if mrow.any?(ternary_class) && mrow.length > 1
539
+ mrow.each_with_index do |object, ind|
540
+ if object.is_a?(ternary_class)
541
+ next if [Math::Function::Fenced, Math::Function::Multiscript].include?(object.class)
542
+ next unless object.parameter_one || object.parameter_two
543
+ next if object.parameter_three
544
+
545
+ object.parameter_three = filter_values(mrow.delete_at(ind + 1))
546
+ end
547
+ end
548
+ end
549
+ end
550
+
551
+ def paren_able?(arr = [], mrow = [])
552
+ arr.any? do |opening, closing|
553
+ symbol_value(mrow.first, opening.to_s) && symbol_value(mrow.last, closing.to_s)
554
+ end
555
+ end
556
+
557
+ def fenceable_classes(mrow = [])
558
+ return false unless mrow.length > 1
559
+
560
+ if paren_able?(PARENTHESIS, mrow)
561
+ open_paren = mrow.shift
562
+ close_paren = mrow.pop
563
+ if mrow.length == 1 && mrow.first.is_a?(Math::Function::Table)
564
+ table = mrow.first
565
+ table.open_paren = open_paren
566
+ table.close_paren = close_paren
567
+ else
568
+ mrow.replace(
569
+ [
570
+ Math::Function::Fenced.new(open_paren, mrow.dup, close_paren),
571
+ ],
572
+ )
573
+ end
574
+ end
430
575
  end
431
576
  end
432
577
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.3.9"
4
+ VERSION = "0.4.2"
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.9
4
+ version: 0.4.2
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-08-10 00:00:00.000000000 Z
11
+ date: 2023-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -104,12 +104,18 @@ files:
104
104
  - lib/plurimath/math/function/fenced.rb
105
105
  - lib/plurimath/math/function/floor.rb
106
106
  - lib/plurimath/math/function/font_style.rb
107
+ - lib/plurimath/math/function/font_style/bold-fraktur.rb
108
+ - lib/plurimath/math/function/font_style/bold-italic.rb
109
+ - lib/plurimath/math/function/font_style/bold-sans-serif.rb
110
+ - lib/plurimath/math/function/font_style/bold-script.rb
107
111
  - lib/plurimath/math/function/font_style/bold.rb
108
112
  - lib/plurimath/math/function/font_style/double_struck.rb
109
113
  - lib/plurimath/math/function/font_style/fraktur.rb
110
114
  - lib/plurimath/math/function/font_style/italic.rb
111
115
  - lib/plurimath/math/function/font_style/monospace.rb
112
116
  - lib/plurimath/math/function/font_style/normal.rb
117
+ - lib/plurimath/math/function/font_style/sans-serif-bold-italic.rb
118
+ - lib/plurimath/math/function/font_style/sans-serif-italic.rb
113
119
  - lib/plurimath/math/function/font_style/sans-serif.rb
114
120
  - lib/plurimath/math/function/font_style/script.rb
115
121
  - lib/plurimath/math/function/frac.rb