@yozora/tokenizer-inline-math 2.0.0-alpha.0 → 2.0.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/README.md +4 -6
- package/lib/cjs/index.js +141 -133
- package/lib/esm/index.js +141 -135
- package/lib/types/index.d.ts +3 -1
- package/lib/types/match.d.ts +3 -0
- package/lib/types/parse.d.ts +3 -0
- package/lib/types/tokenizer.d.ts +4 -4
- package/lib/types/types.d.ts +9 -3
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -82,14 +82,14 @@ so you can use `YozoraParser` directly.
|
|
|
82
82
|
registered in *YastParser* as a plugin-in before it can be used.
|
|
83
83
|
|
|
84
84
|
```typescript {4,9}
|
|
85
|
-
import {
|
|
85
|
+
import { DefaultParser } from '@yozora/core-parser'
|
|
86
86
|
import ParagraphTokenizer from '@yozora/tokenizer-paragraph'
|
|
87
87
|
import TextTokenizer from '@yozora/tokenizer-text'
|
|
88
88
|
import InlineMathTokenizer from '@yozora/tokenizer-inline-math'
|
|
89
89
|
|
|
90
|
-
const parser = new
|
|
91
|
-
.
|
|
92
|
-
.
|
|
90
|
+
const parser = new DefaultParser()
|
|
91
|
+
.useFallbackTokenizer(new ParagraphTokenizer())
|
|
92
|
+
.useFallbackTokenizer(new TextTokenizer())
|
|
93
93
|
.useTokenizer(new InlineMathTokenizer())
|
|
94
94
|
|
|
95
95
|
// parse source markdown content
|
|
@@ -228,7 +228,6 @@ Name | Type | Required | Default
|
|
|
228
228
|
[@yozora/tokenizer-link]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link#readme
|
|
229
229
|
[@yozora/tokenizer-link-reference]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link-reference#readme
|
|
230
230
|
[@yozora/tokenizer-list]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list#readme
|
|
231
|
-
[@yozora/tokenizer-list-item]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list-item#readme
|
|
232
231
|
[@yozora/tokenizer-math]: https://github.com/yozorajs/yozora/tree/main/tokenizers/math#readme
|
|
233
232
|
[@yozora/tokenizer-paragraph]: https://github.com/yozorajs/yozora/tree/main/tokenizers/paragraph#readme
|
|
234
233
|
[@yozora/tokenizer-setext-heading]: https://github.com/yozorajs/yozora/tree/main/tokenizers/setext-heading#readme
|
|
@@ -288,7 +287,6 @@ Name | Type | Required | Default
|
|
|
288
287
|
[doc-@yozora/tokenizer-definition]: https://yozora.guanghechen.com/docs/package/tokenizer-definition
|
|
289
288
|
[doc-@yozora/tokenizer-link-reference]: https://yozora.guanghechen.com/docs/package/tokenizer-link-reference
|
|
290
289
|
[doc-@yozora/tokenizer-list]: https://yozora.guanghechen.com/docs/package/tokenizer-list
|
|
291
|
-
[doc-@yozora/tokenizer-list-item]: https://yozora.guanghechen.com/docs/package/tokenizer-list-item
|
|
292
290
|
[doc-@yozora/tokenizer-math]: https://yozora.guanghechen.com/docs/package/tokenizer-math
|
|
293
291
|
[doc-@yozora/tokenizer-paragraph]: https://yozora.guanghechen.com/docs/package/tokenizer-paragraph
|
|
294
292
|
[doc-@yozora/tokenizer-setext-heading]: https://yozora.guanghechen.com/docs/package/tokenizer-setext-heading
|
package/lib/cjs/index.js
CHANGED
|
@@ -6,152 +6,158 @@ var ast = require('@yozora/ast');
|
|
|
6
6
|
var character = require('@yozora/character');
|
|
7
7
|
var coreTokenizer = require('@yozora/core-tokenizer');
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
switch (c) {
|
|
29
|
-
case character.AsciiCodePoint.BACKSLASH:
|
|
30
|
-
i += 1;
|
|
31
|
-
break;
|
|
32
|
-
case character.AsciiCodePoint.BACKTICK: {
|
|
33
|
-
const _startIndex = i;
|
|
34
|
-
i = coreTokenizer.eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, character.AsciiCodePoint.BACKTICK);
|
|
35
|
-
if (i >= blockEndIndex || nodePoints[i].codePoint !== character.AsciiCodePoint.DOLLAR_SIGN) {
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
const delimiter = {
|
|
39
|
-
type: 'opener',
|
|
40
|
-
startIndex: _startIndex,
|
|
41
|
-
endIndex: i + 1,
|
|
42
|
-
};
|
|
43
|
-
potentialDelimiters.push(delimiter);
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
case character.AsciiCodePoint.DOLLAR_SIGN: {
|
|
47
|
-
const _startIndex = i;
|
|
48
|
-
i = coreTokenizer.eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, character.AsciiCodePoint.BACKTICK);
|
|
49
|
-
if (i < blockEndIndex && nodePoints[i].codePoint === character.AsciiCodePoint.DOLLAR_SIGN) {
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
const thickness = i - _startIndex;
|
|
53
|
-
if (thickness <= 1) {
|
|
54
|
-
if (backtickRequired)
|
|
55
|
-
break;
|
|
56
|
-
const delimiter = {
|
|
57
|
-
type: 'both',
|
|
58
|
-
startIndex: _startIndex,
|
|
59
|
-
endIndex: i,
|
|
60
|
-
};
|
|
61
|
-
potentialDelimiters.push(delimiter);
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
const delimiter = {
|
|
65
|
-
type: 'closer',
|
|
66
|
-
startIndex: _startIndex,
|
|
67
|
-
endIndex: i,
|
|
68
|
-
};
|
|
69
|
-
potentialDelimiters.push(delimiter);
|
|
70
|
-
i -= 1;
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
9
|
+
const match = function (api) {
|
|
10
|
+
const { backtickRequired } = this;
|
|
11
|
+
return { findDelimiter, processSingleDelimiter };
|
|
12
|
+
function* findDelimiter() {
|
|
13
|
+
const nodePoints = api.getNodePoints();
|
|
14
|
+
const blockStartIndex = api.getBlockStartIndex();
|
|
15
|
+
const blockEndIndex = api.getBlockEndIndex();
|
|
16
|
+
const potentialDelimiters = [];
|
|
17
|
+
for (let i = blockStartIndex; i < blockEndIndex; ++i) {
|
|
18
|
+
const c = nodePoints[i].codePoint;
|
|
19
|
+
switch (c) {
|
|
20
|
+
case character.AsciiCodePoint.BACKSLASH:
|
|
21
|
+
i += 1;
|
|
22
|
+
break;
|
|
23
|
+
case character.AsciiCodePoint.BACKTICK: {
|
|
24
|
+
const _startIndex = i;
|
|
25
|
+
i = coreTokenizer.eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, character.AsciiCodePoint.BACKTICK);
|
|
26
|
+
if (i >= blockEndIndex || nodePoints[i].codePoint !== character.AsciiCodePoint.DOLLAR_SIGN) {
|
|
27
|
+
break;
|
|
73
28
|
}
|
|
29
|
+
const delimiter = {
|
|
30
|
+
type: 'opener',
|
|
31
|
+
startIndex: _startIndex,
|
|
32
|
+
endIndex: i + 1,
|
|
33
|
+
};
|
|
34
|
+
potentialDelimiters.push(delimiter);
|
|
35
|
+
break;
|
|
74
36
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (lastEndIndex === endIndex) {
|
|
81
|
-
if (delimiter == null || delimiter.startIndex >= startIndex)
|
|
82
|
-
continue;
|
|
37
|
+
case character.AsciiCodePoint.DOLLAR_SIGN: {
|
|
38
|
+
const _startIndex = i;
|
|
39
|
+
i = coreTokenizer.eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, character.AsciiCodePoint.BACKTICK);
|
|
40
|
+
if (i < blockEndIndex && nodePoints[i].codePoint === character.AsciiCodePoint.DOLLAR_SIGN) {
|
|
41
|
+
break;
|
|
83
42
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
88
|
-
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
89
|
-
const delimiter = potentialDelimiters[pIndex];
|
|
90
|
-
if (delimiter.startIndex >= startIndex && delimiter.type !== 'closer')
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
if (pIndex + 1 >= potentialDelimiters.length)
|
|
94
|
-
break;
|
|
95
|
-
openerDelimiter = potentialDelimiters[pIndex];
|
|
96
|
-
const thickness = openerDelimiter.endIndex - openerDelimiter.startIndex;
|
|
97
|
-
for (let i = pIndex + 1; i < potentialDelimiters.length; ++i) {
|
|
98
|
-
const delimiter = potentialDelimiters[i];
|
|
99
|
-
if (delimiter.type !== 'opener' &&
|
|
100
|
-
delimiter.endIndex - delimiter.startIndex === thickness) {
|
|
101
|
-
closerDelimiter = delimiter;
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (closerDelimiter != null)
|
|
43
|
+
const thickness = i - _startIndex;
|
|
44
|
+
if (thickness <= 1) {
|
|
45
|
+
if (backtickRequired)
|
|
106
46
|
break;
|
|
47
|
+
const delimiter = {
|
|
48
|
+
type: 'both',
|
|
49
|
+
startIndex: _startIndex,
|
|
50
|
+
endIndex: i,
|
|
51
|
+
};
|
|
52
|
+
potentialDelimiters.push(delimiter);
|
|
53
|
+
break;
|
|
107
54
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
startIndex: openerDelimiter.startIndex,
|
|
113
|
-
endIndex: closerDelimiter.endIndex,
|
|
114
|
-
thickness: closerDelimiter.endIndex - closerDelimiter.startIndex,
|
|
55
|
+
const delimiter = {
|
|
56
|
+
type: 'closer',
|
|
57
|
+
startIndex: _startIndex,
|
|
58
|
+
endIndex: i,
|
|
115
59
|
};
|
|
60
|
+
potentialDelimiters.push(delimiter);
|
|
61
|
+
i -= 1;
|
|
62
|
+
break;
|
|
116
63
|
}
|
|
117
64
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
65
|
+
}
|
|
66
|
+
let pIndex = 0;
|
|
67
|
+
let lastEndIndex = -1;
|
|
68
|
+
let delimiter = null;
|
|
69
|
+
while (pIndex < potentialDelimiters.length) {
|
|
70
|
+
const [startIndex, endIndex] = yield delimiter;
|
|
71
|
+
if (lastEndIndex === endIndex) {
|
|
72
|
+
if (delimiter == null || delimiter.startIndex >= startIndex)
|
|
73
|
+
continue;
|
|
126
74
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (character.isSpaceLike(nodePoints[i].codePoint))
|
|
136
|
-
continue;
|
|
137
|
-
isAllSpace = false;
|
|
138
|
-
break;
|
|
75
|
+
lastEndIndex = endIndex;
|
|
76
|
+
let openerDelimiter = null;
|
|
77
|
+
let closerDelimiter = null;
|
|
78
|
+
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
79
|
+
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
80
|
+
const delimiter = potentialDelimiters[pIndex];
|
|
81
|
+
if (delimiter.startIndex >= startIndex && delimiter.type !== 'closer')
|
|
82
|
+
break;
|
|
139
83
|
}
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
84
|
+
if (pIndex + 1 >= potentialDelimiters.length)
|
|
85
|
+
break;
|
|
86
|
+
openerDelimiter = potentialDelimiters[pIndex];
|
|
87
|
+
const thickness = openerDelimiter.endIndex - openerDelimiter.startIndex;
|
|
88
|
+
for (let i = pIndex + 1; i < potentialDelimiters.length; ++i) {
|
|
89
|
+
const delimiter = potentialDelimiters[i];
|
|
90
|
+
if (delimiter.type !== 'opener' &&
|
|
91
|
+
delimiter.endIndex - delimiter.startIndex === thickness) {
|
|
92
|
+
closerDelimiter = delimiter;
|
|
93
|
+
break;
|
|
146
94
|
}
|
|
147
95
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return
|
|
153
|
-
|
|
96
|
+
if (closerDelimiter != null)
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
if (closerDelimiter == null)
|
|
100
|
+
return;
|
|
101
|
+
delimiter = {
|
|
102
|
+
type: 'full',
|
|
103
|
+
startIndex: openerDelimiter.startIndex,
|
|
104
|
+
endIndex: closerDelimiter.endIndex,
|
|
105
|
+
thickness: closerDelimiter.endIndex - closerDelimiter.startIndex,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function processSingleDelimiter(delimiter) {
|
|
110
|
+
const token = {
|
|
111
|
+
nodeType: ast.InlineMathType,
|
|
112
|
+
startIndex: delimiter.startIndex,
|
|
113
|
+
endIndex: delimiter.endIndex,
|
|
114
|
+
thickness: delimiter.thickness,
|
|
115
|
+
};
|
|
116
|
+
return [token];
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const parse = function (api) {
|
|
121
|
+
return {
|
|
122
|
+
parse: tokens => tokens.map(token => {
|
|
123
|
+
const nodePoints = api.getNodePoints();
|
|
124
|
+
let startIndex = token.startIndex + token.thickness;
|
|
125
|
+
let endIndex = token.endIndex - token.thickness;
|
|
126
|
+
let isAllSpace = true;
|
|
127
|
+
for (let i = startIndex; i < endIndex; ++i) {
|
|
128
|
+
if (character.isSpaceLike(nodePoints[i].codePoint))
|
|
129
|
+
continue;
|
|
130
|
+
isAllSpace = false;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
if (!isAllSpace && startIndex + 2 < endIndex) {
|
|
134
|
+
const firstCharacter = nodePoints[startIndex].codePoint;
|
|
135
|
+
const lastCharacter = nodePoints[endIndex - 1].codePoint;
|
|
136
|
+
if (character.isSpaceLike(firstCharacter) && character.isSpaceLike(lastCharacter)) {
|
|
137
|
+
startIndex += 1;
|
|
138
|
+
endIndex -= 1;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const value = character.calcStringFromNodePoints(nodePoints, startIndex, endIndex).replace(/\n/, ' ');
|
|
142
|
+
const node = api.shouldReservePosition
|
|
143
|
+
? { type: ast.InlineMathType, position: api.calcPosition(token), value }
|
|
144
|
+
: { type: ast.InlineMathType, value };
|
|
145
|
+
return node;
|
|
146
|
+
}),
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const uniqueName = '@yozora/tokenizer-inline-math';
|
|
151
|
+
|
|
152
|
+
class InlineMathTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
153
|
+
constructor(props = {}) {
|
|
154
|
+
var _a, _b, _c;
|
|
155
|
+
super({
|
|
156
|
+
name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
|
|
157
|
+
priority: (_b = props.priority) !== null && _b !== void 0 ? _b : coreTokenizer.TokenizerPriority.ATOMIC,
|
|
154
158
|
});
|
|
159
|
+
this.match = match;
|
|
160
|
+
this.parse = parse;
|
|
155
161
|
this.backtickRequired = (_c = props.backtickRequired) !== null && _c !== void 0 ? _c : true;
|
|
156
162
|
}
|
|
157
163
|
}
|
|
@@ -159,3 +165,5 @@ class InlineMathTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
|
159
165
|
exports.InlineMathTokenizer = InlineMathTokenizer;
|
|
160
166
|
exports.InlineMathTokenizerName = uniqueName;
|
|
161
167
|
exports["default"] = InlineMathTokenizer;
|
|
168
|
+
exports.inlineMathMatch = match;
|
|
169
|
+
exports.inlineMathParse = parse;
|
package/lib/esm/index.js
CHANGED
|
@@ -1,155 +1,161 @@
|
|
|
1
1
|
import { InlineMathType } from '@yozora/ast';
|
|
2
2
|
import { AsciiCodePoint, isSpaceLike, calcStringFromNodePoints } from '@yozora/character';
|
|
3
|
-
import { BaseInlineTokenizer, TokenizerPriority
|
|
3
|
+
import { eatOptionalCharacters, BaseInlineTokenizer, TokenizerPriority } from '@yozora/core-tokenizer';
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
switch (c) {
|
|
25
|
-
case AsciiCodePoint.BACKSLASH:
|
|
26
|
-
i += 1;
|
|
27
|
-
break;
|
|
28
|
-
case AsciiCodePoint.BACKTICK: {
|
|
29
|
-
const _startIndex = i;
|
|
30
|
-
i = eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, AsciiCodePoint.BACKTICK);
|
|
31
|
-
if (i >= blockEndIndex || nodePoints[i].codePoint !== AsciiCodePoint.DOLLAR_SIGN) {
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
const delimiter = {
|
|
35
|
-
type: 'opener',
|
|
36
|
-
startIndex: _startIndex,
|
|
37
|
-
endIndex: i + 1,
|
|
38
|
-
};
|
|
39
|
-
potentialDelimiters.push(delimiter);
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
case AsciiCodePoint.DOLLAR_SIGN: {
|
|
43
|
-
const _startIndex = i;
|
|
44
|
-
i = eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, AsciiCodePoint.BACKTICK);
|
|
45
|
-
if (i < blockEndIndex && nodePoints[i].codePoint === AsciiCodePoint.DOLLAR_SIGN) {
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
const thickness = i - _startIndex;
|
|
49
|
-
if (thickness <= 1) {
|
|
50
|
-
if (backtickRequired)
|
|
51
|
-
break;
|
|
52
|
-
const delimiter = {
|
|
53
|
-
type: 'both',
|
|
54
|
-
startIndex: _startIndex,
|
|
55
|
-
endIndex: i,
|
|
56
|
-
};
|
|
57
|
-
potentialDelimiters.push(delimiter);
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
const delimiter = {
|
|
61
|
-
type: 'closer',
|
|
62
|
-
startIndex: _startIndex,
|
|
63
|
-
endIndex: i,
|
|
64
|
-
};
|
|
65
|
-
potentialDelimiters.push(delimiter);
|
|
66
|
-
i -= 1;
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
5
|
+
const match = function (api) {
|
|
6
|
+
const { backtickRequired } = this;
|
|
7
|
+
return { findDelimiter, processSingleDelimiter };
|
|
8
|
+
function* findDelimiter() {
|
|
9
|
+
const nodePoints = api.getNodePoints();
|
|
10
|
+
const blockStartIndex = api.getBlockStartIndex();
|
|
11
|
+
const blockEndIndex = api.getBlockEndIndex();
|
|
12
|
+
const potentialDelimiters = [];
|
|
13
|
+
for (let i = blockStartIndex; i < blockEndIndex; ++i) {
|
|
14
|
+
const c = nodePoints[i].codePoint;
|
|
15
|
+
switch (c) {
|
|
16
|
+
case AsciiCodePoint.BACKSLASH:
|
|
17
|
+
i += 1;
|
|
18
|
+
break;
|
|
19
|
+
case AsciiCodePoint.BACKTICK: {
|
|
20
|
+
const _startIndex = i;
|
|
21
|
+
i = eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, AsciiCodePoint.BACKTICK);
|
|
22
|
+
if (i >= blockEndIndex || nodePoints[i].codePoint !== AsciiCodePoint.DOLLAR_SIGN) {
|
|
23
|
+
break;
|
|
69
24
|
}
|
|
25
|
+
const delimiter = {
|
|
26
|
+
type: 'opener',
|
|
27
|
+
startIndex: _startIndex,
|
|
28
|
+
endIndex: i + 1,
|
|
29
|
+
};
|
|
30
|
+
potentialDelimiters.push(delimiter);
|
|
31
|
+
break;
|
|
70
32
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (lastEndIndex === endIndex) {
|
|
77
|
-
if (delimiter == null || delimiter.startIndex >= startIndex)
|
|
78
|
-
continue;
|
|
33
|
+
case AsciiCodePoint.DOLLAR_SIGN: {
|
|
34
|
+
const _startIndex = i;
|
|
35
|
+
i = eatOptionalCharacters(nodePoints, i + 1, blockEndIndex, AsciiCodePoint.BACKTICK);
|
|
36
|
+
if (i < blockEndIndex && nodePoints[i].codePoint === AsciiCodePoint.DOLLAR_SIGN) {
|
|
37
|
+
break;
|
|
79
38
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
84
|
-
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
85
|
-
const delimiter = potentialDelimiters[pIndex];
|
|
86
|
-
if (delimiter.startIndex >= startIndex && delimiter.type !== 'closer')
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
if (pIndex + 1 >= potentialDelimiters.length)
|
|
90
|
-
break;
|
|
91
|
-
openerDelimiter = potentialDelimiters[pIndex];
|
|
92
|
-
const thickness = openerDelimiter.endIndex - openerDelimiter.startIndex;
|
|
93
|
-
for (let i = pIndex + 1; i < potentialDelimiters.length; ++i) {
|
|
94
|
-
const delimiter = potentialDelimiters[i];
|
|
95
|
-
if (delimiter.type !== 'opener' &&
|
|
96
|
-
delimiter.endIndex - delimiter.startIndex === thickness) {
|
|
97
|
-
closerDelimiter = delimiter;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (closerDelimiter != null)
|
|
39
|
+
const thickness = i - _startIndex;
|
|
40
|
+
if (thickness <= 1) {
|
|
41
|
+
if (backtickRequired)
|
|
102
42
|
break;
|
|
43
|
+
const delimiter = {
|
|
44
|
+
type: 'both',
|
|
45
|
+
startIndex: _startIndex,
|
|
46
|
+
endIndex: i,
|
|
47
|
+
};
|
|
48
|
+
potentialDelimiters.push(delimiter);
|
|
49
|
+
break;
|
|
103
50
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
startIndex: openerDelimiter.startIndex,
|
|
109
|
-
endIndex: closerDelimiter.endIndex,
|
|
110
|
-
thickness: closerDelimiter.endIndex - closerDelimiter.startIndex,
|
|
51
|
+
const delimiter = {
|
|
52
|
+
type: 'closer',
|
|
53
|
+
startIndex: _startIndex,
|
|
54
|
+
endIndex: i,
|
|
111
55
|
};
|
|
56
|
+
potentialDelimiters.push(delimiter);
|
|
57
|
+
i -= 1;
|
|
58
|
+
break;
|
|
112
59
|
}
|
|
113
60
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
61
|
+
}
|
|
62
|
+
let pIndex = 0;
|
|
63
|
+
let lastEndIndex = -1;
|
|
64
|
+
let delimiter = null;
|
|
65
|
+
while (pIndex < potentialDelimiters.length) {
|
|
66
|
+
const [startIndex, endIndex] = yield delimiter;
|
|
67
|
+
if (lastEndIndex === endIndex) {
|
|
68
|
+
if (delimiter == null || delimiter.startIndex >= startIndex)
|
|
69
|
+
continue;
|
|
122
70
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (isSpaceLike(nodePoints[i].codePoint))
|
|
132
|
-
continue;
|
|
133
|
-
isAllSpace = false;
|
|
134
|
-
break;
|
|
71
|
+
lastEndIndex = endIndex;
|
|
72
|
+
let openerDelimiter = null;
|
|
73
|
+
let closerDelimiter = null;
|
|
74
|
+
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
75
|
+
for (; pIndex < potentialDelimiters.length; ++pIndex) {
|
|
76
|
+
const delimiter = potentialDelimiters[pIndex];
|
|
77
|
+
if (delimiter.startIndex >= startIndex && delimiter.type !== 'closer')
|
|
78
|
+
break;
|
|
135
79
|
}
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
80
|
+
if (pIndex + 1 >= potentialDelimiters.length)
|
|
81
|
+
break;
|
|
82
|
+
openerDelimiter = potentialDelimiters[pIndex];
|
|
83
|
+
const thickness = openerDelimiter.endIndex - openerDelimiter.startIndex;
|
|
84
|
+
for (let i = pIndex + 1; i < potentialDelimiters.length; ++i) {
|
|
85
|
+
const delimiter = potentialDelimiters[i];
|
|
86
|
+
if (delimiter.type !== 'opener' &&
|
|
87
|
+
delimiter.endIndex - delimiter.startIndex === thickness) {
|
|
88
|
+
closerDelimiter = delimiter;
|
|
89
|
+
break;
|
|
142
90
|
}
|
|
143
91
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return
|
|
149
|
-
|
|
92
|
+
if (closerDelimiter != null)
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
if (closerDelimiter == null)
|
|
96
|
+
return;
|
|
97
|
+
delimiter = {
|
|
98
|
+
type: 'full',
|
|
99
|
+
startIndex: openerDelimiter.startIndex,
|
|
100
|
+
endIndex: closerDelimiter.endIndex,
|
|
101
|
+
thickness: closerDelimiter.endIndex - closerDelimiter.startIndex,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function processSingleDelimiter(delimiter) {
|
|
106
|
+
const token = {
|
|
107
|
+
nodeType: InlineMathType,
|
|
108
|
+
startIndex: delimiter.startIndex,
|
|
109
|
+
endIndex: delimiter.endIndex,
|
|
110
|
+
thickness: delimiter.thickness,
|
|
111
|
+
};
|
|
112
|
+
return [token];
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const parse = function (api) {
|
|
117
|
+
return {
|
|
118
|
+
parse: tokens => tokens.map(token => {
|
|
119
|
+
const nodePoints = api.getNodePoints();
|
|
120
|
+
let startIndex = token.startIndex + token.thickness;
|
|
121
|
+
let endIndex = token.endIndex - token.thickness;
|
|
122
|
+
let isAllSpace = true;
|
|
123
|
+
for (let i = startIndex; i < endIndex; ++i) {
|
|
124
|
+
if (isSpaceLike(nodePoints[i].codePoint))
|
|
125
|
+
continue;
|
|
126
|
+
isAllSpace = false;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
if (!isAllSpace && startIndex + 2 < endIndex) {
|
|
130
|
+
const firstCharacter = nodePoints[startIndex].codePoint;
|
|
131
|
+
const lastCharacter = nodePoints[endIndex - 1].codePoint;
|
|
132
|
+
if (isSpaceLike(firstCharacter) && isSpaceLike(lastCharacter)) {
|
|
133
|
+
startIndex += 1;
|
|
134
|
+
endIndex -= 1;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const value = calcStringFromNodePoints(nodePoints, startIndex, endIndex).replace(/\n/, ' ');
|
|
138
|
+
const node = api.shouldReservePosition
|
|
139
|
+
? { type: InlineMathType, position: api.calcPosition(token), value }
|
|
140
|
+
: { type: InlineMathType, value };
|
|
141
|
+
return node;
|
|
142
|
+
}),
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const uniqueName = '@yozora/tokenizer-inline-math';
|
|
147
|
+
|
|
148
|
+
class InlineMathTokenizer extends BaseInlineTokenizer {
|
|
149
|
+
constructor(props = {}) {
|
|
150
|
+
var _a, _b, _c;
|
|
151
|
+
super({
|
|
152
|
+
name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
|
|
153
|
+
priority: (_b = props.priority) !== null && _b !== void 0 ? _b : TokenizerPriority.ATOMIC,
|
|
150
154
|
});
|
|
155
|
+
this.match = match;
|
|
156
|
+
this.parse = parse;
|
|
151
157
|
this.backtickRequired = (_c = props.backtickRequired) !== null && _c !== void 0 ? _c : true;
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
|
|
155
|
-
export { InlineMathTokenizer, uniqueName as InlineMathTokenizerName, InlineMathTokenizer as default };
|
|
161
|
+
export { InlineMathTokenizer, uniqueName as InlineMathTokenizerName, InlineMathTokenizer as default, match as inlineMathMatch, parse as inlineMathParse };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { match as inlineMathMatch } from './match';
|
|
2
|
+
export { parse as inlineMathParse } from './parse';
|
|
1
3
|
export { InlineMathTokenizer, InlineMathTokenizer as default } from './tokenizer';
|
|
2
4
|
export { uniqueName as InlineMathTokenizerName } from './types';
|
|
3
|
-
export type { IToken as IInlineMathToken, ITokenizerProps as IInlineMathTokenizerProps, } from './types';
|
|
5
|
+
export type { IThis as IInlineMathHookContext, IToken as IInlineMathToken, ITokenizerProps as IInlineMathTokenizerProps, } from './types';
|
package/lib/types/tokenizer.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { IInlineTokenizer, IMatchInlineHookCreator, IParseInlineHookCreator } from '@yozora/core-tokenizer';
|
|
2
2
|
import { BaseInlineTokenizer } from '@yozora/core-tokenizer';
|
|
3
|
-
import type { IDelimiter, INode, IToken, ITokenizerProps, T } from './types';
|
|
3
|
+
import type { IDelimiter, INode, IThis, IToken, ITokenizerProps, T } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Lexical Analyzer for inlineMath.
|
|
6
6
|
*/
|
|
7
|
-
export declare class InlineMathTokenizer extends BaseInlineTokenizer<T, IDelimiter, IToken, INode> implements IInlineTokenizer<T, IDelimiter, IToken, INode> {
|
|
7
|
+
export declare class InlineMathTokenizer extends BaseInlineTokenizer<T, IDelimiter, IToken, INode, IThis> implements IInlineTokenizer<T, IDelimiter, IToken, INode, IThis> {
|
|
8
8
|
readonly backtickRequired: boolean;
|
|
9
9
|
constructor(props?: ITokenizerProps);
|
|
10
|
-
readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken>;
|
|
11
|
-
readonly parse: IParseInlineHookCreator<T, IToken, INode>;
|
|
10
|
+
readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis>;
|
|
11
|
+
readonly parse: IParseInlineHookCreator<T, IToken, INode, IThis>;
|
|
12
12
|
}
|
package/lib/types/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { IBaseInlineTokenizerProps, IPartialYastInlineToken, IYastTokenDelimiter } from '@yozora/core-tokenizer';
|
|
1
|
+
import type { InlineMath, InlineMathType } from '@yozora/ast';
|
|
2
|
+
import type { IBaseInlineTokenizerProps, IPartialYastInlineToken, ITokenizer, IYastTokenDelimiter } from '@yozora/core-tokenizer';
|
|
3
3
|
export declare type T = InlineMathType;
|
|
4
|
-
export declare type INode =
|
|
4
|
+
export declare type INode = InlineMath;
|
|
5
5
|
export declare const uniqueName = "@yozora/tokenizer-inline-math";
|
|
6
6
|
export interface IToken extends IPartialYastInlineToken<T> {
|
|
7
7
|
/**
|
|
@@ -19,6 +19,12 @@ export interface IDelimiter extends IYastTokenDelimiter {
|
|
|
19
19
|
*/
|
|
20
20
|
thickness: number;
|
|
21
21
|
}
|
|
22
|
+
export interface IThis extends ITokenizer {
|
|
23
|
+
/**
|
|
24
|
+
* Whether if the backtick mark wrapping necessary.
|
|
25
|
+
*/
|
|
26
|
+
readonly backtickRequired: boolean;
|
|
27
|
+
}
|
|
22
28
|
export interface ITokenizerProps extends Partial<IBaseInlineTokenizerProps> {
|
|
23
29
|
/**
|
|
24
30
|
* Whether if the backtick mark wrapping necessary.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yozora/tokenizer-inline-math",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Tokenizer for processing inline math (formulas)",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "guanghechen",
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
"test": "cross-env TS_NODE_FILES=true jest --config ../../jest.config.js --rootDir ."
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@yozora/ast": "^2.0.0
|
|
49
|
-
"@yozora/character": "^2.0.0
|
|
50
|
-
"@yozora/core-tokenizer": "^2.0.0
|
|
48
|
+
"@yozora/ast": "^2.0.0",
|
|
49
|
+
"@yozora/character": "^2.0.0",
|
|
50
|
+
"@yozora/core-tokenizer": "^2.0.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@yozora/tokenizer-inline-code": "^2.0.0
|
|
53
|
+
"@yozora/tokenizer-inline-code": "^2.0.0"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "65e99d1709fdd1c918465dce6b1e91de96bdab5e"
|
|
56
56
|
}
|