@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
|
@@ -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';
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Options} from '@ziloen/micromark-extension-math'
|
|
3
|
+
* @import {Construct, Previous, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// To do: next major: clean spaces in HTML compiler.
|
|
7
|
+
// This has to be coordinated together with `mdast-util-math`.
|
|
8
|
+
|
|
9
|
+
import {ok as assert} from 'devlop'
|
|
10
|
+
import {
|
|
11
|
+
asciiDigit,
|
|
12
|
+
markdownLineEnding,
|
|
13
|
+
markdownSpace
|
|
14
|
+
} from 'micromark-util-character'
|
|
15
|
+
import {codes, types} from 'micromark-util-symbol'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {Options | null | undefined} [options={}]
|
|
19
|
+
* Configuration (default: `{}`).
|
|
20
|
+
* @returns {Construct}
|
|
21
|
+
* Construct.
|
|
22
|
+
*/
|
|
23
|
+
export function mathText(options) {
|
|
24
|
+
const options_ = options || {}
|
|
25
|
+
let single = options_.singleDollarTextMath
|
|
26
|
+
|
|
27
|
+
if (single === null || single === undefined) {
|
|
28
|
+
single = true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
tokenize: tokenizeMathText,
|
|
33
|
+
resolve: resolveMathText,
|
|
34
|
+
previous: previousCode,
|
|
35
|
+
name: 'mathText'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @this {TokenizeContext}
|
|
40
|
+
* @type {Tokenizer}
|
|
41
|
+
*/
|
|
42
|
+
function tokenizeMathText(effects, ok, nok) {
|
|
43
|
+
const self = this
|
|
44
|
+
/** @type {number} */
|
|
45
|
+
let codeOpen = codes.dollarSign
|
|
46
|
+
/** @type {number} */
|
|
47
|
+
let codeClose = codes.dollarSign
|
|
48
|
+
/** @type {'mathText' | 'mathTextDisplay'} */
|
|
49
|
+
let type = 'mathText'
|
|
50
|
+
let sizeOpen = 0
|
|
51
|
+
/** @type {number} */
|
|
52
|
+
let size
|
|
53
|
+
/** @type {number | null | undefined} */
|
|
54
|
+
let previous
|
|
55
|
+
/** @type {Token} */
|
|
56
|
+
let tokenType
|
|
57
|
+
/** @type {Token} */
|
|
58
|
+
let token
|
|
59
|
+
let dataSeen = false
|
|
60
|
+
|
|
61
|
+
return start
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Start of math (text).
|
|
65
|
+
*
|
|
66
|
+
* ```markdown
|
|
67
|
+
* > | $a$
|
|
68
|
+
* ^
|
|
69
|
+
* > | \$a$
|
|
70
|
+
* ^
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @type {State}
|
|
74
|
+
*/
|
|
75
|
+
function start(code) {
|
|
76
|
+
assert(
|
|
77
|
+
code === codes.dollarSign || code === codes.backslash,
|
|
78
|
+
'expected `$` or `\\`'
|
|
79
|
+
)
|
|
80
|
+
assert(
|
|
81
|
+
code === codes.backslash || previousCode.call(self, self.previous),
|
|
82
|
+
'expected correct previous'
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
if (code === codes.backslash) {
|
|
86
|
+
codeOpen = codes.leftParenthesis
|
|
87
|
+
codeClose = codes.rightParenthesis
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
tokenType = effects.enter(type)
|
|
91
|
+
effects.enter('mathTextSequence')
|
|
92
|
+
effects.consume(code)
|
|
93
|
+
sizeOpen++
|
|
94
|
+
return code === codes.backslash ? sequenceOpenBackslash : sequenceOpen
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* In opening sequence.
|
|
99
|
+
*
|
|
100
|
+
* ```markdown
|
|
101
|
+
* > | $a$
|
|
102
|
+
* ^
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @type {State}
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
function sequenceOpen(code) {
|
|
109
|
+
if (code === codes.dollarSign) {
|
|
110
|
+
effects.consume(code)
|
|
111
|
+
sizeOpen++
|
|
112
|
+
return sequenceOpen
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Not enough markers in the sequence.
|
|
116
|
+
if (
|
|
117
|
+
(sizeOpen < 2 && !single) ||
|
|
118
|
+
(sizeOpen === 1 && !validSingleDollarOpen(code))
|
|
119
|
+
) {
|
|
120
|
+
return nok(code)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
effects.exit('mathTextSequence')
|
|
124
|
+
return between(code)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* After the backslash in an opening sequence.
|
|
129
|
+
*
|
|
130
|
+
* ```markdown
|
|
131
|
+
* > | \(a\)
|
|
132
|
+
* ^
|
|
133
|
+
* > | \[a\]
|
|
134
|
+
* ^
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @type {State}
|
|
138
|
+
*/
|
|
139
|
+
function sequenceOpenBackslash(code) {
|
|
140
|
+
if (code !== codes.leftParenthesis && code !== codes.leftSquareBracket) {
|
|
141
|
+
return nok(code)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
codeOpen = code
|
|
145
|
+
codeClose =
|
|
146
|
+
code === codes.leftParenthesis
|
|
147
|
+
? codes.rightParenthesis
|
|
148
|
+
: codes.rightSquareBracket
|
|
149
|
+
type = code === codes.leftParenthesis ? 'mathText' : 'mathTextDisplay'
|
|
150
|
+
|
|
151
|
+
tokenType.type = type
|
|
152
|
+
effects.consume(code)
|
|
153
|
+
effects.exit('mathTextSequence')
|
|
154
|
+
return between
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Between something and something else.
|
|
159
|
+
*
|
|
160
|
+
* ```markdown
|
|
161
|
+
* > | $a$
|
|
162
|
+
* ^^
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* @type {State}
|
|
166
|
+
*/
|
|
167
|
+
function between(code) {
|
|
168
|
+
if (code === codes.eof) {
|
|
169
|
+
return nok(code)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (code === codes.dollarSign && codeOpen === codes.dollarSign) {
|
|
173
|
+
token = effects.enter('mathTextSequence')
|
|
174
|
+
size = 0
|
|
175
|
+
return sequenceClose(code)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (code === codes.backslash && codeOpen !== codes.dollarSign) {
|
|
179
|
+
token = effects.enter('mathTextSequence')
|
|
180
|
+
return sequenceCloseBackslash(code)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Tabs don’t work, and virtual spaces don’t make sense.
|
|
184
|
+
if (code === codes.space) {
|
|
185
|
+
effects.enter('space')
|
|
186
|
+
effects.consume(code)
|
|
187
|
+
effects.exit('space')
|
|
188
|
+
previous = code
|
|
189
|
+
return between
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (markdownLineEnding(code)) {
|
|
193
|
+
effects.enter(types.lineEnding)
|
|
194
|
+
effects.consume(code)
|
|
195
|
+
effects.exit(types.lineEnding)
|
|
196
|
+
previous = code
|
|
197
|
+
return between
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Data.
|
|
201
|
+
effects.enter('mathTextData')
|
|
202
|
+
return data(code)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* In data.
|
|
207
|
+
*
|
|
208
|
+
* ```markdown
|
|
209
|
+
* > | $a$
|
|
210
|
+
* ^
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @type {State}
|
|
214
|
+
*/
|
|
215
|
+
function data(code) {
|
|
216
|
+
if (
|
|
217
|
+
code === codes.eof ||
|
|
218
|
+
code === codes.space ||
|
|
219
|
+
(code === codes.dollarSign && codeOpen === codes.dollarSign) ||
|
|
220
|
+
(code === codes.backslash && codeOpen !== codes.dollarSign) ||
|
|
221
|
+
markdownLineEnding(code)
|
|
222
|
+
) {
|
|
223
|
+
effects.exit('mathTextData')
|
|
224
|
+
return between(code)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
effects.consume(code)
|
|
228
|
+
previous = code
|
|
229
|
+
dataSeen = true
|
|
230
|
+
return data
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* In closing sequence.
|
|
235
|
+
*
|
|
236
|
+
* ```markdown
|
|
237
|
+
* > | `a`
|
|
238
|
+
* ^
|
|
239
|
+
* ```
|
|
240
|
+
*
|
|
241
|
+
* @type {State}
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
function sequenceClose(code) {
|
|
245
|
+
// More.
|
|
246
|
+
if (code === codes.dollarSign) {
|
|
247
|
+
effects.consume(code)
|
|
248
|
+
size++
|
|
249
|
+
return sequenceClose
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Done!
|
|
253
|
+
if (
|
|
254
|
+
size === sizeOpen &&
|
|
255
|
+
(sizeOpen !== 1 || validSingleDollarClose(previous, code))
|
|
256
|
+
) {
|
|
257
|
+
effects.exit('mathTextSequence')
|
|
258
|
+
effects.exit(type)
|
|
259
|
+
return ok(code)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// More or less accents: mark as data.
|
|
263
|
+
token.type = 'mathTextData'
|
|
264
|
+
return data(code)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* In a closing backslash sequence.
|
|
269
|
+
*
|
|
270
|
+
* ```markdown
|
|
271
|
+
* > | \(a\)
|
|
272
|
+
* ^
|
|
273
|
+
* ```
|
|
274
|
+
*
|
|
275
|
+
* @type {State}
|
|
276
|
+
*/
|
|
277
|
+
function sequenceCloseBackslash(code) {
|
|
278
|
+
assert(code === codes.backslash, 'expected `\\`')
|
|
279
|
+
effects.consume(code)
|
|
280
|
+
return sequenceCloseBackslashEnd
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* After the backslash in a closing sequence.
|
|
285
|
+
*
|
|
286
|
+
* @type {State}
|
|
287
|
+
*/
|
|
288
|
+
function sequenceCloseBackslashEnd(code) {
|
|
289
|
+
if (code === codeClose) {
|
|
290
|
+
if (!dataSeen) {
|
|
291
|
+
return nok(code)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
effects.consume(code)
|
|
295
|
+
effects.exit('mathTextSequence')
|
|
296
|
+
effects.exit(type)
|
|
297
|
+
return ok
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
token.type = 'mathTextData'
|
|
301
|
+
previous = codes.backslash
|
|
302
|
+
return data(code)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** @type {Resolver} */
|
|
308
|
+
function resolveMathText(events) {
|
|
309
|
+
let tailExitIndex = events.length - 4
|
|
310
|
+
let headEnterIndex = 3
|
|
311
|
+
/** @type {number} */
|
|
312
|
+
let index
|
|
313
|
+
/** @type {number | undefined} */
|
|
314
|
+
let enter
|
|
315
|
+
|
|
316
|
+
// If we start and end with an EOL or a space.
|
|
317
|
+
if (
|
|
318
|
+
(events[headEnterIndex][1].type === types.lineEnding ||
|
|
319
|
+
events[headEnterIndex][1].type === 'space') &&
|
|
320
|
+
(events[tailExitIndex][1].type === types.lineEnding ||
|
|
321
|
+
events[tailExitIndex][1].type === 'space')
|
|
322
|
+
) {
|
|
323
|
+
index = headEnterIndex
|
|
324
|
+
|
|
325
|
+
// And we have data.
|
|
326
|
+
while (++index < tailExitIndex) {
|
|
327
|
+
if (events[index][1].type === 'mathTextData') {
|
|
328
|
+
// Then we have padding.
|
|
329
|
+
events[tailExitIndex][1].type = 'mathTextPadding'
|
|
330
|
+
events[headEnterIndex][1].type = 'mathTextPadding'
|
|
331
|
+
headEnterIndex += 2
|
|
332
|
+
tailExitIndex -= 2
|
|
333
|
+
break
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Merge adjacent spaces and data.
|
|
339
|
+
index = headEnterIndex - 1
|
|
340
|
+
tailExitIndex++
|
|
341
|
+
|
|
342
|
+
while (++index <= tailExitIndex) {
|
|
343
|
+
if (enter === undefined) {
|
|
344
|
+
if (
|
|
345
|
+
index !== tailExitIndex &&
|
|
346
|
+
events[index][1].type !== types.lineEnding
|
|
347
|
+
) {
|
|
348
|
+
enter = index
|
|
349
|
+
}
|
|
350
|
+
} else if (
|
|
351
|
+
index === tailExitIndex ||
|
|
352
|
+
events[index][1].type === types.lineEnding
|
|
353
|
+
) {
|
|
354
|
+
events[enter][1].type = 'mathTextData'
|
|
355
|
+
|
|
356
|
+
if (index !== enter + 2) {
|
|
357
|
+
events[enter][1].end = events[index - 1][1].end
|
|
358
|
+
events.splice(enter + 2, index - enter - 2)
|
|
359
|
+
tailExitIndex -= index - enter - 2
|
|
360
|
+
index = enter + 2
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
enter = undefined
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return events
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* @this {TokenizeContext}
|
|
372
|
+
* @type {Previous}
|
|
373
|
+
*/
|
|
374
|
+
function previousCode(code) {
|
|
375
|
+
// If there is a previous code, there will always be a tail.
|
|
376
|
+
return (
|
|
377
|
+
code !== codes.dollarSign ||
|
|
378
|
+
this.events[this.events.length - 1][1].type === types.characterEscape
|
|
379
|
+
)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* @param {number | null} code
|
|
384
|
+
* Code.
|
|
385
|
+
* @returns {boolean}
|
|
386
|
+
* Whether `code` can follow an opening single dollar.
|
|
387
|
+
*/
|
|
388
|
+
function validSingleDollarOpen(code) {
|
|
389
|
+
return code !== codes.eof && !markdownLineEnding(code) && !markdownSpace(code)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* @param {number | null | undefined} before
|
|
394
|
+
* Code before the closing dollar.
|
|
395
|
+
* @param {number | null} after
|
|
396
|
+
* Code after the closing dollar.
|
|
397
|
+
* @returns {boolean}
|
|
398
|
+
* Whether a single dollar can close.
|
|
399
|
+
*/
|
|
400
|
+
function validSingleDollarClose(before, after) {
|
|
401
|
+
return (
|
|
402
|
+
before !== undefined &&
|
|
403
|
+
before !== codes.eof &&
|
|
404
|
+
!markdownLineEnding(before) &&
|
|
405
|
+
!markdownSpace(before) &&
|
|
406
|
+
!asciiDigit(after)
|
|
407
|
+
)
|
|
408
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create an extension for `micromark` to enable math syntax.
|
|
3
|
+
*
|
|
4
|
+
* @param {Options | null | undefined} [options={}]
|
|
5
|
+
* Configuration (default: `{}`).
|
|
6
|
+
* @returns {Extension}
|
|
7
|
+
* Extension for `micromark` that can be passed in `extensions`, to
|
|
8
|
+
* enable math syntax.
|
|
9
|
+
*/
|
|
10
|
+
export function math(options?: Options | null | undefined): Extension;
|
|
11
|
+
import type { Options } from '@ziloen/micromark-extension-math';
|
|
12
|
+
import type { Extension } from 'micromark-util-types';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import {Options} from '@ziloen/micromark-extension-math'
|
|
3
|
+
* @import {Extension} from 'micromark-util-types'
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {codes} from 'micromark-util-symbol'
|
|
7
|
+
import {mathFlow} from './math-flow.js'
|
|
8
|
+
import {mathText} from './math-text.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create an extension for `micromark` to enable math syntax.
|
|
12
|
+
*
|
|
13
|
+
* @param {Options | null | undefined} [options={}]
|
|
14
|
+
* Configuration (default: `{}`).
|
|
15
|
+
* @returns {Extension}
|
|
16
|
+
* Extension for `micromark` that can be passed in `extensions`, to
|
|
17
|
+
* enable math syntax.
|
|
18
|
+
*/
|
|
19
|
+
export function math(options) {
|
|
20
|
+
const text = mathText(options)
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
flow: {[codes.dollarSign]: mathFlow, [codes.backslash]: mathFlow},
|
|
24
|
+
text: {[codes.dollarSign]: text, [codes.backslash]: text}
|
|
25
|
+
}
|
|
26
|
+
}
|
package/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/index.js
ADDED
package/lib/html.d.ts
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/lib/html.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
const renderToString = katex.renderToString;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create an extension for `micromark` to support math when serializing to
|
|
11
|
+
* HTML.
|
|
12
|
+
*
|
|
13
|
+
* > 👉 **Note**: this uses KaTeX to render math.
|
|
14
|
+
*
|
|
15
|
+
* @param {Options | null | undefined} [options={}]
|
|
16
|
+
* Configuration (default: `{}`).
|
|
17
|
+
* @returns {HtmlExtension}
|
|
18
|
+
* Extension for `micromark` that can be passed in `htmlExtensions`, to
|
|
19
|
+
* support math when serializing to HTML.
|
|
20
|
+
*/
|
|
21
|
+
export function mathHtml(options) {
|
|
22
|
+
return {
|
|
23
|
+
enter: {
|
|
24
|
+
mathFlow() {
|
|
25
|
+
this.lineEndingIfNeeded();
|
|
26
|
+
this.tag('<div class="math math-display">');
|
|
27
|
+
},
|
|
28
|
+
mathFlowFenceMeta() {
|
|
29
|
+
this.buffer();
|
|
30
|
+
},
|
|
31
|
+
mathText() {
|
|
32
|
+
// Double?
|
|
33
|
+
this.tag('<span class="math math-inline">');
|
|
34
|
+
this.buffer();
|
|
35
|
+
},
|
|
36
|
+
mathTextDisplay() {
|
|
37
|
+
this.tag('<div class="math math-display">');
|
|
38
|
+
this.buffer();
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
exit: {
|
|
42
|
+
mathFlow() {
|
|
43
|
+
const value = this.resume();
|
|
44
|
+
this.tag(math(value.replace(/(?:\r?\n|\r)$/, ''), true));
|
|
45
|
+
this.tag('</div>');
|
|
46
|
+
this.setData('mathFlowOpen');
|
|
47
|
+
this.setData('slurpOneLineEnding');
|
|
48
|
+
},
|
|
49
|
+
mathFlowFence() {
|
|
50
|
+
// After the first fence.
|
|
51
|
+
if (!this.getData('mathFlowOpen')) {
|
|
52
|
+
this.setData('mathFlowOpen', true);
|
|
53
|
+
this.setData('slurpOneLineEnding', true);
|
|
54
|
+
this.buffer();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
mathFlowFenceMeta() {
|
|
58
|
+
this.resume();
|
|
59
|
+
},
|
|
60
|
+
mathFlowValue(token) {
|
|
61
|
+
this.raw(this.sliceSerialize(token));
|
|
62
|
+
},
|
|
63
|
+
mathText() {
|
|
64
|
+
const value = this.resume();
|
|
65
|
+
this.tag(math(value, false));
|
|
66
|
+
this.tag('</span>');
|
|
67
|
+
},
|
|
68
|
+
mathTextDisplay() {
|
|
69
|
+
const value = this.resume();
|
|
70
|
+
this.tag(math(value, true));
|
|
71
|
+
this.tag('</div>');
|
|
72
|
+
},
|
|
73
|
+
mathTextData(token) {
|
|
74
|
+
this.raw(this.sliceSerialize(token));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {string} value
|
|
81
|
+
* Math text.
|
|
82
|
+
* @param {boolean} displayMode
|
|
83
|
+
* Whether the math is in display mode.
|
|
84
|
+
* @returns {string}
|
|
85
|
+
* HTML.
|
|
86
|
+
*/
|
|
87
|
+
function math(value, displayMode) {
|
|
88
|
+
return renderToString(value, {
|
|
89
|
+
...options,
|
|
90
|
+
displayMode
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|