plurimath 0.2.1 → 0.2.3

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 +187 -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 +3229 -1432
  17. data/lib/plurimath/latex/parse.rb +108 -85
  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
@@ -4,140 +4,146 @@ module Plurimath
4
4
  class Asciimath
5
5
  class Constants
6
6
  TABLE_PARENTHESIS = {
7
+ "(:": ":)",
8
+ "ℒ": "ℛ",
7
9
  "[": "]",
8
- "{": "}",
9
10
  "(": ")",
10
- "|": "|",
11
11
  }.freeze
12
12
  PARENTHESIS = {
13
13
  "(:": ":)",
14
- "{:": ":}",
14
+ "": "",
15
15
  "(": ")",
16
16
  "{": "}",
17
17
  "[": "]",
18
18
  }.freeze
19
19
  SYMBOLS = {
20
20
  twoheadrightarrowtail: :"⤖",
21
- twoheadrightarrow: :"↠",
22
- rightarrowtail: :"↣",
23
- Leftrightarrow: :"⇔",
21
+ twoheadrightarrow: :"↠",
22
+ rightarrowtail: :"↣",
23
+ Leftrightarrow: :"⇔",
24
24
  leftrightarrow: :"↔",
25
- Rightarrow: :"⇒",
25
+ Rightarrow: :"⇒",
26
26
  rightarrow: :"→",
27
- varepsilon: :"ɛ",
28
- Leftarrow: :"⇐",
27
+ varepsilon: :"ɛ",
28
+ Leftarrow: :"⇐",
29
29
  leftarrow: :"←",
30
30
  downarrow: :"↓",
31
31
  therefore: :"∴",
32
- backslash: :"\\",
33
- setminus: :"\\",
34
- triangle: :"△",
35
- bigwedge: :"⋀",
32
+ backslash: :"\",
33
+ setminus: :"⧵",
34
+ triangle: :"△",
35
+ bigwedge: :"⋀",
36
36
  rceiling: :"⌉",
37
37
  lceiling: :"⌈",
38
38
  supseteq: :"⊇",
39
39
  subseteq: :"⊆",
40
- vartheta: :"ϑ",
40
+ vartheta: :"ϑ",
41
41
  emptyset: :"∅",
42
- diamond: :"⋄",
42
+ diamond: :"⋄",
43
43
  uparrow: :"↑",
44
- implies: :"⇒",
44
+ implies: :"⇒",
45
45
  partial: :"∂",
46
46
  because: :"∵",
47
- upsilon: :"υ",
48
- epsilon: :"ε",
49
- bigcap: :"⋂",
50
- bigvee: :"⋁",
51
- propto: :"∝",
47
+ upsilon: :"υ",
48
+ epsilon: :"ε",
49
+ bigcap: :"⋂",
50
+ bigvee: :"⋁",
51
+ propto: :"∝",
52
52
  approx: :"≈",
53
53
  exists: :"∃",
54
54
  forall: :"∀",
55
55
  otimes: :"⊗",
56
- ltimes: :"⋉",
57
- bowtie: :"⋈",
58
- rtimes: :"⋊",
59
- models: :"⊨",
60
- mapsto: :"↦",
61
- bigcup: :"⋃",
62
- succeq: :"⪰",
63
- preceq: :"⪯",
64
- rfloor: :"⌋",
65
- lfloor: :"⌊",
66
- square: :"□",
56
+ ltimes: :"⋉",
57
+ bowtie: :"⋈",
58
+ rtimes: :"⋊",
59
+ models: :"⊨",
60
+ mapsto: :"↦",
61
+ bigcup: :"⋃",
62
+ succeq: :"⪰",
63
+ preceq: :"⪯",
64
+ rfloor: :"⌋",
65
+ lfloor: :"⌊",
66
+ square: :"□",
67
67
  supset: :"⊃",
68
68
  subset: :"⊂",
69
- lambda: :"λ",
70
- Lambda: :"Λ",
71
- varphi: :"φ",
69
+ lambda: :"λ",
70
+ Lambda: :"Λ",
71
+ varphi: :"φ",
72
+ rangle: :"〉",
73
+ langle: :"〈",
72
74
  ">->>": :"⤖",
73
- "/_\\": :"△",
74
- "|><|": :"&#x22C8;",
75
- kappa: :"&#x3BA;",
75
+ "/_\\": :"&#x25b3;",
76
+ "|><|": :"&#x22c8;",
77
+ kappa: :"&#x3ba;",
76
78
  Delta: :"&#x394;",
77
- delta: :"&#x3B4;",
78
- gamma: :"&#x3B3;",
79
+ delta: :"&#x3b4;",
80
+ gamma: :"&#x3b3;",
79
81
  Gamma: :"&#x393;",
80
82
  Theta: :"&#x398;",
81
- theta: :"&#x3B8;",
82
- alpha: :"&#x3B1;",
83
- aleph: :"&#2135;",
84
- infty: :"&#221E;",
85
- equiv: :"&#2261;",
86
- frown: :"&#2322;",
87
- notin: :"&#2209;",
88
- angle: :"&#2220;",
83
+ theta: :"&#x3b8;",
84
+ alpha: :"&#x3b1;",
85
+ aleph: :"&#x2135;",
86
+ infty: :"&#x221e;",
87
+ equiv: :"&#x2261;",
88
+ frown: :"&#x2322;",
89
+ notin: :"&#x2209;",
90
+ angle: :"&#x2220;",
91
+ prime: :"&#x2032;",
89
92
  "!in": :"&#x2209;",
90
- cdots: :"&#x22EF;",
91
- vdash: :"&#x22A2;",
93
+ cdots: :"&#x22ef;",
94
+ vdash: :"&#x22a2;",
92
95
  wedge: :"&#x2227;",
93
96
  oplus: :"&#x2295;",
94
97
  nabla: :"&#x2207;",
95
- ddots: :"&#x22F1;",
96
- vdots: :"&#x22EE;",
97
- Sigma: :"&#3A3;",
98
- Omega: :"&#3A9;",
99
- omega: :"&#3C9;",
100
- sigma: :"&#3C3;",
101
- times: :"&#xD7;",
102
- ldots: :"...",
103
- ">-=": :"&#x2AB0;",
104
- "-<=": :"&#x2AAF;",
105
- "><|": :"&#x22CA;",
106
- "|==": :"&#x22A8;",
107
- "|--": :"&#x22A2;",
108
- "^^^": :"&#x22C0;",
109
- "|->": :"&#x21A6;",
110
- ">->": :"&#x21A3;",
111
- "->>": :"&#x21A0;",
112
- "__|": :"&#x230B;",
113
- "|__": :"&#x230A;",
114
- "|><": :"&#x22C9;",
115
- "_|_": :"&#x22A5;",
116
- "***": :"&#x22C6;",
117
- "<=>": :"&#x21D4;",
118
- quad: :"&#xA0;&#xA0;",
119
- star: :"&#x22C6;",
98
+ ddots: :"&#x22f1;",
99
+ vdots: :"&#x22ee;",
100
+ Sigma: :"&#x3a3;",
101
+ Omega: :"&#x3a9;",
102
+ omega: :"&#x3c9;",
103
+ sigma: :"&#x3c3;",
104
+ times: :"&#xd7;",
105
+ ldots: :"&#x2026;",
106
+ ">-=": :"&#x2ab0;",
107
+ "-<=": :"&#x2aaf;",
108
+ "><|": :"&#x22ca;",
109
+ "|==": :"&#x22a8;",
110
+ "|--": :"&#x22a2;",
111
+ "^^^": :"&#x22c0;",
112
+ "|->": :"&#x21a6;",
113
+ ">->": :"&#x21a3;",
114
+ "->>": :"&#x21a0;",
115
+ "__|": :"&#x230b;",
116
+ "|__": :"&#x230a;",
117
+ "|><": :"&#x22c9;",
118
+ "_|_": :"&#x22a5;",
119
+ "***": :"&#x22c6;",
120
+ "<=>": :"&#x21d4;",
121
+ "...": :"&#x2026;",
122
+ "(:": :"&#x2329;",
123
+ ":)": :"&#x232a;",
124
+ quad: :"&#x2001;",
125
+ star: :"&#x22c6;",
120
126
  odot: :"&#x2299;",
121
- cdot: :"&#x22C5;",
127
+ cdot: :"&#x22c5;",
122
128
  rarr: :"&#x2192;",
123
129
  darr: :"&#x2193;",
124
- prop: :"&#x221D;",
125
- lArr: :"&#x21D0;",
126
- rArr: :"&#x21D2;",
130
+ prop: :"&#x221d;",
131
+ lArr: :"&#x21d0;",
132
+ rArr: :"&#x21d2;",
127
133
  uarr: :"&#x2191;",
128
- hArr: :"&#x21D4;",
134
+ hArr: :"&#x21d4;",
129
135
  harr: :"&#x2194;",
130
136
  larr: :"&#x2190;",
131
137
  grad: :"&#x2207;",
132
138
  circ: :"&#x2218;",
133
139
  sube: :"&#x2286;",
134
140
  supe: :"&#x2287;",
135
- succ: :"&#227B;",
136
- prec: :"&#227A;",
137
- cong: :"&#2245;",
138
- beta: :"&#x3B2;",
139
- zeta: :"&#x3B6;",
140
- iota: :"&#x3B9;",
141
+ succ: :"&#x227b;",
142
+ prec: :"&#x227a;",
143
+ cong: :"&#x2245;",
144
+ beta: :"&#x3b2;",
145
+ zeta: :"&#x3b6;",
146
+ iota: :"&#x3b9;",
141
147
  ":'": :"&#x2235;",
142
148
  "^^": :"&#x2227;",
143
149
  "o+": :"&#x2295;",
@@ -146,13 +152,13 @@ module Plurimath
146
152
  "~~": :"&#x2248;",
147
153
  "O/": :"&#x2205;",
148
154
  "->": :"&#x2192;",
149
- "=>": :"&#x21D2;",
150
- ">>": :"&#x232A;",
155
+ "=>": :"&#x21d2;",
156
+ ">>": :"&#x232a;",
151
157
  "<<": :"&#x2329;",
152
158
  "~|": :"&#x2309;",
153
159
  "!=": :"&#x2260;",
154
- ">-": :"&#x227B;",
155
- "-<": :"&#x227A;",
160
+ ">-": :"&#x227b;",
161
+ "-<": :"&#x227a;",
156
162
  "~=": :"&#x2245;",
157
163
  "-=": :"&#x2261;",
158
164
  ":.": :"&#x2234;",
@@ -160,70 +166,85 @@ module Plurimath
160
166
  "<=": :"&#x2264;",
161
167
  "|~": :"&#x2308;",
162
168
  "/_": :"&#x2220;",
163
- "+-": :"&#xB1;",
164
- "-:": :"&#xF7;",
169
+ "''": :"&#x2033;",
170
+ "+-": :"&#xb1;",
171
+ "-:": :"&#xf7;",
172
+ "\\ ": :"&#xa0;",
173
+ "\\": :"\\",
174
+ "//": :/,
165
175
  sup: :"&#x2283;",
166
176
  sub: :"&#x2282;",
167
- top: :"&#x22A4;",
168
- vvv: :"&#x22C1;",
177
+ top: :"&#x22a4;",
178
+ vvv: :"&#x22c1;",
169
179
  vee: :"&#x2228;",
170
- nnn: :"&#x22C2;",
180
+ nnn: :"&#x22c2;",
171
181
  cap: :"&#x2229;",
172
182
  ast: :"&#x2217;",
173
- bot: :"&#x22A5;",
183
+ bot: :"&#x22a5;",
174
184
  del: :"&#x2202;",
175
- uuu: :"&#x22C3;",
176
- cup: :"&#x222A;",
177
- iff: :"&#x21D4;",
178
- eta: :"&#x3B7;",
179
- Phi: :"&#x3A6;",
180
- Psi: :"&#x3A8;",
181
- psi: :"&#x3C8;",
182
- chi: :"&#x3C7;",
183
- phi: :"&#x3D5;",
184
- rho: :"&#x3C1;",
185
- tau: :"&#x3C4;",
186
- div: :"&#xF7;",
187
- neg: :"&#xAC;",
188
- not: :"&#xAC;",
189
- "@": :"&#x2218;",
190
- "*": :"&#x22C5;",
191
- "<": :"&lt;",
192
- ">": :"&gt;",
193
- "-": :"-",
185
+ uuu: :"&#x22c3;",
186
+ cup: :"&#x222a;",
187
+ iff: :"&#x21d4;",
188
+ eta: :"&#x3b7;",
189
+ Phi: :"&#x3a6;",
190
+ Psi: :"&#x3a8;",
191
+ psi: :"&#x3c8;",
192
+ chi: :"&#x3c7;",
193
+ phi: :"&#x3d5;",
194
+ rho: :"&#x3c1;",
195
+ tau: :"&#x3c4;",
196
+ div: :"&#xf7;",
197
+ neg: :"&#xac;",
198
+ not: :"&#xac;",
199
+ "*": :"&#x22c5;",
200
+ "@": :"&#x40;",
201
+ "<": :"&#x3c;",
202
+ ">": :"&#x3e;",
203
+ "/": :"&#x2f;",
204
+ ":": :"&#x3a;",
205
+ "!": :"&#x21;",
206
+ ",": :"&#x2c;",
207
+ ";": :"&#x3b;",
208
+ "?": :"&#x3f;",
209
+ "$": :"&#x24;",
210
+ "~": :"&#x7e;",
211
+ "|": :"&#x7c;",
212
+ "%": :"&#x25;",
213
+ "'": :"&#x2032;",
214
+ "&": :"&#x26;",
215
+ "#": :"&#x23;",
194
216
  "=": :"=",
217
+ "-": :"-",
195
218
  "+": :"+",
196
- "/": :"/",
197
219
  nn: :"&#x2229;",
198
220
  vv: :"&#x2228;",
199
- TT: :"&#x22A4;",
221
+ TT: :"&#x22a4;",
200
222
  EE: :"&#x2203;",
201
223
  ox: :"&#x2297;",
202
224
  to: :"&#x2192;",
203
225
  AA: :"&#x2200;",
204
- uu: :"&#x222A;",
226
+ uu: :"&#x222a;",
205
227
  ne: :"&#x2260;",
206
- ZZ: :"&#x2124;",
207
- RR: :"&#x211D;",
208
- QQ: :"&#x211A;",
209
- NN: :"&#x2115;",
210
- CC: :"&#x2102;",
211
- oo: :"&#x221E;",
228
+ oo: :"&#x221e;",
212
229
  ge: :"&#x2265;",
213
230
  le: :"&#x2264;",
214
231
  in: :"&#x2208;",
215
- nu: :"&#x3BD;",
216
- mu: :"&#x3BC;",
217
- pi: :"&#x3C0;",
218
- Pi: :"&#x3A0;",
219
- xi: :"&#x3BE;",
220
- Xi: :"&#x39E;",
221
- xx: :"&#xD7;",
222
- pm: :"&#xB1;",
223
- gt: :"&gt;",
224
- lt: :"&lt;",
232
+ nu: :"&#x3bd;",
233
+ mu: :"&#x3bc;",
234
+ pi: :"&#x3c0;",
235
+ Pi: :"&#x3a0;",
236
+ xi: :"&#x3be;",
237
+ Xi: :"&#x39e;",
238
+ xx: :"&#xd7;",
239
+ pm: :"&#xb1;",
240
+ gt: :"&#x3e;",
241
+ lt: :"&#x3c;",
242
+ if: :if,
225
243
  }.freeze
226
244
  UNARY_CLASSES = %i[
245
+ underbrace
246
+ overbrace
247
+ underline
227
248
  arccos
228
249
  arcsin
229
250
  arctan
@@ -272,15 +293,8 @@ module Plurimath
272
293
  underset
273
294
  stackrel
274
295
  overset
275
- color
276
- prod
277
296
  frac
278
297
  root
279
- oint
280
- int
281
- sum
282
- mod
283
- log
284
298
  ].freeze
285
299
  FONT_STYLES = %i[
286
300
  mathfrak
@@ -291,11 +305,43 @@ module Plurimath
291
305
  mathbf
292
306
  bbb
293
307
  bb
308
+ rm
294
309
  fr
295
310
  cc
296
311
  sf
297
312
  tt
313
+ ii
298
314
  ].freeze
315
+ SUB_SUP_CLASSES = %w[
316
+ prod
317
+ oint
318
+ lim
319
+ sum
320
+ log
321
+ int
322
+ ].freeze
323
+ SPECIAL_BOLD_ALPHABETS = %w[
324
+ ZZ
325
+ RR
326
+ QQ
327
+ NN
328
+ CC
329
+ ].freeze
330
+
331
+ class << self
332
+ def precompile_constants
333
+ @values ||=
334
+ named_hash(UNARY_CLASSES, :unary_class)
335
+ .merge(named_hash(SYMBOLS.keys, :symbol))
336
+ .merge(named_hash(FONT_STYLES, :fonts))
337
+ .merge(named_hash(SPECIAL_BOLD_ALPHABETS, :special_fonts))
338
+ @values.sort_by { |v, _| -v.length }.to_h
339
+ end
340
+
341
+ def named_hash(hash_or_array, name_key)
342
+ hash_or_array.each_with_object({}) { |d, i| i[d] = name_key }
343
+ end
344
+ end
299
345
  end
300
346
  end
301
347
  end
@@ -4,23 +4,29 @@ require "parslet"
4
4
  module Plurimath
5
5
  class Asciimath
6
6
  class Parse < Parslet::Parser
7
- rule(:space) { str(" ") }
8
- rule(:base) { str("_").as(:_) }
9
- rule(:power) { str("^").as(:^) }
10
- rule(:comma) { (str(",") >> space) | str(",") }
11
-
12
- rule(:symbols) { arr_to_expression(Constants::SYMBOLS.keys, :symbol) }
13
- rule(:font_style) { arr_to_expression(Constants::FONT_STYLES, :fonts) }
7
+ rule(:td) { expression.as(:td) }
8
+ rule(:base) { str("_") }
9
+ rule(:power) { str("^") }
10
+ rule(:space) { match(/\s+/) }
11
+ rule(:comma) { (str(",") >> space.maybe) }
12
+ rule(:number) do
13
+ (match("[0-9]").repeat(1) >> str(".") >> match("[0-9]").repeat(1)).as(:number) |
14
+ match("[0-9]").repeat(1).as(:number) |
15
+ str(".").as(:symbol)
16
+ end
14
17
 
15
- rule(:unary_functions) { arr_to_expression(Constants::UNARY_CLASSES) }
16
- rule(:binary_functions) { arr_to_expression(Constants::BINARY_CLASSES) }
18
+ rule(:controversial_symbols) { power_base | expression }
19
+ rule(:left_right_open_paren) { str("(") | str("[") }
20
+ rule(:left_right_close_paren) { str(")") | str("]") }
21
+ rule(:color_left_parenthesis) { str("(") | str("[") | str("{") }
22
+ rule(:color_right_parenthesis) { str(")") | str("]") | str("}") }
17
23
 
18
- rule(:left_right_open_paren) { str("(") | str("[") }
19
- rule(:left_right_close_paren) { str(")") | str("]") }
24
+ rule(:binary_classes) do
25
+ arr_to_expression(Constants::BINARY_CLASSES, :binary_class)
26
+ end
20
27
 
21
- rule(:left_right) do
22
- (str("left") >> left_right_open_paren.as(:left) >> iteration.as(:left_right_value) >> str("right") >> left_right_close_paren.as(:right)) |
23
- table
28
+ rule(:sub_sup_classes) do
29
+ arr_to_expression(Constants::SUB_SUP_CLASSES, :binary_class)
24
30
  end
25
31
 
26
32
  rule(:open_table) do
@@ -45,58 +51,100 @@ module Plurimath
45
51
  end
46
52
  end
47
53
 
54
+ rule(:left_right) do
55
+ (str("left") >> left_right_open_paren.as(:left) >> iteration.as(:left_right_value) >> str("right") >> left_right_close_paren.as(:right)) |
56
+ ((table.as(:numerator) >> space.maybe >> match(/(?<!\/)\/(?!\/)/) >> space.maybe >> iteration.as(:denominator)).as(:frac) >> expression) |
57
+ (table.as(:table) >> expression.maybe)
58
+ end
59
+
48
60
  rule(:quoted_text) do
49
61
  str('"') >> match("[^\"]").repeat.as(:text) >> str('"')
50
62
  end
51
63
 
52
64
  rule(:symbol_text_or_integer) do
53
- binary_functions |
54
- unary_functions |
55
- symbols |
65
+ sub_sup_classes |
66
+ binary_classes |
67
+ hash_to_expression(Constants.precompile_constants) |
68
+ (match(/[0-9]/).as(:number) >> comma.as(:comma)).repeat(1).as(:comma_separated) |
56
69
  quoted_text |
70
+ (str("d").as(:d) >> str("x").as(:x)).as(:intermediate_exp) |
57
71
  match["a-zA-Z"].as(:symbol) |
58
- match("[0-9]").repeat(1).as(:number)
72
+ match(/[^\[{(\\\/@;:.,'"|\]})0-9a-zA-Z\-><$%^&*_=+!`~\s?]/).as(:symbol) |
73
+ number
74
+ end
75
+
76
+ rule(:power_base) do
77
+ (base >> space.maybe >> sequence.as(:base_value) >> power >> space.maybe >> sequence.as(:power_value)) |
78
+ (space.maybe >> base >> space.maybe >> sequence.as(:base_value)).as(:base) |
79
+ (space.maybe >> power >> space.maybe >> sequence.as(:power_value)).as(:power) |
80
+ (space.maybe >> base >> space.maybe >> power.as(:symbol).as(:base_value)).as(:base) |
81
+ (space.maybe >> power >> space.maybe >> base.as(:symbol).as(:power_value)).as(:power)
82
+ end
83
+
84
+ rule(:power_base_rules) do
85
+ (sub_sup_classes >> power_base).as(:power_base) |
86
+ (binary_classes >> space.maybe >> sequence.as(:base_value).maybe >> space.maybe >> sequence.as(:power_value).maybe).as(:power_base) |
87
+ (sequence.as(:power_base) >> power_base).as(:power_base)
59
88
  end
60
89
 
61
90
  rule(:table) do
62
91
  (open_table.as(:table_left) >> tr >> close_table.as(:table_right)) |
92
+ (open_table.as(:table_left) >> tr >> str("}").as(:table_right)) |
93
+ (str("norm").as(:norm) >> open_table.as(:table_left) >> tr >> close_table.as(:table_right)) |
94
+ (str("{").as(:table_left) >> tr >> close_table.as(:table_right)) |
95
+ (str("|").as(:table_left) >> tr >> str("|").as(:table_right)) |
63
96
  (str("left") >> left_right_open_paren.as(:left) >> tr >> str("right") >> left_right_close_paren.as(:right))
64
97
  end
65
98
 
66
99
  rule(:tr) do
67
- ((str("[").as(:open_tr) >> td.as(:tds_list) >> str("]")).as(:table_row) >> comma >> tr.as(:expr)) |
68
- (str("[").as(:open_tr) >> td.as(:tds_list) >> str("]")).as(:table_row)
100
+ ((left_right_open_paren.as(:open_tr) >> td.as(:tds_list) >> left_right_close_paren).as(:table_row) >> comma >> tr.as(:expr)) |
101
+ (left_right_open_paren.as(:open_tr) >> td.as(:tds_list) >> left_right_close_paren).as(:table_row)
69
102
  end
70
103
 
71
- rule(:td) do
72
- (sequence.as(:td) >> str(",") >> sequence.as(:tds)) |
73
- sequence.as(:td)
104
+ rule(:color_value) do
105
+ (color_left_parenthesis.capture(:paren).as(:lparen) >> expression.as(:rgb_color) >> color_right_parenthesis.maybe.as(:rparen)).as(:intermediate_exp) |
106
+ iteration
74
107
  end
75
108
 
76
109
  rule(:sequence) do
77
- (lparen >> expression >> rparen).as(:intermediate_exp) |
78
- (binary_functions >> sequence.as(:base) >> sequence.maybe.as(:exponent)).as(:binary) |
79
- (str("text") >> lparen.capture(:paren) >> read_text >> rparen) |
80
- (unary_functions >> sequence).as(:unary) |
81
- (font_style >> sequence).as(:fonts) |
110
+ (lparen.as(:lparen) >> space.maybe >> expression.maybe.as(:expr) >> space.maybe >> rparen.maybe.as(:rparen)).as(:intermediate_exp) |
111
+ (str("text") >> lparen.capture(:paren).as(:lparen) >> read_text.as(:text) >> rparen.maybe.as(:rparen)).as(:intermediate_exp) |
82
112
  symbol_text_or_integer
83
113
  end
84
114
 
115
+ rule(:frac) do
116
+ (sequence.as(:numerator) >> space.maybe >> match(/(?<!\/)\/(?!\/)/) >> space.maybe >> iteration.as(:denominator)).as(:frac) |
117
+ ((power_base_rules | power_base).as(:numerator) >> match(/(?<!\/)\/(?!\/)/) >> iteration.as(:denominator)).as(:frac)
118
+ end
119
+
120
+ rule(:mod) do
121
+ (sequence.as(:dividend) >> space.maybe >> str("mod").as(:mod) >> space.maybe >> iteration.as(:divisor)).as(:mod) |
122
+ ((power_base_rules >> power_base).as(:dividend) >> space.maybe >> str("mod").as(:mod) >> space.maybe >> iteration.as(:divisor)).as(:mod) |
123
+ (power_base_rules.as(:dividend) >> space.maybe >> str("mod").as(:mod) >> space.maybe >> iteration.as(:divisor)).as(:mod)
124
+ end
125
+
85
126
  rule(:iteration) do
86
127
  table.as(:table) |
87
- (sequence.as(:dividend) >> str("mod").as(:mod) >> sequence.as(:divisor)).as(:mod) |
88
- (sequence >> base >> sequence.as(:base) >> power >> sequence.as(:exponent)).as(:power_base) |
89
- (sequence >> base >> sequence).as(:base) |
90
- (sequence >> power >> sequence).as(:power) |
128
+ comma.as(:comma) |
129
+ mod |
130
+ (sequence.as(:sequence) >> space.maybe >> str("//").as(:symbol)) |
131
+ (str("color") >> color_value.as(:color) >> sequence.as(:color_value)) |
132
+ frac |
133
+ (power_base_rules >> power_base) |
134
+ power_base_rules |
91
135
  sequence.as(:sequence) |
92
136
  space
93
137
  end
94
138
 
95
139
  rule(:expression) do
96
140
  left_right.as(:left_right) |
97
- (iteration >> expression).as(:expr) |
98
- (iteration >> str("/").as(:/) >> iteration).as(:expr) |
99
- str("")
141
+ (iteration >> space.maybe >> expression).as(:expr) |
142
+ (base.as(:symbol) >> expression.maybe).as(:expr) |
143
+ (power.as(:symbol) >> expression.maybe).as(:expr) |
144
+ str("") |
145
+ (rparen.as(:rparen) >> space.maybe >> controversial_symbols >> comma.as(:comma).maybe >> expression).repeat(1).as(:expr) |
146
+ (power.as(:symbol) >> space.maybe >> expression).as(:expr) |
147
+ comma.as(:comma).maybe
100
148
  end
101
149
 
102
150
  root :expression
@@ -104,16 +152,33 @@ module Plurimath
104
152
  def arr_to_expression(arr, name = nil)
105
153
  type = arr.first.class
106
154
  arr.reduce do |expression, expr_string|
107
- as_value = name.nil? ? expr_string || expression : name
108
- expression = str(expression).as(as_value) if expression.is_a?(type)
109
- expression | str(expr_string).as(as_value)
155
+ expression = str(expression).as(name) if expression.is_a?(type)
156
+ expression | str(expr_string).as(name)
110
157
  end
111
158
  end
112
159
 
113
160
  def read_text
114
161
  dynamic do |_sour, context|
115
162
  rparen = Constants::PARENTHESIS[context.captures[:paren].to_sym]
116
- match("[^#{rparen}]").repeat.as(:text)
163
+ match("[^#{rparen}]").repeat
164
+ end
165
+ end
166
+
167
+ def hash_to_expression(arr)
168
+ type = arr.first.class
169
+ @@expression ||= arr.reduce do |expression, expr_string|
170
+ expression = dynamic_parser_rules(expression) if expression.is_a?(type)
171
+ expression | dynamic_parser_rules(expr_string)
172
+ end
173
+ end
174
+
175
+ def dynamic_parser_rules(expr)
176
+ first_value = str(expr.first.to_s)
177
+ case expr.last
178
+ when :symbol then first_value.as(:symbol)
179
+ when :unary_class then (first_value.as(:unary_class) >> space.maybe >> sequence.maybe).as(:unary)
180
+ when :fonts then first_value.as(:fonts_class) >> space.maybe >> sequence.as(:fonts_value)
181
+ when :special_fonts then first_value.as(:bold_fonts)
117
182
  end
118
183
  end
119
184
  end
@@ -10,11 +10,13 @@ module Plurimath
10
10
 
11
11
  def initialize(text)
12
12
  @text = text
13
+ &.gsub(/(\|:|:\|)/, "|")
14
+ &.gsub(/(\{:)/, "ℒ")
15
+ &.gsub(/(:\})/, "ℛ")
13
16
  end
14
17
 
15
18
  def parse
16
19
  nodes = Parse.new.parse(text)
17
- nodes = JSON.parse(nodes.to_json, symbolize_names: true)
18
20
  transformed_tree = Transform.new.apply(nodes)
19
21
  return transformed_tree if transformed_tree.is_a?(Math::Formula)
20
22