plurimath 0.2.1 → 0.2.2

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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +13 -0
  3. data/.github/workflows/release.yml +22 -0
  4. data/.hound.yml +5 -0
  5. data/.rubocop.yml +8 -0
  6. data/AsciiMath-Supported-Data.adoc +1994 -274
  7. data/Gemfile +2 -0
  8. data/Latex-Supported-Data.adoc +1875 -1868
  9. data/MathML-Supported-Data.adoc +280 -263
  10. data/README.adoc +22 -20
  11. data/lib/plurimath/asciimath/constants.rb +186 -141
  12. data/lib/plurimath/asciimath/parse.rb +104 -39
  13. data/lib/plurimath/asciimath/parser.rb +3 -1
  14. data/lib/plurimath/asciimath/transform.rb +1074 -238
  15. data/lib/plurimath/html/parse.rb +1 -1
  16. data/lib/plurimath/latex/constants.rb +3228 -1432
  17. data/lib/plurimath/latex/parse.rb +106 -83
  18. data/lib/plurimath/latex/parser.rb +11 -4
  19. data/lib/plurimath/latex/transform.rb +354 -99
  20. data/lib/plurimath/math/base.rb +15 -0
  21. data/lib/plurimath/math/formula.rb +90 -13
  22. data/lib/plurimath/math/function/bar.rb +35 -1
  23. data/lib/plurimath/math/function/base.rb +25 -4
  24. data/lib/plurimath/math/function/binary_function.rb +101 -19
  25. data/lib/plurimath/math/function/cancel.rb +8 -0
  26. data/lib/plurimath/math/function/ceil.rb +3 -0
  27. data/lib/plurimath/math/function/color.rb +15 -5
  28. data/lib/plurimath/math/function/f.rb +8 -0
  29. data/lib/plurimath/math/function/fenced.rb +95 -8
  30. data/lib/plurimath/math/function/floor.rb +15 -0
  31. data/lib/plurimath/math/function/font_style/bold.rb +19 -0
  32. data/lib/plurimath/math/function/font_style/double_struck.rb +19 -0
  33. data/lib/plurimath/math/function/font_style/fraktur.rb +19 -0
  34. data/lib/plurimath/math/function/font_style/italic.rb +37 -0
  35. data/lib/plurimath/math/function/font_style/monospace.rb +19 -0
  36. data/lib/plurimath/math/function/font_style/normal.rb +37 -0
  37. data/lib/plurimath/math/function/font_style/sans-serif.rb +19 -0
  38. data/lib/plurimath/math/function/font_style/script.rb +19 -0
  39. data/lib/plurimath/math/function/font_style.rb +18 -5
  40. data/lib/plurimath/math/function/frac.rb +33 -3
  41. data/lib/plurimath/math/function/g.rb +7 -0
  42. data/lib/plurimath/math/function/hat.rb +12 -0
  43. data/lib/plurimath/math/function/inf.rb +21 -0
  44. data/lib/plurimath/math/function/int.rb +23 -2
  45. data/lib/plurimath/math/function/left.rb +25 -1
  46. data/lib/plurimath/math/function/lim.rb +40 -2
  47. data/lib/plurimath/math/function/limits.rb +9 -0
  48. data/lib/plurimath/math/function/log.rb +55 -4
  49. data/lib/plurimath/math/function/longdiv.rb +12 -0
  50. data/lib/plurimath/math/function/mbox.rb +31 -0
  51. data/lib/plurimath/math/function/menclose.rb +46 -0
  52. data/lib/plurimath/math/function/merror.rb +12 -0
  53. data/lib/plurimath/math/function/mod.rb +19 -4
  54. data/lib/plurimath/math/function/msgroup.rb +37 -0
  55. data/lib/plurimath/math/function/msline.rb +12 -0
  56. data/lib/plurimath/math/function/multiscript.rb +19 -0
  57. data/lib/plurimath/math/function/norm.rb +17 -1
  58. data/lib/plurimath/math/function/obrace.rb +17 -0
  59. data/lib/plurimath/math/function/oint.rb +2 -2
  60. data/lib/plurimath/math/function/over.rb +12 -5
  61. data/lib/plurimath/math/function/overset.rb +34 -5
  62. data/lib/plurimath/math/function/phantom.rb +28 -0
  63. data/lib/plurimath/math/function/power.rb +27 -9
  64. data/lib/plurimath/math/function/power_base.rb +109 -11
  65. data/lib/plurimath/math/function/prod.rb +25 -4
  66. data/lib/plurimath/math/function/right.rb +22 -2
  67. data/lib/plurimath/math/function/root.rb +23 -1
  68. data/lib/plurimath/math/function/rule.rb +33 -0
  69. data/lib/plurimath/math/function/scarries.rb +12 -0
  70. data/lib/plurimath/math/function/scarry.rb +12 -0
  71. data/lib/plurimath/math/function/sqrt.rb +23 -1
  72. data/lib/plurimath/math/function/stackrel.rb +27 -0
  73. data/lib/plurimath/math/function/substack.rb +7 -0
  74. data/lib/plurimath/math/function/sum.rb +50 -2
  75. data/lib/plurimath/math/function/sup.rb +3 -0
  76. data/lib/plurimath/math/function/table/align.rb +5 -5
  77. data/lib/plurimath/math/function/table/array.rb +25 -6
  78. data/lib/plurimath/math/function/table/bmatrix.rb +18 -7
  79. data/lib/plurimath/math/function/table/matrix.rb +13 -5
  80. data/lib/plurimath/math/function/table/multline.rb +5 -5
  81. data/lib/plurimath/math/function/table/pmatrix.rb +5 -5
  82. data/lib/plurimath/math/function/table/split.rb +5 -5
  83. data/lib/plurimath/math/function/table/vmatrix.rb +5 -6
  84. data/lib/plurimath/math/function/table.rb +185 -27
  85. data/lib/plurimath/math/function/td.rb +22 -9
  86. data/lib/plurimath/math/function/ternary_function.rb +74 -9
  87. data/lib/plurimath/math/function/text.rb +36 -11
  88. data/lib/plurimath/math/function/tr.rb +23 -4
  89. data/lib/plurimath/math/function/ubrace.rb +17 -0
  90. data/lib/plurimath/math/function/ul.rb +29 -0
  91. data/lib/plurimath/math/function/unary_function.rb +81 -8
  92. data/lib/plurimath/math/function/underline.rb +12 -0
  93. data/lib/plurimath/math/function/underover.rb +107 -0
  94. data/lib/plurimath/math/function/underset.rb +39 -0
  95. data/lib/plurimath/math/function/vec.rb +7 -1
  96. data/lib/plurimath/math/number.rb +5 -5
  97. data/lib/plurimath/math/symbol.rb +51 -12
  98. data/lib/plurimath/math/unicode.rb +11 -0
  99. data/lib/plurimath/math.rb +7 -3
  100. data/lib/plurimath/mathml/constants.rb +224 -147
  101. data/lib/plurimath/mathml/parser.rb +24 -8
  102. data/lib/plurimath/mathml/transform.rb +249 -153
  103. data/lib/plurimath/omml/parser.rb +24 -4
  104. data/lib/plurimath/omml/transform.rb +219 -157
  105. data/lib/plurimath/utility.rb +342 -20
  106. data/lib/plurimath/version.rb +1 -1
  107. metadata +21 -6
  108. data/.github/workflows/test.yml +0 -33
  109. data/lib/plurimath/mathml/parse.rb +0 -68
  110. data/lib/plurimath/omml/constants.rb +0 -154
@@ -6,47 +6,144 @@ module Plurimath
6
6
  "double-struck": Math::Function::FontStyle::DoubleStruck,
7
7
  "sans-serif": Math::Function::FontStyle::SansSerif,
8
8
  monospace: Math::Function::FontStyle::Monospace,
9
+ fraktur: Math::Function::FontStyle::Fraktur,
10
+ script: Math::Function::FontStyle::Script,
11
+ normal: Math::Function::FontStyle::Normal,
12
+ bold: Math::Function::FontStyle::Bold,
9
13
  mathfrak: Math::Function::FontStyle::Fraktur,
10
14
  mathcal: Math::Function::FontStyle::Script,
11
- fraktur: Math::Function::FontStyle::Fraktur,
12
- mathtt: Math::Function::FontStyle::Monospace,
13
15
  mathbb: Math::Function::FontStyle::DoubleStruck,
14
- script: Math::Function::FontStyle::Script,
16
+ mathtt: Math::Function::FontStyle::Monospace,
15
17
  mathsf: Math::Function::FontStyle::SansSerif,
18
+ mathrm: Math::Function::FontStyle::Normal,
19
+ textrm: Math::Function::FontStyle::Normal,
16
20
  mathbf: Math::Function::FontStyle::Bold,
17
- bold: Math::Function::FontStyle::Bold,
21
+ textbf: Math::Function::FontStyle::Bold,
18
22
  bbb: Math::Function::FontStyle::DoubleStruck,
23
+ cal: Math::Function::FontStyle::Script,
19
24
  bf: Math::Function::FontStyle::Bold,
20
25
  sf: Math::Function::FontStyle::SansSerif,
21
26
  tt: Math::Function::FontStyle::Monospace,
22
27
  fr: Math::Function::FontStyle::Fraktur,
28
+ rm: Math::Function::FontStyle::Normal,
23
29
  cc: Math::Function::FontStyle::Script,
30
+ ii: Math::Function::FontStyle::Italic,
24
31
  bb: Math::Function::FontStyle::Bold,
25
32
  }.freeze
33
+ ALIGNMENT_LETTERS = {
34
+ c: "center",
35
+ r: "right",
36
+ l: "left",
37
+ }.freeze
38
+ UNARY_CLASSES = %w[
39
+ arccos
40
+ arcsin
41
+ arctan
42
+ right
43
+ sech
44
+ sinh
45
+ tanh
46
+ cosh
47
+ coth
48
+ csch
49
+ left
50
+ max
51
+ min
52
+ sec
53
+ sin
54
+ deg
55
+ det
56
+ dim
57
+ exp
58
+ gcd
59
+ glb
60
+ lub
61
+ tan
62
+ cos
63
+ cot
64
+ csc
65
+ ln
66
+ lg
67
+ f
68
+ g
69
+ ].freeze
26
70
 
27
71
  class << self
28
- def organize_table(array, table = [], table_data = [], table_row = [])
29
- table_separator = ["&", "\\\\"].freeze
72
+ def organize_table(array, column_align: nil, options: nil)
73
+ table = []
74
+ table_data = []
75
+ table_row = []
76
+ table_separators = ["&", "\\\\"].freeze
77
+ organize_options(array, column_align) if options
78
+ string_columns = column_align&.map(&:value)
30
79
  array.each do |data|
31
- if data.is_a?(Math::Symbol) && table_separator.include?(data.value)
32
- table_row << Math::Function::Td.new(table_data)
80
+ if data.is_a?(Math::Symbol) && table_separators.include?(data.value)
81
+ table_row << Math::Function::Td.new(filter_table_data(table_data).compact)
33
82
  table_data = []
34
83
  if data.value == "\\\\"
35
- table << Math::Function::Tr.new(table_row.flatten)
84
+ organize_tds(table_row.flatten, string_columns.dup, options)
85
+ table << Math::Function::Tr.new(table_row)
36
86
  table_row = []
37
87
  end
38
- else
39
- table_data << data
88
+ next
40
89
  end
90
+ table_data << data
91
+ end
92
+ table_row << Math::Function::Td.new(table_data.compact) if table_data
93
+ unless table_row.nil? || table_row.empty?
94
+ organize_tds(table_row.flatten, string_columns.dup, options)
95
+ table << Math::Function::Tr.new(table_row)
41
96
  end
42
- table_row << Math::Function::Td.new(table_data) if table_data
43
- table << Math::Function::Tr.new(table_row) unless table_row.empty?
97
+ table_separator(string_columns, table, symbol: "|") unless column_align.nil? || column_align.empty?
44
98
  table
45
99
  end
46
100
 
101
+ def organize_options(table_data, column_align)
102
+ return column_align if column_align.length <= 1
103
+
104
+ align = [column_align&.shift]
105
+ table_data.insert(0, *column_align)
106
+ align
107
+ end
108
+
109
+ def table_options(table_data)
110
+ rowline = ""
111
+ table_data.map do |tr|
112
+ if symbol_value(tr&.parameter_one&.first&.parameter_one&.first, "&#x23af;")
113
+ rowline += "solid "
114
+ else
115
+ rowline += "none "
116
+ end
117
+ end
118
+ options = { rowline: rowline.strip } if rowline.include?("solid")
119
+ options || {}
120
+ end
121
+
122
+ def organize_tds(tr_array, column_align, options)
123
+ return tr_array if column_align.nil? || column_align.empty?
124
+
125
+ column_align.reject! { |string| string == "|" }
126
+ column_align = column_align * tr_array.length if options
127
+ tr_array.map.with_index do |td, ind|
128
+ columnalign = ALIGNMENT_LETTERS[column_align[ind]&.to_sym]
129
+ td.parameter_two = { columnalign: columnalign } if columnalign
130
+ end
131
+ end
132
+
133
+ def filter_table_data(table_data)
134
+ table_data.each_with_index do |object, ind|
135
+ if symbol_value(object, "-")
136
+ table_data[ind] = Math::Formula.new(
137
+ [object, table_data.delete_at(ind.next)],
138
+ )
139
+ end
140
+ end
141
+ table_data
142
+ end
143
+
47
144
  def get_table_class(text)
48
145
  Object.const_get(
49
- "Plurimath::Math::Function::Table::#{text.capitalize}",
146
+ "Plurimath::Math::Function::Table::#{text.to_s.capitalize}",
50
147
  )
51
148
  end
52
149
 
@@ -57,16 +154,241 @@ module Plurimath
57
154
  end
58
155
 
59
156
  def get_class(text)
157
+ text = text.to_s.split("_").map(&:capitalize).join
60
158
  Object.const_get(
61
- "Plurimath::Math::Function::#{text.capitalize}",
159
+ "Plurimath::Math::Function::#{text}",
160
+ )
161
+ end
162
+
163
+ def ox_element(node, attributes: [], namespace: "")
164
+ namespace = "#{namespace}:" unless namespace.empty?
165
+
166
+ element = Ox::Element.new("#{namespace}#{node}")
167
+ attributes&.each do |attr_key, attr_value|
168
+ element[attr_key] = attr_value
169
+ end
170
+ element
171
+ end
172
+
173
+ def rpr_element(wi_tag: false)
174
+ rpr_element = ox_element("rPr", namespace: "w")
175
+ attributes = { "w:ascii": "Cambria Math", "w:hAnsi": "Cambria Math" }
176
+ rpr_element << ox_element(
177
+ "rFonts",
178
+ namespace: "w",
179
+ attributes: attributes,
62
180
  )
181
+ rpr_element << ox_element("i", namespace: "w") if wi_tag
182
+ rpr_element
183
+ end
184
+
185
+ def update_nodes(element, nodes)
186
+ nodes&.each { |node| element << node unless node.nil? }
187
+ element
188
+ end
189
+
190
+ def pr_element(main_tag, wi_tag, namespace: "")
191
+ tag_name = "#{main_tag}Pr"
192
+ ox_element(
193
+ tag_name,
194
+ namespace: namespace,
195
+ ) << rpr_element(wi_tag: wi_tag)
196
+ end
197
+
198
+ def filter_values(array)
199
+ return array unless array.is_a?(Array)
200
+
201
+ array = array.flatten.compact
202
+ if array.length > 1
203
+ return Math::Formula.new(array)
204
+ end
205
+
206
+ array.first
207
+ end
208
+
209
+ def text_classes(text)
210
+ return nil if text.empty?
211
+
212
+ text = filter_values(text) unless text.is_a?(String)
213
+ if text.scan(/[[:digit:]]/).length == text.length
214
+ Math::Number.new(text)
215
+ elsif text.match?(/[a-zA-Z]/)
216
+ Math::Function::Text.new(text)
217
+ else
218
+ Math::Symbol.new(text)
219
+ end
220
+ end
221
+
222
+ def nary_fonts(nary)
223
+ narypr = nary.first.flatten.compact
224
+ subsup = narypr.any?("undOvr") ? "underover" : "power_base"
225
+ get_class(subsup).new(
226
+ Math::Symbol.new(narypr.any?(Hash) ? narypr.first[:chr] : "∫"),
227
+ nary[1],
228
+ nary[2],
229
+ )
230
+ end
231
+
232
+ def find_class_name(object)
233
+ new_object = object.value.first.parameter_one if object.is_a?(Math::Formula)
234
+ get_class(new_object) unless new_object.nil?
235
+ end
236
+
237
+ def find_pos_chr(fonts_array, key)
238
+ fonts_array.find { |d| d.is_a?(Hash) && d[key] }
239
+ end
240
+
241
+ def td_values(objects, slicer)
242
+ sliced = objects.slice_when { |object, _| symbol_value(object, slicer) }
243
+ tds = sliced.map do |slice|
244
+ Math::Function::Td.new(
245
+ slice.delete_if { |d| symbol_value(d, slicer) }.compact,
246
+ )
247
+ end
248
+ tds << Math::Function::Td.new([]) if symbol_value(objects.last, slicer)
249
+ tds
250
+ end
251
+
252
+ def symbol_value(object, value)
253
+ object.is_a?(Math::Symbol) && object.value.include?(value)
254
+ end
255
+
256
+ def td_value(td_object)
257
+ if td_object.is_a?(String) && td_object.empty?
258
+ return Math::Function::Text.new(nil)
259
+ end
260
+
261
+ td_object
262
+ end
263
+
264
+ def mathml_unary_classes(text_array)
265
+ return [] if text_array.empty?
266
+
267
+ compacted = text_array.compact
268
+ string = if compacted.count == 1
269
+ compacted.first
270
+ else
271
+ compacted.join
272
+ end
273
+ return string unless string.is_a?(String)
274
+
275
+ classes = Mathml::Constants::CLASSES
276
+ unicode = string_to_html_entity(string)
277
+ symbol = Mathml::Constants::UNICODE_SYMBOLS[unicode.strip.to_sym]
278
+ if classes.include?(symbol&.strip)
279
+ get_class(symbol.strip).new
280
+ elsif classes.any?(string&.strip)
281
+ get_class(string.strip).new
282
+ else
283
+ Math::Symbol.new(unicode)
284
+ end
285
+ end
286
+
287
+ def string_to_html_entity(string)
288
+ entities = HTMLEntities.new
289
+ entities.encode(string, :hexadecimal)
290
+ end
291
+
292
+ def table_separator(separator, value, symbol: "solid")
293
+ sep_symbol = Math::Function::Td.new([Math::Symbol.new("|")])
294
+ separator&.each_with_index do |sep, ind|
295
+ next unless sep == symbol
296
+
297
+ value.map do |val|
298
+ val.parameter_one.insert((ind + 1), sep_symbol) if symbol == "solid"
299
+ val.parameter_one.insert(ind, sep_symbol) if symbol == "|"
300
+ (val.parameter_one[val.parameter_one.index(nil)] = Math::Function::Td.new([])) rescue nil
301
+ val
302
+ end
303
+ end
304
+ value
305
+ end
306
+
307
+ def join_attr_value(attrs, value)
308
+ if value.any?(String)
309
+ new_value = mathml_unary_classes(value)
310
+ array_value = Array(new_value)
311
+ attrs.nil? ? array_value : join_attr_value(attrs, array_value)
312
+ elsif attrs.nil?
313
+ value
314
+ elsif attrs.is_a?(Math::Function::Menclose)
315
+ attrs.parameter_two = filter_values(value)
316
+ attrs
317
+ elsif attrs.is_a?(Math::Function::Fenced)
318
+ attrs.parameter_two = value
319
+ attrs
320
+ elsif attrs.is_a?(Math::Function::FontStyle)
321
+ attrs.parameter_one = filter_values(value)
322
+ attrs
323
+ elsif attrs.is_a?(Math::Function::Color)
324
+ color_value = filter_values(value)
325
+ if attrs.parameter_two
326
+ attrs.parameter_two.parameter_one = color_value
327
+ else
328
+ attrs.parameter_two = color_value
329
+ end
330
+ attrs
331
+ elsif ["solid", "none"].include?(attrs.split.first.downcase)
332
+ table_separator(attrs.split, value)
333
+ end
334
+ end
335
+
336
+ def multiscript(values)
337
+ values.slice_before("mprescripts").map do |value|
338
+ base_value = value.shift
339
+ part_val = value.partition.with_index { |_, i| i.even? }
340
+ first_value = part_val[0].empty? ? nil : filter_values(part_val[0])
341
+ second_value = part_val[1].empty? ? nil : filter_values(part_val[1])
342
+ if base_value.to_s.include?("mprescripts")
343
+ [first_value, second_value]
344
+ else
345
+ Math::Function::PowerBase.new(
346
+ base_value,
347
+ first_value,
348
+ second_value,
349
+ )
350
+ end
351
+ end
352
+ end
353
+
354
+ def unfenced_value(object)
355
+ case object
356
+ when Math::Function::Fenced
357
+ value = filter_values(object.parameter_two)
358
+ unfenced_value(value)
359
+ when Array
360
+ filter_values(object)
361
+ else
362
+ object
363
+ end
364
+ end
365
+
366
+ def frac_values(object)
367
+ case object
368
+ when Math::Formula
369
+ object.value.any? { |d| symbol_value(d, ",") }
370
+ when Array
371
+ object.any? { |d| symbol_value(d, ",") }
372
+ end
373
+ end
374
+
375
+ def table_td(object)
376
+ new_object = case object
377
+ when Math::Function::Td
378
+ object
379
+ else
380
+ Math::Function::Td.new([object])
381
+ end
382
+ Array(new_object)
63
383
  end
64
384
 
65
- def raise_error!(open_tag, close_tag)
66
- message = "Please check your input."\
67
- " Opening tag is \"#{open_tag}\""\
68
- " and closing tag is \"#{close_tag}\""
69
- raise Math::Error.new(message)
385
+ def symbol_object(value)
386
+ value = case value
387
+ when "ℒ" then "{:"
388
+ when "ℛ" then ":}"
389
+ else value
390
+ end
391
+ Math::Symbol.new(value)
70
392
  end
71
393
  end
72
394
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plurimath
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.2"
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.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-04 00:00:00.000000000 Z
11
+ date: 2023-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -45,8 +45,10 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - ".github/workflows/test.yml"
48
+ - ".github/workflows/rake.yml"
49
+ - ".github/workflows/release.yml"
49
50
  - ".gitignore"
51
+ - ".hound.yml"
50
52
  - ".rubocop.yml"
51
53
  - AsciiMath-Supported-Data.adoc
52
54
  - CODE_OF_CONDUCT.md
@@ -74,6 +76,7 @@ files:
74
76
  - lib/plurimath/latex/parser.rb
75
77
  - lib/plurimath/latex/transform.rb
76
78
  - lib/plurimath/math.rb
79
+ - lib/plurimath/math/base.rb
77
80
  - lib/plurimath/math/formula.rb
78
81
  - lib/plurimath/math/function.rb
79
82
  - lib/plurimath/math/function/abs.rb
@@ -105,7 +108,9 @@ files:
105
108
  - lib/plurimath/math/function/font_style/bold.rb
106
109
  - lib/plurimath/math/function/font_style/double_struck.rb
107
110
  - lib/plurimath/math/function/font_style/fraktur.rb
111
+ - lib/plurimath/math/function/font_style/italic.rb
108
112
  - lib/plurimath/math/function/font_style/monospace.rb
113
+ - lib/plurimath/math/function/font_style/normal.rb
109
114
  - lib/plurimath/math/function/font_style/sans-serif.rb
110
115
  - lib/plurimath/math/function/font_style/script.rb
111
116
  - lib/plurimath/math/function/frac.rb
@@ -126,21 +131,31 @@ files:
126
131
  - lib/plurimath/math/function/limsup.rb
127
132
  - lib/plurimath/math/function/ln.rb
128
133
  - lib/plurimath/math/function/log.rb
134
+ - lib/plurimath/math/function/longdiv.rb
129
135
  - lib/plurimath/math/function/lub.rb
130
136
  - lib/plurimath/math/function/max.rb
137
+ - lib/plurimath/math/function/mbox.rb
138
+ - lib/plurimath/math/function/menclose.rb
139
+ - lib/plurimath/math/function/merror.rb
131
140
  - lib/plurimath/math/function/min.rb
132
141
  - lib/plurimath/math/function/mod.rb
142
+ - lib/plurimath/math/function/msgroup.rb
143
+ - lib/plurimath/math/function/msline.rb
133
144
  - lib/plurimath/math/function/multiscript.rb
134
145
  - lib/plurimath/math/function/norm.rb
135
146
  - lib/plurimath/math/function/obrace.rb
136
147
  - lib/plurimath/math/function/oint.rb
137
148
  - lib/plurimath/math/function/over.rb
138
149
  - lib/plurimath/math/function/overset.rb
150
+ - lib/plurimath/math/function/phantom.rb
139
151
  - lib/plurimath/math/function/power.rb
140
152
  - lib/plurimath/math/function/power_base.rb
141
153
  - lib/plurimath/math/function/prod.rb
142
154
  - lib/plurimath/math/function/right.rb
143
155
  - lib/plurimath/math/function/root.rb
156
+ - lib/plurimath/math/function/rule.rb
157
+ - lib/plurimath/math/function/scarries.rb
158
+ - lib/plurimath/math/function/scarry.rb
144
159
  - lib/plurimath/math/function/sec.rb
145
160
  - lib/plurimath/math/function/sech.rb
146
161
  - lib/plurimath/math/function/sin.rb
@@ -169,18 +184,18 @@ files:
169
184
  - lib/plurimath/math/function/ubrace.rb
170
185
  - lib/plurimath/math/function/ul.rb
171
186
  - lib/plurimath/math/function/unary_function.rb
187
+ - lib/plurimath/math/function/underline.rb
172
188
  - lib/plurimath/math/function/underover.rb
173
189
  - lib/plurimath/math/function/underset.rb
174
190
  - lib/plurimath/math/function/vec.rb
175
191
  - lib/plurimath/math/number.rb
176
192
  - lib/plurimath/math/symbol.rb
193
+ - lib/plurimath/math/unicode.rb
177
194
  - lib/plurimath/mathml.rb
178
195
  - lib/plurimath/mathml/constants.rb
179
- - lib/plurimath/mathml/parse.rb
180
196
  - lib/plurimath/mathml/parser.rb
181
197
  - lib/plurimath/mathml/transform.rb
182
198
  - lib/plurimath/omml.rb
183
- - lib/plurimath/omml/constants.rb
184
199
  - lib/plurimath/omml/parser.rb
185
200
  - lib/plurimath/omml/transform.rb
186
201
  - lib/plurimath/unicode.rb
@@ -209,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
224
  - !ruby/object:Gem::Version
210
225
  version: '0'
211
226
  requirements: []
212
- rubygems_version: 3.3.22
227
+ rubygems_version: 3.3.26
213
228
  signing_key:
214
229
  specification_version: 4
215
230
  summary: Converts LaTeX math into MathML.
@@ -1,33 +0,0 @@
1
- name: test
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
- tags:
7
- - '*'
8
- pull_request:
9
-
10
- jobs:
11
- test:
12
- name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
13
- runs-on: ${{ matrix.os }}
14
- continue-on-error: ${{ matrix.experimental }}
15
- strategy:
16
- fail-fast: false
17
- matrix:
18
- ruby: [ '2.6', '2.7', '3.0', '3.1' ]
19
- os: [ 'macos-latest', 'ubuntu-latest', 'windows-latest']
20
- experimental: [false]
21
-
22
- steps:
23
- - uses: actions/checkout@v3
24
-
25
- - name: Use Ruby
26
- uses: ruby/setup-ruby@v1
27
- with:
28
- ruby-version: ${{ matrix.ruby }}
29
- bundler-cache: true
30
-
31
- - name: Run specs
32
- run: |
33
- bundle exec rake
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "parslet"
4
- module Plurimath
5
- class Mathml
6
- class Parse < Parslet::Parser
7
- rule(:parse_record) do
8
- array_to_expression(Constants::CLASSES).as(:class) |
9
- array_to_expression(Constants::UNICODE_SYMBOLS.keys).as(:symbol) |
10
- array_to_expression(Constants::SYMBOLS.keys).as(:symbol) |
11
- match["a-zA-Z"].repeat(1).as(:text) |
12
- match(/[0-9]/).repeat(1).as(:number) |
13
- str("")
14
- end
15
-
16
- rule(:tag) do
17
- (parse_tag(:open) >> iteration.as(:iteration) >> parse_tag(:close)).as(:tag) |
18
- parse_text_tag.as(:tag)
19
- end
20
-
21
- rule(:sequence) { (tag >> sequence.as(:sequence)) | tag }
22
-
23
- rule(:iteration) { (sequence >> iteration.as(:iteration)) | parse_record }
24
-
25
- rule(:expression) do
26
- parse_tag(:open) >> iteration.as(:iteration) >> parse_tag(:close)
27
- end
28
-
29
- root :expression
30
-
31
- def array_to_expression(array, name = nil)
32
- initial_type = array.first.class
33
- array.reduce do |expr, tag|
34
- expr = str_to_expression(expr, name) if expr.is_a?(initial_type)
35
- expr | str_to_expression(tag, name)
36
- end
37
- end
38
-
39
- def str_to_expression(string, name)
40
- return str(string) if name.nil?
41
-
42
- str(string).as(name)
43
- end
44
-
45
- def parse_tag(opts)
46
- tag = str("<")
47
- tag = tag >> str("/") if opts == :close
48
- tag = tag >> array_to_expression(Constants::TAGS, opts)
49
- tag = tag >> attributes.as(:attributes) if opts == :open
50
- tag >> str(">")
51
- end
52
-
53
- def attributes
54
- (match["a-zA-Z"].repeat.as(:name) >>
55
- str("=") >> quoted_string).repeat
56
- end
57
-
58
- def quoted_string
59
- (str('"') >> match("[^\"]").repeat.as(:value) >> str('"')) |
60
- (str("'") >> match("[^\']").repeat.as(:value) >> str("'"))
61
- end
62
-
63
- def parse_text_tag
64
- str("<mtext>") >> match("[^<]").repeat.as(:quoted_text) >> str("</mtext>")
65
- end
66
- end
67
- end
68
- end