plurimath 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.rspec +3 -0
  4. data/.rspec-opal +11 -0
  5. data/Gemfile +3 -0
  6. data/Rakefile +11 -0
  7. data/lib/plurimath/asciimath/transform.rb +15 -0
  8. data/lib/plurimath/latex/constants.rb +3 -0
  9. data/lib/plurimath/latex/parse.rb +20 -11
  10. data/lib/plurimath/latex/transform.rb +24 -2
  11. data/lib/plurimath/math/core.rb +88 -0
  12. data/lib/plurimath/math/formula.rb +68 -24
  13. data/lib/plurimath/math/function/base.rb +8 -2
  14. data/lib/plurimath/math/function/binary_function.rb +36 -4
  15. data/lib/plurimath/math/function/color.rb +14 -0
  16. data/lib/plurimath/math/function/fenced.rb +27 -0
  17. data/lib/plurimath/math/function/floor.rb +1 -1
  18. data/lib/plurimath/math/function/font_style.rb +45 -0
  19. data/lib/plurimath/math/function/frac.rb +6 -0
  20. data/lib/plurimath/math/function/int.rb +7 -0
  21. data/lib/plurimath/math/function/left.rb +19 -1
  22. data/lib/plurimath/math/function/lim.rb +6 -0
  23. data/lib/plurimath/math/function/limits.rb +7 -0
  24. data/lib/plurimath/math/function/log.rb +6 -0
  25. data/lib/plurimath/math/function/menclose.rb +6 -0
  26. data/lib/plurimath/math/function/mod.rb +6 -0
  27. data/lib/plurimath/math/function/msgroup.rb +28 -0
  28. data/lib/plurimath/math/function/multiscript.rb +7 -0
  29. data/lib/plurimath/math/function/nary.rb +94 -0
  30. data/lib/plurimath/math/function/oint.rb +6 -0
  31. data/lib/plurimath/math/function/over.rb +6 -0
  32. data/lib/plurimath/math/function/overset.rb +6 -0
  33. data/lib/plurimath/math/function/power.rb +8 -2
  34. data/lib/plurimath/math/function/power_base.rb +10 -31
  35. data/lib/plurimath/math/function/prod.rb +19 -18
  36. data/lib/plurimath/math/function/right.rb +19 -1
  37. data/lib/plurimath/math/function/root.rb +6 -0
  38. data/lib/plurimath/math/function/rule.rb +7 -0
  39. data/lib/plurimath/math/function/semantics.rb +6 -0
  40. data/lib/plurimath/math/function/stackrel.rb +6 -0
  41. data/lib/plurimath/math/function/substack.rb +6 -0
  42. data/lib/plurimath/math/function/sum.rb +26 -25
  43. data/lib/plurimath/math/function/table.rb +52 -24
  44. data/lib/plurimath/math/function/td.rb +28 -0
  45. data/lib/plurimath/math/function/ternary_function.rb +44 -4
  46. data/lib/plurimath/math/function/text.rb +24 -2
  47. data/lib/plurimath/math/function/tr.rb +28 -0
  48. data/lib/plurimath/math/function/unary_function.rb +43 -3
  49. data/lib/plurimath/math/function/underover.rb +7 -55
  50. data/lib/plurimath/math/function/underset.rb +6 -0
  51. data/lib/plurimath/math/function/vec.rb +40 -0
  52. data/lib/plurimath/math/function.rb +7 -5
  53. data/lib/plurimath/math/number.rb +9 -5
  54. data/lib/plurimath/math/symbol.rb +13 -9
  55. data/lib/plurimath/math.rb +1 -3
  56. data/lib/plurimath/mathml/parser.rb +4 -4
  57. data/lib/plurimath/mathml/transform.rb +3 -4
  58. data/lib/plurimath/omml/parser.rb +3 -3
  59. data/lib/plurimath/omml/transform.rb +12 -11
  60. data/lib/plurimath/setup/oga.rb +5 -0
  61. data/lib/plurimath/setup/opal.rb.erb +8 -0
  62. data/lib/plurimath/setup/ox.rb +5 -0
  63. data/lib/plurimath/utility.rb +48 -13
  64. data/lib/plurimath/version.rb +1 -1
  65. data/lib/plurimath/xml_engine/oga.rb +246 -0
  66. data/lib/plurimath/xml_engine/ox.rb +29 -0
  67. data/lib/plurimath/xml_engine.rb +6 -0
  68. data/lib/plurimath.rb +12 -2
  69. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6fabed12e1b85fa2c5d7b2cacfebaf2bafb8481025f6f0a9b072649ff2991131
4
- data.tar.gz: ec912de1e4e356af0d7458c0b2147ea9aee1fb4676506429ac5e4161cd974c79
3
+ metadata.gz: af2ed460bf37f3496c528c6cb170f2c555873332771086113f90a875312b467a
4
+ data.tar.gz: d9311eaf4dfb84c188966346a38d273e544f035c573afb50898bd9f03f81c9fc
5
5
  SHA512:
6
- metadata.gz: d31d2f5b644402ab58c0f19a9c14e88f91fff26d44dff6c89484b66d45d3760087be0827002c87c3b9ca540ac7dd52ad2ceb014f4b0f6b16fc9f94630f823c70
7
- data.tar.gz: 8f5ea828f70451af6ae075d8e06db4055145e096c83fc39b9a31cdcc57ddfff57afdd736e9f696d83e68d7b6c50ada74fa68f46acc00e878e08c1db22050ed2d
6
+ metadata.gz: cffd311295a1f9e41d372c544909029da3f5798f5744e14e549dd1d7e220755971d5bec0a91cc3695fdef25f3d9b44de606da37876c615eee3cc3818eadbe6e9
7
+ data.tar.gz: f4035ab63d7f2f3f0aef261f9491ed163a1ffec03d52011b7dda140d6ce4c303bd277a5d05487028b8c77c32585359a826d85fcfc46bb32220e4d1b103b54fb3
data/.gitignore CHANGED
@@ -6,7 +6,11 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /Gemfile.lock
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
12
13
  /coverage/
14
+
15
+ # temp files
16
+ *.kate-swp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rspec-opal ADDED
@@ -0,0 +1,11 @@
1
+ --default-path=spec
2
+ -I lib
3
+ -q oga/setup_opal
4
+ -q ll/setup_opal
5
+ --opal-opt=-g,htmlentities
6
+ --opal-opt=-g,equivalent-xml
7
+ --opal-opt=-g,parslet
8
+ --opal-opt=-g,oga
9
+ --format documentation
10
+ --color
11
+ --require spec_helper
data/Gemfile CHANGED
@@ -8,3 +8,6 @@ gem "rspec", "~> 3.0"
8
8
  gem 'simplecov', require: false, group: :test
9
9
  gem 'htmlentities'
10
10
  gem 'equivalent-xml'
11
+ gem 'opal-rspec', "~> 1.1.0a"
12
+ gem 'oga'
13
+ gem 'ox'
data/Rakefile CHANGED
@@ -1,6 +1,17 @@
1
+ require "erb"
1
2
  require "bundler/gem_tasks"
2
3
  require "rspec/core/rake_task"
4
+ require 'opal/rspec/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
8
+ # Opal testing support
9
+ begin
10
+ Opal::RSpec::RakeTask.new(:"spec-opal")
11
+ rescue LoadError
12
+ # Likely the dependencies haven't been upstreamed yet. Ensure you
13
+ # run those tests via the `plurimath-js` repo's `env/plurimath`
14
+ # script.
15
+ end
16
+
6
17
  task :default => :spec
@@ -132,6 +132,13 @@ module Plurimath
132
132
  new_arr
133
133
  end
134
134
 
135
+ rule(sequence: simple(:sequence),
136
+ left_right: sequence(:left_right)) do
137
+ new_arr = [sequence]
138
+ new_arr += left_right unless left_right.empty?
139
+ new_arr
140
+ end
141
+
135
142
  rule(sequence: simple(:sequence),
136
143
  number: simple(:number)) do
137
144
  [sequence, Math::Number.new(number.to_s)]
@@ -629,6 +636,14 @@ module Plurimath
629
636
  sequence.flatten.compact + expr.flatten.compact
630
637
  end
631
638
 
639
+ rule(sequence: simple(:sequence),
640
+ symbol: simple(:symbol)) do
641
+ [
642
+ sequence,
643
+ Math::Symbol.new(symbol),
644
+ ]
645
+ end
646
+
632
647
  rule(binary_class: simple(:function),
633
648
  base_value: simple(:base)) do
634
649
  Utility.get_class(function).new(
@@ -1720,6 +1720,7 @@ module Plurimath
1720
1720
  cap: "∩",
1721
1721
  cup: "∪",
1722
1722
  sim: "∼",
1723
+ int: "∫",
1723
1724
  neq: "≠",
1724
1725
  leq: "≤",
1725
1726
  geq: "≥",
@@ -2853,6 +2854,7 @@ module Plurimath
2853
2854
  mathbfit: :fonts,
2854
2855
  mathfrak: :fonts,
2855
2856
  overline: :unary,
2857
+ underset: :binary,
2856
2858
  overset: :binary,
2857
2859
  ddagger: :symbols,
2858
2860
  trprime: :symbols,
@@ -3245,6 +3247,7 @@ module Plurimath
3245
3247
  textrm: :fonts,
3246
3248
  textbf: :fonts,
3247
3249
  arccos: :unary,
3250
+ cancel: :unary,
3248
3251
  arcsin: :unary,
3249
3252
  arctan: :unary,
3250
3253
  limsup: :unary,
@@ -4,11 +4,18 @@ require "parslet"
4
4
  module Plurimath
5
5
  class Latex
6
6
  class Parse < Parslet::Parser
7
- rule(:base) { str("_") }
8
- rule(:power) { str("^") }
9
- rule(:slash) { str("\\") }
10
- rule(:under_over) { slash >> underover_classes }
11
- rule(:array_args) { (str("{") >> expression.as(:args) >> str("}")) }
7
+ rule(:base) { str("_") }
8
+ rule(:power) { str("^") }
9
+ rule(:slash) { str("\\") }
10
+ rule(:under_over) { slash >> underover_classes }
11
+ rule(:array_args) { (str("{") >> expression.as(:args) >> str("}")) }
12
+ rule(:array_begin) { (str("\\begin{") >> str("array").as(:environment) >> str("}")) }
13
+ rule(:optional_args) { (str("[") >> intermediate_exp.maybe.as(:options) >> str("]")).maybe }
14
+
15
+ rule(:color) do
16
+ (str("{") >> (str("}").absent? >> any).repeat.as(:symbol) >> str("}")) |
17
+ any.as(:symbol)
18
+ end
12
19
 
13
20
  rule(:optional_args) do
14
21
  (str("[") >> intermediate_exp.maybe.as(:options) >> str("]")).maybe
@@ -16,11 +23,7 @@ module Plurimath
16
23
 
17
24
  rule(:begining) do
18
25
  (slash >> str("begin") >> (str("{") >> symbol_text_or_integer >> str("*").as(:asterisk) >> str("}")) >> optional_args.maybe) |
19
- (slash >> str("begin") >> (str("{") >> symbol_text_or_integer >> str("}")))
20
- end
21
-
22
- rule(:array_begin) do
23
- (str("\\begin{") >> str("array").as(:environment) >> str("}"))
26
+ (slash >> str("begin") >> (str("{") >> symbol_text_or_integer >> str("}")))
24
27
  end
25
28
 
26
29
  rule(:ending) do
@@ -123,7 +126,8 @@ module Plurimath
123
126
  rule(:binary_functions) do
124
127
  (intermediate_exp.as(:first_value) >> under_over >> intermediate_exp.as(:second_value)).as(:under_over) |
125
128
  (slash >> str("sqrt").as(:root) >> sqrt_arg.as(:first_value) >> intermediate_exp.as(:second_value)).as(:binary) |
126
- (slash >> str("sqrt").as(:sqrt) >> intermediate_exp.as(:intermediate_exp)).as(:binary)
129
+ (slash >> str("sqrt").as(:sqrt) >> intermediate_exp.as(:intermediate_exp)).as(:binary) |
130
+ (color_rules)
127
131
  end
128
132
 
129
133
  rule(:sequence) do
@@ -242,6 +246,11 @@ module Plurimath
242
246
  (power >> intermediate_exp.as(:supscript)) |
243
247
  (base >> intermediate_exp.as(:subscript))
244
248
  end
249
+
250
+ def color_rules
251
+ (str("{") >> slash >> str("color").as(:binary) >> color.as(:first_value) >> (sequence >> iteration.maybe).as(:second_value).maybe >> str("}")) |
252
+ (slash >> str("color").as(:binary) >> color.as(:first_value) >> expression.as(:second_value).maybe)
253
+ end
245
254
  end
246
255
  end
247
256
  end
@@ -516,7 +516,7 @@ module Plurimath
516
516
 
517
517
  rule(text: simple(:text),
518
518
  first_value: sequence(:first_value),
519
- subscript: simple(:subscript),) do
519
+ subscript: simple(:subscript)) do
520
520
  Math::Function::Base.new(
521
521
  Math::Function::Text.new(first_value.join),
522
522
  subscript,
@@ -525,13 +525,24 @@ module Plurimath
525
525
 
526
526
  rule(text: simple(:text),
527
527
  first_value: simple(:first_value),
528
- subscript: simple(:subscript),) do
528
+ subscript: simple(:subscript)) do
529
529
  Math::Function::Base.new(
530
530
  Math::Function::Text.new(first_value),
531
531
  subscript,
532
532
  )
533
533
  end
534
534
 
535
+ rule(text: simple(:text),
536
+ first_value: simple(:first_value),
537
+ subscript: simple(:subscript),
538
+ supscript: simple(:supscript)) do
539
+ Math::Function::PowerBase.new(
540
+ Math::Function::Text.new(first_value),
541
+ subscript,
542
+ supscript,
543
+ )
544
+ end
545
+
535
546
  rule(unary: simple(:unary),
536
547
  first_value: simple(:first_value)) do
537
548
  Utility.get_class(
@@ -788,6 +799,17 @@ module Plurimath
788
799
  end
789
800
  end
790
801
 
802
+ rule(binary: simple(:binary),
803
+ first_value: simple(:first_value),
804
+ second_value: sequence(:second_value)) do
805
+ Utility.get_class(
806
+ binary.to_s.include?("mod") ? "mod" : binary,
807
+ ).new(
808
+ first_value,
809
+ Utility.filter_values(second_value),
810
+ )
811
+ end
812
+
791
813
  rule(underover: simple(:function),
792
814
  first_value: simple(:first),
793
815
  subscript: simple(:subscript),
@@ -64,6 +64,94 @@ module Plurimath
64
64
  def font_style_t_tag(display_style)
65
65
  to_omml_without_math_tag(display_style)
66
66
  end
67
+
68
+ def ascii_fields_to_print(field, options = {})
69
+ return if field.nil?
70
+
71
+ hashed = common_math_zone_conversion(field, options)
72
+ options[:array] << "#{hashed[:spacing]}|_ \"#{field&.to_asciimath}\"#{hashed[:field_name]}\n"
73
+ return unless Utility.validate_math_zone(field)
74
+
75
+ options[:array] << field&.to_asciimath_math_zone(hashed[:function_spacing], hashed[:last], hashed[:indent])
76
+ end
77
+
78
+ def latex_fields_to_print(field, options = {})
79
+ return if field.nil?
80
+
81
+ hashed = common_math_zone_conversion(field, options)
82
+ options[:array] << "#{hashed[:spacing]}|_ \"#{field&.to_latex}\"#{hashed[:field_name]}\n"
83
+ return unless Utility.validate_math_zone(field)
84
+
85
+ options[:array] << field&.to_latex_math_zone(hashed[:function_spacing], hashed[:last], hashed[:indent])
86
+ end
87
+
88
+ def mathml_fields_to_print(field, options = {})
89
+ return if field.nil?
90
+
91
+ hashed = common_math_zone_conversion(field, options)
92
+ options[:array] << "#{hashed[:spacing]}|_ \"#{dump_mathml(field)}\"#{hashed[:field_name]}\n"
93
+ return unless Utility.validate_math_zone(field)
94
+
95
+ options[:array] << field&.to_mathml_math_zone(hashed[:function_spacing], hashed[:last], hashed[:indent])
96
+ end
97
+
98
+ def omml_fields_to_print(field, options = {})
99
+ return if field.nil?
100
+
101
+ hashed = common_math_zone_conversion(field, options)
102
+ display_style = options[:display_style]
103
+ options[:array] << "#{hashed[:spacing]}|_ \"#{dump_omml(field, display_style)}\"#{hashed[:field_name]}\n"
104
+ return unless Utility.validate_math_zone(field)
105
+
106
+ options[:array] << field&.to_omml_math_zone(hashed[:function_spacing], hashed[:last], hashed[:indent], display_style: display_style)
107
+ end
108
+
109
+ def dump_mathml(field)
110
+ mathml = dump_ox_nodes(field.to_mathml_without_math_tag)
111
+ mathml.gsub(/\n\s*/, "").gsub("&amp;", "&")
112
+ end
113
+
114
+ def dump_omml(field, display_style)
115
+ return if field.nil?
116
+
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;", "&")
120
+ end
121
+
122
+ def omml_nodes(display_style)
123
+ to_omml_without_math_tag(display_style)
124
+ end
125
+
126
+ def validate_mathml_fields(field)
127
+ field.nil? ? Utility.ox_element("mi") : field.to_mathml_without_math_tag
128
+ end
129
+
130
+ def common_math_zone_conversion(field, options = {})
131
+ {
132
+ spacing: options[:spacing],
133
+ last: options[:last] || true,
134
+ indent: !field&.is_a?(Formula),
135
+ function_spacing: "#{options[:spacing]}#{options[:additional_space]}",
136
+ field_name: options[:field_name] ? " #{options[:field_name]}" : "",
137
+ }
138
+ end
139
+
140
+ def filtered_values(value)
141
+ @values = Utility.filter_math_zone_values(value)
142
+ end
143
+
144
+ def dump_ox_nodes(nodes)
145
+ Plurimath.xml_engine.dump(nodes)
146
+ end
147
+
148
+ def gsub_spacing(spacing, last)
149
+ spacing.gsub(/\|\_/, last ? " " : "| ")
150
+ end
151
+
152
+ def invert_unicode_symbols
153
+ Mathml::Constants::UNICODE_SYMBOLS.invert[class_name] || class_name
154
+ end
67
155
  end
68
156
  end
69
157
  end
@@ -4,6 +4,12 @@ module Plurimath
4
4
  module Math
5
5
  class Formula < Core
6
6
  attr_accessor :value, :left_right_wrapper, :displaystyle, :input_string
7
+ MATH_ZONE_TYPES = %i[
8
+ omml
9
+ latex
10
+ mathml
11
+ asciimath
12
+ ].freeze
7
13
 
8
14
  def initialize(
9
15
  value = [],
@@ -18,7 +24,9 @@ module Plurimath
18
24
  end
19
25
 
20
26
  def ==(object)
21
- object.value == value &&
27
+ object.respond_to?(:value) &&
28
+ object.respond_to?(:left_right_wrapper) &&
29
+ object.value == value &&
22
30
  object.left_right_wrapper == left_right_wrapper
23
31
  end
24
32
 
@@ -38,7 +46,7 @@ module Plurimath
38
46
  style = Utility.ox_element("mstyle", attributes: style_attrs)
39
47
  Utility.update_nodes(style, mathml_content)
40
48
  Utility.update_nodes(math, [style])
41
- Ox.dump(math, indent: 2).gsub("&amp;", "&")
49
+ Plurimath.xml_engine.dump(math, indent: 2).gsub("&amp;", "&")
42
50
  rescue
43
51
  parse_error!(:mathml)
44
52
  end
@@ -100,7 +108,7 @@ module Plurimath
100
108
  math_element = Utility.ox_element("oMath", namespace: "m")
101
109
  content = omml_content(boolean_display_style(display_style))
102
110
  para_element << Utility.update_nodes(math_element, content)
103
- Ox.dump(para_element, indent: 2).gsub("&amp;", "&").lstrip
111
+ Plurimath.xml_engine.dump(para_element, indent: 2).gsub("&amp;", "&").lstrip
104
112
  rescue
105
113
  parse_error!(:omml)
106
114
  end
@@ -110,20 +118,54 @@ module Plurimath
110
118
  end
111
119
 
112
120
  def to_omml_without_math_tag(display_style)
113
- return nary_tag(display_style) if nary_tag_able?(display_style)
114
-
115
121
  omml_content(display_style)
116
122
  end
117
123
 
118
- def nary_tag(display_style)
119
- nary_element = Utility.ox_element("nary", namespace: "m")
120
- e_tag = Utility.ox_element("e", namespace: "m")
121
- Utility.update_nodes(e_tag, value.last.insert_t_tag(display_style))
122
- Utility.update_nodes(
123
- nary_element,
124
- (value.first.omml_nary_tag(display_style) << e_tag),
125
- )
126
- [nary_element]
124
+ def to_display(type = nil)
125
+ return type_error! unless MATH_ZONE_TYPES.include?(type.downcase.to_sym)
126
+
127
+ math_zone = case type
128
+ when :asciimath
129
+ " |_ \"#{to_asciimath}\"\n#{to_asciimath_math_zone(" ").join}"
130
+ when :latex
131
+ " |_ \"#{to_latex}\"\n#{to_latex_math_zone(" ").join}"
132
+ when :mathml
133
+ " |_ \"#{to_mathml.gsub(/\n\s*/, "")}\"\n#{to_mathml_math_zone(" ").join}"
134
+ when :omml
135
+ " |_ \"#{to_omml.gsub(/\n\s*/, "")}\"\n#{to_omml_math_zone(" ", display_style: displaystyle).join}"
136
+ end
137
+ <<~MATHZONE.sub(/\n$/, "")
138
+ |_ Math zone
139
+ #{math_zone}
140
+ MATHZONE
141
+ end
142
+
143
+ def to_asciimath_math_zone(spacing = "", last = false, indent = true)
144
+ filtered_values(value).map.with_index(1) do |object, index|
145
+ last = index == @values.length
146
+ object.to_asciimath_math_zone(new_space(spacing, indent), last, indent)
147
+ end
148
+ end
149
+
150
+ def to_latex_math_zone(spacing = "", last = false, indent = true)
151
+ filtered_values(value).map.with_index(1) do |object, index|
152
+ last = index == @values.length
153
+ object.to_latex_math_zone(new_space(spacing, indent), last, indent)
154
+ end
155
+ end
156
+
157
+ def to_mathml_math_zone(spacing = "", last = false, indent = true)
158
+ filtered_values(value).map.with_index(1) do |object, index|
159
+ last = index == @values.length
160
+ object.to_mathml_math_zone(new_space(spacing, indent), last, indent)
161
+ end
162
+ end
163
+
164
+ def to_omml_math_zone(spacing = "", last = false, indent = true, display_style:)
165
+ filtered_values(value).map.with_index(1) do |object, index|
166
+ last = index == @values.length
167
+ object.to_omml_math_zone(new_space(spacing, indent), last, indent, display_style: display_style)
168
+ end
127
169
  end
128
170
 
129
171
  def extract_class_from_text
@@ -136,16 +178,6 @@ module Plurimath
136
178
  value.first.nary_attr_value
137
179
  end
138
180
 
139
- def nary_tag_able?(display_style)
140
- value.length == 2 &&
141
- ["underover", "powerbase"].include?(value&.first&.class_name) &&
142
- !value.first.parameter_one.is_a?(Function::FontStyle) &&
143
- (
144
- value&.first&.parameter_one&.to_omml_without_math_tag(display_style)&.length == 1 ||
145
- value&.first&.parameter_one.to_omml_without_math_tag(display_style).match?(/^&#x\w*\d*;$/)
146
- )
147
- end
148
-
149
181
  def validate_function_formula
150
182
  (value.none?(Function::Left) || value.none?(Function::Right))
151
183
  end
@@ -156,6 +188,18 @@ module Plurimath
156
188
  YAML.load(display_style.to_s)
157
189
  end
158
190
 
191
+ def new_space(spacing, indent)
192
+ if value.any? { |val| val.class_name == "left" } && value.any? { |val| val.class_name == "right" }
193
+ return spacing
194
+ end
195
+
196
+ (indent && wrapable?(spacing)) ? spacing + "|_ " : spacing
197
+ end
198
+
199
+ def wrapable?(spacing)
200
+ left_right_wrapper && !spacing.end_with?("|_ ")
201
+ end
202
+
159
203
  def parse_error!(type)
160
204
  Math.parse_error!(input_string, type)
161
205
  end
@@ -6,6 +6,12 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Base < BinaryFunction
9
+ FUNCTION = {
10
+ name: "subscript",
11
+ first_value: "base",
12
+ second_value: "script",
13
+ }.freeze
14
+
9
15
  def to_asciimath
10
16
  first_value = parameter_one.to_asciimath if parameter_one
11
17
  second_value = "_#{wrapped(parameter_two)}" if parameter_two
@@ -16,8 +22,8 @@ module Plurimath
16
22
  tag_name = (Utility::MUNDER_CLASSES.include?(parameter_one&.class_name) ? "under" : "sub")
17
23
  sub_tag = Utility.ox_element("m#{tag_name}")
18
24
  mathml_value = []
19
- mathml_value << parameter_one&.to_mathml_without_math_tag
20
- mathml_value << parameter_two&.to_mathml_without_math_tag if parameter_two
25
+ mathml_value << validate_mathml_fields(parameter_one)
26
+ mathml_value << validate_mathml_fields(parameter_two)
21
27
  Utility.update_nodes(sub_tag, mathml_value)
22
28
  end
23
29
 
@@ -64,6 +64,42 @@ module Plurimath
64
64
  !(parameter_one.nil? && parameter_two.nil?)
65
65
  end
66
66
 
67
+ def to_asciimath_math_zone(spacing, last = false, _)
68
+ parameters = self.class::FUNCTION
69
+ new_spacing = gsub_spacing(spacing, last)
70
+ new_arr = ["#{spacing}\"#{to_asciimath}\" #{parameters[:name]}\n"]
71
+ ascii_fields_to_print(parameter_one, { spacing: new_spacing, field_name: parameters[:first_value], additional_space: "| |_ " , array: new_arr })
72
+ ascii_fields_to_print(parameter_two, { spacing: new_spacing, field_name: parameters[:second_value], additional_space: " |_ " , array: new_arr })
73
+ new_arr
74
+ end
75
+
76
+ def to_latex_math_zone(spacing, last = false, _)
77
+ parameters = self.class::FUNCTION
78
+ new_spacing = gsub_spacing(spacing, last)
79
+ new_arr = ["#{spacing}\"#{to_latex}\" #{parameters[:name]}\n"]
80
+ latex_fields_to_print(parameter_one, { spacing: new_spacing, field_name: parameters[:first_value], additional_space: "| |_ " , array: new_arr })
81
+ latex_fields_to_print(parameter_two, { spacing: new_spacing, field_name: parameters[:second_value], additional_space: " |_ " , array: new_arr })
82
+ new_arr
83
+ end
84
+
85
+ def to_mathml_math_zone(spacing, last = false, _)
86
+ parameters = self.class::FUNCTION
87
+ new_spacing = gsub_spacing(spacing, last)
88
+ new_arr = ["#{spacing}\"#{dump_mathml(self)}\" #{parameters[:name]}\n"]
89
+ mathml_fields_to_print(parameter_one, { spacing: new_spacing, field_name: parameters[:first_value], additional_space: "| |_ ", array: new_arr })
90
+ mathml_fields_to_print(parameter_two, { spacing: new_spacing, field_name: parameters[:second_value], additional_space: " |_ ", array: new_arr })
91
+ new_arr
92
+ end
93
+
94
+ def to_omml_math_zone(spacing, last = false, _, display_style:)
95
+ parameters = self.class::FUNCTION
96
+ new_spacing = gsub_spacing(spacing, last)
97
+ new_arr = ["#{spacing}\"#{dump_omml(self, display_style)}\" #{parameters[:name]}\n"]
98
+ omml_fields_to_print(parameter_one, { spacing: new_spacing, field_name: parameters[:first_value], additional_space: "| |_ ", array: new_arr, display_style: display_style })
99
+ omml_fields_to_print(parameter_two, { spacing: new_spacing, field_name: parameters[:second_value], additional_space: " |_ ", array: new_arr, display_style: display_style })
100
+ new_arr
101
+ end
102
+
67
103
  protected
68
104
 
69
105
  def latex_wrapped(field)
@@ -80,10 +116,6 @@ module Plurimath
80
116
  "(#{field.to_asciimath})"
81
117
  end
82
118
 
83
- def invert_unicode_symbols
84
- Mathml::Constants::UNICODE_SYMBOLS.invert[class_name] || class_name
85
- end
86
-
87
119
  def empty_tag(wrapper_tag)
88
120
  r_tag = Utility.ox_element("r", namespace: "m")
89
121
  r_tag << (Utility.ox_element("t", namespace: "m") << "&#8203;")
@@ -6,6 +6,12 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Color < BinaryFunction
9
+ FUNCTION = {
10
+ name: "color",
11
+ first_value: "mathcolor",
12
+ second_value: "text",
13
+ }.freeze
14
+
9
15
  def to_asciimath
10
16
  first_value = "(#{parameter_one&.to_asciimath&.gsub(/\s/, '')})"
11
17
  second_value = "(#{parameter_two&.to_asciimath})"
@@ -31,6 +37,14 @@ module Plurimath
31
37
  def to_omml_without_math_tag(display_style)
32
38
  Array(parameter_two.insert_t_tag(display_style))
33
39
  end
40
+
41
+ def to_omml_math_zone(spacing, last = false, _, display_style:)
42
+ parameters = self.class::FUNCTION
43
+ new_spacing = gsub_spacing(spacing, last)
44
+ new_arr = ["#{spacing}\"#{dump_omml(self, display_style)}\" #{parameters[:name]}\n"]
45
+ omml_fields_to_print(parameter_two, { spacing: new_spacing, field_name: "text", additional_space: "| |_ ", array: new_arr, display_style: display_style })
46
+ new_arr
47
+ end
34
48
  end
35
49
  end
36
50
  end
@@ -56,6 +56,33 @@ module Plurimath
56
56
  [d]
57
57
  end
58
58
 
59
+ def to_asciimath_math_zone(spacing, last = false, indent = true)
60
+ filtered_values(parameter_two).map.with_index(1) do |object, index|
61
+ last = index == @values.length
62
+ object.to_asciimath_math_zone(spacing, last, indent)
63
+ end
64
+ end
65
+
66
+ def to_latex_math_zone(spacing, last = false, indent = true)
67
+ filtered_values(parameter_two).map.with_index(1) do |object, index|
68
+ last = index == @values.length
69
+ object.to_latex_math_zone(spacing, last, indent)
70
+ end
71
+ end
72
+
73
+ def to_mathml_math_zone(spacing, last = false, indent = true)
74
+ filtered_values(parameter_two).map.with_index(1) do |object, index|
75
+ last = index == @values.length
76
+ object.to_mathml_math_zone(spacing, last, indent)
77
+ end
78
+ end
79
+
80
+ def to_omml_math_zone(spacing, last = false, indent = true, display_style:)
81
+ filtered_values(parameter_two).map.with_index(1) do |object, index|
82
+ object.to_omml_math_zone(spacing, last, !indent, display_style: display_style)
83
+ end
84
+ end
85
+
59
86
  protected
60
87
 
61
88
  def first_value(dpr)
@@ -7,7 +7,7 @@ module Plurimath
7
7
  module Function
8
8
  class Floor < UnaryFunction
9
9
  def to_latex
10
- "\\lfloor #{parameter_one.to_latex} \\rfloor"
10
+ "{\\lfloor #{parameter_one.to_latex} \\rfloor}"
11
11
  end
12
12
 
13
13
  def to_mathml_without_math_tag
@@ -59,6 +59,51 @@ module Plurimath
59
59
  )
60
60
  [r_tag]
61
61
  end
62
+
63
+ def to_asciimath_math_zone(spacing, last = false, _)
64
+ new_spacing = gsub_spacing(spacing, last)
65
+ new_arr = [
66
+ "#{spacing}\"#{to_asciimath}\" function apply\n",
67
+ "#{new_spacing}|_ \"#{parameter_two}\" font family\n",
68
+ ]
69
+ ascii_fields_to_print(parameter_one, { spacing: new_spacing, field_name: "argument", additional_space: "| |_ " , array: new_arr })
70
+ new_arr
71
+ end
72
+
73
+ def to_latex_math_zone(spacing, last = false, _)
74
+ new_spacing = gsub_spacing(spacing, last)
75
+ new_arr = [
76
+ "#{spacing}\"#{to_latex}\" function apply\n",
77
+ "#{new_spacing}|_ \"#{parameter_two}\" font family\n",
78
+ ]
79
+ latex_fields_to_print(parameter_one, { spacing: new_spacing, field_name: "argument", additional_space: "| |_ " , array: new_arr })
80
+ new_arr
81
+ end
82
+
83
+ def to_mathml_math_zone(spacing, last = false, _)
84
+ new_spacing = gsub_spacing(spacing, last)
85
+ new_arr = [
86
+ "#{spacing}\"#{dump_mathml(self)}\" function apply\n",
87
+ "#{new_spacing}|_ \"#{omml_and_mathml_font_family}\" font family\n",
88
+ ]
89
+ mathml_fields_to_print(parameter_one, { spacing: new_spacing, field_name: "argument", additional_space: "| |_ ", array: new_arr })
90
+ new_arr
91
+ end
92
+
93
+ def to_omml_math_zone(spacing, last = false, _, display_style:)
94
+ new_spacing = gsub_spacing(spacing, last)
95
+ new_arr = [
96
+ "#{spacing}\"#{dump_omml(self, display_style)}\" function apply\n",
97
+ "#{new_spacing}|_ \"#{omml_and_mathml_font_family}\" font family\n",
98
+ ]
99
+ omml_fields_to_print(parameter_one, { spacing: new_spacing, field_name: "argument", additional_space: "| |_ ", array: new_arr, display_style: display_style })
100
+ new_arr
101
+ end
102
+
103
+ def omml_and_mathml_font_family
104
+ fonts = Utility::FONT_STYLES.select { |_font, font_class| font_class == self.class }.keys.map(&:to_s)
105
+ Omml::Parser::SUPPORTED_FONTS.values.find { |value| fonts.include?(value) }
106
+ end
62
107
  end
63
108
  end
64
109
  end