plurimath 0.6.0 → 0.7.0

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/lib/plurimath/asciimath/parse.rb +3 -2
  4. data/lib/plurimath/asciimath/transform.rb +32 -5
  5. data/lib/plurimath/latex/constants.rb +2 -1
  6. data/lib/plurimath/latex/transform.rb +9 -13
  7. data/lib/plurimath/math/core.rb +134 -20
  8. data/lib/plurimath/math/formula.rb +88 -18
  9. data/lib/plurimath/math/function/abs.rb +28 -15
  10. data/lib/plurimath/math/function/bar.rb +5 -0
  11. data/lib/plurimath/math/function/base.rb +14 -0
  12. data/lib/plurimath/math/function/binary_function.rb +2 -8
  13. data/lib/plurimath/math/function/ceil.rb +24 -9
  14. data/lib/plurimath/math/function/ddot.rb +6 -1
  15. data/lib/plurimath/math/function/deg.rb +4 -1
  16. data/lib/plurimath/math/function/det.rb +4 -1
  17. data/lib/plurimath/math/function/dim.rb +4 -1
  18. data/lib/plurimath/math/function/dot.rb +5 -0
  19. data/lib/plurimath/math/function/exp.rb +4 -1
  20. data/lib/plurimath/math/function/fenced.rb +25 -16
  21. data/lib/plurimath/math/function/floor.rb +23 -13
  22. data/lib/plurimath/math/function/font_style.rb +18 -8
  23. data/lib/plurimath/math/function/frac.rb +32 -18
  24. data/lib/plurimath/math/function/gcd.rb +4 -1
  25. data/lib/plurimath/math/function/glb.rb +8 -1
  26. data/lib/plurimath/math/function/hat.rb +16 -5
  27. data/lib/plurimath/math/function/hom.rb +4 -1
  28. data/lib/plurimath/math/function/inf.rb +16 -0
  29. data/lib/plurimath/math/function/int.rb +28 -9
  30. data/lib/plurimath/math/function/ker.rb +4 -1
  31. data/lib/plurimath/math/function/lcm.rb +17 -1
  32. data/lib/plurimath/math/function/left.rb +1 -1
  33. data/lib/plurimath/math/function/lg.rb +4 -1
  34. data/lib/plurimath/math/function/lim.rb +10 -0
  35. data/lib/plurimath/math/function/liminf.rb +4 -1
  36. data/lib/plurimath/math/function/limits.rb +22 -9
  37. data/lib/plurimath/math/function/limsup.rb +4 -1
  38. data/lib/plurimath/math/function/linebreak.rb +95 -0
  39. data/lib/plurimath/math/function/ln.rb +4 -1
  40. data/lib/plurimath/math/function/log.rb +21 -12
  41. data/lib/plurimath/math/function/longdiv.rb +19 -0
  42. data/lib/plurimath/math/function/lub.rb +4 -1
  43. data/lib/plurimath/math/function/max.rb +4 -1
  44. data/lib/plurimath/math/function/mbox.rb +8 -7
  45. data/lib/plurimath/math/function/merror.rb +12 -3
  46. data/lib/plurimath/math/function/min.rb +4 -1
  47. data/lib/plurimath/math/function/mod.rb +42 -15
  48. data/lib/plurimath/math/function/msgroup.rb +4 -0
  49. data/lib/plurimath/math/function/msline.rb +10 -0
  50. data/lib/plurimath/math/function/multiscript.rb +20 -0
  51. data/lib/plurimath/math/function/nary.rb +39 -5
  52. data/lib/plurimath/math/function/norm.rb +24 -15
  53. data/lib/plurimath/math/function/obrace.rb +5 -0
  54. data/lib/plurimath/math/function/oint.rb +42 -20
  55. data/lib/plurimath/math/function/over.rb +23 -10
  56. data/lib/plurimath/math/function/overset.rb +13 -10
  57. data/lib/plurimath/math/function/phantom.rb +24 -6
  58. data/lib/plurimath/math/function/power.rb +13 -4
  59. data/lib/plurimath/math/function/power_base.rb +28 -6
  60. data/lib/plurimath/math/function/prod.rb +33 -14
  61. data/lib/plurimath/math/function/right.rb +1 -1
  62. data/lib/plurimath/math/function/rule.rb +1 -1
  63. data/lib/plurimath/math/function/scarries.rb +14 -0
  64. data/lib/plurimath/math/function/semantics.rb +9 -0
  65. data/lib/plurimath/math/function/sqrt.rb +5 -0
  66. data/lib/plurimath/math/function/stackrel.rb +8 -0
  67. data/lib/plurimath/math/function/substack.rb +12 -51
  68. data/lib/plurimath/math/function/sum.rb +43 -20
  69. data/lib/plurimath/math/function/sup.rb +11 -2
  70. data/lib/plurimath/math/function/table/array.rb +1 -1
  71. data/lib/plurimath/math/function/table/matrix.rb +4 -0
  72. data/lib/plurimath/math/function/table.rb +10 -2
  73. data/lib/plurimath/math/function/td.rb +14 -4
  74. data/lib/plurimath/math/function/ternary_function.rb +8 -10
  75. data/lib/plurimath/math/function/text.rb +1 -1
  76. data/lib/plurimath/math/function/tilde.rb +5 -0
  77. data/lib/plurimath/math/function/tr.rb +1 -1
  78. data/lib/plurimath/math/function/ubrace.rb +5 -0
  79. data/lib/plurimath/math/function/unary_function.rb +72 -26
  80. data/lib/plurimath/math/function/underover.rb +25 -8
  81. data/lib/plurimath/math/function/underset.rb +19 -9
  82. data/lib/plurimath/math/function/vec.rb +5 -0
  83. data/lib/plurimath/math/number.rb +3 -3
  84. data/lib/plurimath/math/symbol.rb +13 -5
  85. data/lib/plurimath/mathml/parser.rb +2 -0
  86. data/lib/plurimath/mathml/transform.rb +23 -15
  87. data/lib/plurimath/omml/transform.rb +22 -10
  88. data/lib/plurimath/unitsml.rb +2 -1
  89. data/lib/plurimath/utility.rb +29 -28
  90. data/lib/plurimath/version.rb +1 -1
  91. metadata +3 -3
  92. data/lib/plurimath/math/function/scarry.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af2ed460bf37f3496c528c6cb170f2c555873332771086113f90a875312b467a
4
- data.tar.gz: d9311eaf4dfb84c188966346a38d273e544f035c573afb50898bd9f03f81c9fc
3
+ metadata.gz: f58b20082cd94488f247f22399522d777ea751a4eba4f21e45a7a792fc6d30f3
4
+ data.tar.gz: f6e55fa7493ac10ac6e8ded470ea547640b3b5b53f00ac36c8cf941d56d5cc87
5
5
  SHA512:
6
- metadata.gz: cffd311295a1f9e41d372c544909029da3f5798f5744e14e549dd1d7e220755971d5bec0a91cc3695fdef25f3d9b44de606da37876c615eee3cc3818eadbe6e9
7
- data.tar.gz: f4035ab63d7f2f3f0aef261f9491ed163a1ffec03d52011b7dda140d6ce4c303bd277a5d05487028b8c77c32585359a826d85fcfc46bb32220e4d1b103b54fb3
6
+ metadata.gz: 133860ffcca6250cb3bef1e9eb186536685b3697a7d26bcda1d287170d74b9ac98083d352143cc6a9fc3649832229c0e1c3c1963c3e787db4d8b6f992b3f5802
7
+ data.tar.gz: 3a2044197aa65f0820961c14a602ca6df69c316e48203b2d448263032837336053715d95c52290b5241486426d000588d632cd820563ddf6466b0f4ab5d46569
data/Gemfile CHANGED
@@ -11,3 +11,4 @@ gem 'equivalent-xml'
11
11
  gem 'opal-rspec', "~> 1.1.0a"
12
12
  gem 'oga'
13
13
  gem 'ox'
14
+ gem "unitsml"
@@ -69,7 +69,8 @@ module Plurimath
69
69
  end
70
70
 
71
71
  rule(:quoted_text) do
72
- (str('"') >> match("[^\"]").repeat.as(:text) >> str('"')) |
72
+ (str('"') >> str("unitsml(") >> match("[^\)\"]").repeat.as(:unitsml) >> str(')"')) |
73
+ (str('"') >> match("[^\"]").repeat.as(:text) >> str('"')) |
73
74
  (str('"') >> str("").as(:text))
74
75
  end
75
76
 
@@ -188,7 +189,7 @@ module Plurimath
188
189
  def dynamic_parser_rules(expr)
189
190
  first_value = str(expr.first.to_s)
190
191
  case expr.last
191
- when :symbol then first_value.as(:symbol)
192
+ when :symbol then (str("\\").as(:slash) >> match("\s").repeat >> str("\n")) | first_value.as(:symbol)
192
193
  when :unary_class then (first_value.as(:unary_class) >> space? >> sequence.maybe).as(:unary)
193
194
  when :fonts then first_value.as(:fonts_class) >> space? >> sequence.as(:fonts_value)
194
195
  when :special_fonts then first_value.as(:bold_fonts)
@@ -8,6 +8,7 @@ module Plurimath
8
8
  rule(unary: simple(:unary)) { unary }
9
9
  rule(table: simple(:table)) { table }
10
10
  rule(comma: simple(:comma)) { Utility.symbol_object(comma) }
11
+ rule(slash: simple(:slash)) { Math::Function::Linebreak.new }
11
12
  rule(unary: sequence(:unary)) { Utility.filter_values(unary) }
12
13
  rule(rparen: simple(:rparen)) { Utility.symbol_object(rparen) }
13
14
  rule(number: simple(:number)) { Math::Number.new(number) }
@@ -27,6 +28,12 @@ module Plurimath
27
28
  rule(power_value: sequence(:power_value)) { power_value }
28
29
  rule(mod: simple(:mod), expr: simple(:expr)) { [mod, expr] }
29
30
 
31
+ rule(unitsml: simple(:unitsml)) do
32
+ Utility.filter_values(
33
+ Unitsml.new(unitsml.to_s).to_formula.value,
34
+ )
35
+ end
36
+
30
37
  rule(bold_fonts: simple(:font)) do
31
38
  Math::Function::FontStyle::DoubleStruck.new(
32
39
  Utility.symbol_object(font.to_s[0]),
@@ -303,11 +310,15 @@ module Plurimath
303
310
  end
304
311
 
305
312
  rule(td: simple(:td)) do
306
- Math::Function::Td.new(
307
- [
308
- Utility.td_value(td),
309
- ],
310
- )
313
+ if td.is_a?(Math::Formula) && td.value.any?(Math::Function::Table)
314
+ Utility.td_values(td.value, ",")
315
+ else
316
+ Math::Function::Td.new(
317
+ [
318
+ Utility.td_value(td),
319
+ ],
320
+ )
321
+ end
311
322
  end
312
323
 
313
324
  rule(td: sequence(:td)) do
@@ -631,6 +642,13 @@ module Plurimath
631
642
  new_arr
632
643
  end
633
644
 
645
+ rule(sequence: sequence(:sequence),
646
+ left_right: simple(:left_right)) do
647
+ new_arr = sequence.flatten.compact
648
+ new_arr << left_right unless left_right.to_s.strip.empty?
649
+ new_arr
650
+ end
651
+
634
652
  rule(sequence: sequence(:sequence),
635
653
  expr: sequence(:expr)) do
636
654
  sequence.flatten.compact + expr.flatten.compact
@@ -860,6 +878,15 @@ module Plurimath
860
878
  )
861
879
  end
862
880
 
881
+ rule(unary_class: simple(:function),
882
+ unitsml: simple(:unitsml)) do
883
+ Utility.get_class(function).new(
884
+ Utility.filter_values(
885
+ Unitsml.new(unitsml.to_s).to_formula.value,
886
+ ),
887
+ )
888
+ end
889
+
863
890
  rule(number: simple(:number),
864
891
  comma: simple(:comma)) do
865
892
  [
@@ -2856,6 +2856,7 @@ module Plurimath
2856
2856
  overline: :unary,
2857
2857
  underset: :binary,
2858
2858
  overset: :binary,
2859
+ phantom: :unary,
2859
2860
  ddagger: :symbols,
2860
2861
  trprime: :symbols,
2861
2862
  closure: :symbols,
@@ -3562,7 +3563,7 @@ module Plurimath
3562
3563
  tanh: :unary,
3563
3564
  cosh: :unary,
3564
3565
  ddot: :unary,
3565
- mbox: :unary,
3566
+ mbox: :text,
3566
3567
  text: :text,
3567
3568
  '"': :symbols,
3568
3569
  sum: :ternary,
@@ -14,7 +14,7 @@ module Plurimath
14
14
  rule(lparen: simple(:lparen)) { Math::Symbol.new(lparen) }
15
15
  rule(rparen: simple(:rparen)) { Math::Symbol.new(rparen) }
16
16
  rule(limits: simple(:limits)) { limits }
17
- rule("\\\\" => simple(:slash)) { Math::Symbol.new(slash) }
17
+ rule("\\\\" => simple(:slash)) { Math::Function::Linebreak.new }
18
18
  rule(expression: simple(:expr)) { expr }
19
19
  rule(environment: simple(:env)) { env }
20
20
  rule(ternary: simple(:ternary)) { Utility.get_class(ternary).new }
@@ -488,19 +488,19 @@ module Plurimath
488
488
 
489
489
  rule(text: simple(:text),
490
490
  first_value: simple(:first_value)) do
491
- Math::Function::Text.new(first_value)
491
+ Utility.get_class(text).new(first_value)
492
492
  end
493
493
 
494
494
  rule(text: simple(:text),
495
495
  first_value: sequence(:first_value)) do
496
- Math::Function::Text.new(first_value.join)
496
+ Utility.get_class(text).new(first_value.join)
497
497
  end
498
498
 
499
499
  rule(text: simple(:text),
500
500
  first_value: simple(:first_value),
501
501
  supscript: simple(:supscript),) do
502
502
  Math::Function::Power.new(
503
- Math::Function::Text.new(first_value),
503
+ Utility.get_class(text).new(first_value),
504
504
  supscript,
505
505
  )
506
506
  end
@@ -509,7 +509,7 @@ module Plurimath
509
509
  first_value: sequence(:first_value),
510
510
  supscript: simple(:supscript),) do
511
511
  Math::Function::Power.new(
512
- Math::Function::Text.new(first_value.join),
512
+ Utility.get_class(text).new(first_value.join),
513
513
  supscript,
514
514
  )
515
515
  end
@@ -518,7 +518,7 @@ module Plurimath
518
518
  first_value: sequence(:first_value),
519
519
  subscript: simple(:subscript)) do
520
520
  Math::Function::Base.new(
521
- Math::Function::Text.new(first_value.join),
521
+ Utility.get_class(text).new(first_value.join),
522
522
  subscript,
523
523
  )
524
524
  end
@@ -527,7 +527,7 @@ module Plurimath
527
527
  first_value: simple(:first_value),
528
528
  subscript: simple(:subscript)) do
529
529
  Math::Function::Base.new(
530
- Math::Function::Text.new(first_value),
530
+ Utility.get_class(text).new(first_value),
531
531
  subscript,
532
532
  )
533
533
  end
@@ -537,7 +537,7 @@ module Plurimath
537
537
  subscript: simple(:subscript),
538
538
  supscript: simple(:supscript)) do
539
539
  Math::Function::PowerBase.new(
540
- Math::Function::Text.new(first_value),
540
+ Utility.get_class(text).new(first_value),
541
541
  subscript,
542
542
  supscript,
543
543
  )
@@ -948,12 +948,8 @@ module Plurimath
948
948
 
949
949
  rule(substack: simple(:substack),
950
950
  expression: sequence(:value)) do
951
- tds = Utility.td_values(value, "\\\\")
952
-
953
- substack_values = tds.map { |td| Math::Function::Tr.new([td]) }
954
951
  Math::Function::Substack.new(
955
- substack_values.shift,
956
- substack_values.shift,
952
+ Utility.organize_table(value),
957
953
  )
958
954
  end
959
955
  end
@@ -3,6 +3,11 @@
3
3
  module Plurimath
4
4
  module Math
5
5
  class Core
6
+ REPLACABLES = {
7
+ /&amp;/ => "&",
8
+ /^\n/ => "",
9
+ }
10
+
6
11
  def class_name
7
12
  self.class.name.split("::").last.downcase
8
13
  end
@@ -24,18 +29,18 @@ module Plurimath
24
29
  end
25
30
 
26
31
  def empty_tag(wrapper_tag)
27
- r_tag = Utility.ox_element("r", namespace: "m")
28
- r_tag << (Utility.ox_element("t", namespace: "m") << "&#8203;")
32
+ r_tag = ox_element("r", namespace: "m")
33
+ r_tag << (ox_element("t", namespace: "m") << "&#8203;")
29
34
  wrapper_tag << r_tag
30
35
  end
31
36
 
32
- def omml_parameter(field, display_style, tag_name: , namespace: "m")
33
- tag = Utility.ox_element(tag_name, namespace: namespace)
37
+ def omml_parameter(field, display_style, tag_name:, namespace: "m")
38
+ tag = ox_element(tag_name, namespace: namespace)
34
39
  return empty_tag(tag) unless field
35
40
 
36
41
  Utility.update_nodes(
37
42
  tag,
38
- field&.insert_t_tag(display_style),
43
+ field.insert_t_tag(display_style),
39
44
  )
40
45
  end
41
46
 
@@ -44,12 +49,13 @@ module Plurimath
44
49
  end
45
50
 
46
51
  def r_element(string, rpr_tag: true)
47
- r_tag = Utility.ox_element("r", namespace: "m")
52
+ r_tag = ox_element("r", namespace: "m")
48
53
  if rpr_tag
49
- sty_tag = Utility.ox_element("sty", namespace: "m", attributes: { "m:val": "p" })
50
- r_tag << (Utility.ox_element("rPr", namespace: "m") << sty_tag)
54
+ attrs = { "m:val": "p" }
55
+ sty_tag = ox_element("sty", namespace: "m", attributes: attrs)
56
+ r_tag << (ox_element("rPr", namespace: "m") << sty_tag)
51
57
  end
52
- r_tag << (Utility.ox_element("t", namespace: "m") << string)
58
+ r_tag << (ox_element("t", namespace: "m") << string)
53
59
  Array(r_tag)
54
60
  end
55
61
 
@@ -57,7 +63,7 @@ module Plurimath
57
63
  false
58
64
  end
59
65
 
60
- def extract_class_from_text
66
+ def extract_class_name_from_text
61
67
  ""
62
68
  end
63
69
 
@@ -107,16 +113,13 @@ module Plurimath
107
113
  end
108
114
 
109
115
  def dump_mathml(field)
110
- mathml = dump_ox_nodes(field.to_mathml_without_math_tag)
111
- mathml.gsub(/\n\s*/, "").gsub("&amp;", "&")
116
+ dump_ox_nodes(field.to_mathml_without_math_tag).gsub(/\n\s*/, "")
112
117
  end
113
118
 
114
119
  def dump_omml(field, display_style)
115
120
  return if field.nil?
116
121
 
117
- omml = field.omml_nodes(display_style)
118
- omml_string = omml.is_a?(Array) ? omml.flatten.map { |obj| dump_ox_nodes(obj) }.join : dump_ox_nodes(omml)
119
- omml_string.gsub(/\n\s*/, "").gsub("&amp;", "&")
122
+ dump_ox_nodes(field.omml_nodes(display_style)).gsub(/\n\s*/, "")
120
123
  end
121
124
 
122
125
  def omml_nodes(display_style)
@@ -124,16 +127,16 @@ module Plurimath
124
127
  end
125
128
 
126
129
  def validate_mathml_fields(field)
127
- field.nil? ? Utility.ox_element("mi") : field.to_mathml_without_math_tag
130
+ field.nil? ? ox_element("mi") : field.to_mathml_without_math_tag
128
131
  end
129
132
 
130
133
  def common_math_zone_conversion(field, options = {})
131
134
  {
132
135
  spacing: options[:spacing],
133
136
  last: options[:last] || true,
134
- indent: !field&.is_a?(Formula),
137
+ indent: !field.is_a?(Formula),
135
138
  function_spacing: "#{options[:spacing]}#{options[:additional_space]}",
136
- field_name: options[:field_name] ? " #{options[:field_name]}" : "",
139
+ field_name: (options[:field_name] ? " #{options[:field_name]}" : ""),
137
140
  }
138
141
  end
139
142
 
@@ -142,16 +145,127 @@ module Plurimath
142
145
  end
143
146
 
144
147
  def dump_ox_nodes(nodes)
145
- Plurimath.xml_engine.dump(nodes)
148
+ return dump_nodes(nodes) unless nodes.is_a?(Array)
149
+
150
+ nodes.flatten.map { |node| dump_nodes(node) }.join
151
+ end
152
+
153
+ def dump_nodes(nodes, indent: nil)
154
+ replacable_values(
155
+ Plurimath.xml_engine.dump(nodes, indent: indent),
156
+ )
157
+ end
158
+
159
+ def replacable_values(string)
160
+ REPLACABLES.each { |regex, str| string.gsub!(regex, str) }
161
+ string
146
162
  end
147
163
 
148
164
  def gsub_spacing(spacing, last)
149
- spacing.gsub(/\|\_/, last ? " " : "| ")
165
+ spacing.gsub(/\|_/, last ? " " : "| ")
150
166
  end
151
167
 
152
168
  def invert_unicode_symbols
153
169
  Mathml::Constants::UNICODE_SYMBOLS.invert[class_name] || class_name
154
170
  end
171
+
172
+ def separate_table
173
+ false
174
+ end
175
+
176
+ def linebreak
177
+ false
178
+ end
179
+
180
+ def cloned_objects
181
+ object = self.class.new rescue self.class.new(nil)
182
+ variables.each { |var| object.set(var, variable_value(get(var))) }
183
+ object
184
+ end
185
+
186
+ def variable_value(value)
187
+ case value
188
+ when Core
189
+ value.cloned_objects
190
+ when Array
191
+ value.map { |object| variable_value(object) }
192
+ else
193
+ value
194
+ end
195
+ end
196
+
197
+ def line_breaking(obj)
198
+ variables.each do |variable|
199
+ field = get(variable)
200
+ case field
201
+ when Core
202
+ field.line_breaking(obj)
203
+ updated_object_values(variable, obj: obj, update_value: true) if obj.value_exist?
204
+ when Array
205
+ if result(field).length > 1
206
+ updated_object_values(variable, obj: obj)
207
+ else
208
+ field.each { |object| object.line_breaking(obj) }
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ def updated_object_values(param, obj:, update_value: false)
215
+ object = self.class.new(nil)
216
+ found = false
217
+ variables.each do |variable|
218
+ value = if param == variable
219
+ found = true
220
+ if update_value
221
+ return_value = obj.value
222
+ obj.value = []
223
+ return_value
224
+ else
225
+ formula = Formula.new(get(variable))
226
+ formula.line_breaking(obj)
227
+ set(variable, obj)
228
+ get(variable)
229
+ end
230
+ else
231
+ return_value = get(variable)
232
+ set(variable, nil) if found
233
+ return_value
234
+ end
235
+ object.set(variable, Utility.filter_values(value))
236
+ end
237
+ object.hide_function_name = true if object.methods.include?(:hide_function_name)
238
+ obj.update(object)
239
+ end
240
+
241
+ def get(variable)
242
+ instance_variable_get(variable)
243
+ end
244
+
245
+ def set(variable, value)
246
+ instance_variable_set(variable, value)
247
+ end
248
+
249
+ def variables
250
+ instance_variables
251
+ end
252
+
253
+ def ox_element(node, attributes: [], namespace: "")
254
+ Utility.ox_element(
255
+ node,
256
+ attributes: attributes,
257
+ namespace: namespace,
258
+ )
259
+ end
260
+
261
+ def result(value = [])
262
+ value = get("@value") || value
263
+ value.slice_after { |d| d.is_a?(Math::Function::Linebreak) }.to_a
264
+ end
265
+
266
+ def is_unary?
267
+ is_a?(Math::Function::UnaryFunction)
268
+ end
155
269
  end
156
270
  end
157
271
  end
@@ -4,6 +4,7 @@ module Plurimath
4
4
  module Math
5
5
  class Formula < Core
6
6
  attr_accessor :value, :left_right_wrapper, :displaystyle, :input_string
7
+
7
8
  MATH_ZONE_TYPES = %i[
8
9
  omml
9
10
  latex
@@ -36,21 +37,29 @@ module Plurimath
36
37
  parse_error!(:asciimath)
37
38
  end
38
39
 
39
- def to_mathml(display_style: displaystyle)
40
+ def to_mathml(display_style: displaystyle, split_on_linebreak: false)
41
+ return line_breaked_mathml(display_style) if split_on_linebreak
42
+
40
43
  math_attrs = {
41
44
  xmlns: "http://www.w3.org/1998/Math/MathML",
42
45
  display: "block",
43
46
  }
44
47
  style_attrs = { displaystyle: boolean_display_style(display_style) }
45
- math = Utility.ox_element("math", attributes: math_attrs)
46
- style = Utility.ox_element("mstyle", attributes: style_attrs)
48
+ math = ox_element("math", attributes: math_attrs)
49
+ style = ox_element("mstyle", attributes: style_attrs)
47
50
  Utility.update_nodes(style, mathml_content)
48
51
  Utility.update_nodes(math, [style])
49
- Plurimath.xml_engine.dump(math, indent: 2).gsub("&amp;", "&")
52
+ dump_nodes(math, indent: 2)
50
53
  rescue
51
54
  parse_error!(:mathml)
52
55
  end
53
56
 
57
+ def line_breaked_mathml(display_style)
58
+ new_line_support.map do |formula|
59
+ formula.to_mathml(display_style: display_style)
60
+ end.join
61
+ end
62
+
54
63
  def to_mathml_without_math_tag
55
64
  return mathml_content unless left_right_wrapper
56
65
 
@@ -76,7 +85,7 @@ module Plurimath
76
85
  parse_error!(:html)
77
86
  end
78
87
 
79
- def omml_math_attrs
88
+ def omml_attrs
80
89
  {
81
90
  "xmlns:m": "http://schemas.openxmlformats.org/officeDocument/2006/math",
82
91
  "xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006",
@@ -99,16 +108,20 @@ module Plurimath
99
108
  }
100
109
  end
101
110
 
102
- def to_omml(display_style: displaystyle)
103
- para_element = Utility.ox_element(
104
- "oMathPara",
105
- attributes: omml_math_attrs,
106
- namespace: "m",
107
- )
108
- math_element = Utility.ox_element("oMath", namespace: "m")
109
- content = omml_content(boolean_display_style(display_style))
110
- para_element << Utility.update_nodes(math_element, content)
111
- Plurimath.xml_engine.dump(para_element, indent: 2).gsub("&amp;", "&").lstrip
111
+ def to_omml(display_style: displaystyle, split_on_linebreak: false)
112
+ objects = split_on_linebreak ? new_line_support : [self]
113
+
114
+ para_element = Utility.ox_element("oMathPara", attributes: omml_attrs, namespace: "m")
115
+ objects.each.with_index(1) do |object, index|
116
+ para_element << Utility.update_nodes(
117
+ Utility.ox_element("oMath", namespace: "m"),
118
+ object.omml_content(boolean_display_style(display_style)),
119
+ )
120
+ next if objects.length == index
121
+
122
+ para_element << omml_br_tag
123
+ end
124
+ dump_nodes(para_element, indent: 2)
112
125
  rescue
113
126
  parse_error!(:omml)
114
127
  end
@@ -168,8 +181,8 @@ module Plurimath
168
181
  end
169
182
  end
170
183
 
171
- def extract_class_from_text
172
- return false unless (value.length < 2 && value&.first&.is_a?(Function::Text))
184
+ def extract_class_name_from_text
185
+ return unless value.length < 2 && value.first.is_a?(Function::Text)
173
186
 
174
187
  value.first.parameter_one
175
188
  end
@@ -182,10 +195,62 @@ module Plurimath
182
195
  (value.none?(Function::Left) || value.none?(Function::Right))
183
196
  end
184
197
 
198
+ def value_exist?
199
+ value && !value.empty?
200
+ end
201
+
202
+ def update(object)
203
+ self.value = Array(object)
204
+ end
205
+
206
+ def cloned_objects
207
+ cloned_obj = value.map(&:cloned_objects)
208
+ formula = self.class.new(cloned_obj)
209
+ formula.left_right_wrapper = @left_right_wrapper
210
+ formula
211
+ end
212
+
213
+ def new_line_support(array = [])
214
+ cloned = cloned_objects
215
+ obj = self.class.new
216
+ cloned.line_breaking(obj)
217
+ array << cloned
218
+ obj.value_exist? ? obj.new_line_support(array) : array
219
+ end
220
+
221
+ def line_breaking(obj)
222
+ if result.size > 1
223
+ breaked_result = result.first.last.omml_line_break(result)
224
+ update(Array(breaked_result.shift))
225
+ obj.update(breaked_result.flatten)
226
+ reprocess_value(obj)
227
+ return
228
+ end
229
+
230
+ value.each.with_index(1) do |object, index|
231
+ object.line_breaking(obj)
232
+ break obj.insert(value.slice!(index..value.size)) if obj.value_exist?
233
+ end
234
+ end
235
+
236
+ def reprocess_value(obj)
237
+ new_obj = self.class.new([])
238
+ self.line_breaking(new_obj)
239
+ if new_obj.value_exist?
240
+ obj.value.insert(0, Function::Linebreak.new)
241
+ obj.value.insert(0, self.class.new(new_obj.value))
242
+ end
243
+ end
244
+
245
+ def insert(values)
246
+ update(Array(value) + values)
247
+ end
248
+
249
+
185
250
  protected
186
251
 
187
252
  def boolean_display_style(display_style = displaystyle)
188
- YAML.load(display_style.to_s)
253
+ YAML.safe_load(display_style.to_s)
189
254
  end
190
255
 
191
256
  def new_space(spacing, indent)
@@ -203,6 +268,11 @@ module Plurimath
203
268
  def parse_error!(type)
204
269
  Math.parse_error!(input_string, type)
205
270
  end
271
+
272
+ def omml_br_tag
273
+ r_tag = ox_element("r", namespace: "m")
274
+ r_tag << ox_element("br")
275
+ end
206
276
  end
207
277
  end
208
278
  end
@@ -6,32 +6,45 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Abs < UnaryFunction
9
+ attr_accessor :open_paren, :close_paren
10
+
9
11
  def to_mathml_without_math_tag
10
12
  symbol = Utility.ox_element("mo") << "|"
11
- first_value = mathml_value&.insert(0, symbol)
12
- Utility.update_nodes(
13
- Utility.ox_element("mrow"),
14
- first_value << symbol,
15
- )
13
+ first_value = mathml_value
14
+ first_value = first_value&.insert(0, symbol) unless open_paren
15
+ first_value << symbol unless close_paren
16
+ Utility.update_nodes(ox_element("mrow"), first_value)
16
17
  end
17
18
 
18
19
  def to_omml_without_math_tag(display_style)
19
- md = (Utility.ox_element("d", namespace: "m") << mdpr_tag)
20
- me = Utility.ox_element("e", namespace: "m")
21
- Utility.update_nodes(me, omml_value(display_style))
22
- Utility.update_nodes(md, Array(me))
23
- [md]
20
+ Array(
21
+ md_tag << omml_parameter(parameter_one, display_style, tag_name: "e"),
22
+ )
23
+ end
24
+
25
+ def line_breaking(obj)
26
+ parameter_one.line_breaking(obj)
27
+ if obj.value_exist?
28
+ ceil_object = self.class.new(Utility.filter_values(obj.value))
29
+ ceil_object.open_paren = true
30
+ ceil_object.close_paren = false
31
+ obj.update(ceil_object)
32
+ self.close_paren = true
33
+ self.open_paren = false unless open_paren
34
+ end
24
35
  end
25
36
 
26
37
  protected
27
38
 
28
- def mdpr_tag
39
+ def md_tag
29
40
  attribute = { "m:val": "|" }
41
+ sepchr_attr = { "m:val": "" }
30
42
  mdpr = Utility.pr_element("d", namespace: "m")
31
- mdpr << Utility.ox_element("begChr", namespace: "m", attributes: attribute)
32
- mdpr << Utility.ox_element("endChr", namespace: "m", attributes: attribute)
33
- mdpr << Utility.ox_element("sepChr", namespace: "m", attributes: { "m:val": "" })
34
- mdpr << Utility.ox_element("grow", namespace: "m")
43
+ mdpr << ox_element("begChr", namespace: "m", attributes: attribute) unless open_paren
44
+ mdpr << ox_element("endChr", namespace: "m", attributes: attribute) unless close_paren
45
+ mdpr << ox_element("sepChr", namespace: "m", attributes: sepchr_attr)
46
+ mdpr << ox_element("grow", namespace: "m")
47
+ ox_element("d", namespace: "m") << mdpr
35
48
  end
36
49
  end
37
50
  end
@@ -48,6 +48,11 @@ module Plurimath
48
48
  Ul.new(parameter_one, attributes)
49
49
  end
50
50
 
51
+ def line_breaking(obj)
52
+ parameter_one&.line_breaking(obj)
53
+ obj.update(Utility.filter_values(obj.value)) if obj.value_exist?
54
+ end
55
+
51
56
  protected
52
57
 
53
58
  def acc_tag(display_style)