plurimath 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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