@yozora/tokenizer-image-reference 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 +145 -127
- package/lib/esm/index.js +145 -129
- package/lib/types/index.d.ts +3 -1
- package/lib/types/match.d.ts +33 -0
- package/lib/types/parse.d.ts +3 -0
- package/lib/types/tokenizer.d.ts +4 -31
- package/lib/types/types.d.ts +5 -4
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -84,14 +84,14 @@ so you can use `YozoraParser` / `GfmExParser` / `GfmParser` directly.
|
|
|
84
84
|
registered in *YastParser* as a plugin-in before it can be used.
|
|
85
85
|
|
|
86
86
|
```typescript {4,9}
|
|
87
|
-
import {
|
|
87
|
+
import { DefaultParser } from '@yozora/core-parser'
|
|
88
88
|
import ParagraphTokenizer from '@yozora/tokenizer-paragraph'
|
|
89
89
|
import TextTokenizer from '@yozora/tokenizer-text'
|
|
90
90
|
import ImageReferenceTokenizer from '@yozora/tokenizer-image-reference'
|
|
91
91
|
|
|
92
|
-
const parser = new
|
|
93
|
-
.
|
|
94
|
-
.
|
|
92
|
+
const parser = new DefaultParser()
|
|
93
|
+
.useFallbackTokenizer(new ParagraphTokenizer())
|
|
94
|
+
.useFallbackTokenizer(new TextTokenizer())
|
|
95
95
|
.useTokenizer(new ImageReferenceTokenizer())
|
|
96
96
|
|
|
97
97
|
// parse source markdown content
|
|
@@ -231,7 +231,6 @@ Name | Type | Required | Default
|
|
|
231
231
|
[@yozora/tokenizer-link]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link#readme
|
|
232
232
|
[@yozora/tokenizer-link-reference]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link-reference#readme
|
|
233
233
|
[@yozora/tokenizer-list]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list#readme
|
|
234
|
-
[@yozora/tokenizer-list-item]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list-item#readme
|
|
235
234
|
[@yozora/tokenizer-math]: https://github.com/yozorajs/yozora/tree/main/tokenizers/math#readme
|
|
236
235
|
[@yozora/tokenizer-paragraph]: https://github.com/yozorajs/yozora/tree/main/tokenizers/paragraph#readme
|
|
237
236
|
[@yozora/tokenizer-setext-heading]: https://github.com/yozorajs/yozora/tree/main/tokenizers/setext-heading#readme
|
|
@@ -291,7 +290,6 @@ Name | Type | Required | Default
|
|
|
291
290
|
[doc-@yozora/tokenizer-definition]: https://yozora.guanghechen.com/docs/package/tokenizer-definition
|
|
292
291
|
[doc-@yozora/tokenizer-link-reference]: https://yozora.guanghechen.com/docs/package/tokenizer-link-reference
|
|
293
292
|
[doc-@yozora/tokenizer-list]: https://yozora.guanghechen.com/docs/package/tokenizer-list
|
|
294
|
-
[doc-@yozora/tokenizer-list-item]: https://yozora.guanghechen.com/docs/package/tokenizer-list-item
|
|
295
293
|
[doc-@yozora/tokenizer-math]: https://yozora.guanghechen.com/docs/package/tokenizer-math
|
|
296
294
|
[doc-@yozora/tokenizer-paragraph]: https://yozora.guanghechen.com/docs/package/tokenizer-paragraph
|
|
297
295
|
[doc-@yozora/tokenizer-setext-heading]: https://yozora.guanghechen.com/docs/package/tokenizer-setext-heading
|
package/lib/cjs/index.js
CHANGED
|
@@ -5,152 +5,170 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var ast = require('@yozora/ast');
|
|
6
6
|
var character = require('@yozora/character');
|
|
7
7
|
var coreTokenizer = require('@yozora/core-tokenizer');
|
|
8
|
-
var tokenizerImage = require('@yozora/tokenizer-image');
|
|
9
8
|
var tokenizerLink = require('@yozora/tokenizer-link');
|
|
9
|
+
var tokenizerImage = require('@yozora/tokenizer-image');
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
for (let i = startIndex; i < endIndex; ++i) {
|
|
29
|
-
const c = nodePoints[i].codePoint;
|
|
30
|
-
switch (c) {
|
|
31
|
-
case character.AsciiCodePoint.BACKSLASH:
|
|
32
|
-
i += 1;
|
|
33
|
-
break;
|
|
34
|
-
case character.AsciiCodePoint.EXCLAMATION_MARK: {
|
|
35
|
-
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== character.AsciiCodePoint.OPEN_BRACKET) {
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
type: 'opener',
|
|
40
|
-
startIndex: i,
|
|
41
|
-
endIndex: i + 2,
|
|
42
|
-
brackets: [],
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
case character.AsciiCodePoint.CLOSE_BRACKET: {
|
|
46
|
-
const delimiter = {
|
|
47
|
-
type: 'closer',
|
|
48
|
-
startIndex: i,
|
|
49
|
-
endIndex: i + 1,
|
|
50
|
-
brackets: [],
|
|
51
|
-
};
|
|
52
|
-
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== character.AsciiCodePoint.OPEN_BRACKET) {
|
|
53
|
-
return delimiter;
|
|
54
|
-
}
|
|
55
|
-
const result = coreTokenizer.eatLinkLabel(nodePoints, i + 1, endIndex);
|
|
56
|
-
if (result.nextIndex < 0)
|
|
57
|
-
return delimiter;
|
|
58
|
-
if (result.labelAndIdentifier == null) {
|
|
59
|
-
return {
|
|
60
|
-
type: 'closer',
|
|
61
|
-
startIndex: i,
|
|
62
|
-
endIndex: result.nextIndex,
|
|
63
|
-
brackets: [
|
|
64
|
-
{
|
|
65
|
-
startIndex: i + 1,
|
|
66
|
-
endIndex: result.nextIndex,
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
type: 'closer',
|
|
73
|
-
startIndex: i,
|
|
74
|
-
endIndex: result.nextIndex,
|
|
75
|
-
brackets: [
|
|
76
|
-
{
|
|
77
|
-
startIndex: i + 1,
|
|
78
|
-
endIndex: result.nextIndex,
|
|
79
|
-
label: result.labelAndIdentifier.label,
|
|
80
|
-
identifier: result.labelAndIdentifier.identifier,
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
};
|
|
84
|
-
}
|
|
11
|
+
const match = function (api) {
|
|
12
|
+
return {
|
|
13
|
+
findDelimiter: () => coreTokenizer.genFindDelimiter(_findDelimiter),
|
|
14
|
+
isDelimiterPair,
|
|
15
|
+
processDelimiterPair,
|
|
16
|
+
};
|
|
17
|
+
function _findDelimiter(startIndex, endIndex) {
|
|
18
|
+
const nodePoints = api.getNodePoints();
|
|
19
|
+
for (let i = startIndex; i < endIndex; ++i) {
|
|
20
|
+
const c = nodePoints[i].codePoint;
|
|
21
|
+
switch (c) {
|
|
22
|
+
case character.AsciiCodePoint.BACKSLASH:
|
|
23
|
+
i += 1;
|
|
24
|
+
break;
|
|
25
|
+
case character.AsciiCodePoint.EXCLAMATION_MARK: {
|
|
26
|
+
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== character.AsciiCodePoint.OPEN_BRACKET) {
|
|
27
|
+
break;
|
|
85
28
|
}
|
|
29
|
+
return {
|
|
30
|
+
type: 'opener',
|
|
31
|
+
startIndex: i,
|
|
32
|
+
endIndex: i + 2,
|
|
33
|
+
brackets: [],
|
|
34
|
+
};
|
|
86
35
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
label: bracket.label,
|
|
112
|
-
identifier: bracket.identifier,
|
|
113
|
-
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
36
|
+
case character.AsciiCodePoint.CLOSE_BRACKET: {
|
|
37
|
+
const delimiter = {
|
|
38
|
+
type: 'closer',
|
|
39
|
+
startIndex: i,
|
|
40
|
+
endIndex: i + 1,
|
|
41
|
+
brackets: [],
|
|
42
|
+
};
|
|
43
|
+
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== character.AsciiCodePoint.OPEN_BRACKET) {
|
|
44
|
+
return delimiter;
|
|
45
|
+
}
|
|
46
|
+
const result = coreTokenizer.eatLinkLabel(nodePoints, i + 1, endIndex);
|
|
47
|
+
if (result.nextIndex < 0)
|
|
48
|
+
return delimiter;
|
|
49
|
+
if (result.labelAndIdentifier == null) {
|
|
50
|
+
return {
|
|
51
|
+
type: 'closer',
|
|
52
|
+
startIndex: i,
|
|
53
|
+
endIndex: result.nextIndex,
|
|
54
|
+
brackets: [
|
|
55
|
+
{
|
|
56
|
+
startIndex: i + 1,
|
|
57
|
+
endIndex: result.nextIndex,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
114
60
|
};
|
|
115
|
-
return { tokens: [token] };
|
|
116
61
|
}
|
|
117
|
-
return {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
identifier: labelAndIdentifier.identifier,
|
|
130
|
-
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
62
|
+
return {
|
|
63
|
+
type: 'closer',
|
|
64
|
+
startIndex: i,
|
|
65
|
+
endIndex: result.nextIndex,
|
|
66
|
+
brackets: [
|
|
67
|
+
{
|
|
68
|
+
startIndex: i + 1,
|
|
69
|
+
endIndex: result.nextIndex,
|
|
70
|
+
label: result.labelAndIdentifier.label,
|
|
71
|
+
identifier: result.labelAndIdentifier.identifier,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
131
74
|
};
|
|
132
|
-
return { tokens: [token] };
|
|
133
75
|
}
|
|
134
|
-
return { tokens: internalTokens };
|
|
135
76
|
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
function isDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
81
|
+
const nodePoints = api.getNodePoints();
|
|
82
|
+
const balancedBracketsStatus = tokenizerLink.checkBalancedBracketsStatus(openerDelimiter.endIndex, closerDelimiter.startIndex, internalTokens, nodePoints);
|
|
83
|
+
switch (balancedBracketsStatus) {
|
|
84
|
+
case -1:
|
|
85
|
+
return { paired: false, opener: false, closer: true };
|
|
86
|
+
case 0:
|
|
87
|
+
return { paired: true };
|
|
88
|
+
case 1:
|
|
89
|
+
return { paired: false, opener: true, closer: false };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function processDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
93
|
+
const nodePoints = api.getNodePoints();
|
|
94
|
+
const bracket = closerDelimiter.brackets[0];
|
|
95
|
+
if (bracket != null && bracket.identifier != null) {
|
|
96
|
+
if (api.hasDefinition(bracket.identifier)) {
|
|
97
|
+
const token = {
|
|
98
|
+
nodeType: ast.ImageReferenceType,
|
|
99
|
+
startIndex: openerDelimiter.startIndex,
|
|
100
|
+
endIndex: bracket.endIndex,
|
|
101
|
+
referenceType: 'full',
|
|
102
|
+
label: bracket.label,
|
|
103
|
+
identifier: bracket.identifier,
|
|
104
|
+
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
105
|
+
};
|
|
106
|
+
return { tokens: [token] };
|
|
107
|
+
}
|
|
108
|
+
return { tokens: internalTokens };
|
|
109
|
+
}
|
|
110
|
+
const { nextIndex, labelAndIdentifier } = coreTokenizer.eatLinkLabel(nodePoints, openerDelimiter.endIndex - 1, closerDelimiter.startIndex + 1);
|
|
111
|
+
if (nextIndex === closerDelimiter.startIndex + 1 &&
|
|
112
|
+
labelAndIdentifier != null &&
|
|
113
|
+
api.hasDefinition(labelAndIdentifier.identifier)) {
|
|
114
|
+
const token = {
|
|
115
|
+
nodeType: ast.ImageReferenceType,
|
|
116
|
+
startIndex: openerDelimiter.startIndex,
|
|
117
|
+
endIndex: closerDelimiter.endIndex,
|
|
118
|
+
referenceType: bracket == null ? 'shortcut' : 'collapsed',
|
|
119
|
+
label: labelAndIdentifier.label,
|
|
120
|
+
identifier: labelAndIdentifier.identifier,
|
|
121
|
+
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
122
|
+
};
|
|
123
|
+
return { tokens: [token] };
|
|
124
|
+
}
|
|
125
|
+
return { tokens: internalTokens };
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const parse = function (api) {
|
|
130
|
+
return {
|
|
131
|
+
parse: tokens => tokens.map(token => {
|
|
132
|
+
const { identifier, label, referenceType } = token;
|
|
133
|
+
const children = api.parseInlineTokens(token.children);
|
|
134
|
+
const alt = tokenizerImage.calcImageAlt(children);
|
|
135
|
+
const node = api.shouldReservePosition
|
|
136
|
+
? {
|
|
137
|
+
type: ast.ImageReferenceType,
|
|
138
|
+
position: api.calcPosition(token),
|
|
139
|
+
identifier,
|
|
140
|
+
label,
|
|
141
|
+
referenceType,
|
|
142
|
+
alt,
|
|
143
|
+
}
|
|
144
|
+
: {
|
|
142
145
|
type: ast.ImageReferenceType,
|
|
143
146
|
identifier,
|
|
144
147
|
label,
|
|
145
148
|
referenceType,
|
|
146
149
|
alt,
|
|
147
150
|
};
|
|
148
|
-
|
|
149
|
-
|
|
151
|
+
return node;
|
|
152
|
+
}),
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const uniqueName = '@yozora/tokenizer-image-reference';
|
|
157
|
+
|
|
158
|
+
class ImageReferenceTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
159
|
+
constructor(props = {}) {
|
|
160
|
+
var _a, _b;
|
|
161
|
+
super({
|
|
162
|
+
name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
|
|
163
|
+
priority: (_b = props.priority) !== null && _b !== void 0 ? _b : coreTokenizer.TokenizerPriority.LINKS,
|
|
150
164
|
});
|
|
165
|
+
this.match = match;
|
|
166
|
+
this.parse = parse;
|
|
151
167
|
}
|
|
152
168
|
}
|
|
153
169
|
|
|
154
170
|
exports.ImageReferenceTokenizer = ImageReferenceTokenizer;
|
|
155
171
|
exports.ImageReferenceTokenizerName = uniqueName;
|
|
156
172
|
exports["default"] = ImageReferenceTokenizer;
|
|
173
|
+
exports.imageReferenceMatch = match;
|
|
174
|
+
exports.imageReferenceParse = parse;
|
package/lib/esm/index.js
CHANGED
|
@@ -1,150 +1,166 @@
|
|
|
1
1
|
import { ImageReferenceType } from '@yozora/ast';
|
|
2
2
|
import { AsciiCodePoint } from '@yozora/character';
|
|
3
|
-
import {
|
|
4
|
-
import { calcImageAlt } from '@yozora/tokenizer-image';
|
|
3
|
+
import { genFindDelimiter, eatLinkLabel, BaseInlineTokenizer, TokenizerPriority } from '@yozora/core-tokenizer';
|
|
5
4
|
import { checkBalancedBracketsStatus } from '@yozora/tokenizer-link';
|
|
5
|
+
import { calcImageAlt } from '@yozora/tokenizer-image';
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
for (let i = startIndex; i < endIndex; ++i) {
|
|
25
|
-
const c = nodePoints[i].codePoint;
|
|
26
|
-
switch (c) {
|
|
27
|
-
case AsciiCodePoint.BACKSLASH:
|
|
28
|
-
i += 1;
|
|
29
|
-
break;
|
|
30
|
-
case AsciiCodePoint.EXCLAMATION_MARK: {
|
|
31
|
-
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_BRACKET) {
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
type: 'opener',
|
|
36
|
-
startIndex: i,
|
|
37
|
-
endIndex: i + 2,
|
|
38
|
-
brackets: [],
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
case AsciiCodePoint.CLOSE_BRACKET: {
|
|
42
|
-
const delimiter = {
|
|
43
|
-
type: 'closer',
|
|
44
|
-
startIndex: i,
|
|
45
|
-
endIndex: i + 1,
|
|
46
|
-
brackets: [],
|
|
47
|
-
};
|
|
48
|
-
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_BRACKET) {
|
|
49
|
-
return delimiter;
|
|
50
|
-
}
|
|
51
|
-
const result = eatLinkLabel(nodePoints, i + 1, endIndex);
|
|
52
|
-
if (result.nextIndex < 0)
|
|
53
|
-
return delimiter;
|
|
54
|
-
if (result.labelAndIdentifier == null) {
|
|
55
|
-
return {
|
|
56
|
-
type: 'closer',
|
|
57
|
-
startIndex: i,
|
|
58
|
-
endIndex: result.nextIndex,
|
|
59
|
-
brackets: [
|
|
60
|
-
{
|
|
61
|
-
startIndex: i + 1,
|
|
62
|
-
endIndex: result.nextIndex,
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
type: 'closer',
|
|
69
|
-
startIndex: i,
|
|
70
|
-
endIndex: result.nextIndex,
|
|
71
|
-
brackets: [
|
|
72
|
-
{
|
|
73
|
-
startIndex: i + 1,
|
|
74
|
-
endIndex: result.nextIndex,
|
|
75
|
-
label: result.labelAndIdentifier.label,
|
|
76
|
-
identifier: result.labelAndIdentifier.identifier,
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
};
|
|
80
|
-
}
|
|
7
|
+
const match = function (api) {
|
|
8
|
+
return {
|
|
9
|
+
findDelimiter: () => genFindDelimiter(_findDelimiter),
|
|
10
|
+
isDelimiterPair,
|
|
11
|
+
processDelimiterPair,
|
|
12
|
+
};
|
|
13
|
+
function _findDelimiter(startIndex, endIndex) {
|
|
14
|
+
const nodePoints = api.getNodePoints();
|
|
15
|
+
for (let i = startIndex; i < endIndex; ++i) {
|
|
16
|
+
const c = nodePoints[i].codePoint;
|
|
17
|
+
switch (c) {
|
|
18
|
+
case AsciiCodePoint.BACKSLASH:
|
|
19
|
+
i += 1;
|
|
20
|
+
break;
|
|
21
|
+
case AsciiCodePoint.EXCLAMATION_MARK: {
|
|
22
|
+
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_BRACKET) {
|
|
23
|
+
break;
|
|
81
24
|
}
|
|
25
|
+
return {
|
|
26
|
+
type: 'opener',
|
|
27
|
+
startIndex: i,
|
|
28
|
+
endIndex: i + 2,
|
|
29
|
+
brackets: [],
|
|
30
|
+
};
|
|
82
31
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
label: bracket.label,
|
|
108
|
-
identifier: bracket.identifier,
|
|
109
|
-
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
32
|
+
case AsciiCodePoint.CLOSE_BRACKET: {
|
|
33
|
+
const delimiter = {
|
|
34
|
+
type: 'closer',
|
|
35
|
+
startIndex: i,
|
|
36
|
+
endIndex: i + 1,
|
|
37
|
+
brackets: [],
|
|
38
|
+
};
|
|
39
|
+
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_BRACKET) {
|
|
40
|
+
return delimiter;
|
|
41
|
+
}
|
|
42
|
+
const result = eatLinkLabel(nodePoints, i + 1, endIndex);
|
|
43
|
+
if (result.nextIndex < 0)
|
|
44
|
+
return delimiter;
|
|
45
|
+
if (result.labelAndIdentifier == null) {
|
|
46
|
+
return {
|
|
47
|
+
type: 'closer',
|
|
48
|
+
startIndex: i,
|
|
49
|
+
endIndex: result.nextIndex,
|
|
50
|
+
brackets: [
|
|
51
|
+
{
|
|
52
|
+
startIndex: i + 1,
|
|
53
|
+
endIndex: result.nextIndex,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
110
56
|
};
|
|
111
|
-
return { tokens: [token] };
|
|
112
57
|
}
|
|
113
|
-
return {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
identifier: labelAndIdentifier.identifier,
|
|
126
|
-
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
58
|
+
return {
|
|
59
|
+
type: 'closer',
|
|
60
|
+
startIndex: i,
|
|
61
|
+
endIndex: result.nextIndex,
|
|
62
|
+
brackets: [
|
|
63
|
+
{
|
|
64
|
+
startIndex: i + 1,
|
|
65
|
+
endIndex: result.nextIndex,
|
|
66
|
+
label: result.labelAndIdentifier.label,
|
|
67
|
+
identifier: result.labelAndIdentifier.identifier,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
127
70
|
};
|
|
128
|
-
return { tokens: [token] };
|
|
129
71
|
}
|
|
130
|
-
return { tokens: internalTokens };
|
|
131
72
|
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
function isDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
77
|
+
const nodePoints = api.getNodePoints();
|
|
78
|
+
const balancedBracketsStatus = checkBalancedBracketsStatus(openerDelimiter.endIndex, closerDelimiter.startIndex, internalTokens, nodePoints);
|
|
79
|
+
switch (balancedBracketsStatus) {
|
|
80
|
+
case -1:
|
|
81
|
+
return { paired: false, opener: false, closer: true };
|
|
82
|
+
case 0:
|
|
83
|
+
return { paired: true };
|
|
84
|
+
case 1:
|
|
85
|
+
return { paired: false, opener: true, closer: false };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function processDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
89
|
+
const nodePoints = api.getNodePoints();
|
|
90
|
+
const bracket = closerDelimiter.brackets[0];
|
|
91
|
+
if (bracket != null && bracket.identifier != null) {
|
|
92
|
+
if (api.hasDefinition(bracket.identifier)) {
|
|
93
|
+
const token = {
|
|
94
|
+
nodeType: ImageReferenceType,
|
|
95
|
+
startIndex: openerDelimiter.startIndex,
|
|
96
|
+
endIndex: bracket.endIndex,
|
|
97
|
+
referenceType: 'full',
|
|
98
|
+
label: bracket.label,
|
|
99
|
+
identifier: bracket.identifier,
|
|
100
|
+
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
101
|
+
};
|
|
102
|
+
return { tokens: [token] };
|
|
103
|
+
}
|
|
104
|
+
return { tokens: internalTokens };
|
|
105
|
+
}
|
|
106
|
+
const { nextIndex, labelAndIdentifier } = eatLinkLabel(nodePoints, openerDelimiter.endIndex - 1, closerDelimiter.startIndex + 1);
|
|
107
|
+
if (nextIndex === closerDelimiter.startIndex + 1 &&
|
|
108
|
+
labelAndIdentifier != null &&
|
|
109
|
+
api.hasDefinition(labelAndIdentifier.identifier)) {
|
|
110
|
+
const token = {
|
|
111
|
+
nodeType: ImageReferenceType,
|
|
112
|
+
startIndex: openerDelimiter.startIndex,
|
|
113
|
+
endIndex: closerDelimiter.endIndex,
|
|
114
|
+
referenceType: bracket == null ? 'shortcut' : 'collapsed',
|
|
115
|
+
label: labelAndIdentifier.label,
|
|
116
|
+
identifier: labelAndIdentifier.identifier,
|
|
117
|
+
children: api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex),
|
|
118
|
+
};
|
|
119
|
+
return { tokens: [token] };
|
|
120
|
+
}
|
|
121
|
+
return { tokens: internalTokens };
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const parse = function (api) {
|
|
126
|
+
return {
|
|
127
|
+
parse: tokens => tokens.map(token => {
|
|
128
|
+
const { identifier, label, referenceType } = token;
|
|
129
|
+
const children = api.parseInlineTokens(token.children);
|
|
130
|
+
const alt = calcImageAlt(children);
|
|
131
|
+
const node = api.shouldReservePosition
|
|
132
|
+
? {
|
|
133
|
+
type: ImageReferenceType,
|
|
134
|
+
position: api.calcPosition(token),
|
|
135
|
+
identifier,
|
|
136
|
+
label,
|
|
137
|
+
referenceType,
|
|
138
|
+
alt,
|
|
139
|
+
}
|
|
140
|
+
: {
|
|
138
141
|
type: ImageReferenceType,
|
|
139
142
|
identifier,
|
|
140
143
|
label,
|
|
141
144
|
referenceType,
|
|
142
145
|
alt,
|
|
143
146
|
};
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
return node;
|
|
148
|
+
}),
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const uniqueName = '@yozora/tokenizer-image-reference';
|
|
153
|
+
|
|
154
|
+
class ImageReferenceTokenizer extends BaseInlineTokenizer {
|
|
155
|
+
constructor(props = {}) {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
super({
|
|
158
|
+
name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
|
|
159
|
+
priority: (_b = props.priority) !== null && _b !== void 0 ? _b : TokenizerPriority.LINKS,
|
|
146
160
|
});
|
|
161
|
+
this.match = match;
|
|
162
|
+
this.parse = parse;
|
|
147
163
|
}
|
|
148
164
|
}
|
|
149
165
|
|
|
150
|
-
export { ImageReferenceTokenizer, uniqueName as ImageReferenceTokenizerName, ImageReferenceTokenizer as default };
|
|
166
|
+
export { ImageReferenceTokenizer, uniqueName as ImageReferenceTokenizerName, ImageReferenceTokenizer as default, match as imageReferenceMatch, parse as imageReferenceParse };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { match as imageReferenceMatch } from './match';
|
|
2
|
+
export { parse as imageReferenceParse } from './parse';
|
|
1
3
|
export { ImageReferenceTokenizer, ImageReferenceTokenizer as default } from './tokenizer';
|
|
2
4
|
export { uniqueName as ImageReferenceTokenizerName } from './types';
|
|
3
|
-
export type { IToken as IImageReferenceToken, ITokenizerProps as IImageReferenceTokenizerProps, } from './types';
|
|
5
|
+
export type { IThis as IImageReferenceHookContext, IToken as IImageReferenceToken, ITokenizerProps as IImageReferenceTokenizerProps, } from './types';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IMatchInlineHookCreator } from '@yozora/core-tokenizer';
|
|
2
|
+
import type { IDelimiter, IThis, IToken, T } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Syntax for image-references is like the syntax for link-references, with one
|
|
5
|
+
* difference. Instead of link text, we have an image description. The rules for
|
|
6
|
+
* this are the same as for link text, except that
|
|
7
|
+
*
|
|
8
|
+
* a) an image description starts with '![' rather than '[', and
|
|
9
|
+
* b) an image description may contain links.
|
|
10
|
+
*
|
|
11
|
+
* An image description has inline elements as its contents. When an image is
|
|
12
|
+
* rendered to HTML, this is standardly used as the image’s alt attribute.
|
|
13
|
+
*
|
|
14
|
+
* One type of opener delimiter: '!['
|
|
15
|
+
*
|
|
16
|
+
* Three types of closer delimiter: ']', '][]' something like '][bar]'
|
|
17
|
+
*
|
|
18
|
+
* ------
|
|
19
|
+
*
|
|
20
|
+
* A 'opener' type delimiter is one of the following forms:
|
|
21
|
+
*
|
|
22
|
+
* - '!['
|
|
23
|
+
*
|
|
24
|
+
* A 'closer' type delimiter is one of the following forms:
|
|
25
|
+
*
|
|
26
|
+
* - ']'
|
|
27
|
+
* - '][]'
|
|
28
|
+
* - '][identifier]'
|
|
29
|
+
*
|
|
30
|
+
* @see https://github.com/syntax-tree/mdast#imagereference
|
|
31
|
+
* @see https://github.github.com/gfm/#images
|
|
32
|
+
*/
|
|
33
|
+
export declare const match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis>;
|
package/lib/types/tokenizer.d.ts
CHANGED
|
@@ -1,40 +1,13 @@
|
|
|
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 ImageReference.
|
|
6
|
-
*
|
|
7
|
-
* Syntax for image-references is like the syntax for link-references, with one
|
|
8
|
-
* difference. Instead of link text, we have an image description. The rules for
|
|
9
|
-
* this are the same as for link text, except that
|
|
10
|
-
*
|
|
11
|
-
* a) an image description starts with '![' rather than '[', and
|
|
12
|
-
* b) an image description may contain links.
|
|
13
|
-
*
|
|
14
|
-
* An image description has inline elements as its contents. When an image is
|
|
15
|
-
* rendered to HTML, this is standardly used as the image’s alt attribute.
|
|
16
|
-
*
|
|
17
|
-
* One type of opener delimiter: '!['
|
|
18
|
-
*
|
|
19
|
-
* Three types of closer delimiter: ']', '][]' something like '][bar]'
|
|
20
|
-
*
|
|
21
|
-
* ------
|
|
22
|
-
*
|
|
23
|
-
* A 'opener' type delimiter is one of the following forms:
|
|
24
|
-
*
|
|
25
|
-
* - '!['
|
|
26
|
-
*
|
|
27
|
-
* A 'closer' type delimiter is one of the following forms:
|
|
28
|
-
*
|
|
29
|
-
* - ']'
|
|
30
|
-
* - '][]'
|
|
31
|
-
* - '][identifier]'
|
|
32
|
-
*
|
|
33
6
|
* @see https://github.com/syntax-tree/mdast#imagereference
|
|
34
7
|
* @see https://github.github.com/gfm/#images
|
|
35
8
|
*/
|
|
36
|
-
export declare class ImageReferenceTokenizer extends BaseInlineTokenizer<T, IDelimiter, IToken, INode> implements IInlineTokenizer<T, IDelimiter, IToken, INode> {
|
|
9
|
+
export declare class ImageReferenceTokenizer extends BaseInlineTokenizer<T, IDelimiter, IToken, INode, IThis> implements IInlineTokenizer<T, IDelimiter, IToken, INode, IThis> {
|
|
37
10
|
constructor(props?: ITokenizerProps);
|
|
38
|
-
readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken>;
|
|
39
|
-
readonly parse: IParseInlineHookCreator<T, IToken, INode>;
|
|
11
|
+
readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis>;
|
|
12
|
+
readonly parse: IParseInlineHookCreator<T, IToken, INode, IThis>;
|
|
40
13
|
}
|
package/lib/types/types.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { IBaseInlineTokenizerProps, IPartialYastInlineToken, IYastTokenDelimiter } from '@yozora/core-tokenizer';
|
|
1
|
+
import type { Association, ImageReference, ImageReferenceType, Reference } from '@yozora/ast';
|
|
2
|
+
import type { IBaseInlineTokenizerProps, IPartialYastInlineToken, ITokenizer, IYastTokenDelimiter } from '@yozora/core-tokenizer';
|
|
3
3
|
import type { ILinkReferenceDelimiterBracket } from '@yozora/tokenizer-link-reference';
|
|
4
4
|
export declare const uniqueName = "@yozora/tokenizer-image-reference";
|
|
5
5
|
export declare type T = ImageReferenceType;
|
|
6
|
-
export declare type INode =
|
|
7
|
-
export interface IToken extends IPartialYastInlineToken<T>,
|
|
6
|
+
export declare type INode = ImageReference;
|
|
7
|
+
export interface IToken extends IPartialYastInlineToken<T>, Association, Reference {
|
|
8
8
|
}
|
|
9
9
|
export interface IDelimiter extends IYastTokenDelimiter {
|
|
10
10
|
brackets: ILinkReferenceDelimiterBracket[];
|
|
11
11
|
}
|
|
12
|
+
export declare type IThis = ITokenizer;
|
|
12
13
|
export declare type ITokenizerProps = Partial<IBaseInlineTokenizerProps>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yozora/tokenizer-image-reference",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "guanghechen",
|
|
6
6
|
"url": "https://github.com/guanghechen/"
|
|
@@ -35,11 +35,12 @@
|
|
|
35
35
|
"test": "cross-env TS_NODE_FILES=true jest --config ../../jest.config.js --rootDir ."
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@yozora/ast": "^2.0.0
|
|
39
|
-
"@yozora/character": "^2.0.0
|
|
40
|
-
"@yozora/core-tokenizer": "^2.0.0
|
|
41
|
-
"@yozora/tokenizer-image": "^2.0.0
|
|
42
|
-
"@yozora/tokenizer-link": "^2.0.0
|
|
38
|
+
"@yozora/ast": "^2.0.0",
|
|
39
|
+
"@yozora/character": "^2.0.0",
|
|
40
|
+
"@yozora/core-tokenizer": "^2.0.0",
|
|
41
|
+
"@yozora/tokenizer-image": "^2.0.0",
|
|
42
|
+
"@yozora/tokenizer-link": "^2.0.0",
|
|
43
|
+
"@yozora/tokenizer-link-reference": "^2.0.0"
|
|
43
44
|
},
|
|
44
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "65e99d1709fdd1c918465dce6b1e91de96bdab5e"
|
|
45
46
|
}
|