@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.
- package/dev/index.d.ts +62 -0
- package/dev/index.js +3 -0
- package/dev/lib/html.d.ts +15 -0
- package/dev/lib/html.js +91 -0
- package/dev/lib/math-flow.d.ts +3 -0
- package/dev/lib/math-flow.js +548 -0
- package/dev/lib/math-text.d.ts +9 -0
- package/dev/lib/math-text.js +408 -0
- package/dev/lib/syntax.d.ts +12 -0
- package/dev/lib/syntax.js +26 -0
- package/index.d.ts +62 -0
- package/index.js +3 -0
- package/lib/html.d.ts +15 -0
- package/lib/html.js +93 -0
- package/lib/math-flow.d.ts +3 -0
- package/lib/math-flow.js +478 -0
- package/lib/math-text.d.ts +9 -0
- package/lib/math-text.js +339 -0
- package/lib/syntax.d.ts +12 -0
- package/lib/syntax.js +30 -0
- package/license +22 -0
- package/package.json +124 -0
- package/readme.md +463 -0
package/dev/index.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type {KatexOptions} from 'katex'
|
|
2
|
+
|
|
3
|
+
export {mathHtml} from './lib/html.js'
|
|
4
|
+
export {math} from './lib/syntax.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for HTML output.
|
|
8
|
+
*
|
|
9
|
+
* > π **Note**: passed to `katex.renderToString`.
|
|
10
|
+
* > `displayMode` is overwritten by this plugin, to `false` for math in
|
|
11
|
+
* > text (inline), and `true` for math in flow (block).
|
|
12
|
+
*/
|
|
13
|
+
export interface HtmlOptions extends KatexOptions {
|
|
14
|
+
/**
|
|
15
|
+
* The field `displayMode` cannot be passed to `micromark-extension-math`.
|
|
16
|
+
* It is overwritten by it,
|
|
17
|
+
* to `false` for math in text (inline) and `true` for math in flow (block).
|
|
18
|
+
*/
|
|
19
|
+
displayMode?: never
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Configuration.
|
|
24
|
+
*/
|
|
25
|
+
export interface Options {
|
|
26
|
+
/**
|
|
27
|
+
* Whether to support math (text) with a single dollar (default: `true`).
|
|
28
|
+
*
|
|
29
|
+
* Single dollars work in Pandoc and many other places, but often interfere
|
|
30
|
+
* with βnormalβ dollars in text.
|
|
31
|
+
* If you turn this off, you can use two or more dollars for text math.
|
|
32
|
+
*/
|
|
33
|
+
singleDollarTextMath?: boolean | null | undefined
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Augment types.
|
|
38
|
+
*/
|
|
39
|
+
declare module 'micromark-util-types' {
|
|
40
|
+
/**
|
|
41
|
+
* Compile data.
|
|
42
|
+
*/
|
|
43
|
+
interface CompileData {
|
|
44
|
+
mathFlowOpen?: boolean
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Token types.
|
|
49
|
+
*/
|
|
50
|
+
interface TokenTypeMap {
|
|
51
|
+
mathFlow: 'mathFlow'
|
|
52
|
+
mathFlowFence: 'mathFlowFence'
|
|
53
|
+
mathFlowFenceMeta: 'mathFlowFenceMeta'
|
|
54
|
+
mathFlowFenceSequence: 'mathFlowFenceSequence'
|
|
55
|
+
mathFlowValue: 'mathFlowValue'
|
|
56
|
+
mathText: 'mathText'
|
|
57
|
+
mathTextData: 'mathTextData'
|
|
58
|
+
mathTextDisplay: 'mathTextDisplay'
|
|
59
|
+
mathTextPadding: 'mathTextPadding'
|
|
60
|
+
mathTextSequence: 'mathTextSequence'
|
|
61
|
+
}
|
|
62
|
+
}
|
package/dev/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create an extension for `micromark` to support math when serializing to
|
|
3
|
+
* HTML.
|
|
4
|
+
*
|
|
5
|
+
* > π **Note**: this uses KaTeX to render math.
|
|
6
|
+
*
|
|
7
|
+
* @param {Options | null | undefined} [options={}]
|
|
8
|
+
* Configuration (default: `{}`).
|
|
9
|
+
* @returns {HtmlExtension}
|
|
10
|
+
* Extension for `micromark` that can be passed in `htmlExtensions`, to
|
|
11
|
+
* support math when serializing to HTML.
|
|
12
|
+
*/
|
|
13
|
+
export function mathHtml(options?: Options | null | undefined): HtmlExtension;
|
|
14
|
+
import type { HtmlOptions as Options } from '@ziloen/micromark-extension-math';
|
|
15
|
+
import type { HtmlExtension } from 'micromark-util-types';
|
package/dev/lib/html.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {HtmlOptions as Options} from '@ziloen/micromark-extension-math'
|
|
3
|
+
* @import {HtmlExtension} from 'micromark-util-types'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import katex from 'katex'
|
|
7
|
+
|
|
8
|
+
const renderToString = katex.renderToString
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create an extension for `micromark` to support math when serializing to
|
|
12
|
+
* HTML.
|
|
13
|
+
*
|
|
14
|
+
* > π **Note**: this uses KaTeX to render math.
|
|
15
|
+
*
|
|
16
|
+
* @param {Options | null | undefined} [options={}]
|
|
17
|
+
* Configuration (default: `{}`).
|
|
18
|
+
* @returns {HtmlExtension}
|
|
19
|
+
* Extension for `micromark` that can be passed in `htmlExtensions`, to
|
|
20
|
+
* support math when serializing to HTML.
|
|
21
|
+
*/
|
|
22
|
+
export function mathHtml(options) {
|
|
23
|
+
return {
|
|
24
|
+
enter: {
|
|
25
|
+
mathFlow() {
|
|
26
|
+
this.lineEndingIfNeeded()
|
|
27
|
+
this.tag('<div class="math math-display">')
|
|
28
|
+
},
|
|
29
|
+
mathFlowFenceMeta() {
|
|
30
|
+
this.buffer()
|
|
31
|
+
},
|
|
32
|
+
mathText() {
|
|
33
|
+
// Double?
|
|
34
|
+
this.tag('<span class="math math-inline">')
|
|
35
|
+
this.buffer()
|
|
36
|
+
},
|
|
37
|
+
mathTextDisplay() {
|
|
38
|
+
this.tag('<div class="math math-display">')
|
|
39
|
+
this.buffer()
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
exit: {
|
|
43
|
+
mathFlow() {
|
|
44
|
+
const value = this.resume()
|
|
45
|
+
this.tag(math(value.replace(/(?:\r?\n|\r)$/, ''), true))
|
|
46
|
+
this.tag('</div>')
|
|
47
|
+
this.setData('mathFlowOpen')
|
|
48
|
+
this.setData('slurpOneLineEnding')
|
|
49
|
+
},
|
|
50
|
+
mathFlowFence() {
|
|
51
|
+
// After the first fence.
|
|
52
|
+
if (!this.getData('mathFlowOpen')) {
|
|
53
|
+
this.setData('mathFlowOpen', true)
|
|
54
|
+
this.setData('slurpOneLineEnding', true)
|
|
55
|
+
this.buffer()
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
mathFlowFenceMeta() {
|
|
59
|
+
this.resume()
|
|
60
|
+
},
|
|
61
|
+
mathFlowValue(token) {
|
|
62
|
+
this.raw(this.sliceSerialize(token))
|
|
63
|
+
},
|
|
64
|
+
mathText() {
|
|
65
|
+
const value = this.resume()
|
|
66
|
+
this.tag(math(value, false))
|
|
67
|
+
this.tag('</span>')
|
|
68
|
+
},
|
|
69
|
+
mathTextDisplay() {
|
|
70
|
+
const value = this.resume()
|
|
71
|
+
this.tag(math(value, true))
|
|
72
|
+
this.tag('</div>')
|
|
73
|
+
},
|
|
74
|
+
mathTextData(token) {
|
|
75
|
+
this.raw(this.sliceSerialize(token))
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {string} value
|
|
82
|
+
* Math text.
|
|
83
|
+
* @param {boolean} displayMode
|
|
84
|
+
* Whether the math is in display mode.
|
|
85
|
+
* @returns {string}
|
|
86
|
+
* HTML.
|
|
87
|
+
*/
|
|
88
|
+
function math(value, displayMode) {
|
|
89
|
+
return renderToString(value, {...options, displayMode})
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Construct, State, TokenizeContext, Tokenizer} from 'micromark-util-types'
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {ok as assert} from 'devlop'
|
|
6
|
+
import {factorySpace} from 'micromark-factory-space'
|
|
7
|
+
import {markdownLineEnding} from 'micromark-util-character'
|
|
8
|
+
import {codes, constants, types} from 'micromark-util-symbol'
|
|
9
|
+
|
|
10
|
+
/** @type {Construct} */
|
|
11
|
+
export const mathFlow = {
|
|
12
|
+
tokenize: tokenizeMathFenced,
|
|
13
|
+
concrete: true,
|
|
14
|
+
name: 'mathFlow'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** @type {Construct} */
|
|
18
|
+
const nonLazyContinuation = {
|
|
19
|
+
tokenize: tokenizeNonLazyContinuation,
|
|
20
|
+
partial: true
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @this {TokenizeContext}
|
|
25
|
+
* @type {Tokenizer}
|
|
26
|
+
*/
|
|
27
|
+
function tokenizeMathFenced(effects, ok, nok) {
|
|
28
|
+
const self = this
|
|
29
|
+
const tail = self.events[self.events.length - 1]
|
|
30
|
+
const initialSize =
|
|
31
|
+
tail && tail[1].type === types.linePrefix
|
|
32
|
+
? tail[2].sliceSerialize(tail[1], true).length
|
|
33
|
+
: 0
|
|
34
|
+
let sizeOpen = 0
|
|
35
|
+
let backslashContentSeen = false
|
|
36
|
+
let isBackslashMath = false
|
|
37
|
+
|
|
38
|
+
return start
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Start of math.
|
|
42
|
+
*
|
|
43
|
+
* ```markdown
|
|
44
|
+
* > | $$
|
|
45
|
+
* ^
|
|
46
|
+
* | \frac{1}{2}
|
|
47
|
+
* | $$
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @type {State}
|
|
51
|
+
*/
|
|
52
|
+
function start(code) {
|
|
53
|
+
assert(
|
|
54
|
+
code === codes.dollarSign || code === codes.backslash,
|
|
55
|
+
'expected `$` or `\\`'
|
|
56
|
+
)
|
|
57
|
+
effects.enter('mathFlow')
|
|
58
|
+
effects.enter('mathFlowFence')
|
|
59
|
+
effects.enter('mathFlowFenceSequence')
|
|
60
|
+
|
|
61
|
+
if (code === codes.backslash) {
|
|
62
|
+
effects.consume(code)
|
|
63
|
+
return sequenceOpenBackslash
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return sequenceOpen(code)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* In opening fence sequence.
|
|
71
|
+
*
|
|
72
|
+
* ```markdown
|
|
73
|
+
* > | $$
|
|
74
|
+
* ^
|
|
75
|
+
* | \frac{1}{2}
|
|
76
|
+
* | $$
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @type {State}
|
|
80
|
+
*/
|
|
81
|
+
function sequenceOpen(code) {
|
|
82
|
+
if (code === codes.dollarSign) {
|
|
83
|
+
effects.consume(code)
|
|
84
|
+
sizeOpen++
|
|
85
|
+
return sequenceOpen
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (sizeOpen < 2) {
|
|
89
|
+
return nok(code)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
effects.exit('mathFlowFenceSequence')
|
|
93
|
+
return factorySpace(effects, metaBefore, types.whitespace)(code)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* After the backslash in an opening fence sequence.
|
|
98
|
+
*
|
|
99
|
+
* ```markdown
|
|
100
|
+
* > | \[
|
|
101
|
+
* ^
|
|
102
|
+
* | \frac{1}{2}
|
|
103
|
+
* | \]
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @type {State}
|
|
107
|
+
*/
|
|
108
|
+
function sequenceOpenBackslash(code) {
|
|
109
|
+
if (code !== codes.leftSquareBracket) {
|
|
110
|
+
return nok(code)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
isBackslashMath = true
|
|
114
|
+
effects.consume(code)
|
|
115
|
+
effects.exit('mathFlowFenceSequence')
|
|
116
|
+
effects.exit('mathFlowFence')
|
|
117
|
+
|
|
118
|
+
if (self.interrupt) {
|
|
119
|
+
return ok
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return backslashContentStart
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* In opening fence, before meta.
|
|
127
|
+
*
|
|
128
|
+
* ```markdown
|
|
129
|
+
* > | $$asciimath
|
|
130
|
+
* ^
|
|
131
|
+
* | x < y
|
|
132
|
+
* | $$
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @type {State}
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
function metaBefore(code) {
|
|
139
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
140
|
+
return metaAfter(code)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
effects.enter('mathFlowFenceMeta')
|
|
144
|
+
effects.enter(types.chunkString, {contentType: constants.contentTypeString})
|
|
145
|
+
return meta(code)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* In meta.
|
|
150
|
+
*
|
|
151
|
+
* ```markdown
|
|
152
|
+
* > | $$asciimath
|
|
153
|
+
* ^
|
|
154
|
+
* | x < y
|
|
155
|
+
* | $$
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @type {State}
|
|
159
|
+
*/
|
|
160
|
+
function meta(code) {
|
|
161
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
162
|
+
effects.exit(types.chunkString)
|
|
163
|
+
effects.exit('mathFlowFenceMeta')
|
|
164
|
+
return metaAfter(code)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (code === codes.dollarSign) {
|
|
168
|
+
return nok(code)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
effects.consume(code)
|
|
172
|
+
return meta
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* After meta.
|
|
177
|
+
*
|
|
178
|
+
* ```markdown
|
|
179
|
+
* > | $$
|
|
180
|
+
* ^
|
|
181
|
+
* | \frac{1}{2}
|
|
182
|
+
* | $$
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
185
|
+
* @type {State}
|
|
186
|
+
*/
|
|
187
|
+
function metaAfter(code) {
|
|
188
|
+
// Guaranteed to be eol/eof.
|
|
189
|
+
effects.exit('mathFlowFence')
|
|
190
|
+
|
|
191
|
+
if (self.interrupt) {
|
|
192
|
+
return ok(code)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return effects.attempt(
|
|
196
|
+
nonLazyContinuation,
|
|
197
|
+
beforeNonLazyContinuation,
|
|
198
|
+
after
|
|
199
|
+
)(code)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* After eol/eof in math, at a non-lazy closing fence or content.
|
|
204
|
+
*
|
|
205
|
+
* ```markdown
|
|
206
|
+
* | $$
|
|
207
|
+
* > | \frac{1}{2}
|
|
208
|
+
* ^
|
|
209
|
+
* > | $$
|
|
210
|
+
* ^
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @type {State}
|
|
214
|
+
*/
|
|
215
|
+
function beforeNonLazyContinuation(code) {
|
|
216
|
+
return effects.attempt(
|
|
217
|
+
{tokenize: tokenizeClosingFence, partial: true},
|
|
218
|
+
after,
|
|
219
|
+
contentStart
|
|
220
|
+
)(code)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Before math content, definitely not before a closing fence.
|
|
225
|
+
*
|
|
226
|
+
* ```markdown
|
|
227
|
+
* | $$
|
|
228
|
+
* > | \frac{1}{2}
|
|
229
|
+
* ^
|
|
230
|
+
* | $$
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* @type {State}
|
|
234
|
+
*/
|
|
235
|
+
function contentStart(code) {
|
|
236
|
+
return (
|
|
237
|
+
initialSize
|
|
238
|
+
? factorySpace(
|
|
239
|
+
effects,
|
|
240
|
+
beforeContentChunk,
|
|
241
|
+
types.linePrefix,
|
|
242
|
+
initialSize + 1
|
|
243
|
+
)
|
|
244
|
+
: beforeContentChunk
|
|
245
|
+
)(code)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Before math content, after optional prefix.
|
|
250
|
+
*
|
|
251
|
+
* ```markdown
|
|
252
|
+
* | $$
|
|
253
|
+
* > | \frac{1}{2}
|
|
254
|
+
* ^
|
|
255
|
+
* | $$
|
|
256
|
+
* ```
|
|
257
|
+
*
|
|
258
|
+
* @type {State}
|
|
259
|
+
*/
|
|
260
|
+
function beforeContentChunk(code) {
|
|
261
|
+
if (code === codes.eof) {
|
|
262
|
+
return after(code)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (markdownLineEnding(code)) {
|
|
266
|
+
return effects.attempt(
|
|
267
|
+
nonLazyContinuation,
|
|
268
|
+
beforeNonLazyContinuation,
|
|
269
|
+
after
|
|
270
|
+
)(code)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
effects.enter('mathFlowValue')
|
|
274
|
+
return contentChunk(code)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* In math content.
|
|
279
|
+
*
|
|
280
|
+
* ```markdown
|
|
281
|
+
* | $$
|
|
282
|
+
* > | \frac{1}{2}
|
|
283
|
+
* ^
|
|
284
|
+
* | $$
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* @type {State}
|
|
288
|
+
*/
|
|
289
|
+
function contentChunk(code) {
|
|
290
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
291
|
+
effects.exit('mathFlowValue')
|
|
292
|
+
return beforeContentChunk(code)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
effects.consume(code)
|
|
296
|
+
return contentChunk
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* After math (ha!).
|
|
301
|
+
*
|
|
302
|
+
* ```markdown
|
|
303
|
+
* | $$
|
|
304
|
+
* | \frac{1}{2}
|
|
305
|
+
* > | $$
|
|
306
|
+
* ^
|
|
307
|
+
* ```
|
|
308
|
+
*
|
|
309
|
+
* @type {State}
|
|
310
|
+
*/
|
|
311
|
+
function after(code) {
|
|
312
|
+
if (isBackslashMath && !backslashContentSeen) {
|
|
313
|
+
return nok(code)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
effects.exit('mathFlow')
|
|
317
|
+
return ok(code)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Before math content or a closing backslash fence.
|
|
322
|
+
*
|
|
323
|
+
* @type {State}
|
|
324
|
+
*/
|
|
325
|
+
function backslashContentStart(code) {
|
|
326
|
+
return effects.attempt(
|
|
327
|
+
{tokenize: tokenizeClosingBackslashFence, partial: true},
|
|
328
|
+
after,
|
|
329
|
+
backslashBeforeContentChunk
|
|
330
|
+
)(code)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Before math content, definitely not before a closing backslash fence.
|
|
335
|
+
*
|
|
336
|
+
* @type {State}
|
|
337
|
+
*/
|
|
338
|
+
function backslashBeforeContentChunk(code) {
|
|
339
|
+
if (code === codes.eof) {
|
|
340
|
+
return after(code)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (markdownLineEnding(code)) {
|
|
344
|
+
return effects.attempt(
|
|
345
|
+
nonLazyContinuation,
|
|
346
|
+
backslashContentStart,
|
|
347
|
+
after
|
|
348
|
+
)(code)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (code === codes.backslash) {
|
|
352
|
+
effects.enter('mathFlowValue')
|
|
353
|
+
effects.consume(code)
|
|
354
|
+
backslashContentSeen = true
|
|
355
|
+
effects.exit('mathFlowValue')
|
|
356
|
+
return backslashBeforeContentChunk
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
effects.enter('mathFlowValue')
|
|
360
|
+
return backslashContentChunk(code)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* In backslash-delimited math content.
|
|
365
|
+
*
|
|
366
|
+
* @type {State}
|
|
367
|
+
*/
|
|
368
|
+
function backslashContentChunk(code) {
|
|
369
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
370
|
+
effects.exit('mathFlowValue')
|
|
371
|
+
return backslashBeforeContentChunk(code)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (code === codes.backslash) {
|
|
375
|
+
effects.exit('mathFlowValue')
|
|
376
|
+
return backslashContentStart(code)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
effects.consume(code)
|
|
380
|
+
backslashContentSeen = true
|
|
381
|
+
return backslashContentChunk
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** @type {Tokenizer} */
|
|
385
|
+
function tokenizeClosingFence(effects, ok, nok) {
|
|
386
|
+
let size = 0
|
|
387
|
+
|
|
388
|
+
assert(self.parser.constructs.disable.null, 'expected `disable.null`')
|
|
389
|
+
/**
|
|
390
|
+
* Before closing fence, at optional whitespace.
|
|
391
|
+
*
|
|
392
|
+
* ```markdown
|
|
393
|
+
* | $$
|
|
394
|
+
* | \frac{1}{2}
|
|
395
|
+
* > | $$
|
|
396
|
+
* ^
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
return factorySpace(
|
|
400
|
+
effects,
|
|
401
|
+
beforeSequenceClose,
|
|
402
|
+
types.linePrefix,
|
|
403
|
+
self.parser.constructs.disable.null.includes('codeIndented')
|
|
404
|
+
? undefined
|
|
405
|
+
: constants.tabSize
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* In closing fence, after optional whitespace, at sequence.
|
|
410
|
+
*
|
|
411
|
+
* ```markdown
|
|
412
|
+
* | $$
|
|
413
|
+
* | \frac{1}{2}
|
|
414
|
+
* > | $$
|
|
415
|
+
* ^
|
|
416
|
+
* ```
|
|
417
|
+
*
|
|
418
|
+
* @type {State}
|
|
419
|
+
*/
|
|
420
|
+
function beforeSequenceClose(code) {
|
|
421
|
+
effects.enter('mathFlowFence')
|
|
422
|
+
effects.enter('mathFlowFenceSequence')
|
|
423
|
+
return sequenceClose(code)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* In closing fence sequence.
|
|
428
|
+
*
|
|
429
|
+
* ```markdown
|
|
430
|
+
* | $$
|
|
431
|
+
* | \frac{1}{2}
|
|
432
|
+
* > | $$
|
|
433
|
+
* ^
|
|
434
|
+
* ```
|
|
435
|
+
*
|
|
436
|
+
* @type {State}
|
|
437
|
+
*/
|
|
438
|
+
function sequenceClose(code) {
|
|
439
|
+
if (code === codes.dollarSign) {
|
|
440
|
+
size++
|
|
441
|
+
effects.consume(code)
|
|
442
|
+
return sequenceClose
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (size < sizeOpen) {
|
|
446
|
+
return nok(code)
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
effects.exit('mathFlowFenceSequence')
|
|
450
|
+
return factorySpace(effects, afterSequenceClose, types.whitespace)(code)
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* After closing fence sequence, after optional whitespace.
|
|
455
|
+
*
|
|
456
|
+
* ```markdown
|
|
457
|
+
* | $$
|
|
458
|
+
* | \frac{1}{2}
|
|
459
|
+
* > | $$
|
|
460
|
+
* ^
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* @type {State}
|
|
464
|
+
*/
|
|
465
|
+
function afterSequenceClose(code) {
|
|
466
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
467
|
+
effects.exit('mathFlowFence')
|
|
468
|
+
return ok(code)
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
return nok(code)
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/** @type {Tokenizer} */
|
|
476
|
+
function tokenizeClosingBackslashFence(effects, ok, nok) {
|
|
477
|
+
return beforeSequenceClose
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* In closing fence sequence.
|
|
481
|
+
*
|
|
482
|
+
* @type {State}
|
|
483
|
+
*/
|
|
484
|
+
function beforeSequenceClose(code) {
|
|
485
|
+
if (code !== codes.backslash) {
|
|
486
|
+
return nok(code)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
effects.enter('mathFlowFence')
|
|
490
|
+
effects.enter('mathFlowFenceSequence')
|
|
491
|
+
effects.consume(code)
|
|
492
|
+
return sequenceClose
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* After the backslash in a closing fence sequence.
|
|
497
|
+
*
|
|
498
|
+
* @type {State}
|
|
499
|
+
*/
|
|
500
|
+
function sequenceClose(code) {
|
|
501
|
+
if (code !== codes.rightSquareBracket) {
|
|
502
|
+
return nok(code)
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
effects.consume(code)
|
|
506
|
+
effects.exit('mathFlowFenceSequence')
|
|
507
|
+
return factorySpace(effects, afterSequenceClose, types.whitespace)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* After closing fence sequence, after optional whitespace.
|
|
512
|
+
*
|
|
513
|
+
* @type {State}
|
|
514
|
+
*/
|
|
515
|
+
function afterSequenceClose(code) {
|
|
516
|
+
effects.exit('mathFlowFence')
|
|
517
|
+
return ok(code)
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* @this {TokenizeContext}
|
|
524
|
+
* @type {Tokenizer}
|
|
525
|
+
*/
|
|
526
|
+
function tokenizeNonLazyContinuation(effects, ok, nok) {
|
|
527
|
+
const self = this
|
|
528
|
+
|
|
529
|
+
return start
|
|
530
|
+
|
|
531
|
+
/** @type {State} */
|
|
532
|
+
function start(code) {
|
|
533
|
+
if (code === null) {
|
|
534
|
+
return ok(code)
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
assert(markdownLineEnding(code), 'expected eol')
|
|
538
|
+
effects.enter(types.lineEnding)
|
|
539
|
+
effects.consume(code)
|
|
540
|
+
effects.exit(types.lineEnding)
|
|
541
|
+
return lineStart
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** @type {State} */
|
|
545
|
+
function lineStart(code) {
|
|
546
|
+
return self.parser.lazy[self.now().line] ? nok(code) : ok(code)
|
|
547
|
+
}
|
|
548
|
+
}
|