plurimath 0.7.2 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/Latex-Supported-Data.adoc +1 -0
  4. data/UnicodeMath-Supported-Data.adoc +1342 -0
  5. data/UnitsML-Supported-Data.adoc +444 -0
  6. data/lib/plurimath/asciimath/parse.rb +1 -1
  7. data/lib/plurimath/asciimath/transform.rb +2 -6
  8. data/lib/plurimath/latex/constants.rb +2 -0
  9. data/lib/plurimath/math/core.rb +38 -6
  10. data/lib/plurimath/math/formula.rb +60 -6
  11. data/lib/plurimath/math/function/abs.rb +4 -0
  12. data/lib/plurimath/math/function/arg.rb +22 -0
  13. data/lib/plurimath/math/function/bar.rb +4 -0
  14. data/lib/plurimath/math/function/base.rb +49 -0
  15. data/lib/plurimath/math/function/binary_function.rb +6 -0
  16. data/lib/plurimath/math/function/cancel.rb +5 -0
  17. data/lib/plurimath/math/function/ceil.rb +6 -0
  18. data/lib/plurimath/math/function/color.rb +20 -1
  19. data/lib/plurimath/math/function/ddot.rb +4 -0
  20. data/lib/plurimath/math/function/dot.rb +5 -0
  21. data/lib/plurimath/math/function/fenced.rb +98 -7
  22. data/lib/plurimath/math/function/floor.rb +6 -0
  23. data/lib/plurimath/math/function/font_style/monospace.rb +4 -0
  24. data/lib/plurimath/math/function/font_style.rb +31 -6
  25. data/lib/plurimath/math/function/frac.rb +69 -15
  26. data/lib/plurimath/math/function/hat.rb +4 -0
  27. data/lib/plurimath/math/function/inf.rb +30 -0
  28. data/lib/plurimath/math/function/int.rb +47 -1
  29. data/lib/plurimath/math/function/intent.rb +22 -0
  30. data/lib/plurimath/math/function/left.rb +4 -0
  31. data/lib/plurimath/math/function/lim.rb +6 -0
  32. data/lib/plurimath/math/function/limits.rb +28 -0
  33. data/lib/plurimath/math/function/linebreak.rb +5 -0
  34. data/lib/plurimath/math/function/log.rb +27 -20
  35. data/lib/plurimath/math/function/longdiv.rb +4 -0
  36. data/lib/plurimath/math/function/mbox.rb +4 -0
  37. data/lib/plurimath/math/function/menclose.rb +74 -5
  38. data/lib/plurimath/math/function/merror.rb +2 -0
  39. data/lib/plurimath/math/function/mglyph.rb +64 -0
  40. data/lib/plurimath/math/function/mlabeledtr.rb +29 -0
  41. data/lib/plurimath/math/function/mod.rb +4 -0
  42. data/lib/plurimath/math/function/mpadded.rb +84 -0
  43. data/lib/plurimath/math/function/ms.rb +33 -0
  44. data/lib/plurimath/math/function/msgroup.rb +4 -0
  45. data/lib/plurimath/math/function/msline.rb +2 -4
  46. data/lib/plurimath/math/function/multiscript.rb +70 -6
  47. data/lib/plurimath/math/function/nary.rb +69 -10
  48. data/lib/plurimath/math/function/none.rb +25 -0
  49. data/lib/plurimath/math/function/norm.rb +6 -0
  50. data/lib/plurimath/math/function/obrace.rb +4 -0
  51. data/lib/plurimath/math/function/oint.rb +25 -1
  52. data/lib/plurimath/math/function/over.rb +6 -0
  53. data/lib/plurimath/math/function/overset.rb +46 -1
  54. data/lib/plurimath/math/function/phantom.rb +18 -2
  55. data/lib/plurimath/math/function/power.rb +37 -0
  56. data/lib/plurimath/math/function/power_base.rb +45 -18
  57. data/lib/plurimath/math/function/prod.rb +46 -0
  58. data/lib/plurimath/math/function/right.rb +4 -0
  59. data/lib/plurimath/math/function/root.rb +9 -1
  60. data/lib/plurimath/math/function/rule.rb +4 -0
  61. data/lib/plurimath/math/function/sqrt.rb +7 -1
  62. data/lib/plurimath/math/function/stackrel.rb +6 -0
  63. data/lib/plurimath/math/function/substack.rb +4 -0
  64. data/lib/plurimath/math/function/sum.rb +45 -24
  65. data/lib/plurimath/math/function/table/bmatrix.rb +18 -5
  66. data/lib/plurimath/math/function/table/cases.rb +24 -0
  67. data/lib/plurimath/math/function/table/eqarray.rb +24 -0
  68. data/lib/plurimath/math/function/table/matrix.rb +23 -3
  69. data/lib/plurimath/math/function/table/pmatrix.rb +4 -0
  70. data/lib/plurimath/math/function/table/vmatrix.rb +10 -0
  71. data/lib/plurimath/math/function/table.rb +58 -7
  72. data/lib/plurimath/math/function/td.rb +9 -0
  73. data/lib/plurimath/math/function/ternary_function.rb +14 -1
  74. data/lib/plurimath/math/function/text.rb +6 -0
  75. data/lib/plurimath/math/function/tilde.rb +4 -0
  76. data/lib/plurimath/math/function/tr.rb +9 -0
  77. data/lib/plurimath/math/function/ubrace.rb +5 -0
  78. data/lib/plurimath/math/function/ul.rb +4 -0
  79. data/lib/plurimath/math/function/unary_function.rb +4 -0
  80. data/lib/plurimath/math/function/underover.rb +14 -0
  81. data/lib/plurimath/math/function/underset.rb +49 -1
  82. data/lib/plurimath/math/function/vec.rb +4 -0
  83. data/lib/plurimath/math/number.rb +33 -3
  84. data/lib/plurimath/math/symbol.rb +68 -3
  85. data/lib/plurimath/math.rb +3 -2
  86. data/lib/plurimath/mathml/constants.rb +16 -0
  87. data/lib/plurimath/mathml/parser.rb +42 -2
  88. data/lib/plurimath/mathml/transform.rb +80 -29
  89. data/lib/plurimath/omml/parser.rb +8 -0
  90. data/lib/plurimath/omml/transform.rb +29 -26
  91. data/lib/plurimath/unicode_math/constants.rb +1014 -0
  92. data/lib/plurimath/unicode_math/parse.rb +233 -0
  93. data/lib/plurimath/unicode_math/parser.rb +58 -0
  94. data/lib/plurimath/unicode_math/parsing_rules/absence_rules.rb +138 -0
  95. data/lib/plurimath/unicode_math/parsing_rules/common_rules.rb +114 -0
  96. data/lib/plurimath/unicode_math/parsing_rules/constants_rules.rb +102 -0
  97. data/lib/plurimath/unicode_math/parsing_rules/helper.rb +19 -0
  98. data/lib/plurimath/unicode_math/parsing_rules/masked.rb +62 -0
  99. data/lib/plurimath/unicode_math/parsing_rules/sub_sup.rb +254 -0
  100. data/lib/plurimath/unicode_math/transform.rb +3831 -0
  101. data/lib/plurimath/{unicode.rb → unicode_math.rb} +2 -2
  102. data/lib/plurimath/unitsml.rb +14 -1
  103. data/lib/plurimath/utility.rb +346 -11
  104. data/lib/plurimath/version.rb +1 -1
  105. data/lib/plurimath/xml_engine/oga.rb +5 -0
  106. data/lib/plurimath/xml_engine/ox.rb +5 -0
  107. metadata +25 -3
@@ -53,6 +53,10 @@ module Plurimath
53
53
  obj.update(Utility.filter_values(obj.value)) if obj.value_exist?
54
54
  end
55
55
 
56
+ def to_unicodemath
57
+ "#{unicodemath_parens(parameter_one)}̅"
58
+ end
59
+
56
60
  protected
57
61
 
58
62
  def acc_tag(display_style)
@@ -6,12 +6,25 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Base < BinaryFunction
9
+ attr_accessor :options
9
10
  FUNCTION = {
10
11
  name: "subscript",
11
12
  first_value: "base",
12
13
  second_value: "script",
13
14
  }.freeze
14
15
 
16
+ def initialize(parameter_one = nil,
17
+ parameter_two = nil,
18
+ options = {})
19
+ super(parameter_one, parameter_two)
20
+ @options = options unless options.empty?
21
+ end
22
+
23
+ def ==(object)
24
+ super(object) &&
25
+ object.options == options
26
+ end
27
+
15
28
  def to_asciimath
16
29
  first_value = parameter_one.to_asciimath if parameter_one
17
30
  second_value = "_#{wrapped(parameter_two)}" if parameter_two
@@ -55,6 +68,20 @@ module Plurimath
55
68
  [ssub_element]
56
69
  end
57
70
 
71
+ def to_unicodemath
72
+ first_value = parameter_one.to_unicodemath if parameter_one
73
+ second_value = if parameter_two.is_a?(self.class)
74
+ "_#{size_overrides}#{parameter_two.to_unicodemath}"
75
+ elsif parameter_two&.mini_sized?
76
+ parameter_two.to_unicodemath
77
+ elsif parameter_two.nil?
78
+ "()"
79
+ else
80
+ "_#{size_overrides}#{unicodemath_parens(parameter_two)}"
81
+ end
82
+ "#{first_value}#{second_value}"
83
+ end
84
+
58
85
  def line_breaking(obj)
59
86
  parameter_one&.line_breaking(obj)
60
87
  if obj.value_exist?
@@ -68,6 +95,28 @@ module Plurimath
68
95
  obj.update(self.class.new(nil, Utility.filter_values(obj.value)))
69
96
  end
70
97
  end
98
+
99
+ def new_nary_function(fourth_value)
100
+ Nary.new(parameter_one, parameter_two, nil, fourth_value)
101
+ end
102
+
103
+ def is_nary_function?
104
+ parameter_one.is_nary_function? || parameter_one.is_nary_symbol?
105
+ end
106
+
107
+ protected
108
+
109
+ def size_overrides
110
+ return if options.nil? || options&.empty?
111
+
112
+ "Ⅎ#{UnicodeMath::Constants::SIZE_OVERRIDES_SYMBOLS.invert[options[:size]]}" if options[:size]
113
+ end
114
+
115
+ def unicodemath_parens(field)
116
+ return "〖#{field.to_unicodemath}〗" unless options.nil? || options&.empty?
117
+
118
+ super(field)
119
+ end
71
120
  end
72
121
  end
73
122
  end
@@ -131,6 +131,12 @@ module Plurimath
131
131
  underset = Underset.new(overset, parameter_one)
132
132
  Array(underset.to_omml_without_math_tag(display_style))
133
133
  end
134
+
135
+ def prime_unicode?(field)
136
+ return unless field.is_a?(Math::Symbol)
137
+
138
+ UnicodeMath::Constants::PREFIXED_PRIMES.any? { |prefix, prime| field.value.include?(prime) || field.value.include?("&#x27;") }
139
+ end
134
140
  end
135
141
  end
136
142
  end
@@ -18,6 +18,11 @@ module Plurimath
18
18
  def to_omml_without_math_tag(display_style)
19
19
  omml_value(display_style)
20
20
  end
21
+
22
+ def to_unicodemath
23
+ first_value = unicodemath_parens(parameter_one) if parameter_one
24
+ "╱#{first_value}"
25
+ end
21
26
  end
22
27
  end
23
28
  end
@@ -31,6 +31,12 @@ module Plurimath
31
31
  "<i>&#x2308;</i>#{first_value}<i>&#x2309;</i>"
32
32
  end
33
33
 
34
+ def to_unicodemath
35
+ first_value = "&#x2308;" unless open_paren
36
+ second_value = "&#x2309;" unless close_paren
37
+ "#{first_value}#{parameter_one&.to_unicodemath}#{second_value}"
38
+ end
39
+
34
40
  def line_breaking(obj)
35
41
  parameter_one.line_breaking(obj)
36
42
  if obj.value_exist?
@@ -6,12 +6,20 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Color < BinaryFunction
9
+ attr_accessor :options
9
10
  FUNCTION = {
10
11
  name: "color",
11
12
  first_value: "mathcolor",
12
13
  second_value: "text",
13
14
  }.freeze
14
15
 
16
+ def initialize(parameter_one = nil,
17
+ parameter_two = nil,
18
+ options = {})
19
+ super(parameter_one, parameter_two)
20
+ @options = options unless options.empty?
21
+ end
22
+
15
23
  def to_asciimath
16
24
  first_value = "(#{parameter_one&.to_asciimath&.gsub(/\s/, '')})"
17
25
  second_value = "(#{parameter_two&.to_asciimath})"
@@ -19,10 +27,11 @@ module Plurimath
19
27
  end
20
28
 
21
29
  def to_mathml_without_math_tag
30
+ color_value = parameter_one&.to_asciimath&.gsub(/\s/, "")&.gsub(/"/, "")
22
31
  Utility.update_nodes(
23
32
  Utility.ox_element(
24
33
  "mstyle",
25
- attributes: { mathcolor: parameter_one&.to_asciimath&.gsub(/\s/, "")&.gsub(/"/, "") },
34
+ attributes: { attr_key => color_value },
26
35
  ),
27
36
  [parameter_two&.to_mathml_without_math_tag],
28
37
  )
@@ -45,6 +54,16 @@ module Plurimath
45
54
  omml_fields_to_print(parameter_two, { spacing: new_spacing, field_name: "text", additional_space: "| |_ ", array: new_arr, display_style: display_style })
46
55
  new_arr
47
56
  end
57
+
58
+ def to_unicodemath
59
+ "✎(#{parameter_one.to_unicodemath}&#{parameter_two.to_unicodemath})"
60
+ end
61
+
62
+ protected
63
+
64
+ def attr_key
65
+ (options && options[:backcolor]) ? :mathbackground : :mathcolor
66
+ end
48
67
  end
49
68
  end
50
69
  end
@@ -33,6 +33,10 @@ module Plurimath
33
33
  "#{first_value}<i>..</i>"
34
34
  end
35
35
 
36
+ def to_unicodemath
37
+ "#{unicodemath_parens(parameter_one)}̈"
38
+ end
39
+
36
40
  def line_breaking(obj)
37
41
  parameter_one&.line_breaking(obj)
38
42
  obj.update(Utility.filter_values(obj.value)) if obj.value_exist?
@@ -41,6 +41,11 @@ module Plurimath
41
41
  end
42
42
  end
43
43
 
44
+ def to_unicodemath
45
+ first_value = unicodemath_parens(parameter_one) if parameter_one
46
+ "#{first_value}̇"
47
+ end
48
+
44
49
  def line_breaking(obj)
45
50
  parameter_one&.line_breaking(obj)
46
51
  obj.update(Utility.filter_values(obj.value)) if obj.value_exist?
@@ -6,6 +6,22 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Fenced < TernaryFunction
9
+ attr_accessor :options
10
+
11
+ def initialize(
12
+ parameter_one = nil,
13
+ parameter_two = nil,
14
+ parameter_three = nil,
15
+ options = {})
16
+ super(parameter_one, parameter_two, parameter_three)
17
+ @options = options
18
+ end
19
+
20
+ def ==(object)
21
+ super(object) &&
22
+ object.options == options
23
+ end
24
+
9
25
  def to_asciimath
10
26
  first_value = parameter_one ? parameter_one.to_asciimath : "("
11
27
  third_value = parameter_three ? parameter_three.to_asciimath : ")"
@@ -13,9 +29,9 @@ module Plurimath
13
29
  end
14
30
 
15
31
  def to_mathml_without_math_tag
16
- first_value = Utility.ox_element("mo") << (mathml_paren(parameter_one) || "")
32
+ first_value = Utility.ox_element("mo", attributes: options&.dig(:open_paren)) << (mathml_paren(parameter_one) || "")
17
33
  second_value = parameter_two&.map(&:to_mathml_without_math_tag) || []
18
- third_value = Utility.ox_element("mo") << (mathml_paren(parameter_three) || "")
34
+ third_value = Utility.ox_element("mo", attributes: options&.dig(:close_paren)) << (mathml_paren(parameter_three) || "")
19
35
  Utility.update_nodes(
20
36
  Utility.ox_element("mrow"),
21
37
  (second_value.insert(0, first_value) << third_value),
@@ -37,17 +53,41 @@ module Plurimath
37
53
  end
38
54
 
39
55
  def to_omml_without_math_tag(display_style)
56
+ attrs = { "m:val": (options ? options[:separators] : "") }
40
57
  d = Utility.ox_element("d", namespace: "m")
41
58
  dpr = Utility.ox_element("dPr", namespace: "m")
42
- parameter = Formula.new(Array(parameter_two))
43
59
  open_paren(dpr)
60
+ dpr << Utility.ox_element("sepChr", namespace: "m", attributes: attrs)
44
61
  close_paren(dpr)
45
- fenced_value = omml_parameter(parameter, display_style, tag_name: "e")
46
- dpr << Utility.pr_element("ctrl", true, namespace: "m")
47
- Utility.update_nodes(d, [dpr, fenced_value])
62
+ Utility.update_nodes(
63
+ d,
64
+ [
65
+ dpr,
66
+ omml_parameter(
67
+ Formula.new(Array(parameter_two)),
68
+ display_style,
69
+ tag_name: "e",
70
+ ),
71
+ ],
72
+ )
48
73
  [d]
49
74
  end
50
75
 
76
+ def to_unicodemath
77
+ return mini_sized_unicode if mini_sized?
78
+
79
+ fenced_value = parameter_two&.map do |param|
80
+ next param.choose_frac if choose_frac?(param)
81
+
82
+ param.to_unicodemath
83
+ end&.join(" ")
84
+ return fenced_value if choose_frac?(parameter_two.first)
85
+
86
+ fenced_value = "(#{fenced_value})" if parameter_one&.value&.include?("|")
87
+
88
+ "#{unicode_open_paren}#{fenced_value}#{unicode_close_paren}"
89
+ end
90
+
51
91
  def to_asciimath_math_zone(spacing, last = false, indent = true)
52
92
  filtered_values(parameter_two).map.with_index(1) do |object, index|
53
93
  last = index == @values.length
@@ -82,6 +122,17 @@ module Plurimath
82
122
  obj.update(value_split(obj, field_values))
83
123
  end
84
124
 
125
+ def mini_sized?
126
+ parameter_one&.mini_sized? ||
127
+ Math::Formula.new(parameter_two)&.mini_sized? ||
128
+ parameter_three&.mini_sized?
129
+ end
130
+
131
+ def mini_sized_unicode
132
+ fenced_value = parameter_two&.map(&:to_unicodemath)&.join
133
+ "#{parameter_one.to_unicodemath}#{fenced_value}#{parameter_three.to_unicodemath}"
134
+ end
135
+
85
136
  protected
86
137
 
87
138
  def open_paren(dpr)
@@ -118,7 +169,8 @@ module Plurimath
118
169
  end
119
170
 
120
171
  def mathml_paren(field)
121
- return "" if field&.value&.include?(":")
172
+ unicodemath_syntax = ["&#x3016;", "&#x3017;", "&#x2524;", "&#x251c;"]
173
+ return "" if field&.value&.include?(":") || unicodemath_syntax.include?(field&.value&.to_s)
122
174
 
123
175
  field&.value
124
176
  end
@@ -132,6 +184,45 @@ module Plurimath
132
184
  self.parameter_three = nil
133
185
  object
134
186
  end
187
+
188
+ def unicode_open_paren
189
+ paren = parameter_one&.to_unicodemath
190
+ return "├#{convert_paren_size(paren_size: options&.dig(:open_paren, :minsize))}#{paren}" if options&.key?(:open_paren)
191
+ return "├#{paren}" if options&.key?(:open_prefixed) && !open_or_begin?
192
+ return "├" if options&.key?(:open_prefixed) || paren == "{:"
193
+
194
+ paren
195
+ end
196
+
197
+ def unicode_close_paren
198
+ paren = parameter_three&.to_unicodemath
199
+ return "┤#{convert_paren_size(paren_size: options&.dig(:close_paren, :minsize))}#{paren}" if options&.key?(:close_paren)
200
+ return "┤#{paren}" if options&.key?(:close_prefixed) && !close_or_end?
201
+ return "┤" if options&.key?(:close_prefixed) || paren == ":}"
202
+
203
+ paren
204
+ end
205
+
206
+ def choose_frac?(param)
207
+ param&.is_a?(Math::Function::Frac) && param&.options&.key?(:choose)
208
+ end
209
+
210
+ def convert_paren_size(paren_size:)
211
+ paren = paren_size.delete_suffix("em").to_f
212
+ (::Math.log(paren) / ::Math.log(1.25)).round
213
+ end
214
+
215
+ def open_or_begin?
216
+ parameter_one&.value&.include?("&#x251c;") ||
217
+ parameter_one&.value&.include?("&#x3016;") ||
218
+ parameter_one&.value&.include?("{:")
219
+ end
220
+
221
+ def close_or_end?
222
+ parameter_three&.value&.include?("&#x2524;") ||
223
+ parameter_three&.value&.include?("&#x3017;") ||
224
+ parameter_three&.value&.include?(":}")
225
+ end
135
226
  end
136
227
  end
137
228
  end
@@ -28,6 +28,12 @@ module Plurimath
28
28
  array
29
29
  end
30
30
 
31
+ def to_unicodemath
32
+ first_value = "&#x230a;" unless open_paren
33
+ second_value = "&#x230b;" unless close_paren
34
+ "#{first_value}#{parameter_one&.to_unicodemath}#{second_value}"
35
+ end
36
+
31
37
  def line_breaking(obj)
32
38
  parameter_one.line_breaking(obj)
33
39
  if obj.value_exist?
@@ -33,6 +33,10 @@ module Plurimath
33
33
  def to_omml_without_math_tag(display_style)
34
34
  font_styles(display_style, sty: nil, scr: "monospace")
35
35
  end
36
+
37
+ def to_unicodemath
38
+ "ᅲ#{unicodemath_parens(parameter_one)}"
39
+ end
36
40
  end
37
41
  end
38
42
  end
@@ -15,7 +15,7 @@ module Plurimath
15
15
  Utility.update_nodes(
16
16
  Utility.ox_element(
17
17
  "mstyle",
18
- attributes: { mathvariant: parameter_two },
18
+ attributes: { mathvariant: font_family(mathml: true) },
19
19
  ),
20
20
  [first_value],
21
21
  )
@@ -33,6 +33,10 @@ module Plurimath
33
33
  parameter_one&.to_latex
34
34
  end
35
35
 
36
+ def to_unicodemath
37
+ "#{font_family(unicode: true)}#{parameter_one&.to_unicodemath}"
38
+ end
39
+
36
40
  def validate_function_formula
37
41
  true
38
42
  end
@@ -82,7 +86,7 @@ module Plurimath
82
86
  new_spacing = gsub_spacing(spacing, last)
83
87
  new_arr = [
84
88
  "#{spacing}\"#{dump_mathml(self)}\" function apply\n",
85
- "#{new_spacing}|_ \"#{omml_and_mathml_font_family}\" font family\n",
89
+ "#{new_spacing}|_ \"#{font_family(mathml: true)}\" font family\n",
86
90
  ]
87
91
  mathml_fields_to_print(parameter_one, { spacing: new_spacing, field_name: "argument", additional_space: "| |_ ", array: new_arr })
88
92
  new_arr
@@ -92,15 +96,28 @@ module Plurimath
92
96
  new_spacing = gsub_spacing(spacing, last)
93
97
  new_arr = [
94
98
  "#{spacing}\"#{dump_omml(self, display_style)}\" function apply\n",
95
- "#{new_spacing}|_ \"#{omml_and_mathml_font_family}\" font family\n",
99
+ "#{new_spacing}|_ \"#{font_family(omml: true)}\" font family\n",
96
100
  ]
97
101
  omml_fields_to_print(parameter_one, { spacing: new_spacing, field_name: "argument", additional_space: "| |_ ", array: new_arr, display_style: display_style })
98
102
  new_arr
99
103
  end
100
104
 
101
- def omml_and_mathml_font_family
102
- fonts = Utility::FONT_STYLES.select { |_font, font_class| font_class == self.class }.keys.map(&:to_s)
103
- Omml::Parser::SUPPORTED_FONTS.values.find { |value| fonts.include?(value) }
105
+ def font_family(unicode: false, omml: false, mathml: false)
106
+ fonts = font_classes
107
+ fonts = font_classes(parameter_to_class) if fonts.empty?
108
+ supported_fonts(fonts, unicode: unicode, omml: omml, mathml: mathml)
109
+ end
110
+
111
+ def supported_fonts(fonts_array = [], unicode: false, omml: false, mathml: false)
112
+ if unicode
113
+ font = UnicodeMath::Constants::FONTS_CLASSES.find { |value| fonts_array.include?(value) }
114
+ return "\\#{font}" if font
115
+ end
116
+ return Omml::Parser::SUPPORTED_FONTS.values.find { |value| fonts_array.include?(value) } if omml
117
+ if mathml
118
+ Mathml::Constants::SUPPORTED_FONT_STYLES.find { |string, object| fonts_array.include?(string.to_s) }&.first ||
119
+ parameter_two
120
+ end
104
121
  end
105
122
 
106
123
  def line_breaking(obj)
@@ -114,6 +131,14 @@ module Plurimath
114
131
  )
115
132
  )
116
133
  end
134
+
135
+ def font_classes(object = self)
136
+ Utility::FONT_STYLES.select { |_font, font_class| font_class == object.class }.keys.map(&:to_s)
137
+ end
138
+
139
+ def parameter_to_class
140
+ Utility::FONT_STYLES.select { |font, _font_class| font == parameter_two.to_sym }&.values&.first&.new('')
141
+ end
117
142
  end
118
143
  end
119
144
  end
@@ -6,12 +6,25 @@ module Plurimath
6
6
  module Math
7
7
  module Function
8
8
  class Frac < BinaryFunction
9
+ attr_accessor :options
9
10
  FUNCTION = {
10
11
  name: "fraction",
11
12
  first_value: "numerator",
12
13
  second_value: "denominator",
13
14
  }.freeze
14
15
 
16
+ def initialize(parameter_one = nil,
17
+ parameter_two = nil,
18
+ options = {})
19
+ super(parameter_one, parameter_two)
20
+ @options = options if options && !options&.empty?
21
+ end
22
+
23
+ def ==(object)
24
+ super(object) &&
25
+ object.options == options
26
+ end
27
+
15
28
  def to_asciimath
16
29
  first_value = "(#{parameter_one&.to_asciimath})" if parameter_one
17
30
  second_value = "(#{parameter_two&.to_asciimath})" if parameter_two
@@ -19,12 +32,14 @@ module Plurimath
19
32
  end
20
33
 
21
34
  def to_mathml_without_math_tag
22
- tag_name = hide_function_name ? "mfrac" : "mrow"
35
+ tag_name = hide_function_name ? "mrow" : "mfrac"
23
36
  mathml_value = [
24
37
  parameter_one&.to_mathml_without_math_tag,
25
38
  parameter_two&.to_mathml_without_math_tag,
26
39
  ]
27
- Utility.update_nodes(ox_element("mfrac"), mathml_value)
40
+ frac_tag = ox_element(tag_name)
41
+ frac_tag.attributes.merge!(options) if tag_name == "mfrac" && options
42
+ Utility.update_nodes(frac_tag, mathml_value)
28
43
  end
29
44
 
30
45
  def to_latex
@@ -35,26 +50,35 @@ module Plurimath
35
50
 
36
51
  def to_omml_without_math_tag(display_style)
37
52
  f_element = Utility.ox_element("f", namespace: "m")
38
- fpr_element = Utility.ox_element("fPr", namespace: "m")
39
- fpr_element << Utility.pr_element("ctrl", true, namespace: "m")
40
- Array(
41
- Utility.update_nodes(
42
- f_element,
43
- [
44
- fpr_element,
45
- omml_parameter(parameter_one, display_style, tag_name: "num"),
46
- omml_parameter(parameter_two, display_style, tag_name: "den"),
47
- ],
48
- ),
53
+ Utility.update_nodes(
54
+ f_element,
55
+ [
56
+ fpr_element,
57
+ omml_parameter(parameter_one, display_style, tag_name: "num"),
58
+ omml_parameter(parameter_two, display_style, tag_name: "den"),
59
+ ],
49
60
  )
50
61
  end
51
62
 
63
+ def to_unicodemath
64
+ return unicodemath_fraction if options&.dig(:unicodemath_fraction)
65
+
66
+ first_value = unicodemath_parens(parameter_one) if parameter_one
67
+ second_value = unicodemath_parens(parameter_two) if parameter_two
68
+ return "#{first_value}/#{second_value}" unless options
69
+
70
+ return "#{first_value}¦#{second_value}" if options && options.key?(:linethickness)
71
+ return "#{parameter_one.to_unicodemath}⊘#{parameter_two.to_unicodemath}" if options && options.key?(:displaystyle)
72
+ "#{first_value}∕#{second_value}" if options && options.key?(:ldiv)
73
+ end
74
+
52
75
  def line_breaking(obj)
53
76
  parameter_one&.line_breaking(obj)
54
77
  if obj.value_exist?
55
- obj.update(self.class.new(Utility.filter_values(obj.value), parameter_two))
78
+ frac = self.class.new(Utility.filter_values(obj.value), parameter_two)
79
+ frac.hide_function_name = true
80
+ obj.update(frac)
56
81
  self.parameter_two = nil
57
- self.hide_function_name = true
58
82
  return
59
83
  end
60
84
 
@@ -65,6 +89,36 @@ module Plurimath
65
89
  obj.update(frac)
66
90
  end
67
91
  end
92
+
93
+ def choose_frac
94
+ first_value = unicodemath_parens(parameter_one) if parameter_one
95
+ second_value = unicodemath_parens(parameter_two) if parameter_two
96
+ "#{first_value}⒞#{second_value}"
97
+ end
98
+
99
+ protected
100
+
101
+ def fpr_element
102
+ fpr_element = Utility.ox_element("fPr", namespace: "m")
103
+ if options
104
+ attributes = { "m:val": attr_value }
105
+ fpr_element << Utility.ox_element("type", namespace: "m", attributes: attributes)
106
+ end
107
+ fpr_element << Utility.pr_element("ctrl", true, namespace: "m")
108
+ end
109
+
110
+ def attr_value
111
+ if options[:linethickness] == "0"
112
+ "noBar"
113
+ else
114
+ options[:bevelled] == 'true' ? 'skw' : "bar"
115
+ end
116
+ end
117
+
118
+ def unicodemath_fraction
119
+ frac_array = [parameter_one.value.to_i, parameter_two.value.to_i]
120
+ UnicodeMath::Constants::UNICODE_FRACTIONS.key(frac_array)
121
+ end
68
122
  end
69
123
  end
70
124
  end
@@ -54,6 +54,10 @@ module Plurimath
54
54
  end
55
55
  end
56
56
 
57
+ def to_unicodemath
58
+ "#{unicodemath_parens(parameter_one)}̂"
59
+ end
60
+
57
61
  def line_breaking(obj)
58
62
  parameter_one&.line_breaking(obj)
59
63
  if obj.value_exist?
@@ -49,6 +49,36 @@ module Plurimath
49
49
  self.parameter_two = nil
50
50
  end
51
51
  end
52
+
53
+ def to_unicodemath
54
+ "inf#{sub_value}#{sup_value}"
55
+ end
56
+
57
+ protected
58
+
59
+ def sup_value
60
+ return unless parameter_two
61
+
62
+ if parameter_two&.mini_sized? || prime_unicode?(parameter_two)
63
+ parameter_two.to_unicodemath
64
+ elsif parameter_two.is_a?(Math::Function::Power)
65
+ "^#{parameter_two.to_unicodemath}"
66
+ else
67
+ "^#{unicodemath_parens(parameter_two)}"
68
+ end
69
+ end
70
+
71
+ def sub_value
72
+ return unless parameter_one
73
+
74
+ if parameter_one&.mini_sized?
75
+ parameter_one.to_unicodemath
76
+ elsif parameter_one.is_a?(Math::Function::Base)
77
+ "_#{parameter_one.to_unicodemath}"
78
+ else
79
+ "_#{unicodemath_parens(parameter_one)}"
80
+ end
81
+ end
52
82
  end
53
83
  end
54
84
  end