plurimath 0.8.16 → 0.8.17

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 (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