@ziloen/micromark-extension-math 3.1.0-patch.0

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.
@@ -0,0 +1,478 @@
1
+ /**
2
+ * @import {Construct, State, TokenizeContext, Tokenizer} from 'micromark-util-types'
3
+ */
4
+
5
+ import { factorySpace } from 'micromark-factory-space';
6
+ import { markdownLineEnding } from 'micromark-util-character';
7
+ /** @type {Construct} */
8
+ export const mathFlow = {
9
+ tokenize: tokenizeMathFenced,
10
+ concrete: true,
11
+ name: 'mathFlow'
12
+ };
13
+
14
+ /** @type {Construct} */
15
+ const nonLazyContinuation = {
16
+ tokenize: tokenizeNonLazyContinuation,
17
+ partial: true
18
+ };
19
+
20
+ /**
21
+ * @this {TokenizeContext}
22
+ * @type {Tokenizer}
23
+ */
24
+ function tokenizeMathFenced(effects, ok, nok) {
25
+ const self = this;
26
+ const tail = self.events[self.events.length - 1];
27
+ const initialSize = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0;
28
+ let sizeOpen = 0;
29
+ let backslashContentSeen = false;
30
+ let isBackslashMath = false;
31
+ return start;
32
+
33
+ /**
34
+ * Start of math.
35
+ *
36
+ * ```markdown
37
+ * > | $$
38
+ * ^
39
+ * | \frac{1}{2}
40
+ * | $$
41
+ * ```
42
+ *
43
+ * @type {State}
44
+ */
45
+ function start(code) {
46
+ effects.enter('mathFlow');
47
+ effects.enter('mathFlowFence');
48
+ effects.enter('mathFlowFenceSequence');
49
+ if (code === 92) {
50
+ effects.consume(code);
51
+ return sequenceOpenBackslash;
52
+ }
53
+ return sequenceOpen(code);
54
+ }
55
+
56
+ /**
57
+ * In opening fence sequence.
58
+ *
59
+ * ```markdown
60
+ * > | $$
61
+ * ^
62
+ * | \frac{1}{2}
63
+ * | $$
64
+ * ```
65
+ *
66
+ * @type {State}
67
+ */
68
+ function sequenceOpen(code) {
69
+ if (code === 36) {
70
+ effects.consume(code);
71
+ sizeOpen++;
72
+ return sequenceOpen;
73
+ }
74
+ if (sizeOpen < 2) {
75
+ return nok(code);
76
+ }
77
+ effects.exit('mathFlowFenceSequence');
78
+ return factorySpace(effects, metaBefore, "whitespace")(code);
79
+ }
80
+
81
+ /**
82
+ * After the backslash in an opening fence sequence.
83
+ *
84
+ * ```markdown
85
+ * > | \[
86
+ * ^
87
+ * | \frac{1}{2}
88
+ * | \]
89
+ * ```
90
+ *
91
+ * @type {State}
92
+ */
93
+ function sequenceOpenBackslash(code) {
94
+ if (code !== 91) {
95
+ return nok(code);
96
+ }
97
+ isBackslashMath = true;
98
+ effects.consume(code);
99
+ effects.exit('mathFlowFenceSequence');
100
+ effects.exit('mathFlowFence');
101
+ if (self.interrupt) {
102
+ return ok;
103
+ }
104
+ return backslashContentStart;
105
+ }
106
+
107
+ /**
108
+ * In opening fence, before meta.
109
+ *
110
+ * ```markdown
111
+ * > | $$asciimath
112
+ * ^
113
+ * | x < y
114
+ * | $$
115
+ * ```
116
+ *
117
+ * @type {State}
118
+ */
119
+
120
+ function metaBefore(code) {
121
+ if (code === null || markdownLineEnding(code)) {
122
+ return metaAfter(code);
123
+ }
124
+ effects.enter('mathFlowFenceMeta');
125
+ effects.enter("chunkString", {
126
+ contentType: "string"
127
+ });
128
+ return meta(code);
129
+ }
130
+
131
+ /**
132
+ * In meta.
133
+ *
134
+ * ```markdown
135
+ * > | $$asciimath
136
+ * ^
137
+ * | x < y
138
+ * | $$
139
+ * ```
140
+ *
141
+ * @type {State}
142
+ */
143
+ function meta(code) {
144
+ if (code === null || markdownLineEnding(code)) {
145
+ effects.exit("chunkString");
146
+ effects.exit('mathFlowFenceMeta');
147
+ return metaAfter(code);
148
+ }
149
+ if (code === 36) {
150
+ return nok(code);
151
+ }
152
+ effects.consume(code);
153
+ return meta;
154
+ }
155
+
156
+ /**
157
+ * After meta.
158
+ *
159
+ * ```markdown
160
+ * > | $$
161
+ * ^
162
+ * | \frac{1}{2}
163
+ * | $$
164
+ * ```
165
+ *
166
+ * @type {State}
167
+ */
168
+ function metaAfter(code) {
169
+ // Guaranteed to be eol/eof.
170
+ effects.exit('mathFlowFence');
171
+ if (self.interrupt) {
172
+ return ok(code);
173
+ }
174
+ return effects.attempt(nonLazyContinuation, beforeNonLazyContinuation, after)(code);
175
+ }
176
+
177
+ /**
178
+ * After eol/eof in math, at a non-lazy closing fence or content.
179
+ *
180
+ * ```markdown
181
+ * | $$
182
+ * > | \frac{1}{2}
183
+ * ^
184
+ * > | $$
185
+ * ^
186
+ * ```
187
+ *
188
+ * @type {State}
189
+ */
190
+ function beforeNonLazyContinuation(code) {
191
+ return effects.attempt({
192
+ tokenize: tokenizeClosingFence,
193
+ partial: true
194
+ }, after, contentStart)(code);
195
+ }
196
+
197
+ /**
198
+ * Before math content, definitely not before a closing fence.
199
+ *
200
+ * ```markdown
201
+ * | $$
202
+ * > | \frac{1}{2}
203
+ * ^
204
+ * | $$
205
+ * ```
206
+ *
207
+ * @type {State}
208
+ */
209
+ function contentStart(code) {
210
+ return (initialSize ? factorySpace(effects, beforeContentChunk, "linePrefix", initialSize + 1) : beforeContentChunk)(code);
211
+ }
212
+
213
+ /**
214
+ * Before math content, after optional prefix.
215
+ *
216
+ * ```markdown
217
+ * | $$
218
+ * > | \frac{1}{2}
219
+ * ^
220
+ * | $$
221
+ * ```
222
+ *
223
+ * @type {State}
224
+ */
225
+ function beforeContentChunk(code) {
226
+ if (code === null) {
227
+ return after(code);
228
+ }
229
+ if (markdownLineEnding(code)) {
230
+ return effects.attempt(nonLazyContinuation, beforeNonLazyContinuation, after)(code);
231
+ }
232
+ effects.enter('mathFlowValue');
233
+ return contentChunk(code);
234
+ }
235
+
236
+ /**
237
+ * In math content.
238
+ *
239
+ * ```markdown
240
+ * | $$
241
+ * > | \frac{1}{2}
242
+ * ^
243
+ * | $$
244
+ * ```
245
+ *
246
+ * @type {State}
247
+ */
248
+ function contentChunk(code) {
249
+ if (code === null || markdownLineEnding(code)) {
250
+ effects.exit('mathFlowValue');
251
+ return beforeContentChunk(code);
252
+ }
253
+ effects.consume(code);
254
+ return contentChunk;
255
+ }
256
+
257
+ /**
258
+ * After math (ha!).
259
+ *
260
+ * ```markdown
261
+ * | $$
262
+ * | \frac{1}{2}
263
+ * > | $$
264
+ * ^
265
+ * ```
266
+ *
267
+ * @type {State}
268
+ */
269
+ function after(code) {
270
+ if (isBackslashMath && !backslashContentSeen) {
271
+ return nok(code);
272
+ }
273
+ effects.exit('mathFlow');
274
+ return ok(code);
275
+ }
276
+
277
+ /**
278
+ * Before math content or a closing backslash fence.
279
+ *
280
+ * @type {State}
281
+ */
282
+ function backslashContentStart(code) {
283
+ return effects.attempt({
284
+ tokenize: tokenizeClosingBackslashFence,
285
+ partial: true
286
+ }, after, backslashBeforeContentChunk)(code);
287
+ }
288
+
289
+ /**
290
+ * Before math content, definitely not before a closing backslash fence.
291
+ *
292
+ * @type {State}
293
+ */
294
+ function backslashBeforeContentChunk(code) {
295
+ if (code === null) {
296
+ return after(code);
297
+ }
298
+ if (markdownLineEnding(code)) {
299
+ return effects.attempt(nonLazyContinuation, backslashContentStart, after)(code);
300
+ }
301
+ if (code === 92) {
302
+ effects.enter('mathFlowValue');
303
+ effects.consume(code);
304
+ backslashContentSeen = true;
305
+ effects.exit('mathFlowValue');
306
+ return backslashBeforeContentChunk;
307
+ }
308
+ effects.enter('mathFlowValue');
309
+ return backslashContentChunk(code);
310
+ }
311
+
312
+ /**
313
+ * In backslash-delimited math content.
314
+ *
315
+ * @type {State}
316
+ */
317
+ function backslashContentChunk(code) {
318
+ if (code === null || markdownLineEnding(code)) {
319
+ effects.exit('mathFlowValue');
320
+ return backslashBeforeContentChunk(code);
321
+ }
322
+ if (code === 92) {
323
+ effects.exit('mathFlowValue');
324
+ return backslashContentStart(code);
325
+ }
326
+ effects.consume(code);
327
+ backslashContentSeen = true;
328
+ return backslashContentChunk;
329
+ }
330
+
331
+ /** @type {Tokenizer} */
332
+ function tokenizeClosingFence(effects, ok, nok) {
333
+ let size = 0;
334
+ /**
335
+ * Before closing fence, at optional whitespace.
336
+ *
337
+ * ```markdown
338
+ * | $$
339
+ * | \frac{1}{2}
340
+ * > | $$
341
+ * ^
342
+ * ```
343
+ */
344
+ return factorySpace(effects, beforeSequenceClose, "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4);
345
+
346
+ /**
347
+ * In closing fence, after optional whitespace, at sequence.
348
+ *
349
+ * ```markdown
350
+ * | $$
351
+ * | \frac{1}{2}
352
+ * > | $$
353
+ * ^
354
+ * ```
355
+ *
356
+ * @type {State}
357
+ */
358
+ function beforeSequenceClose(code) {
359
+ effects.enter('mathFlowFence');
360
+ effects.enter('mathFlowFenceSequence');
361
+ return sequenceClose(code);
362
+ }
363
+
364
+ /**
365
+ * In closing fence sequence.
366
+ *
367
+ * ```markdown
368
+ * | $$
369
+ * | \frac{1}{2}
370
+ * > | $$
371
+ * ^
372
+ * ```
373
+ *
374
+ * @type {State}
375
+ */
376
+ function sequenceClose(code) {
377
+ if (code === 36) {
378
+ size++;
379
+ effects.consume(code);
380
+ return sequenceClose;
381
+ }
382
+ if (size < sizeOpen) {
383
+ return nok(code);
384
+ }
385
+ effects.exit('mathFlowFenceSequence');
386
+ return factorySpace(effects, afterSequenceClose, "whitespace")(code);
387
+ }
388
+
389
+ /**
390
+ * After closing fence sequence, after optional whitespace.
391
+ *
392
+ * ```markdown
393
+ * | $$
394
+ * | \frac{1}{2}
395
+ * > | $$
396
+ * ^
397
+ * ```
398
+ *
399
+ * @type {State}
400
+ */
401
+ function afterSequenceClose(code) {
402
+ if (code === null || markdownLineEnding(code)) {
403
+ effects.exit('mathFlowFence');
404
+ return ok(code);
405
+ }
406
+ return nok(code);
407
+ }
408
+ }
409
+
410
+ /** @type {Tokenizer} */
411
+ function tokenizeClosingBackslashFence(effects, ok, nok) {
412
+ return beforeSequenceClose;
413
+
414
+ /**
415
+ * In closing fence sequence.
416
+ *
417
+ * @type {State}
418
+ */
419
+ function beforeSequenceClose(code) {
420
+ if (code !== 92) {
421
+ return nok(code);
422
+ }
423
+ effects.enter('mathFlowFence');
424
+ effects.enter('mathFlowFenceSequence');
425
+ effects.consume(code);
426
+ return sequenceClose;
427
+ }
428
+
429
+ /**
430
+ * After the backslash in a closing fence sequence.
431
+ *
432
+ * @type {State}
433
+ */
434
+ function sequenceClose(code) {
435
+ if (code !== 93) {
436
+ return nok(code);
437
+ }
438
+ effects.consume(code);
439
+ effects.exit('mathFlowFenceSequence');
440
+ return factorySpace(effects, afterSequenceClose, "whitespace");
441
+ }
442
+
443
+ /**
444
+ * After closing fence sequence, after optional whitespace.
445
+ *
446
+ * @type {State}
447
+ */
448
+ function afterSequenceClose(code) {
449
+ effects.exit('mathFlowFence');
450
+ return ok(code);
451
+ }
452
+ }
453
+ }
454
+
455
+ /**
456
+ * @this {TokenizeContext}
457
+ * @type {Tokenizer}
458
+ */
459
+ function tokenizeNonLazyContinuation(effects, ok, nok) {
460
+ const self = this;
461
+ return start;
462
+
463
+ /** @type {State} */
464
+ function start(code) {
465
+ if (code === null) {
466
+ return ok(code);
467
+ }
468
+ effects.enter("lineEnding");
469
+ effects.consume(code);
470
+ effects.exit("lineEnding");
471
+ return lineStart;
472
+ }
473
+
474
+ /** @type {State} */
475
+ function lineStart(code) {
476
+ return self.parser.lazy[self.now().line] ? nok(code) : ok(code);
477
+ }
478
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @param {Options | null | undefined} [options={}]
3
+ * Configuration (default: `{}`).
4
+ * @returns {Construct}
5
+ * Construct.
6
+ */
7
+ export function mathText(options?: Options | null | undefined): Construct;
8
+ import type { Options } from '@ziloen/micromark-extension-math';
9
+ import type { Construct } from 'micromark-util-types';