plurimath 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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