plurimath 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/Latex-Supported-Data.adoc +1 -0
  4. data/lib/plurimath/asciimath/parse.rb +1 -1
  5. data/lib/plurimath/asciimath/transform.rb +2 -6
  6. data/lib/plurimath/latex/constants.rb +2 -0
  7. data/lib/plurimath/math/core.rb +38 -6
  8. data/lib/plurimath/math/formula.rb +60 -6
  9. data/lib/plurimath/math/function/abs.rb +4 -0
  10. data/lib/plurimath/math/function/arg.rb +22 -0
  11. data/lib/plurimath/math/function/bar.rb +4 -0
  12. data/lib/plurimath/math/function/base.rb +49 -0
  13. data/lib/plurimath/math/function/binary_function.rb +6 -0
  14. data/lib/plurimath/math/function/cancel.rb +5 -0
  15. data/lib/plurimath/math/function/ceil.rb +6 -0
  16. data/lib/plurimath/math/function/color.rb +20 -1
  17. data/lib/plurimath/math/function/ddot.rb +4 -0
  18. data/lib/plurimath/math/function/dot.rb +5 -0
  19. data/lib/plurimath/math/function/fenced.rb +98 -7
  20. data/lib/plurimath/math/function/floor.rb +6 -0
  21. data/lib/plurimath/math/function/font_style/monospace.rb +4 -0
  22. data/lib/plurimath/math/function/font_style.rb +31 -6
  23. data/lib/plurimath/math/function/frac.rb +69 -15
  24. data/lib/plurimath/math/function/hat.rb +4 -0
  25. data/lib/plurimath/math/function/inf.rb +30 -0
  26. data/lib/plurimath/math/function/int.rb +47 -1
  27. data/lib/plurimath/math/function/intent.rb +22 -0
  28. data/lib/plurimath/math/function/left.rb +4 -0
  29. data/lib/plurimath/math/function/lim.rb +6 -0
  30. data/lib/plurimath/math/function/limits.rb +28 -0
  31. data/lib/plurimath/math/function/linebreak.rb +5 -0
  32. data/lib/plurimath/math/function/log.rb +27 -20
  33. data/lib/plurimath/math/function/longdiv.rb +4 -0
  34. data/lib/plurimath/math/function/mbox.rb +4 -0
  35. data/lib/plurimath/math/function/menclose.rb +74 -5
  36. data/lib/plurimath/math/function/merror.rb +2 -0
  37. data/lib/plurimath/math/function/mglyph.rb +64 -0
  38. data/lib/plurimath/math/function/mlabeledtr.rb +29 -0
  39. data/lib/plurimath/math/function/mod.rb +4 -0
  40. data/lib/plurimath/math/function/mpadded.rb +84 -0
  41. data/lib/plurimath/math/function/ms.rb +33 -0
  42. data/lib/plurimath/math/function/msgroup.rb +4 -0
  43. data/lib/plurimath/math/function/msline.rb +2 -4
  44. data/lib/plurimath/math/function/multiscript.rb +70 -6
  45. data/lib/plurimath/math/function/nary.rb +69 -10
  46. data/lib/plurimath/math/function/none.rb +25 -0
  47. data/lib/plurimath/math/function/norm.rb +6 -0
  48. data/lib/plurimath/math/function/obrace.rb +4 -0
  49. data/lib/plurimath/math/function/oint.rb +25 -1
  50. data/lib/plurimath/math/function/over.rb +6 -0
  51. data/lib/plurimath/math/function/overset.rb +46 -1
  52. data/lib/plurimath/math/function/phantom.rb +18 -2
  53. data/lib/plurimath/math/function/power.rb +37 -0
  54. data/lib/plurimath/math/function/power_base.rb +45 -18
  55. data/lib/plurimath/math/function/prod.rb +46 -0
  56. data/lib/plurimath/math/function/right.rb +4 -0
  57. data/lib/plurimath/math/function/root.rb +9 -1
  58. data/lib/plurimath/math/function/rule.rb +4 -0
  59. data/lib/plurimath/math/function/sqrt.rb +7 -1
  60. data/lib/plurimath/math/function/stackrel.rb +6 -0
  61. data/lib/plurimath/math/function/substack.rb +4 -0
  62. data/lib/plurimath/math/function/sum.rb +45 -24
  63. data/lib/plurimath/math/function/table/bmatrix.rb +18 -5
  64. data/lib/plurimath/math/function/table/cases.rb +24 -0
  65. data/lib/plurimath/math/function/table/eqarray.rb +24 -0
  66. data/lib/plurimath/math/function/table/matrix.rb +23 -3
  67. data/lib/plurimath/math/function/table/pmatrix.rb +4 -0
  68. data/lib/plurimath/math/function/table/vmatrix.rb +10 -0
  69. data/lib/plurimath/math/function/table.rb +58 -7
  70. data/lib/plurimath/math/function/td.rb +9 -0
  71. data/lib/plurimath/math/function/ternary_function.rb +14 -1
  72. data/lib/plurimath/math/function/text.rb +6 -0
  73. data/lib/plurimath/math/function/tilde.rb +4 -0
  74. data/lib/plurimath/math/function/tr.rb +9 -0
  75. data/lib/plurimath/math/function/ubrace.rb +5 -0
  76. data/lib/plurimath/math/function/ul.rb +4 -0
  77. data/lib/plurimath/math/function/unary_function.rb +4 -0
  78. data/lib/plurimath/math/function/underover.rb +14 -0
  79. data/lib/plurimath/math/function/underset.rb +49 -1
  80. data/lib/plurimath/math/function/vec.rb +4 -0
  81. data/lib/plurimath/math/number.rb +33 -3
  82. data/lib/plurimath/math/symbol.rb +68 -3
  83. data/lib/plurimath/math.rb +3 -2
  84. data/lib/plurimath/mathml/constants.rb +16 -0
  85. data/lib/plurimath/mathml/parser.rb +42 -2
  86. data/lib/plurimath/mathml/transform.rb +80 -29
  87. data/lib/plurimath/omml/parser.rb +8 -0
  88. data/lib/plurimath/omml/transform.rb +29 -26
  89. data/lib/plurimath/unicode_math/constants.rb +1015 -0
  90. data/lib/plurimath/unicode_math/parse.rb +233 -0
  91. data/lib/plurimath/unicode_math/parser.rb +58 -0
  92. data/lib/plurimath/unicode_math/parsing_rules/absence_rules.rb +138 -0
  93. data/lib/plurimath/unicode_math/parsing_rules/common_rules.rb +114 -0
  94. data/lib/plurimath/unicode_math/parsing_rules/constants_rules.rb +102 -0
  95. data/lib/plurimath/unicode_math/parsing_rules/helper.rb +19 -0
  96. data/lib/plurimath/unicode_math/parsing_rules/masked.rb +62 -0
  97. data/lib/plurimath/unicode_math/parsing_rules/sub_sup.rb +254 -0
  98. data/lib/plurimath/unicode_math/transform.rb +3831 -0
  99. data/lib/plurimath/{unicode.rb → unicode_math.rb} +2 -2
  100. data/lib/plurimath/unitsml.rb +14 -1
  101. data/lib/plurimath/utility.rb +346 -11
  102. data/lib/plurimath/version.rb +1 -1
  103. data/lib/plurimath/xml_engine/oga.rb +5 -0
  104. data/lib/plurimath/xml_engine/ox.rb +5 -0
  105. metadata +23 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d27853f7e998552c58b54113306cf188d8c8e64bad83cf31a688abc7414dd6d9
4
- data.tar.gz: ccd6b77d70a82d3e2727a65d6f3976e4afc1b3454753ddb7d6a6837206735b7c
3
+ metadata.gz: e695891a5d39be6da60ecc15c99e10084cd0e547eb01f19101fc04e86aad3af9
4
+ data.tar.gz: ec8a0ac035d3623d64e2a28bd2c6b51666586c1543e86735e497bfd93de6616d
5
5
  SHA512:
6
- metadata.gz: a8a69ff2bb1379646f798502cfb307adb9df9be44c129da7d1d2bf2ee1cca61086a0d1124e5d22d0460ab166da44ac9a82bf41ba770a097eef4d78f35127635d
7
- data.tar.gz: 48aa6427c4a764e3736a0ca8b7af503bcc1d8000fb2807f5fe42ba902f1cd73221e74384da0ac0f14b482c3792c7941eb59d70699790cc100cad4b6ba5fab60a
6
+ metadata.gz: 86c19de5ceaf9218d6d48aaf1f8845412d90012497776cf4535c62d23660e8d3af7b4ad2f2cb67147251d246ddad596f90305f2347088c10cc6effa5de5e09a6
7
+ data.tar.gz: 52d275e8b523063b33413bc604e5dea41ad2f14ac7f06cd65638ccf8c0f44c8556f06af1236ea151abdc961dda2685adf907c6a6df46f2a3ae0a8a4bc5a645d3
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "submodules/unicodemath-tests"]
2
+ path = submodules/unicodemath-tests
3
+ url = git@github.com:plurimath/unicodemath-tests.git
@@ -944,6 +944,7 @@
944
944
  * `supseteqq`
945
945
  * `leqqslant`
946
946
  * `geqqslant`
947
+ * `emptyset`
947
948
  * `horizbar`
948
949
  * `Question`
949
950
  * `medspace`
@@ -69,7 +69,7 @@ module Plurimath
69
69
  end
70
70
 
71
71
  rule(:quoted_text) do
72
- (str('"') >> str("unitsml(") >> match("[^\)\"]").repeat.as(:unitsml) >> str(')"')) |
72
+ (str('"') >> str("unitsml(") >> (str(')"').absent? >> any).repeat.as(:unitsml) >> str(')"')) |
73
73
  (str('"') >> match("[^\"]").repeat.as(:text) >> str('"')) |
74
74
  (str('"') >> str("").as(:text))
75
75
  end
@@ -29,9 +29,7 @@ module Plurimath
29
29
  rule(mod: simple(:mod), expr: simple(:expr)) { [mod, expr] }
30
30
 
31
31
  rule(unitsml: simple(:unitsml)) do
32
- Utility.filter_values(
33
- Unitsml.new(unitsml.to_s).to_formula.value,
34
- )
32
+ Unitsml.new(unitsml.to_s).to_formula
35
33
  end
36
34
 
37
35
  rule(bold_fonts: simple(:font)) do
@@ -881,9 +879,7 @@ module Plurimath
881
879
  rule(unary_class: simple(:function),
882
880
  unitsml: simple(:unitsml)) do
883
881
  Utility.get_class(function).new(
884
- Utility.filter_values(
885
- Unitsml.new(unitsml.to_s).to_formula.value,
886
- ),
882
+ Unitsml.new(unitsml.to_s).to_formula,
887
883
  )
888
884
  end
889
885
 
@@ -883,6 +883,7 @@ module Plurimath
883
883
  supseteqq: "⫆",
884
884
  leqqslant: "⫹",
885
885
  geqqslant: "⫺",
886
+ emptyset: "∅",
886
887
  horizbar: "―",
887
888
  Question: "⁇",
888
889
  medspace: " ",
@@ -2705,6 +2706,7 @@ module Plurimath
2705
2706
  leqqslant: :symbols,
2706
2707
  geqqslant: :symbols,
2707
2708
  mbfitsans: :fonts,
2709
+ emptyset: :symbols,
2708
2710
  horizbar: :symbols,
2709
2711
  Question: :symbols,
2710
2712
  medspace: :symbols,
@@ -28,9 +28,11 @@ module Plurimath
28
28
  ""
29
29
  end
30
30
 
31
- def empty_tag(wrapper_tag)
31
+ def empty_tag(wrapper_tag = nil)
32
32
  r_tag = ox_element("r", namespace: "m")
33
33
  r_tag << (ox_element("t", namespace: "m") << "&#8203;")
34
+ return r_tag unless wrapper_tag
35
+
34
36
  wrapper_tag << r_tag
35
37
  end
36
38
 
@@ -38,10 +40,12 @@ module Plurimath
38
40
  tag = ox_element(tag_name, namespace: namespace)
39
41
  return empty_tag(tag) unless field
40
42
 
41
- Utility.update_nodes(
42
- tag,
43
- field.insert_t_tag(display_style),
44
- )
43
+ field_value = if field.is_a?(Array)
44
+ field.map { |object| object.insert_t_tag(display_style) }
45
+ else
46
+ field.insert_t_tag(display_style)
47
+ end
48
+ Utility.update_nodes(tag, field_value)
45
49
  end
46
50
 
47
51
  def validate_function_formula
@@ -127,7 +131,11 @@ module Plurimath
127
131
  end
128
132
 
129
133
  def validate_mathml_fields(field)
130
- field.nil? ? ox_element("mi") : field.to_mathml_without_math_tag
134
+ if field.is_a?(Array)
135
+ field&.map(&:to_mathml_without_math_tag)
136
+ else
137
+ field&.to_mathml_without_math_tag
138
+ end
131
139
  end
132
140
 
133
141
  def common_math_zone_conversion(field, options = {})
@@ -266,6 +274,30 @@ module Plurimath
266
274
  def is_unary?
267
275
  is_a?(Math::Function::UnaryFunction)
268
276
  end
277
+
278
+ def is_nary_function?;end
279
+
280
+ def is_nary_symbol?;end
281
+
282
+ def is_binary_function?
283
+ is_a?(Function::BinaryFunction)
284
+ end
285
+
286
+ def is_ternary_function?
287
+ is_a?(Function::TernaryFunction)
288
+ end
289
+
290
+ def mini_sized?
291
+ false
292
+ end
293
+
294
+ def unicodemath_parens(field)
295
+ if field.is_a?(Math::Function::Fenced)
296
+ field.to_unicodemath
297
+ else
298
+ "(#{field.to_unicodemath})" if field
299
+ end
300
+ end
269
301
  end
270
302
  end
271
303
  end
@@ -3,7 +3,7 @@
3
3
  module Plurimath
4
4
  module Math
5
5
  class Formula < Core
6
- attr_accessor :value, :left_right_wrapper, :displaystyle, :input_string
6
+ attr_accessor :value, :left_right_wrapper, :displaystyle, :input_string, :unitsml
7
7
 
8
8
  MATH_ZONE_TYPES = %i[
9
9
  omml
@@ -16,12 +16,14 @@ module Plurimath
16
16
  value = [],
17
17
  left_right_wrapper = true,
18
18
  display_style: true,
19
- input_string: nil
19
+ input_string: nil,
20
+ unitsml: false
20
21
  )
21
22
  @value = value.is_a?(Array) ? value : [value]
22
23
  left_right_wrapper = false if @value.first.is_a?(Function::Left)
23
24
  @left_right_wrapper = left_right_wrapper
24
25
  @displaystyle = boolean_display_style(display_style)
26
+ @unitsml = unitsml if unitsml
25
27
  end
26
28
 
27
29
  def ==(object)
@@ -49,6 +51,7 @@ module Plurimath
49
51
  style = ox_element("mstyle", attributes: style_attrs)
50
52
  Utility.update_nodes(style, mathml_content)
51
53
  Utility.update_nodes(math, [style])
54
+ unitsml_post_processing(math)
52
55
  dump_nodes(math, indent: 2)
53
56
  rescue
54
57
  parse_error!(:mathml)
@@ -63,10 +66,9 @@ module Plurimath
63
66
  def to_mathml_without_math_tag
64
67
  return mathml_content unless left_right_wrapper
65
68
 
66
- Utility.update_nodes(
67
- Utility.ox_element("mrow"),
68
- mathml_content,
69
- )
69
+ mrow = ox_element("mrow")
70
+ mrow.attributes[:unitsml] = true if unitsml
71
+ Utility.update_nodes(mrow, mathml_content)
70
72
  end
71
73
 
72
74
  def mathml_content
@@ -134,6 +136,12 @@ module Plurimath
134
136
  omml_content(display_style)
135
137
  end
136
138
 
139
+ def to_unicodemath
140
+ Utility.html_entity_to_unicode(unicodemath_value).gsub(/\s\/\s/, "/")
141
+ rescue
142
+ parse_error!(:unicodemath)
143
+ end
144
+
137
145
  def to_display(type = nil)
138
146
  return type_error! unless MATH_ZONE_TYPES.include?(type.downcase.to_sym)
139
147
 
@@ -247,6 +255,10 @@ module Plurimath
247
255
  end
248
256
 
249
257
 
258
+ def mini_sized?
259
+ true if value&.first&.mini_sized?
260
+ end
261
+
250
262
  protected
251
263
 
252
264
  def boolean_display_style(display_style = displaystyle)
@@ -273,6 +285,48 @@ module Plurimath
273
285
  r_tag = ox_element("r", namespace: "m")
274
286
  r_tag << ox_element("br")
275
287
  end
288
+
289
+ def unitsml_post_processing(nodes)
290
+ nodes.each.with_index do |node, index|
291
+ if node.is_a?(Ox::Element) && node.attributes&.dig(:unitsml)
292
+ previous = nodes[index-1]
293
+ if previous && ["mi", "mn"].include?(previous.name)
294
+ if text_in_tag?(node.nodes)
295
+ nodes.insert(index, space_element(attributes: true))
296
+ else
297
+ nodes.insert(index, space_element)
298
+ end
299
+ end
300
+
301
+ node.attributes.delete_if {|k, v| k == :unitsml }
302
+ end
303
+
304
+ unitsml_post_processing(node.nodes) if !node.nodes.any?(String)
305
+ end
306
+ end
307
+
308
+ def space_element(attributes: false)
309
+ element = (ox_element("mo") << "&#x2062;")
310
+ element.attributes[:rspace] = "thickmathspace" if attributes
311
+ element
312
+ end
313
+
314
+ def text_in_tag?(nodes)
315
+ next_nodes = nodes.first.nodes
316
+ if next_nodes.all?(String)
317
+ Utility.html_entity_to_unicode(next_nodes.first).match?(/\p{L}|\p{N}/)
318
+ else
319
+ text_in_tag?(next_nodes)
320
+ end
321
+ end
322
+
323
+ def negated_value?
324
+ value.last.is_a?(Math::Symbol) && value.last.value == "&#x338;"
325
+ end
326
+
327
+ def unicodemath_value
328
+ (negated_value? || mini_sized?) ? value&.map(&:to_unicodemath)&.join : value&.map(&:to_unicodemath)&.join(" ")
329
+ end
276
330
  end
277
331
  end
278
332
  end
@@ -34,6 +34,10 @@ module Plurimath
34
34
  end
35
35
  end
36
36
 
37
+ def to_unicodemath
38
+ "⒜#{unicodemath_parens(parameter_one)}"
39
+ end
40
+
37
41
  protected
38
42
 
39
43
  def md_tag
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "binary_function"
4
+
5
+ module Plurimath
6
+ module Math
7
+ module Function
8
+ class Arg < BinaryFunction
9
+ def to_mathml_without_math_tag
10
+ first_value = parameter_one.to_mathml_without_math_tag
11
+ first_value.attributes[:arg] = Utility.html_entity_to_unicode(parameter_two.value)
12
+ first_value
13
+ end
14
+
15
+ def to_unicodemath
16
+ first_value = "(#{parameter_two&.to_unicodemath} #{parameter_one&.to_unicodemath})" if parameter_one || parameter_two
17
+ "ⓐ#{first_value}"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -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?