plurimath 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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: 68c5bd436055069db4d68d88fcf13f5bf6b06a60392b0846eec79e1b6cf50103
4
- data.tar.gz: 454baf1fab16e319ade3c52cd4be5104d1d6e61bd817944b119b38e723b6cb89
3
+ metadata.gz: e695891a5d39be6da60ecc15c99e10084cd0e547eb01f19101fc04e86aad3af9
4
+ data.tar.gz: ec8a0ac035d3623d64e2a28bd2c6b51666586c1543e86735e497bfd93de6616d
5
5
  SHA512:
6
- metadata.gz: 13b1df4e1875a76fea760fafd455cef19cf0ba808077420aff2f538ac90f427a97bc23319c649ff48227bb14a42cce7b9e09ae918282d822fb8ca18821dce08b
7
- data.tar.gz: 42c8370e6610c6fb6a59b80913e6e8886b6489257427133c932640e9a2d13e4b75c56e03951a775eef960fcb61fd686cd8518b54cac809eccb5254bfae5714b3
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&.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?