plurimath 0.8.16 → 0.8.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/gen_docs.yml +10 -8
  3. data/README.adoc +4 -0
  4. data/Rakefile +55 -8
  5. data/intent_supported_classes.adoc +82 -0
  6. data/lib/plurimath/formatter/number_formatter.rb +6 -6
  7. data/lib/plurimath/formatter/numeric_formatter.rb +5 -2
  8. data/lib/plurimath/formatter/standard.rb +2 -0
  9. data/lib/plurimath/math/core.rb +2 -2
  10. data/lib/plurimath/math/formula.rb +10 -3
  11. data/lib/plurimath/math/function/abs.rb +5 -1
  12. data/lib/plurimath/math/function/fenced.rb +19 -7
  13. data/lib/plurimath/math/function/frac.rb +8 -1
  14. data/lib/plurimath/math/function/inf.rb +5 -1
  15. data/lib/plurimath/math/function/int.rb +5 -1
  16. data/lib/plurimath/math/function/intent.rb +6 -2
  17. data/lib/plurimath/math/function/lim.rb +5 -1
  18. data/lib/plurimath/math/function/nary.rb +13 -1
  19. data/lib/plurimath/math/function/oint.rb +5 -1
  20. data/lib/plurimath/math/function/prod.rb +5 -1
  21. data/lib/plurimath/math/function/sum.rb +5 -1
  22. data/lib/plurimath/math/function/table/array.rb +1 -1
  23. data/lib/plurimath/math/function/table/bmatrix.rb +1 -1
  24. data/lib/plurimath/math/function/table/cases.rb +2 -2
  25. data/lib/plurimath/math/function/table/eqarray.rb +2 -2
  26. data/lib/plurimath/math/function/table/pmatrix.rb +1 -1
  27. data/lib/plurimath/math/function/table/vmatrix.rb +1 -1
  28. data/lib/plurimath/math/function/table.rb +12 -0
  29. data/lib/plurimath/math/function/unary_function.rb +5 -1
  30. data/lib/plurimath/math/symbols/bigwedge.rb +4 -0
  31. data/lib/plurimath/math/symbols/cap.rb +0 -4
  32. data/lib/plurimath/math/symbols/clockoint.rb +1 -1
  33. data/lib/plurimath/math/symbols/cntclockoint.rb +1 -1
  34. data/lib/plurimath/math/symbols/coprod.rb +1 -1
  35. data/lib/plurimath/math/symbols/dd.rb +4 -0
  36. data/lib/plurimath/math/symbols/dint.rb +4 -0
  37. data/lib/plurimath/math/symbols/duni.rb +4 -0
  38. data/lib/plurimath/math/symbols/ii.rb +4 -0
  39. data/lib/plurimath/math/symbols/iiiint.rb +1 -1
  40. data/lib/plurimath/math/symbols/iiint.rb +4 -0
  41. data/lib/plurimath/math/symbols/iint.rb +1 -1
  42. data/lib/plurimath/math/symbols/intclockwise.rb +1 -1
  43. data/lib/plurimath/math/symbols/intercal.rb +4 -0
  44. data/lib/plurimath/math/symbols/jj.rb +4 -0
  45. data/lib/plurimath/math/symbols/oiiint.rb +1 -1
  46. data/lib/plurimath/math/symbols/oiint.rb +1 -1
  47. data/lib/plurimath/math/symbols/oint.rb +1 -1
  48. data/lib/plurimath/math/symbols/upcase_dd.rb +4 -0
  49. data/lib/plurimath/mathml/transform.rb +2 -0
  50. data/lib/plurimath/utility/intent_encoding.rb +21 -21
  51. data/lib/plurimath/version.rb +1 -1
  52. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9de48dbb937f65122d95415947e417692fc0d5a11d48e7a1caa1b54f3c4465bf
4
- data.tar.gz: 2f1e748929a2569b2e7b291381624648fc11a3fc2b93d44406a9a92c2fa21068
3
+ metadata.gz: f232ae9e7e95e99742976ce89205bd3a21269cfaf2df31941de6fbd9594aff9e
4
+ data.tar.gz: 93a5a1f1e6faf693ea589c17cb0429aaba81426c838ce9c993747c8db185beb4
5
5
  SHA512:
6
- metadata.gz: c8054b884f09d830a6b7a1e98d1c5679434540f6ad018c4135654f3ea4495336aa4971e43be842def4ad0fc139664ffa477c12407cef5553c55c46f9d0f2037d
7
- data.tar.gz: 852c85f6edab822fc8e880ceded6913283be3e65300069be0fd7a898b6d057bb1143fee9f1e5b182a9dee36213c564e11038cb38040b58586c5acbd16b0d063d
6
+ metadata.gz: 41e48748d0e213ee5910a6e5e6fcf2d012e87bc7a0731d1036b2e432e40677460c841fe50340763cf7c8778a9ac30ed91c2f1b6795b601bb2ad843f148a2cebc
7
+ data.tar.gz: 5262d5b7474b0544c82937e50e1b44342d2b2b64aa85adadf4b9a5ec0f9afbbfb23db8d45e514c25745c326c22aef8eae8321ad699a803e04ed084793c9d86e3
@@ -9,6 +9,13 @@ on:
9
9
  jobs:
10
10
  generate_docs:
11
11
  runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ filename:
15
+ - supported_parens_list.adoc
16
+ - supported_symbols_list.adoc
17
+ - intent_supported_classes.adoc
18
+
12
19
  steps:
13
20
  - uses: actions/checkout@v4
14
21
 
@@ -17,12 +24,7 @@ jobs:
17
24
  ruby-version: '3.3'
18
25
  bundler-cache: true
19
26
 
20
- - name: Generate supported_parens_list.adoc
21
- run: |
22
- rm -f supported_parens_list.adoc
23
- bundle exec rake supported_parens_list.adoc
24
-
25
- - name: Generate supported_symbols_list.adoc
27
+ - name: Generate documentation
26
28
  run: |
27
- rm -f supported_symbols_list.adoc
28
- bundle exec rake supported_symbols_list.adoc
29
+ rm -f ${{ matrix.filename }}
30
+ bundle exec rake ${{ matrix.filename }}
data/README.adoc CHANGED
@@ -583,6 +583,10 @@ Consult the following tables for details on supported symbols and parentheses:
583
583
  * link:supported_symbols_list.adoc[Symbols]
584
584
  * link:supported_parens_list.adoc[Parentheses]
585
585
 
586
+ The following table shows the classes that support MathML "intent" encoding:
587
+
588
+ * link:intent_supported_classes.adoc[Classes that support MathML Intent]
589
+
586
590
  NOTE: To regenerate these files, delete them and run:
587
591
  `bundle exec rake supported_symbols_list.adoc`.
588
592
 
data/Rakefile CHANGED
@@ -18,6 +18,7 @@ end
18
18
  DOC_FILES = {
19
19
  "supported_parens_list.adoc" => :paren,
20
20
  "supported_symbols_list.adoc" => :symbols,
21
+ "intent_supported_classes.adoc" => :intent,
21
22
  }.freeze
22
23
 
23
24
  DOC_FILES.each do |file_name, type|
@@ -28,17 +29,26 @@ end
28
29
 
29
30
  def write_doc_file(doc_file, type:)
30
31
  File.open(doc_file, "a") do |file|
31
- file.write(file_header)
32
-
33
- Plurimath::Utility.send(:"#{type}_files").each do |klass|
34
- next if klass::INPUT.empty?
35
-
36
- file_name = File.basename(klass.const_source_location(:INPUT).first, ".rb")
37
- file.write(documentation_content(file_name, klass))
32
+ case type
33
+ when :intent
34
+ write_intent_doc_file(file)
35
+ else
36
+ paren_symbols_doc(file, type)
38
37
  end
38
+ end
39
+ end
40
+
41
+ def paren_symbols_doc(file, type)
42
+ file.write(file_header)
39
43
 
40
- file.write("|===")
44
+ Plurimath::Utility.send(:"#{type}_files").each do |klass|
45
+ next if klass::INPUT.empty?
46
+
47
+ file_name = File.basename(klass.const_source_location(:INPUT).first, ".rb")
48
+ file.write(documentation_content(file_name, klass))
41
49
  end
50
+
51
+ file.write("|===")
42
52
  end
43
53
 
44
54
  def documentation_content(file_name, klass)
@@ -75,4 +85,41 @@ def format_input(format, klass)
75
85
  end.join(", ").gsub(/\|/, "\\|")
76
86
  end
77
87
 
88
+ def write_intent_doc_file(file)
89
+ file.write("= List of classes supporting `intent` encoding with relevant values\n")
90
+
91
+ intent_classes.each do |klass|
92
+ intents = klass.new.intent_names.values.map do |intent|
93
+ "`#{intent}`"
94
+ end
95
+
96
+ file.write(
97
+ <<~INTENT
98
+
99
+ * `#{klass.name.gsub("Plurimath::Math::", "")}`
100
+ ** #{intents.join("\n** ")}
101
+ INTENT
102
+ )
103
+ end
104
+
105
+ file.write("\nIntent for unary classes like, sin, cos, tan, etc. will be `Function`.\n")
106
+ end
107
+
108
+ def intent_classes
109
+ intent_classes = [
110
+ Plurimath::Math::Function::TernaryFunction.descendants,
111
+ Plurimath::Math::Function::BinaryFunction.descendants,
112
+ Plurimath::Math::Function::UnaryFunction.descendants,
113
+ Plurimath::Math::Function::Table.descendants,
114
+ Plurimath::Math::Symbols::Symbol.descendants,
115
+ Plurimath::Math::Function::UnaryFunction,
116
+ Plurimath::Math::Function::Table,
117
+ Plurimath::Math::Function::Nary,
118
+ Plurimath::Math::Formula,
119
+ ].flatten
120
+ intent_classes.select do |klass|
121
+ klass.instance_methods(false).include?(:intent_names)
122
+ end
123
+ end
124
+
78
125
  task :default => :spec
@@ -0,0 +1,82 @@
1
+ = List of classes supporting `intent` encoding with relevant values
2
+
3
+ * `Function::Fenced`
4
+ ** `open-closed-interval`
5
+ ** `closed-open-interval`
6
+ ** `binomial-coefficient`
7
+ ** `closed-interval`
8
+ ** `open-interval`
9
+ ** `:fenced`
10
+
11
+ * `Function::Int`
12
+ ** `:integral`
13
+
14
+ * `Function::Oint`
15
+ ** `:contour integral`
16
+
17
+ * `Function::Prod`
18
+ ** `:product`
19
+
20
+ * `Function::Sum`
21
+ ** `:sum`
22
+
23
+ * `Function::Frac`
24
+ ** `:derivative`
25
+ ** `:partial-derivative`
26
+
27
+ * `Function::Inf`
28
+ ** `:function`
29
+
30
+ * `Function::Intent`
31
+ ** `:derivative`
32
+
33
+ * `Function::Lim`
34
+ ** `:function`
35
+
36
+ * `Function::Abs`
37
+ ** `absolute-value`
38
+
39
+ * `Symbols::Dd`
40
+ ** `ⅆ`
41
+
42
+ * `Symbols::Ii`
43
+ ** `ⅈ`
44
+
45
+ * `Symbols::Intercal`
46
+ ** `transpose`
47
+
48
+ * `Symbols::Jj`
49
+ ** `ⅉ`
50
+
51
+ * `Symbols::UpcaseDd`
52
+ ** `ⅅ`
53
+
54
+ * `Function::UnaryFunction`
55
+ ** `:function`
56
+
57
+ * `Function::Table`
58
+ ** `:curly-braced-matrix`
59
+ ** `:parenthesized-matrix`
60
+ ** `:bracketed-matrix`
61
+ ** `:normed-matrix`
62
+ ** `:determinant`
63
+ ** `:equations`
64
+ ** `:cases`
65
+
66
+ * `Function::Nary`
67
+ ** `:n-ary`
68
+ ** `:anticlockwise contour integral`
69
+ ** `:coproduct`
70
+ ** `:quadruple integral`
71
+ ** `:triple integral`
72
+ ** `:double integral`
73
+ ** `:clockwise contour integral`
74
+ ** `:volume integral`
75
+ ** `:surface integral`
76
+ ** `:contour integral`
77
+
78
+ * `Formula`
79
+ ** `:partial-derivative`
80
+ ** `:derivative`
81
+
82
+ Intent for unary classes like, sin, cos, tan, etc. will be `Function`.
@@ -3,7 +3,7 @@
3
3
  module Plurimath
4
4
  module Formatter
5
5
  class NumberFormatter
6
- attr_reader :number, :data_reader
6
+ attr_reader :number, :data_reader, :prefix
7
7
 
8
8
  STRING_SYMBOLS = {
9
9
  dot: ".".freeze,
@@ -13,6 +13,7 @@ module Plurimath
13
13
  def initialize(number, data_reader = {})
14
14
  @number = number
15
15
  @data_reader = data_reader
16
+ @prefix = "-" if number.negative?
16
17
  end
17
18
 
18
19
  def format(precision: nil)
@@ -20,16 +21,15 @@ module Plurimath
20
21
  int, frac, integer_format, fraction_format, signif_format = *partition_tokens(number)
21
22
  result = integer_format.apply(int, data_reader)
22
23
  result << fraction_format.apply(frac, data_reader, int) if frac
23
-
24
24
  result = signif_format.apply(result, integer_format, fraction_format)
25
-
26
- result
25
+ result = "+#{result}" if number.positive? && data_reader[:number_sign] == :plus
26
+ "#{prefix}#{result}"
27
27
  end
28
28
 
29
29
  private
30
30
 
31
31
  def partition_tokens(number)
32
- int, fraction = parse_number(number, data_reader)
32
+ int, fraction = parse_number(number)
33
33
  [
34
34
  int,
35
35
  fraction,
@@ -46,7 +46,7 @@ module Plurimath
46
46
  parts.size == 2 ? parts[1].size : 0
47
47
  end
48
48
 
49
- def parse_number(number, options = {})
49
+ def parse_number(number, options = data_reader)
50
50
  precision = options[:precision] || precision_from(number)
51
51
 
52
52
  num = if precision == 0
@@ -72,7 +72,9 @@ module Plurimath
72
72
 
73
73
  def update_exponent_value(number_str)
74
74
  exponent_number = BigDecimal(number_str) - 1
75
- "#{"+" if @exponent_sign == :plus}#{exponent_number.to_i}"
75
+ return exponent_number.to_i if exponent_number.negative? || @exponent_sign != :plus
76
+
77
+ "+#{exponent_number.to_i}"
76
78
  end
77
79
 
78
80
  def notation_chars(num_str)
@@ -112,7 +114,8 @@ module Plurimath
112
114
 
113
115
  chars.first.delete!(".")
114
116
  chars.first.insert(index + 1, ".") unless chars.first[index + 2].nil?
115
- chars[-1] = (chars[-1].to_i - index).to_s
117
+ exponent = chars[-1]
118
+ chars[-1] = "#{"+" if exponent.to_s.start_with?("+")}#{exponent.to_i - index}"
116
119
  end
117
120
  end
118
121
  end
@@ -10,6 +10,7 @@ module Plurimath
10
10
  fraction_group_digits: 3,
11
11
  exponent_sign: "plus",
12
12
  fraction_group: "'",
13
+ number_sign: "plus",
13
14
  notation: :basic,
14
15
  group_digits: 3,
15
16
  significant: 0,
@@ -38,6 +39,7 @@ module Plurimath
38
39
  options[:fraction_group] ||= default_options[:fraction_group]
39
40
  options[:exponent_sign] ||= default_options[:exponent_sign]
40
41
  options[:group_digits] ||= default_options[:group_digits]
42
+ options[:number_sign] ||= default_options[:number_sign]
41
43
  options[:significant] ||= default_options[:significant]
42
44
  options[:notation] ||= default_options[:notation]
43
45
  options[:decimal] ||= default_options[:decimal]
@@ -344,10 +344,10 @@ module Plurimath
344
344
  ox_element("mrow") << xml_engine_node
345
345
  end
346
346
 
347
- def intentify(tag, intent, func_name:, intent_name: nil)
347
+ def intentify(tag, intent, func_name:, intent_name: nil, options: {})
348
348
  return tag unless intent
349
349
 
350
- Utility::IntentEncoding.send("#{func_name}_intent", tag, intent_name)
350
+ Utility::IntentEncoding.send("#{func_name}_intent", tag, intent_name, options)
351
351
  end
352
352
 
353
353
  def masked_tag(tag)
@@ -297,6 +297,13 @@ module Plurimath
297
297
  true if value&.first&.mini_sized?
298
298
  end
299
299
 
300
+ def intent_names
301
+ {
302
+ partial_derivative: ":partial-derivative",
303
+ derivative: ":derivative",
304
+ }
305
+ end
306
+
300
307
  protected
301
308
 
302
309
  def boolean_display_style(display_style = displaystyle)
@@ -489,7 +496,7 @@ module Plurimath
489
496
  prime_str = encode(nodes.last.nodes.first) if valid_prime?(nodes.last)
490
497
  second_arg.insert(-1, prime_str) unless second_arg.match?(/[0-9]$/)
491
498
  end
492
- ":partial-derivative(#{first_arg},$f,#{second_arg})"
499
+ "#{intent_names[:partial_derivative]}(#{first_arg},$f,#{second_arg})"
493
500
  end
494
501
 
495
502
  def f_arg(tag_nodes, index)
@@ -561,7 +568,7 @@ module Plurimath
561
568
  end
562
569
  break
563
570
  end
564
- intent_name = ":derivative(1,#{second_arg},#{third_arg})"
571
+ intent_name = "#{intent_names[:derivative]}(1,#{second_arg},#{third_arg})"
565
572
  mrow = ox_element("mrow", attributes: { intent: intent_name })
566
573
  nodes.insert(0, Utility.update_nodes(mrow, mrow_nodes))
567
574
  end
@@ -576,7 +583,7 @@ module Plurimath
576
583
 
577
584
  if DERIVATIVE_CONSTS.include?(node.nodes[0]&.nodes&.first)
578
585
  iteration += 1
579
- node["intent"] = ":derivative#{derivative_intent_name(node.nodes[1], nodes[iteration..-1], type: node.name)}"
586
+ node["intent"] = "#{intent_names[:derivative]}#{derivative_intent_name(node.nodes[1], nodes[iteration..-1], type: node.name)}"
580
587
  next_node = nodes[iteration]
581
588
  case next_node.name
582
589
  when "mi", "mrow"
@@ -14,7 +14,7 @@ module Plurimath
14
14
  first_value = first_value&.insert(0, symbol) unless open_paren
15
15
  first_value << symbol unless close_paren
16
16
  mrow = Utility.update_nodes(ox_element("mrow"), first_value)
17
- intentify(mrow, intent, func_name: :abs, intent_name: :"absolute-value")
17
+ intentify(mrow, intent, func_name: :abs, intent_name: intent_names[:name])
18
18
  end
19
19
 
20
20
  def to_omml_without_math_tag(display_style, options:)
@@ -39,6 +39,10 @@ module Plurimath
39
39
  "⒜#{unicodemath_parens(parameter_one, options: options)}"
40
40
  end
41
41
 
42
+ def intent_names
43
+ { name: "absolute-value" }
44
+ end
45
+
42
46
  protected
43
47
 
44
48
  def md_tag
@@ -39,6 +39,7 @@ module Plurimath
39
39
  intent,
40
40
  func_name: :interval_fence,
41
41
  intent_name: intent_value(mrow_value, options: options),
42
+ options: intent_names,
42
43
  )
43
44
  end
44
45
 
@@ -145,6 +146,17 @@ module Plurimath
145
146
  "#{parameter_one.to_unicodemath(options: options)}#{fenced_value}#{parameter_three.to_unicodemath(options: options)}"
146
147
  end
147
148
 
149
+ def intent_names
150
+ {
151
+ open_closed_interval: "open-closed-interval",
152
+ closed_open_interval: "closed-open-interval",
153
+ binomial_coefficient: "binomial-coefficient",
154
+ closed_interval: "closed-interval",
155
+ open_interval: "open-interval",
156
+ fenced: ":fenced",
157
+ }
158
+ end
159
+
148
160
  protected
149
161
 
150
162
  def open_paren(dpr, options:)
@@ -253,11 +265,11 @@ module Plurimath
253
265
  end
254
266
 
255
267
  def intent_value(value, options:)
256
- return "binomial-coefficient" if binomial_coefficient?(value)
268
+ return :binomial_coefficient if binomial_coefficient?(value)
257
269
 
258
270
  open_paren = symbol_or_paren(parameter_one, lang: :latex, options: options)
259
271
  close_paren = symbol_or_paren(parameter_three, lang: :latex, options: options)
260
- return "fenced" unless interval_intent?(value, open_paren, close_paren)
272
+ return :fenced unless interval_intent?(value, open_paren, close_paren)
261
273
 
262
274
  interval_intent(value, open_paren, close_paren)
263
275
  end
@@ -270,15 +282,15 @@ module Plurimath
270
282
  def interval_intent(value, open_paren, close_paren)
271
283
  case open_paren
272
284
  when "("
273
- 'open-closed-interval' if close_paren == ']'
285
+ :open_closed_interval if close_paren == ']'
274
286
  when "["
275
- return 'closed-interval' if close_paren == ']'
287
+ return :closed_interval if close_paren == ']'
276
288
 
277
- 'closed-open-interval' if (close_paren == '[' || close_paren == ')')
289
+ :closed_open_interval if (close_paren == '[' || close_paren == ')')
278
290
  when "]"
279
- return 'open-closed-interval' if close_paren == ']'
291
+ return :open_closed_interval if close_paren == ']'
280
292
 
281
- 'open-interval' if close_paren == '['
293
+ :open_interval if close_paren == '['
282
294
  end
283
295
  end
284
296
 
@@ -41,7 +41,7 @@ module Plurimath
41
41
  frac_tag.set_attr(self.options.reject { |opt| opt == :choose }) if tag_name == "mfrac" && self.options
42
42
  Utility.update_nodes(frac_tag, mathml_value)
43
43
  update_derivative(frac_tag, mathml_value[0], mathml_value[1]) if intent
44
- intentify(frac_tag, intent, func_name: :frac)
44
+ intentify(frac_tag, intent, func_name: :frac, options: intent_names)
45
45
  end
46
46
 
47
47
  def to_latex(options:)
@@ -98,6 +98,13 @@ module Plurimath
98
98
  "#{first_value}⒞#{second_value}"
99
99
  end
100
100
 
101
+ def intent_names
102
+ {
103
+ derivative: ":derivative",
104
+ partial_derivative: ":partial-derivative",
105
+ }
106
+ end
107
+
101
108
  protected
102
109
 
103
110
  def fpr_element
@@ -36,7 +36,7 @@ module Plurimath
36
36
  parameter_two&.to_mathml_without_math_tag(intent, options: options),
37
37
  ],
38
38
  )
39
- intentify(inf_tag, intent, func_name: :function, intent_name: :function)
39
+ intentify(inf_tag, intent, func_name: :function, intent_name: intent_names[:name])
40
40
  end
41
41
 
42
42
  def to_omml_without_math_tag(display_style, options:)
@@ -57,6 +57,10 @@ module Plurimath
57
57
  "inf#{sub_value(options: options)}#{sup_value(options: options)}"
58
58
  end
59
59
 
60
+ def intent_names
61
+ { name: ":function" }
62
+ end
63
+
60
64
  protected
61
65
 
62
66
  def sup_value(options:)
@@ -62,7 +62,7 @@ module Plurimath
62
62
  wrap_mrow(parameter_three&.to_mathml_without_math_tag(intent, options: options), intent),
63
63
  ].flatten.compact,
64
64
  )
65
- intentify(mrow, intent, func_name: :naryand, intent_name: :integral)
65
+ intentify(mrow, intent, func_name: :naryand, intent_name: intent_names[:name])
66
66
  end
67
67
 
68
68
  def to_omml_without_math_tag(display_style, options:)
@@ -116,6 +116,10 @@ module Plurimath
116
116
  true
117
117
  end
118
118
 
119
+ def intent_names
120
+ { name: ":integral" }
121
+ end
122
+
119
123
  protected
120
124
 
121
125
  def sup_value(options:)
@@ -17,15 +17,19 @@ module Plurimath
17
17
  "ⓘ#{first_value}"
18
18
  end
19
19
 
20
+ def intent_names
21
+ { name: ":derivative" }
22
+ end
23
+
20
24
  private
21
25
 
22
26
  def encoded_intent(tag)
23
- if parameter_two.value == ":derivative" && encodable?
27
+ if parameter_two.value == intent_names[:name] && encodable?
24
28
  field = parameter_one.value
25
29
  unicode = encode(field[0].parameter_one.value)
26
30
  unfenced_str = fence_value(tag.nodes[1].nodes[1..-2]) if tag.nodes[1]["intent"] == ":fenced"
27
31
  fenced_str = "(#{unfenced_str})" unless unfenced_str.empty?
28
- ":derivative(1,#{unicode}#{fenced_str},#{unfenced_str})"
32
+ "#{intent_names[:name]}(1,#{unicode}#{fenced_str},#{unfenced_str})"
29
33
  else
30
34
  Utility.html_entity_to_unicode(parameter_two.value)
31
35
  end
@@ -42,7 +42,7 @@ module Plurimath
42
42
  parameter_two&.to_mathml_without_math_tag(intent, options: options),
43
43
  ],
44
44
  )
45
- intentify(lim_tag, intent, func_name: :function, intent_name: :function)
45
+ intentify(lim_tag, intent, func_name: :function, intent_name: intent_names[:name])
46
46
  end
47
47
 
48
48
  def to_omml_without_math_tag(display_style, options:)
@@ -64,6 +64,10 @@ module Plurimath
64
64
  self.parameter_two = nil
65
65
  end
66
66
  end
67
+
68
+ def intent_names
69
+ { name: ":function" }
70
+ end
67
71
  end
68
72
  end
69
73
  end
@@ -124,6 +124,17 @@ module Plurimath
124
124
  end
125
125
  end
126
126
 
127
+ def intent_names
128
+ @@names ||= Symbols::Symbol.descendants.map.with_object({}) do |symbol, hash|
129
+ sym_instance = symbol.new
130
+ next unless sym_instance.is_nary_symbol?
131
+
132
+ intent_name = sym_instance.nary_intent_name
133
+ next pp symbol.const_source_location(:INPUT) if intent_name.nil?
134
+ hash[intent_name.gsub(/\s|-/, '_').to_sym] = intent_name
135
+ end
136
+ end
137
+
127
138
  protected
128
139
 
129
140
  def chr_value(narypr, options:)
@@ -197,8 +208,9 @@ module Plurimath
197
208
  end
198
209
  end
199
210
 
211
+ # Function calling intent name for a specific symbol
200
212
  def intent_name
201
- return "n-ary" unless parameter_one&.is_nary_symbol?
213
+ return ":n-ary" unless parameter_one&.is_nary_symbol?
202
214
 
203
215
  parameter_one.nary_intent_name
204
216
  end
@@ -119,6 +119,10 @@ module Plurimath
119
119
  true
120
120
  end
121
121
 
122
+ def intent_names
123
+ { name: ":contour integral"}
124
+ end
125
+
122
126
  private
123
127
 
124
128
  def ternary_intentify(tag, intent)
@@ -126,7 +130,7 @@ module Plurimath
126
130
  tag,
127
131
  intent,
128
132
  func_name: :naryand,
129
- intent_name: "contour integral",
133
+ intent_name: intent_names[:name],
130
134
  )
131
135
  end
132
136
  end
@@ -116,6 +116,10 @@ module Plurimath
116
116
  true
117
117
  end
118
118
 
119
+ def intent_names
120
+ { name: ":product" }
121
+ end
122
+
119
123
  private
120
124
 
121
125
  def sup_value(options:)
@@ -152,7 +156,7 @@ module Plurimath
152
156
  tag,
153
157
  intent,
154
158
  func_name: :naryand,
155
- intent_name: :product,
159
+ intent_name: intent_names[:name],
156
160
  )
157
161
  end
158
162
  end
@@ -122,6 +122,10 @@ module Plurimath
122
122
  true
123
123
  end
124
124
 
125
+ def intent_names
126
+ { name: ":sum"}
127
+ end
128
+
125
129
  private
126
130
 
127
131
  def sum_tag
@@ -138,7 +142,7 @@ module Plurimath
138
142
  tag,
139
143
  intent,
140
144
  func_name: :naryand,
141
- intent_name: :sum,
145
+ intent_name: intent_names[:name],
142
146
  )
143
147
  end
144
148
  end
@@ -42,7 +42,7 @@ module Plurimath
42
42
  def attributes(intent)
43
43
  return table_attribute unless intent
44
44
 
45
- table_attribute.merge(intent: ":equations")
45
+ table_attribute.merge(intent: intent_names[:equations])
46
46
  end
47
47
  end
48
48
  end
@@ -54,7 +54,7 @@ module Plurimath
54
54
  return {} unless intent
55
55
 
56
56
  {
57
- intent: capital_bmatrix? ? ":curly-braced-matrix" : ":bracketed-matrix"
57
+ intent: intent_names.dig(capital_bmatrix? ? :curly_braced_matrix : :bracketed_matrix)
58
58
  }
59
59
  end
60
60
  end
@@ -22,7 +22,7 @@ module Plurimath
22
22
  def to_mathml_without_math_tag(intent, **)
23
23
  table_tag = super
24
24
  set_table_intent(table_tag) if intent
25
- table_tag.attributes["intent"] = ":equations" if intent
25
+ table_tag.attributes["intent"] = intent_names[:equations] if intent
26
26
  table_tag
27
27
  end
28
28
 
@@ -30,7 +30,7 @@ module Plurimath
30
30
 
31
31
  def set_table_intent(tag)
32
32
  table = tag.nodes.find { |tag| tag.name == "mtable" }
33
- table["intent"] = ":cases"
33
+ table["intent"] = intent_names[:cases]
34
34
  end
35
35
  end
36
36
  end
@@ -22,7 +22,7 @@ module Plurimath
22
22
  def to_mathml_without_math_tag(intent, **)
23
23
  matrix = super
24
24
  set_table_intent(matrix) if intent
25
- matrix["intent"] = ":equations" if intent
25
+ matrix["intent"] = intent_names[:equations] if intent
26
26
  matrix
27
27
  end
28
28
 
@@ -32,7 +32,7 @@ module Plurimath
32
32
  matrix = tag.nodes.find { |tag| tag.name == "mtable" }
33
33
  return unless matrix
34
34
 
35
- matrix["intent"] = ":cases"
35
+ matrix["intent"] = intent_names[:cases]
36
36
  end
37
37
  end
38
38
  end
@@ -25,7 +25,7 @@ module Plurimath
25
25
 
26
26
  def to_mathml_without_math_tag(intent, **)
27
27
  matrix = super
28
- matrix["intent"] = ":parenthesized-matrix" if intent
28
+ matrix["intent"] = intent_names[:parenthesized_matrix] if intent
29
29
  matrix
30
30
  end
31
31
  end
@@ -40,7 +40,7 @@ module Plurimath
40
40
  end
41
41
 
42
42
  def intent_attr_value(intent)
43
- capital_vmatrix? ? ":normed-matrix" : ":determinant"
43
+ intent_names.dig(capital_vmatrix? ? :normed_matrix : :determinant)
44
44
  end
45
45
  end
46
46
  end
@@ -125,6 +125,18 @@ module Plurimath
125
125
  ]
126
126
  end
127
127
 
128
+ def intent_names
129
+ {
130
+ curly_braced_matrix: ":curly-braced-matrix",
131
+ parenthesized_matrix: ":parenthesized-matrix",
132
+ bracketed_matrix: ":bracketed-matrix",
133
+ normed_matrix: ":normed-matrix",
134
+ determinant: ":determinant",
135
+ equations: ":equations",
136
+ cases: ":cases",
137
+ }
138
+ end
139
+
128
140
  protected
129
141
 
130
142
  def mathml_parenthesis(field, intent, options:)
@@ -35,7 +35,7 @@ module Plurimath
35
35
  new_arr += mathml_value(intent, options: options)
36
36
  mrow = ox_element("mrow")
37
37
  Utility.update_nodes(mrow, new_arr)
38
- intentify(mrow, intent, func_name: :function, intent_name: :function)
38
+ intentify(mrow, intent, func_name: :function, intent_name: intent_names[:name])
39
39
  else
40
40
  new_arr.first
41
41
  end
@@ -153,6 +153,10 @@ module Plurimath
153
153
  !parameter_one
154
154
  end
155
155
 
156
+ def intent_names
157
+ { name: ":function" }
158
+ end
159
+
156
160
  protected
157
161
 
158
162
  def asciimath_value(options:)
@@ -36,6 +36,10 @@ module Plurimath
36
36
  "&#x22c0;"
37
37
  end
38
38
 
39
+ def nary_intent_name
40
+ ":n-ary"
41
+ end
42
+
39
43
  def is_nary_symbol?
40
44
  true
41
45
  end
@@ -35,10 +35,6 @@ module Plurimath
35
35
  def to_html(**)
36
36
  "&#x2229;"
37
37
  end
38
-
39
- def is_nary_symbol?
40
- true
41
- end
42
38
  end
43
39
  end
44
40
  end
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "n-ary"
44
+ ":n-ary"
45
45
  end
46
46
 
47
47
  def tag_name
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "anticlockwise contour integral"
44
+ ":anticlockwise contour integral"
45
45
  end
46
46
 
47
47
  def tag_name
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "coproduct"
44
+ ":coproduct"
45
45
  end
46
46
  end
47
47
  end
@@ -37,6 +37,10 @@ module Plurimath
37
37
  "&#x2146;"
38
38
  end
39
39
 
40
+ def intent_names
41
+ { name: encoded }
42
+ end
43
+
40
44
  private
41
45
 
42
46
  def encoded
@@ -36,6 +36,10 @@ module Plurimath
36
36
  "&#x22c2;"
37
37
  end
38
38
 
39
+ def nary_intent_name
40
+ ":n-ary"
41
+ end
42
+
39
43
  def is_nary_symbol?
40
44
  true
41
45
  end
@@ -36,6 +36,10 @@ module Plurimath
36
36
  "&#x22c3;"
37
37
  end
38
38
 
39
+ def nary_intent_name
40
+ ":n-ary"
41
+ end
42
+
39
43
  def is_nary_symbol?
40
44
  true
41
45
  end
@@ -37,6 +37,10 @@ module Plurimath
37
37
  "&#x2148;"
38
38
  end
39
39
 
40
+ def intent_names
41
+ { name: encoded }
42
+ end
43
+
40
44
  private
41
45
 
42
46
  def encoded
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "quadruple integral"
44
+ ":quadruple integral"
45
45
  end
46
46
  end
47
47
  end
@@ -36,6 +36,10 @@ module Plurimath
36
36
  "&#x222d;"
37
37
  end
38
38
 
39
+ def nary_intent_name
40
+ ":triple integral"
41
+ end
42
+
39
43
  def is_nary_symbol?
40
44
  true
41
45
  end
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "double integral"
44
+ ":double integral"
45
45
  end
46
46
  end
47
47
  end
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "clockwise contour integral"
44
+ ":clockwise contour integral"
45
45
  end
46
46
 
47
47
  def tag_name
@@ -36,6 +36,10 @@ module Plurimath
36
36
  def to_html(**)
37
37
  "&#x22ba;"
38
38
  end
39
+
40
+ def intent_names
41
+ { name: "transpose" }
42
+ end
39
43
  end
40
44
  end
41
45
  end
@@ -37,6 +37,10 @@ module Plurimath
37
37
  "&#x2149;"
38
38
  end
39
39
 
40
+ def intent_names
41
+ { name: encoded }
42
+ end
43
+
40
44
  private
41
45
 
42
46
  def encoded
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "volume integral"
44
+ ":volume integral"
45
45
  end
46
46
 
47
47
  def tag_name
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "surface integral"
44
+ ":surface integral"
45
45
  end
46
46
 
47
47
  def tag_name
@@ -41,7 +41,7 @@ module Plurimath
41
41
  end
42
42
 
43
43
  def nary_intent_name
44
- "contour integral"
44
+ ":contour integral"
45
45
  end
46
46
 
47
47
  def tag_name
@@ -37,6 +37,10 @@ module Plurimath
37
37
  "&#x2145;"
38
38
  end
39
39
 
40
+ def intent_names
41
+ { name: encoded }
42
+ end
43
+
40
44
  private
41
45
 
42
46
  def encoded
@@ -245,6 +245,8 @@ module Plurimath
245
245
  elsif Constants::CLASSES.any?(mover&.last&.class_name)
246
246
  mover.last.parameter_one = mover.shift if mover.length > 1
247
247
  mover.last
248
+ elsif mover&.last&.class_name == "period" && mover.length == 2
249
+ Math::Function::Dot.new(mover[0])
248
250
  else
249
251
  Math::Function::Overset.new(mover[1], mover[0])
250
252
  end
@@ -19,21 +19,21 @@ module Plurimath
19
19
  # Intent common code end
20
20
 
21
21
  # Naryand intent begin
22
- def naryand_intent(field, intent_name)
23
- return nary_intent(field, intent_name) if field.name == "mrow"
22
+ def naryand_intent(field, intent_name, options)
23
+ return nary_intent(field, intent_name, options) if field.name == "mrow"
24
24
 
25
25
  base, power = power_base_intent(field)
26
26
  base, power = power_or_base_intent(field) unless base && power
27
- field["intent"] = ":#{intent_name}(#{base},#{power})"
27
+ field["intent"] = "#{intent_name}(#{base},#{power})"
28
28
  field
29
29
  end
30
30
 
31
- def nary_intent(field, intent_name)
31
+ def nary_intent(field, intent_name, _)
32
32
  sub_sup = field.nodes[0]
33
33
  base, power = power_base_intent(sub_sup)
34
34
  base, power = power_or_base_intent(sub_sup) unless base || power
35
35
  naryand = node_value(field.nodes[1], "naryand")
36
- field["intent"] = ":#{intent_name}(#{base},#{power},#{naryand})"
36
+ field["intent"] = "#{intent_name}(#{base},#{power},#{naryand})"
37
37
  field
38
38
  end
39
39
  # Naryand intent end
@@ -57,14 +57,14 @@ module Plurimath
57
57
  # SubSup intent end
58
58
 
59
59
  # Function intent begin
60
- def function_intent(tag, intent_name = "function")
61
- tag.attributes["intent"] = ":#{intent_name}"
60
+ def function_intent(tag, intent_name = ":function", _)
61
+ tag.attributes["intent"] = intent_name
62
62
  tag
63
63
  end
64
64
  # Function intent end
65
65
 
66
66
  # Binomial fraction intent begin
67
- def binomial_fraction_intent(tag, intent_name)
67
+ def binomial_fraction_intent(tag, intent_name, _)
68
68
  numerator = node_value(tag.nodes[1].nodes[0], "t")
69
69
  denominator = node_value(tag.nodes[1].nodes[1], "b")
70
70
  tag["intent"] = "#{intent_name}(#{numerator},#{denominator})"
@@ -73,30 +73,31 @@ module Plurimath
73
73
  # Binomial fraction intent end
74
74
 
75
75
  # Interval fence intent begin
76
- def interval_fence_intent(tag, intent_name)
77
- return function_intent(tag, intent_name) if intent_name == "fenced"
78
- return binomial_fraction_intent(tag, intent_name) if intent_name == "binomial-coefficient"
76
+ def interval_fence_intent(tag, intent_name, options)
77
+ intent = options[intent_name]
78
+ return function_intent(tag, intent, options) if intent_name == :fenced
79
+ return binomial_fraction_intent(tag, intent, options) if intent_name == :binomial_coefficient
79
80
 
80
81
  first_value = fence_node_value(tag.nodes[1], "a")
81
82
  second_value = fence_node_value(tag.nodes[3], "b")
82
- tag["intent"] = "#{intent_name}(#{first_value},#{second_value})"
83
+ tag["intent"] = "#{intent}(#{first_value},#{second_value})"
83
84
  tag
84
85
  end
85
86
  # Interval fence intent end
86
87
 
87
88
  # Frac derivative intent begin
88
- def frac_intent(tag, intent_name)
89
+ def frac_intent(tag, _, options)
89
90
  num = tag.nodes[0]
90
91
  den = tag.nodes[1]
91
- return partial_derivative(tag) if partial_derivative?(num, den)
92
- return derivative(tag) if derivative?(num, den)
92
+ return partial_derivative(tag, options[:partial_derivative]) if partial_derivative?(num, den)
93
+ return derivative(tag, options[:derivative]) if derivative?(num, den)
93
94
 
94
95
  tag
95
96
  end
96
97
  # Frac derivative intent end
97
98
 
98
99
  # Abs intent begin
99
- def abs_intent(tag, intent_name)
100
+ def abs_intent(tag, intent_name, _options)
100
101
  tag["intent"] = "#{intent_name}(#{node_value(tag.nodes[1], 'a')})"
101
102
  tag
102
103
  end
@@ -156,9 +157,9 @@ module Plurimath
156
157
  found_node&.nodes[1]
157
158
  end
158
159
 
159
- def partial_derivative(node)
160
+ def partial_derivative(node, intent_name)
160
161
  intent = "(#{partial_arg(node)},#{f_arg(node&.nodes[0])},#{den_arg(node&.nodes[1])})"
161
- node["intent"] = ":partial-derivative#{intent}"
162
+ node["intent"] = intent_name + intent
162
163
  node
163
164
  end
164
165
 
@@ -255,11 +256,10 @@ module Plurimath
255
256
  node.nodes.length >= 2
256
257
  end
257
258
 
258
- def derivative(node)
259
+ def derivative(node, intent_name)
259
260
  num = node.nodes[0]
260
261
  den = node.nodes[1]
261
- intent_name = ":derivative(1,#{num_arg(num)},#{derivative_den_arg(den)})"
262
- node["intent"] = intent_name
262
+ node["intent"] = "#{intent_name}(1,#{num_arg(num)},#{derivative_den_arg(den)})"
263
263
  node
264
264
  end
265
265
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.8.16"
4
+ VERSION = "0.8.17"
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.8.16
4
+ version: 0.8.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-30 00:00:00.000000000 Z
11
+ date: 2024-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -95,6 +95,7 @@ files:
95
95
  - bin/console
96
96
  - bin/setup
97
97
  - exe/plurimath
98
+ - intent_supported_classes.adoc
98
99
  - lib/plurimath.rb
99
100
  - lib/plurimath/asciimath.rb
100
101
  - lib/plurimath/asciimath/constants.rb