plurimath 0.4.1 → 0.4.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ae20aeedcb99f6b913e591de0bf18624aae42c750df4ea706d90a6c47be4193
4
- data.tar.gz: d1e9513bd715e585b57fffc72f1c0a6e163b6ac7ea4d270fe2e8323301f89036
3
+ metadata.gz: 0ec251305cefca33f4a6d66180a797595d43ef370d55f7b67bdeac63b37e3111
4
+ data.tar.gz: 2c041edf5748e938813a20e0d397080d2f8cedcf96b19e9e39e98edae6b47ef8
5
5
  SHA512:
6
- metadata.gz: 6532186819c4523f46d6dc3503df5b88972f5c68cb54a3bd3e7ff66a1d8bd6d8b4346eac33a0ef2504bfcb4a1f813eb7130e9bb55b8196e3b2878b0733c7dad0
7
- data.tar.gz: c9cbda12a71c9e0e57c04a92737945eef6ff79a6cbc35c3e0bdc7b0eddc0443af0e8614bd5d803db64de7e036b385324fe5f0c91a5faa3c601886d63eade5325
6
+ metadata.gz: 37065161c1a09768bbec28f0d98e5438be18a5a0affa9e6024f7027ad002324c1e66e63c22f921f43fd32fa2bf1b723ace3f08b99464a8af3b7e6d265e092df6
7
+ data.tar.gz: 596e9cb2ce7f7d41ab8f93b4c0f330ffcdfec6adba518b49086dc4792c12f7eafed799ee087ea2ea82a3753389c179fab8883445c1b804a52fe779314941280c
@@ -2853,6 +2853,7 @@ module Plurimath
2853
2853
  mathbfit: :fonts,
2854
2854
  mathfrak: :fonts,
2855
2855
  overline: :unary,
2856
+ overset: :binary,
2856
2857
  ddagger: :symbols,
2857
2858
  trprime: :symbols,
2858
2859
  closure: :symbols,
@@ -95,11 +95,18 @@ module Plurimath
95
95
  end
96
96
 
97
97
  rule(:intermediate_exp) do
98
- (lparen.as(:left_paren) >> expression.maybe.as(:expression) >> rparen.as(:right_paren)).as(:intermediate_exp) |
98
+ (lparen.as(:left_paren) >> expression.maybe.as(:expression) >> (rparen | (str("\\") >> (match("\s") >> str(".")).maybe).as(:rparen)).maybe.as(:right_paren)).as(:intermediate_exp) |
99
99
  (str("{") >> expression.maybe.as(:expression) >> str("}")) |
100
100
  symbol_text_or_integer
101
101
  end
102
102
 
103
+ rule(:parsing_text_values) do
104
+ (str("{") >> parsing_text_values >> str("}")) >> parsing_text_values |
105
+ (str("{") >> parsing_text_values >> str("}")) |
106
+ (match("[^}]") >> parsing_text_values) |
107
+ match("[^}]").repeat
108
+ end
109
+
103
110
  rule(:power_base) do
104
111
  (subscript >> power >> intermediate_exp.as(:supscript)).as(:power_base) |
105
112
  (supscript >> base >> intermediate_exp.as(:subscript)).as(:power_base) |
@@ -130,7 +137,8 @@ module Plurimath
130
137
  (begining >> expression.as(:table_data) >> ending).as(:environment) |
131
138
  (slash >> environment >> intermediate_exp).as(:table_data) |
132
139
  power_base |
133
- intermediate_exp
140
+ intermediate_exp |
141
+ intermediate_exp.as(:intermediate_exp) >> rparen.as(:symbol)
134
142
  end
135
143
 
136
144
  rule(:left_right) do
@@ -204,7 +212,7 @@ module Plurimath
204
212
  when :binary
205
213
  (slashed_value(first_value, :binary) >> intermediate_exp.as(:first_value) >> intermediate_exp.as(:second_value)).as(:binary)
206
214
  when :text
207
- (slashed_value(first_value, :text) >> (str("{") >> match("[^}]").repeat.as(:first_value) >> str("}")))
215
+ (slashed_value(first_value, :text) >> (str("{") >> parsing_text_values.as(:first_value) >> str("}")))
208
216
  when :ternary
209
217
  (slashed_value(first_value, :ternary_functions) >> dynamic_power_base >> sequence.as(:third_value).maybe).as(:ternary_class) |
210
218
  slashed_value(first_value, :ternary)
@@ -45,13 +45,9 @@ module Plurimath
45
45
  end
46
46
 
47
47
  rule(symbols: simple(:sym)) do
48
- if sym.is_a?(Parslet::Slice)
49
- Math::Symbol.new(
50
- Constants::UNICODE_SYMBOLS[sym.to_sym] || sym,
51
- )
52
- else
53
- sym
54
- end
48
+ Math::Symbol.new(
49
+ Constants::UNICODE_SYMBOLS[sym.to_sym] || sym,
50
+ )
55
51
  end
56
52
 
57
53
  rule(lparen: simple(:lparen),
@@ -404,6 +400,16 @@ module Plurimath
404
400
  )
405
401
  end
406
402
 
403
+ rule(number: simple(:number),
404
+ subscript: simple(:subscript),
405
+ supscript: simple(:supscript)) do
406
+ Math::Function::PowerBase.new(
407
+ Math::Number.new(number),
408
+ subscript,
409
+ supscript,
410
+ )
411
+ end
412
+
407
413
  rule(symbols: simple(:sym),
408
414
  subscript: simple(:subscript)) do
409
415
  Math::Function::Base.new(
@@ -469,6 +475,47 @@ module Plurimath
469
475
  Math::Function::Text.new(first_value)
470
476
  end
471
477
 
478
+ rule(text: simple(:text),
479
+ first_value: sequence(:first_value)) do
480
+ Math::Function::Text.new(first_value.join)
481
+ end
482
+
483
+ rule(text: simple(:text),
484
+ first_value: simple(:first_value),
485
+ supscript: simple(:supscript),) do
486
+ Math::Function::Power.new(
487
+ Math::Function::Text.new(first_value),
488
+ supscript,
489
+ )
490
+ end
491
+
492
+ rule(text: simple(:text),
493
+ first_value: sequence(:first_value),
494
+ supscript: simple(:supscript),) do
495
+ Math::Function::Power.new(
496
+ Math::Function::Text.new(first_value.join),
497
+ supscript,
498
+ )
499
+ end
500
+
501
+ rule(text: simple(:text),
502
+ first_value: sequence(:first_value),
503
+ subscript: simple(:subscript),) do
504
+ Math::Function::Base.new(
505
+ Math::Function::Text.new(first_value.join),
506
+ subscript,
507
+ )
508
+ end
509
+
510
+ rule(text: simple(:text),
511
+ first_value: simple(:first_value),
512
+ subscript: simple(:subscript),) do
513
+ Math::Function::Base.new(
514
+ Math::Function::Text.new(first_value),
515
+ subscript,
516
+ )
517
+ end
518
+
472
519
  rule(unary: simple(:unary),
473
520
  first_value: simple(:first_value)) do
474
521
  Utility.get_class(
@@ -521,6 +568,28 @@ module Plurimath
521
568
  )
522
569
  end
523
570
 
571
+ rule(fonts: simple(:fonts),
572
+ intermediate_exp: simple(:int_exp),
573
+ subscript: simple(:subscript),
574
+ supscript: simple(:supscript)) do
575
+ font_style = if Utility::FONT_STYLES[fonts.to_sym].nil?
576
+ Math::Function::FontStyle.new(
577
+ int_exp,
578
+ fonts.to_s,
579
+ )
580
+ else
581
+ Utility::FONT_STYLES[fonts.to_sym].new(
582
+ int_exp,
583
+ fonts.to_s,
584
+ )
585
+ end
586
+ Math::Function::PowerBase.new(
587
+ font_style,
588
+ subscript,
589
+ supscript,
590
+ )
591
+ end
592
+
524
593
  rule(root: simple(:root),
525
594
  first_value: simple(:first_value),
526
595
  second_value: simple(:second_value)) do
@@ -626,6 +695,23 @@ module Plurimath
626
695
  )
627
696
  end
628
697
 
698
+ rule(binary: simple(:binary),
699
+ subscript: simple(:subscript),
700
+ supscript: simple(:supscript)) do
701
+ if binary.is_a?(Parslet::Slice)
702
+ Utility.get_class(binary).new(
703
+ subscript,
704
+ supscript,
705
+ )
706
+ else
707
+ Math::Function::PowerBase.new(
708
+ binary,
709
+ subscript,
710
+ subscript,
711
+ )
712
+ end
713
+ end
714
+
629
715
  rule(binary: simple(:binary),
630
716
  subscript: simple(:subscript)) do
631
717
  if binary.is_a?(Parslet::Slice)
@@ -1,11 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Bar < BinaryFunction
8
+ class Bar < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_asciimath
10
17
  first_value = "(#{parameter_one.to_asciimath})" if parameter_one
11
18
  "bar#{first_value}"
@@ -21,7 +28,7 @@ module Plurimath
21
28
  return mo_tag unless parameter_one
22
29
 
23
30
  mover_tag = Utility.ox_element("mover")
24
- mover_tag.attributes.merge!(parameter_two) if parameter_two && !parameter_two.empty?
31
+ mover_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
25
32
  Utility.update_nodes(
26
33
  mover_tag,
27
34
  [
@@ -32,13 +39,13 @@ module Plurimath
32
39
  end
33
40
 
34
41
  def to_omml_without_math_tag(display_style)
35
- return r_element("&#xaf;", rpr_tag: false) unless all_values_exist?
42
+ return r_element("&#xaf;", rpr_tag: false) unless parameter_one
36
43
 
37
- parameter_two && parameter_two[:accent] ? acc_tag(display_style) : bar_tag(display_style)
44
+ attributes && attributes[:accent] ? acc_tag(display_style) : bar_tag(display_style)
38
45
  end
39
46
 
40
47
  def swap_class
41
- Ul.new(parameter_one, parameter_two)
48
+ Ul.new(parameter_one, attributes)
42
49
  end
43
50
 
44
51
  protected
@@ -56,6 +56,10 @@ module Plurimath
56
56
  [r_tag]
57
57
  end
58
58
 
59
+ def any_value_exist?
60
+ !(parameter_one.nil? || parameter_two.nil?)
61
+ end
62
+
59
63
  def all_values_exist?
60
64
  !(parameter_one.nil? && parameter_two.nil?)
61
65
  end
@@ -6,6 +6,13 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Ddot < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_mathml_without_math_tag
10
17
  second_value = Utility.ox_element("mo") << ".."
11
18
  Utility.update_nodes(
@@ -1,19 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Dot < BinaryFunction
8
+ class Dot < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_mathml_without_math_tag
10
17
  dot_tag = (Utility.ox_element("mo") << ".")
11
- return dot_tag unless all_values_exist?
18
+ return dot_tag unless parameter_one
12
19
 
13
20
  first_value = parameter_one&.to_mathml_without_math_tag
14
21
  dot_tag = (Utility.ox_element("mo") << ".")
15
22
  over_tag = Utility.ox_element("mover")
16
- over_tag.attributes.merge!({ accent: parameter_two[:accent] }) if parameter_two
23
+ over_tag.attributes.merge!({ accent: attributes[:accent] }) if attributes && attributes[:accent]
17
24
  Utility.update_nodes(
18
25
  over_tag,
19
26
  [
@@ -24,9 +31,9 @@ module Plurimath
24
31
  end
25
32
 
26
33
  def to_omml_without_math_tag(display_style)
27
- return r_element(".", rpr_tag: false) unless all_values_exist?
34
+ return r_element(".", rpr_tag: false) unless parameter_one
28
35
 
29
- if parameter_two && parameter_two[:accent]
36
+ if attributes && attributes[:accent]
30
37
  acc_tag(display_style)
31
38
  else
32
39
  symbol = Symbol.new(".")
@@ -30,11 +30,9 @@ module Plurimath
30
30
  end
31
31
 
32
32
  def to_latex
33
- open_paren = parameter_one ? parameter_one.value : "("
34
33
  fenced_value = parameter_two&.map(&:to_latex)&.join(" ")
35
- close_paren = parameter_three ? parameter_three.value : ")"
36
- first_value = latex_paren(open_paren)
37
- second_value = latex_paren(close_paren)
34
+ first_value = latex_paren(parameter_one&.value)
35
+ second_value = latex_paren(parameter_three&.value)
38
36
  "#{first_value} #{fenced_value} #{second_value}"
39
37
  end
40
38
 
@@ -88,8 +86,8 @@ module Plurimath
88
86
  return "" if paren.nil? || paren.empty?
89
87
 
90
88
  paren = %w[{ }].include?(paren) ? "\\#{paren}" : paren
91
- paren = "\\#{Latex::Constants::UNICODE_SYMBOLS.invert[paren]}" if paren.to_s.match?(/&#x.{0,4};/)
92
- paren.to_s
89
+ paren = "\\#{Latex::Constants::UNICODE_SYMBOLS.invert[paren]}" if paren&.to_s&.match?(/&#x.{0,4};/)
90
+ paren&.to_s
93
91
  end
94
92
 
95
93
  def mathml_paren(field)
@@ -21,6 +21,10 @@ module Plurimath
21
21
  )
22
22
  end
23
23
 
24
+ def to_omml_without_math_tag(display_style)
25
+ font_styles(display_style)
26
+ end
27
+
24
28
  def to_html
25
29
  parameter_one&.to_html
26
30
  end
@@ -1,11 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Hat < BinaryFunction
8
+ class Hat < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_asciimath
10
17
  first_value = "(#{parameter_one.to_asciimath})" if parameter_one
11
18
  "hat#{first_value}"
@@ -21,7 +28,7 @@ module Plurimath
21
28
  return mo_tag unless parameter_one
22
29
 
23
30
  mover_tag = Utility.ox_element("mover")
24
- mover_tag.attributes.merge!(parameter_two) if parameter_two && !parameter_two.empty?
31
+ mover_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
25
32
  Utility.update_nodes(
26
33
  mover_tag,
27
34
  [
@@ -36,9 +43,9 @@ module Plurimath
36
43
  end
37
44
 
38
45
  def to_omml_without_math_tag(display_style)
39
- return r_element("^", rpr_tag: false) unless all_values_exist?
46
+ return r_element("^", rpr_tag: false) unless parameter_one
40
47
 
41
- if parameter_two && parameter_two[:accent]
48
+ if attributes && attributes[:accent]
42
49
  accent_tag(display_style)
43
50
  else
44
51
  symbol = Symbol.new("&#x302;")
@@ -1,11 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Obrace < BinaryFunction
8
+ class Obrace < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_asciimath
10
17
  first_value = "(#{parameter_one.to_asciimath})" if parameter_one
11
18
  "obrace#{first_value}"
@@ -21,7 +28,7 @@ module Plurimath
21
28
  return mo_tag unless parameter_one
22
29
 
23
30
  over_tag = Utility.ox_element("mover")
24
- over_tag.attributes.merge!(parameter_two) if parameter_two && !parameter_two.empty?
31
+ over_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
25
32
  Utility.update_nodes(
26
33
  over_tag,
27
34
  [
@@ -36,9 +43,9 @@ module Plurimath
36
43
  end
37
44
 
38
45
  def to_omml_without_math_tag(display_style)
39
- return r_element("⏞", rpr_tag: false) unless all_values_exist?
46
+ return r_element("⏞", rpr_tag: false) unless parameter_one
40
47
 
41
- if parameter_two && parameter_two[:accent]
48
+ if attributes && attributes[:accent]
42
49
  acc_tag(display_style)
43
50
  else
44
51
  symbol = Symbol.new("⏞")
@@ -55,6 +55,10 @@ module Plurimath
55
55
  !(parameter_one.nil? || parameter_two.nil? || parameter_three.nil?)
56
56
  end
57
57
 
58
+ def all_values_exist?
59
+ !(parameter_one.nil? && parameter_two.nil? && parameter_three.nil?)
60
+ end
61
+
58
62
  protected
59
63
 
60
64
  def latex_wrapped(field)
@@ -108,8 +112,8 @@ module Plurimath
108
112
  def narypr(function_symbol, function_type: "undOvr")
109
113
  chr_arg = { "m:val": function_symbol }
110
114
  limloc_arg = { "m:val": function_type }
111
- subhide_arg = { "m:val": "0" }
112
- suphide_arg = { "m:val": "0" }
115
+ subhide_arg = { "m:val": parameter_one ? "0" : "1" }
116
+ suphide_arg = { "m:val": parameter_two ? "0" : "1" }
113
117
  chr_tag = Utility.ox_element("chr", attributes: chr_arg, namespace: "m")
114
118
  limloc_tag = Utility.ox_element("limLoc", attributes: limloc_arg, namespace: "m")
115
119
  subhide_tag = Utility.ox_element("subHide", attributes: subhide_arg, namespace: "m")
@@ -126,10 +130,6 @@ module Plurimath
126
130
  )
127
131
  end
128
132
 
129
- def all_values_exist?
130
- !(parameter_one.nil? && parameter_two.nil? && parameter_three.nil?)
131
- end
132
-
133
133
  def validate_mathml_tag(parameter)
134
134
  return Array(Utility.ox_element("mrow")) unless parameter
135
135
 
@@ -68,7 +68,7 @@ module Plurimath
68
68
  if lang == "omml"
69
69
  entities = HTMLEntities.new
70
70
  entities.encode(
71
- entities.decode(parameter_one.gsub(/ /, "&nbsp;")),
71
+ entities.decode(parameter_one&.gsub(/ /, "&#xa0;")),
72
72
  :named,
73
73
  )
74
74
  else
@@ -1,23 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Tilde < BinaryFunction
8
+ class Tilde < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_mathml_without_math_tag
10
17
  mover = Utility.ox_element("mover")
11
- mover.attributes.merge!({ accent: parameter_two[:accent]}) if parameter_two
18
+ mover.attributes.merge!({ accent: attributes[:accent]}) if attributes && attributes[:accent]
12
19
  first_value = (Utility.ox_element("mo") << "~")
13
20
  second_value = parameter_one.to_mathml_without_math_tag if parameter_one
14
21
  Utility.update_nodes(mover, [second_value, first_value])
15
22
  end
16
23
 
17
24
  def to_omml_without_math_tag(display_style)
18
- return r_element("~", rpr_tag: false) unless all_values_exist?
25
+ return r_element("~", rpr_tag: false) unless parameter_one
19
26
 
20
- if parameter_two && parameter_two[:accent]
27
+ if attributes && attributes[:accent]
21
28
  acc_tag(display_style)
22
29
  else
23
30
  symbol = Symbol.new("~")
@@ -1,11 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Ubrace < BinaryFunction
8
+ class Ubrace < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_asciimath
10
17
  first_value = "(#{parameter_one.to_asciimath})" if parameter_one
11
18
  "ubrace#{first_value}"
@@ -21,7 +28,7 @@ module Plurimath
21
28
  return mo_tag unless parameter_one
22
29
 
23
30
  over_tag = Utility.ox_element("munder")
24
- over_tag.attributes.merge!(parameter_two) if parameter_two && !parameter_two.empty?
31
+ over_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
25
32
  Utility.update_nodes(
26
33
  over_tag,
27
34
  [
@@ -44,7 +51,7 @@ module Plurimath
44
51
  end
45
52
 
46
53
  def to_omml_without_math_tag(display_style)
47
- return r_element("⏟", rpr_tag: false) unless all_values_exist?
54
+ return r_element("⏟", rpr_tag: false) unless parameter_one
48
55
 
49
56
  symbol = Symbol.new("⏟")
50
57
  Underset.new(parameter_one, symbol).to_omml_without_math_tag(true)
@@ -1,11 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Ul < BinaryFunction
8
+ class Ul < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_asciimath
10
17
  first_value = "(#{parameter_one.to_asciimath})" if parameter_one
11
18
  "underline#{first_value}"
@@ -21,7 +28,7 @@ module Plurimath
21
28
  return mo_tag unless parameter_one
22
29
 
23
30
  munder_tag = Utility.ox_element("munder")
24
- munder_tag.attributes.merge!(parameter_two) if parameter_two && !parameter_two.empty?
31
+ munder_tag.attributes.merge!(attributes) if attributes && !attributes.empty?
25
32
  Utility.update_nodes(
26
33
  munder_tag,
27
34
  [
@@ -32,9 +39,9 @@ module Plurimath
32
39
  end
33
40
 
34
41
  def to_omml_without_math_tag(display_style)
35
- return r_element("&#x332;", rpr_tag: false) unless all_values_exist?
42
+ return r_element("&#x332;", rpr_tag: false) unless parameter_one
36
43
 
37
- if parameter_two && parameter_two[:accentunder]
44
+ if attributes && attributes[:accentunder]
38
45
  groupchr_tag(display_style)
39
46
  else
40
47
  symbol = Symbol.new("&#x332;")
@@ -47,7 +54,7 @@ module Plurimath
47
54
  end
48
55
 
49
56
  def swap_class
50
- Bar.new(parameter_one, parameter_two)
57
+ Bar.new(parameter_one, attributes)
51
58
  end
52
59
 
53
60
  protected
@@ -39,8 +39,7 @@ module Plurimath
39
39
  end
40
40
 
41
41
  def to_latex
42
- first_value = "{#{latex_value}}" if parameter_one
43
- "\\#{class_name}#{first_value}"
42
+ "\\#{class_name}{#{latex_value}}"
44
43
  end
45
44
 
46
45
  def to_html
@@ -49,7 +48,7 @@ module Plurimath
49
48
  elsif parameter_one
50
49
  "<i>#{parameter_one.to_html}</i>"
51
50
  end
52
- "<i>#{class_name}</i>#{first_value}"
51
+ "<i>#{invert_unicode_symbols}</i>#{first_value}"
53
52
  end
54
53
 
55
54
  def to_omml_without_math_tag(display_style)
@@ -78,6 +77,10 @@ module Plurimath
78
77
 
79
78
  protected
80
79
 
80
+ def invert_unicode_symbols
81
+ Mathml::Constants::UNICODE_SYMBOLS.invert[class_name] || class_name
82
+ end
83
+
81
84
  def asciimath_value
82
85
  return "" unless parameter_one
83
86
 
@@ -1,15 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "binary_function"
3
+ require_relative "unary_function"
4
4
 
5
5
  module Plurimath
6
6
  module Math
7
7
  module Function
8
- class Vec < BinaryFunction
8
+ class Vec < UnaryFunction
9
+ attr_accessor :attributes
10
+
11
+ def initialize(parameter_one = nil, attributes = {})
12
+ super(parameter_one)
13
+ @attributes = attributes
14
+ end
15
+
9
16
  def to_mathml_without_math_tag
10
17
  mover = Utility.ox_element("mover")
11
18
  first_value = parameter_one&.to_mathml_without_math_tag
12
- mover.attributes.merge!({ accent: parameter_two[:accent] }) if parameter_two
19
+ mover.attributes.merge!({ accent: attributes[:accent] }) if attributes && attributes[:accent]
13
20
  Utility.update_nodes(
14
21
  mover,
15
22
  [
@@ -20,9 +27,9 @@ module Plurimath
20
27
  end
21
28
 
22
29
  def to_omml_without_math_tag(display_style)
23
- return r_element("&#x2192;", rpr_tag: false) unless all_values_exist?
30
+ return r_element("&#x2192;", rpr_tag: false) unless parameter_one
24
31
 
25
- if parameter_two && parameter_two[:accent]
32
+ if attributes && attributes[:accent]
26
33
  acc_tag(display_style)
27
34
  else
28
35
  symbol = Symbol.new("→")
@@ -7,7 +7,7 @@ module Plurimath
7
7
  class Parser
8
8
  attr_accessor :text
9
9
 
10
- SUPPORTED_ATTRIBUTES = %w[
10
+ SUPPORTED_ATTRS = %w[
11
11
  columnlines
12
12
  mathvariant
13
13
  accentunder
@@ -24,11 +24,11 @@ module Plurimath
24
24
 
25
25
  def parse
26
26
  ox_nodes = Ox.load(text, strip_namespace: true)
27
- display_style = ox_nodes&.locate("*/mstyle/@displaystyle")&.first || true
27
+ display_style = ox_nodes&.locate("*/mstyle/@displaystyle")&.first
28
28
  nodes = parse_nodes(ox_nodes.nodes)
29
29
  Math::Formula.new(
30
30
  Transform.new.apply(nodes).flatten.compact,
31
- display_style: display_style,
31
+ display_style: (display_style || true),
32
32
  )
33
33
  end
34
34
 
@@ -39,12 +39,7 @@ module Plurimath
39
39
  if node.is_a?(String)
40
40
  node
41
41
  elsif !node.attributes.empty?
42
- {
43
- node.name.to_sym => {
44
- attributes: validate_attributes(node.attributes),
45
- value: parse_nodes(node.nodes),
46
- },
47
- }
42
+ attrs_hash(node)
48
43
  else
49
44
  { node.name.to_sym => parse_nodes(node.nodes) }
50
45
  end
@@ -52,9 +47,18 @@ module Plurimath
52
47
  end
53
48
 
54
49
  def validate_attributes(attributes)
55
- attributes&.select! { |key, _| SUPPORTED_ATTRIBUTES.include?(key&.to_s) }
50
+ attributes&.select! { |key, _| SUPPORTED_ATTRS.include?(key&.to_s) }
56
51
  attributes&.transform_keys(&:to_sym) if attributes&.any?
57
52
  end
53
+
54
+ def attrs_hash(node)
55
+ {
56
+ node.name.to_sym => {
57
+ attributes: validate_attributes(node.attributes),
58
+ value: parse_nodes(node.nodes),
59
+ },
60
+ }
61
+ end
58
62
  end
59
63
  end
60
64
  end
@@ -136,16 +136,17 @@ module Plurimath
136
136
  end
137
137
 
138
138
  rule(msubsup: sequence(:function)) do
139
- base_class = function[0].is_a?(Math::Formula) ? function[0]&.value&.first : function[0]
140
- if base_class.is_a?(Math::Function::BinaryFunction)
141
- base_class.parameter_one = function[1]
142
- base_class.parameter_two = function[2]
143
- base_class
144
- elsif base_class.is_a?(Math::Function::TernaryFunction)
145
- base_class.parameter_one = function[1]
146
- base_class.parameter_two = function[2]
147
- base_class.parameter_three = function[3]
148
- base_class
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
149
150
  else
150
151
  Math::Function::PowerBase.new(
151
152
  function[0],
@@ -156,16 +157,17 @@ module Plurimath
156
157
  end
157
158
 
158
159
  rule(munderover: sequence(:function)) do
159
- base_class = function[0].is_a?(Math::Formula) ? function[0]&.value&.first : function[0]
160
- if base_class.is_a?(Math::Function::BinaryFunction)
161
- base_class.parameter_one = function[1]
162
- base_class.parameter_two = function[2]
163
- base_class
164
- elsif base_class.is_a?(Math::Function::TernaryFunction)
165
- base_class.parameter_one = function[1]
166
- base_class.parameter_two = function[2]
167
- base_class.parameter_three = function[3]
168
- 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
169
171
  else
170
172
  Math::Function::Underover.new(
171
173
  function[0],
@@ -177,6 +179,7 @@ module Plurimath
177
179
 
178
180
  rule(mrow: subtree(:mrow)) do
179
181
  flatten_mrow = Utility.populate_function_classes(mrow)
182
+ Utility.fenceable_classes(flatten_mrow)
180
183
  if flatten_mrow.length == 1
181
184
  flatten_mrow.first
182
185
  else
@@ -198,13 +201,9 @@ module Plurimath
198
201
  end
199
202
 
200
203
  rule(mover: subtree(:mover)) do
201
- Utility.binary_function_classes(mover, under: true)
202
204
  if mover&.length == 1
203
- if mover.first.class_name == "underline"
204
- mover.first.swap_class
205
- else
206
- mover.first
207
- end
205
+ base_object = mover.first
206
+ base_object.class_name == "underline" ? base_object.swap_class : base_object
208
207
  elsif Constants::CLASSES.any?(mover&.last&.class_name)
209
208
  mover.last.parameter_one = mover.shift if mover.length > 1
210
209
  mover.last
@@ -219,19 +218,16 @@ module Plurimath
219
218
  rule(munder: sequence(:munder)) do
220
219
  if munder.any?(String)
221
220
  munder.each_with_index do |object, ind|
222
- 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])
223
224
  end
224
225
  end
225
- Utility.binary_function_classes(munder, under: true)
226
- 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)
227
229
  munder.last.parameter_one = munder.shift if munder.length > 1
228
230
  munder.last
229
- elsif munder.length == 1
230
- if munder.first.class_name == "bar"
231
- munder.first.swap_class
232
- else
233
- munder.last
234
- end
235
231
  else
236
232
  Math::Function::Underset.new(
237
233
  munder[1],
@@ -336,10 +332,13 @@ module Plurimath
336
332
  rule(attributes: subtree(:attrs),
337
333
  value: sequence(:value)) do
338
334
  approved_attrs = if attrs.is_a?(Hash)
339
- attrs.keys.any? { |k| ["accentunder", "accent"].include?(k.to_s) } ? attrs : nil
340
- else
341
- attrs
342
- end
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
343
342
  Utility.join_attr_value(approved_attrs, value&.flatten&.compact)
344
343
  end
345
344
  end
@@ -137,8 +137,8 @@ module Plurimath
137
137
  chr_value = chr ? chr[:chr] : Math::Function::Hat.new
138
138
  index = acc_value.index { |d| d[:chr] }
139
139
  acc_value[index] = chr_value
140
- Utility.binary_function_classes(acc_value)
141
- acc_value.first.parameter_two = { accent: true }
140
+ Utility.unary_function_classes(acc_value)
141
+ acc_value.first.attributes = { accent: true }
142
142
  acc_value.first
143
143
  end
144
144
 
@@ -149,12 +149,22 @@ module Plurimath
149
149
  end
150
150
 
151
151
  rule(nary: subtree(:nary)) do
152
- Math::Formula.new(
153
- [
154
- Utility.nary_fonts(nary),
155
- Utility.filter_values(nary[3]),
156
- ],
157
- )
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
160
+ else
161
+ Math::Formula.new(
162
+ [
163
+ Utility.nary_fonts(nary),
164
+ Utility.filter_values(nary[3]),
165
+ ],
166
+ )
167
+ end
158
168
  end
159
169
 
160
170
  rule(groupChr: subtree(:groupchr)) do
@@ -175,7 +185,6 @@ module Plurimath
175
185
  end
176
186
 
177
187
  rule(sSubSup: subtree(:sSubSup)) do
178
- function_classes = [Math::Formula, Math::Function::FontStyle]
179
188
  subsup = sSubSup.flatten.compact
180
189
  subsup.each_with_index do |object, ind|
181
190
  subsup[ind] = Utility.mathml_unary_classes([object]) if object.is_a?(String)
@@ -235,7 +244,6 @@ module Plurimath
235
244
  end
236
245
 
237
246
  rule(limLow: subtree(:lim)) do
238
- flatten_lim = lim.flatten.compact
239
247
  second_value = Utility.filter_values(lim[2])
240
248
  unicode = Mathml::Constants::UNICODE_SYMBOLS.invert[second_value.class_name]
241
249
  second_value = unicode ? Math::Symbol.new(unicode.to_s) : second_value
@@ -72,7 +72,7 @@ module Plurimath
72
72
  max
73
73
  min
74
74
  ].freeze
75
- OMML_FONTS = {
75
+ OMML_FONTS = {
76
76
  "sans-serif-bi": Math::Function::FontStyle::SansSerifBoldItalic,
77
77
  "sans-serif-i": Math::Function::FontStyle::SansSerifItalic,
78
78
  "sans-serif-b": Math::Function::FontStyle::BoldSansSerif,
@@ -81,12 +81,24 @@ module Plurimath
81
81
  "fraktur-p": Math::Function::FontStyle::Fraktur,
82
82
  "fraktur-b": Math::Function::FontStyle::BoldFraktur,
83
83
  "script-b": Math::Function::FontStyle::BoldScript,
84
- "monospace": Math::Function::FontStyle::Monospace,
85
84
  "script-p": Math::Function::FontStyle::Script,
86
- "bi": Math::Function::FontStyle::BoldItalic,
87
- "p": Math::Function::FontStyle::Normal,
88
- "i": Math::Function::FontStyle::Italic,
89
- "b": Math::Function::FontStyle::Bold,
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
+ "[": "]",
90
102
  }.freeze
91
103
 
92
104
  class << self
@@ -344,7 +356,7 @@ module Plurimath
344
356
  value
345
357
  elsif attrs.is_a?(String) && ["solid", "none"].include?(attrs.split.first.downcase)
346
358
  table_separator(attrs.split, value)
347
- elsif attrs.is_a?(Hash) && (attrs.key?(:accent) || attrs.key?(:accentunder))
359
+ elsif attrs.is_a?(Hash) && (attrs.key?(:accent) || attrs.key?(:accentunder))
348
360
  attr_is_accent(attrs, value)
349
361
  elsif attrs.is_a?(Math::Core)
350
362
  attr_is_function(attrs, value)
@@ -352,9 +364,9 @@ module Plurimath
352
364
  end
353
365
 
354
366
  def attr_is_accent(attrs, value)
355
- value.last.parameter_one = value.shift if value.length > 1
356
- if value.last.is_a?(Math::Function::BinaryFunction)
357
- value.last.parameter_two = attrs.transform_values { |v| YAML.load(v) }
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) }
358
370
  end
359
371
  value
360
372
  end
@@ -470,9 +482,9 @@ module Plurimath
470
482
  (
471
483
  object.is_a?(Math::Function::TernaryFunction) && object.any_value_exist?
472
484
  ) &&
473
- mrow.length <= 2
485
+ (mrow.length <= 2)
474
486
  ) ||
475
- object.is_a?(Math::Function::UnaryFunction) && mrow.length == 1
487
+ (object.is_a?(Math::Function::UnaryFunction) && mrow.length == 1)
476
488
  )
477
489
  end
478
490
 
@@ -494,7 +506,7 @@ module Plurimath
494
506
  if object.is_a?(Math::Function::Mod)
495
507
  next unless mrow.length >= 1
496
508
 
497
- object.parameter_one = mrow.delete_at(ind - 1) unless ind == 0
509
+ object.parameter_one = mrow.delete_at(ind - 1) unless ind.zero?
498
510
  object.parameter_two = mrow.delete_at(ind)
499
511
  elsif Mathml::Constants::UNICODE_SYMBOLS.invert[object.class_name] && mrow.length > 1
500
512
  next if object.parameter_one || mrow.length > 2
@@ -510,9 +522,11 @@ module Plurimath
510
522
  if mrow.any?(String) || mrow.any?(unary_class)
511
523
  mrow.each_with_index do |object, ind|
512
524
  mrow[ind] = mathml_unary_classes([object]) if object.is_a?(String)
525
+ object = mrow[ind] if object.is_a?(String)
513
526
  next unless object.is_a?(unary_class)
514
527
  next if object.is_a?(Math::Function::Text)
515
528
  next if object.parameter_one || mrow[ind + 1].nil?
529
+ next unless ind.zero?
516
530
 
517
531
  object.parameter_one = mrow.delete_at(ind + 1)
518
532
  end
@@ -533,6 +547,32 @@ module Plurimath
533
547
  end
534
548
  end
535
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
575
+ end
536
576
  end
537
577
  end
538
578
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.4.1"
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.4.1
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-24 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