@yozora/tokenizer-link 1.2.2 → 2.0.0-alpha.2
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 +56 -42
- package/lib/esm/index.js +56 -42
- package/lib/types/index.d.ts +2 -4
- package/lib/types/match.d.ts +31 -0
- package/lib/types/parse.d.ts +3 -0
- package/lib/types/tokenizer.d.ts +6 -57
- package/lib/types/types.d.ts +13 -12
- package/lib/types/util/check-brackets.d.ts +3 -3
- package/lib/types/util/link-destination.d.ts +2 -2
- package/lib/types/util/link-title.d.ts +2 -2
- package/package.json +5 -5
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 LinkTokenizer from '@yozora/tokenizer-link'
|
|
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 LinkTokenizer())
|
|
96
96
|
|
|
97
97
|
// parse source markdown content
|
|
@@ -229,7 +229,6 @@ Name | Type | Required | Default
|
|
|
229
229
|
[@yozora/tokenizer-link]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link#readme
|
|
230
230
|
[@yozora/tokenizer-link-reference]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link-reference#readme
|
|
231
231
|
[@yozora/tokenizer-list]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list#readme
|
|
232
|
-
[@yozora/tokenizer-list-item]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list-item#readme
|
|
233
232
|
[@yozora/tokenizer-math]: https://github.com/yozorajs/yozora/tree/main/tokenizers/math#readme
|
|
234
233
|
[@yozora/tokenizer-paragraph]: https://github.com/yozorajs/yozora/tree/main/tokenizers/paragraph#readme
|
|
235
234
|
[@yozora/tokenizer-setext-heading]: https://github.com/yozorajs/yozora/tree/main/tokenizers/setext-heading#readme
|
|
@@ -289,7 +288,6 @@ Name | Type | Required | Default
|
|
|
289
288
|
[doc-@yozora/tokenizer-definition]: https://yozora.guanghechen.com/docs/package/tokenizer-definition
|
|
290
289
|
[doc-@yozora/tokenizer-link-reference]: https://yozora.guanghechen.com/docs/package/tokenizer-link-reference
|
|
291
290
|
[doc-@yozora/tokenizer-list]: https://yozora.guanghechen.com/docs/package/tokenizer-list
|
|
292
|
-
[doc-@yozora/tokenizer-list-item]: https://yozora.guanghechen.com/docs/package/tokenizer-list-item
|
|
293
291
|
[doc-@yozora/tokenizer-math]: https://yozora.guanghechen.com/docs/package/tokenizer-math
|
|
294
292
|
[doc-@yozora/tokenizer-paragraph]: https://yozora.guanghechen.com/docs/package/tokenizer-paragraph
|
|
295
293
|
[doc-@yozora/tokenizer-setext-heading]: https://yozora.guanghechen.com/docs/package/tokenizer-setext-heading
|
package/lib/cjs/index.js
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var ast = require('@yozora/ast');
|
|
6
5
|
var character = require('@yozora/character');
|
|
7
6
|
var coreTokenizer = require('@yozora/core-tokenizer');
|
|
8
|
-
|
|
9
|
-
const uniqueName = '@yozora/tokenizer-link';
|
|
7
|
+
var ast = require('@yozora/ast');
|
|
10
8
|
|
|
11
9
|
const checkBalancedBracketsStatus = (startIndex, endIndex, internalTokens, nodePoints) => {
|
|
12
10
|
let i = startIndex;
|
|
@@ -153,15 +151,14 @@ function eatLinkTitle(nodePoints, startIndex, endIndex) {
|
|
|
153
151
|
return -1;
|
|
154
152
|
}
|
|
155
153
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
_findDelimiter(startIndex, endIndex, nodePoints, api) {
|
|
154
|
+
const match = function (api) {
|
|
155
|
+
return {
|
|
156
|
+
findDelimiter: () => coreTokenizer.genFindDelimiter(_findDelimiter),
|
|
157
|
+
isDelimiterPair,
|
|
158
|
+
processDelimiterPair,
|
|
159
|
+
};
|
|
160
|
+
function _findDelimiter(startIndex, endIndex) {
|
|
161
|
+
const nodePoints = api.getNodePoints();
|
|
165
162
|
const blockEndIndex = api.getBlockEndIndex();
|
|
166
163
|
for (let i = startIndex; i < endIndex; ++i) {
|
|
167
164
|
const p = nodePoints[i];
|
|
@@ -178,8 +175,7 @@ class LinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
|
178
175
|
return delimiter;
|
|
179
176
|
}
|
|
180
177
|
case character.AsciiCodePoint.CLOSE_BRACKET: {
|
|
181
|
-
if (i + 1 >= endIndex ||
|
|
182
|
-
nodePoints[i + 1].codePoint !== character.AsciiCodePoint.OPEN_PARENTHESIS)
|
|
178
|
+
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== character.AsciiCodePoint.OPEN_PARENTHESIS)
|
|
183
179
|
break;
|
|
184
180
|
const destinationStartIndex = coreTokenizer.eatOptionalWhitespaces(nodePoints, i + 2, blockEndIndex);
|
|
185
181
|
const destinationEndIndex = eatLinkDestination(nodePoints, destinationStartIndex, blockEndIndex);
|
|
@@ -192,8 +188,7 @@ class LinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
|
192
188
|
const _startIndex = i;
|
|
193
189
|
const _endIndex = coreTokenizer.eatOptionalWhitespaces(nodePoints, titleEndIndex, blockEndIndex) + 1;
|
|
194
190
|
if (_endIndex > blockEndIndex ||
|
|
195
|
-
nodePoints[_endIndex - 1].codePoint !==
|
|
196
|
-
character.AsciiCodePoint.CLOSE_PARENTHESIS)
|
|
191
|
+
nodePoints[_endIndex - 1].codePoint !== character.AsciiCodePoint.CLOSE_PARENTHESIS)
|
|
197
192
|
break;
|
|
198
193
|
return {
|
|
199
194
|
type: 'closer',
|
|
@@ -214,7 +209,8 @@ class LinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
|
214
209
|
}
|
|
215
210
|
return null;
|
|
216
211
|
}
|
|
217
|
-
isDelimiterPair(openerDelimiter, closerDelimiter, internalTokens
|
|
212
|
+
function isDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
213
|
+
const nodePoints = api.getNodePoints();
|
|
218
214
|
const hasInternalLinkToken = internalTokens.find(coreTokenizer.isLinkToken) != null;
|
|
219
215
|
if (hasInternalLinkToken) {
|
|
220
216
|
return { paired: false, opener: false, closer: false };
|
|
@@ -229,8 +225,8 @@ class LinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
|
229
225
|
return { paired: false, opener: true, closer: false };
|
|
230
226
|
}
|
|
231
227
|
}
|
|
232
|
-
processDelimiterPair(openerDelimiter, closerDelimiter, internalTokens
|
|
233
|
-
const children = api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex
|
|
228
|
+
function processDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
229
|
+
const children = api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex);
|
|
234
230
|
const token = {
|
|
235
231
|
nodeType: ast.LinkType,
|
|
236
232
|
startIndex: openerDelimiter.startIndex,
|
|
@@ -241,35 +237,53 @@ class LinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
|
241
237
|
};
|
|
242
238
|
return { tokens: [token] };
|
|
243
239
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const parse = function (api) {
|
|
243
|
+
return {
|
|
244
|
+
parse: tokens => tokens.map(token => {
|
|
245
|
+
const nodePoints = api.getNodePoints();
|
|
246
|
+
let url = '';
|
|
247
|
+
if (token.destinationContent != null) {
|
|
248
|
+
let { startIndex, endIndex } = token.destinationContent;
|
|
249
|
+
if (nodePoints[startIndex].codePoint === character.AsciiCodePoint.OPEN_ANGLE) {
|
|
250
|
+
startIndex += 1;
|
|
251
|
+
endIndex -= 1;
|
|
252
|
+
}
|
|
253
|
+
const destination = character.calcEscapedStringFromNodePoints(nodePoints, startIndex, endIndex, true);
|
|
254
|
+
url = coreTokenizer.encodeLinkDestination(destination);
|
|
251
255
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
256
|
+
let title;
|
|
257
|
+
if (token.titleContent != null) {
|
|
258
|
+
const { startIndex, endIndex } = token.titleContent;
|
|
259
|
+
title = character.calcEscapedStringFromNodePoints(nodePoints, startIndex + 1, endIndex - 1);
|
|
260
|
+
}
|
|
261
|
+
const children = api.parseInlineTokens(token.children);
|
|
262
|
+
const node = api.shouldReservePosition
|
|
263
|
+
? { type: ast.LinkType, position: api.calcPosition(token), url, title, children }
|
|
264
|
+
: { type: ast.LinkType, url, title, children };
|
|
265
|
+
return node;
|
|
266
|
+
}),
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const uniqueName = '@yozora/tokenizer-link';
|
|
271
|
+
|
|
272
|
+
class LinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
|
|
273
|
+
constructor(props = {}) {
|
|
274
|
+
var _a, _b;
|
|
275
|
+
super({
|
|
276
|
+
name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
|
|
277
|
+
priority: (_b = props.priority) !== null && _b !== void 0 ? _b : coreTokenizer.TokenizerPriority.LINKS,
|
|
278
|
+
});
|
|
279
|
+
this.match = match;
|
|
280
|
+
this.parse = parse;
|
|
267
281
|
}
|
|
268
282
|
}
|
|
269
283
|
|
|
270
284
|
exports.LinkTokenizer = LinkTokenizer;
|
|
271
285
|
exports.LinkTokenizerName = uniqueName;
|
|
272
286
|
exports.checkBalancedBracketsStatus = checkBalancedBracketsStatus;
|
|
273
|
-
exports[
|
|
287
|
+
exports["default"] = LinkTokenizer;
|
|
274
288
|
exports.eatLinkDestination = eatLinkDestination;
|
|
275
289
|
exports.eatLinkTitle = eatLinkTitle;
|
package/lib/esm/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { LinkType } from '@yozora/ast';
|
|
2
1
|
import { AsciiCodePoint, isWhitespaceCharacter, isAsciiControlCharacter, VirtualCodePoint, calcEscapedStringFromNodePoints } from '@yozora/character';
|
|
3
|
-
import { eatOptionalBlankLines,
|
|
4
|
-
|
|
5
|
-
const uniqueName = '@yozora/tokenizer-link';
|
|
2
|
+
import { eatOptionalBlankLines, genFindDelimiter, eatOptionalWhitespaces, isLinkToken, encodeLinkDestination, BaseInlineTokenizer, TokenizerPriority } from '@yozora/core-tokenizer';
|
|
3
|
+
import { LinkType } from '@yozora/ast';
|
|
6
4
|
|
|
7
5
|
const checkBalancedBracketsStatus = (startIndex, endIndex, internalTokens, nodePoints) => {
|
|
8
6
|
let i = startIndex;
|
|
@@ -149,15 +147,14 @@ function eatLinkTitle(nodePoints, startIndex, endIndex) {
|
|
|
149
147
|
return -1;
|
|
150
148
|
}
|
|
151
149
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
_findDelimiter(startIndex, endIndex, nodePoints, api) {
|
|
150
|
+
const match = function (api) {
|
|
151
|
+
return {
|
|
152
|
+
findDelimiter: () => genFindDelimiter(_findDelimiter),
|
|
153
|
+
isDelimiterPair,
|
|
154
|
+
processDelimiterPair,
|
|
155
|
+
};
|
|
156
|
+
function _findDelimiter(startIndex, endIndex) {
|
|
157
|
+
const nodePoints = api.getNodePoints();
|
|
161
158
|
const blockEndIndex = api.getBlockEndIndex();
|
|
162
159
|
for (let i = startIndex; i < endIndex; ++i) {
|
|
163
160
|
const p = nodePoints[i];
|
|
@@ -174,8 +171,7 @@ class LinkTokenizer extends BaseInlineTokenizer {
|
|
|
174
171
|
return delimiter;
|
|
175
172
|
}
|
|
176
173
|
case AsciiCodePoint.CLOSE_BRACKET: {
|
|
177
|
-
if (i + 1 >= endIndex ||
|
|
178
|
-
nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_PARENTHESIS)
|
|
174
|
+
if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_PARENTHESIS)
|
|
179
175
|
break;
|
|
180
176
|
const destinationStartIndex = eatOptionalWhitespaces(nodePoints, i + 2, blockEndIndex);
|
|
181
177
|
const destinationEndIndex = eatLinkDestination(nodePoints, destinationStartIndex, blockEndIndex);
|
|
@@ -188,8 +184,7 @@ class LinkTokenizer extends BaseInlineTokenizer {
|
|
|
188
184
|
const _startIndex = i;
|
|
189
185
|
const _endIndex = eatOptionalWhitespaces(nodePoints, titleEndIndex, blockEndIndex) + 1;
|
|
190
186
|
if (_endIndex > blockEndIndex ||
|
|
191
|
-
nodePoints[_endIndex - 1].codePoint !==
|
|
192
|
-
AsciiCodePoint.CLOSE_PARENTHESIS)
|
|
187
|
+
nodePoints[_endIndex - 1].codePoint !== AsciiCodePoint.CLOSE_PARENTHESIS)
|
|
193
188
|
break;
|
|
194
189
|
return {
|
|
195
190
|
type: 'closer',
|
|
@@ -210,7 +205,8 @@ class LinkTokenizer extends BaseInlineTokenizer {
|
|
|
210
205
|
}
|
|
211
206
|
return null;
|
|
212
207
|
}
|
|
213
|
-
isDelimiterPair(openerDelimiter, closerDelimiter, internalTokens
|
|
208
|
+
function isDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
209
|
+
const nodePoints = api.getNodePoints();
|
|
214
210
|
const hasInternalLinkToken = internalTokens.find(isLinkToken) != null;
|
|
215
211
|
if (hasInternalLinkToken) {
|
|
216
212
|
return { paired: false, opener: false, closer: false };
|
|
@@ -225,8 +221,8 @@ class LinkTokenizer extends BaseInlineTokenizer {
|
|
|
225
221
|
return { paired: false, opener: true, closer: false };
|
|
226
222
|
}
|
|
227
223
|
}
|
|
228
|
-
processDelimiterPair(openerDelimiter, closerDelimiter, internalTokens
|
|
229
|
-
const children = api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex
|
|
224
|
+
function processDelimiterPair(openerDelimiter, closerDelimiter, internalTokens) {
|
|
225
|
+
const children = api.resolveInternalTokens(internalTokens, openerDelimiter.endIndex, closerDelimiter.startIndex);
|
|
230
226
|
const token = {
|
|
231
227
|
nodeType: LinkType,
|
|
232
228
|
startIndex: openerDelimiter.startIndex,
|
|
@@ -237,29 +233,47 @@ class LinkTokenizer extends BaseInlineTokenizer {
|
|
|
237
233
|
};
|
|
238
234
|
return { tokens: [token] };
|
|
239
235
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const parse = function (api) {
|
|
239
|
+
return {
|
|
240
|
+
parse: tokens => tokens.map(token => {
|
|
241
|
+
const nodePoints = api.getNodePoints();
|
|
242
|
+
let url = '';
|
|
243
|
+
if (token.destinationContent != null) {
|
|
244
|
+
let { startIndex, endIndex } = token.destinationContent;
|
|
245
|
+
if (nodePoints[startIndex].codePoint === AsciiCodePoint.OPEN_ANGLE) {
|
|
246
|
+
startIndex += 1;
|
|
247
|
+
endIndex -= 1;
|
|
248
|
+
}
|
|
249
|
+
const destination = calcEscapedStringFromNodePoints(nodePoints, startIndex, endIndex, true);
|
|
250
|
+
url = encodeLinkDestination(destination);
|
|
247
251
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
252
|
+
let title;
|
|
253
|
+
if (token.titleContent != null) {
|
|
254
|
+
const { startIndex, endIndex } = token.titleContent;
|
|
255
|
+
title = calcEscapedStringFromNodePoints(nodePoints, startIndex + 1, endIndex - 1);
|
|
256
|
+
}
|
|
257
|
+
const children = api.parseInlineTokens(token.children);
|
|
258
|
+
const node = api.shouldReservePosition
|
|
259
|
+
? { type: LinkType, position: api.calcPosition(token), url, title, children }
|
|
260
|
+
: { type: LinkType, url, title, children };
|
|
261
|
+
return node;
|
|
262
|
+
}),
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const uniqueName = '@yozora/tokenizer-link';
|
|
267
|
+
|
|
268
|
+
class LinkTokenizer extends BaseInlineTokenizer {
|
|
269
|
+
constructor(props = {}) {
|
|
270
|
+
var _a, _b;
|
|
271
|
+
super({
|
|
272
|
+
name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
|
|
273
|
+
priority: (_b = props.priority) !== null && _b !== void 0 ? _b : TokenizerPriority.LINKS,
|
|
274
|
+
});
|
|
275
|
+
this.match = match;
|
|
276
|
+
this.parse = parse;
|
|
263
277
|
}
|
|
264
278
|
}
|
|
265
279
|
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { LinkTokenizer } from './tokenizer';
|
|
2
1
|
export * from './util/check-brackets';
|
|
3
2
|
export * from './util/link-destination';
|
|
4
3
|
export * from './util/link-title';
|
|
5
|
-
export { LinkTokenizer } from './tokenizer';
|
|
4
|
+
export { LinkTokenizer, LinkTokenizer as default } from './tokenizer';
|
|
6
5
|
export { uniqueName as LinkTokenizerName } from './types';
|
|
7
|
-
export type {
|
|
8
|
-
export default LinkTokenizer;
|
|
6
|
+
export type { IThis as ILinkHookContext, IToken as ILinkToken, ITokenizerProps as ILinkTokenizerProps, } from './types';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IMatchInlineHookCreator } from '@yozora/core-tokenizer';
|
|
2
|
+
import type { IDelimiter, IThis, IToken, T } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* An inline link consists of a link text followed immediately by a left
|
|
5
|
+
* parenthesis '(', optional whitespace, an optional link destination, an
|
|
6
|
+
* optional link title separated from the link destination by whitespace,
|
|
7
|
+
* optional whitespace, and a right parenthesis ')'. The link’s text consists
|
|
8
|
+
* of the inlines contained in the link text (excluding the enclosing square
|
|
9
|
+
* brackets).
|
|
10
|
+
* The link’s URI consists of the link destination, excluding enclosing '<...>'
|
|
11
|
+
* if present, with backslash-escapes in effect as described above. The link’s
|
|
12
|
+
* title consists of the link title, excluding its enclosing delimiters, with
|
|
13
|
+
* backslash-escapes in effect as described above.
|
|
14
|
+
*
|
|
15
|
+
* ------
|
|
16
|
+
*
|
|
17
|
+
* A 'opener' type delimiter is one of the following forms:
|
|
18
|
+
*
|
|
19
|
+
* - '['
|
|
20
|
+
*
|
|
21
|
+
* A 'closer' type delimiter is one of the following forms:
|
|
22
|
+
*
|
|
23
|
+
* - '](url)'
|
|
24
|
+
* - '](url "title")'
|
|
25
|
+
* - '](<url>)'
|
|
26
|
+
* - '](<url> "title")'
|
|
27
|
+
*
|
|
28
|
+
* @see https://github.com/syntax-tree/mdast#link
|
|
29
|
+
* @see https://github.github.com/gfm/#links
|
|
30
|
+
*/
|
|
31
|
+
export declare const match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis>;
|
package/lib/types/tokenizer.d.ts
CHANGED
|
@@ -1,64 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { NodePoint } from '@yozora/character';
|
|
3
|
-
import type { MatchInlinePhaseApi, ResultOfIsDelimiterPair, ResultOfProcessDelimiterPair, Tokenizer, TokenizerMatchInlineHook, TokenizerParseInlineHook, YastInlineToken } from '@yozora/core-tokenizer';
|
|
1
|
+
import type { IInlineTokenizer, IMatchInlineHookCreator, IParseInlineHookCreator } from '@yozora/core-tokenizer';
|
|
4
2
|
import { BaseInlineTokenizer } from '@yozora/core-tokenizer';
|
|
5
|
-
import type {
|
|
3
|
+
import type { IDelimiter, INode, IThis, IToken, ITokenizerProps, T } from './types';
|
|
6
4
|
/**
|
|
7
5
|
* Lexical Analyzer for InlineLink.
|
|
8
|
-
*
|
|
9
|
-
* An inline link consists of a link text followed immediately by a left
|
|
10
|
-
* parenthesis '(', optional whitespace, an optional link destination, an
|
|
11
|
-
* optional link title separated from the link destination by whitespace,
|
|
12
|
-
* optional whitespace, and a right parenthesis ')'. The link’s text consists
|
|
13
|
-
* of the inlines contained in the link text (excluding the enclosing square
|
|
14
|
-
* brackets).
|
|
15
|
-
* The link’s URI consists of the link destination, excluding enclosing '<...>'
|
|
16
|
-
* if present, with backslash-escapes in effect as described above. The link’s
|
|
17
|
-
* title consists of the link title, excluding its enclosing delimiters, with
|
|
18
|
-
* backslash-escapes in effect as described above.
|
|
19
|
-
*
|
|
20
|
-
* ------
|
|
21
|
-
*
|
|
22
|
-
* A 'opener' type delimiter is one of the following forms:
|
|
23
|
-
*
|
|
24
|
-
* - '['
|
|
25
|
-
*
|
|
26
|
-
* A 'closer' type delimiter is one of the following forms:
|
|
27
|
-
*
|
|
28
|
-
* - '](url)'
|
|
29
|
-
* - '](url "title")'
|
|
30
|
-
* - '](<url>)'
|
|
31
|
-
* - '](<url> "title")'
|
|
32
|
-
*
|
|
33
6
|
* @see https://github.com/syntax-tree/mdast#link
|
|
34
7
|
* @see https://github.github.com/gfm/#links
|
|
35
8
|
*/
|
|
36
|
-
export declare class LinkTokenizer extends BaseInlineTokenizer<
|
|
37
|
-
constructor(props?:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* parenthesis '(', optional whitespace, an optional link destination, an
|
|
41
|
-
* optional link title separated from the link destination by whitespace,
|
|
42
|
-
* optional whitespace, and a right parenthesis ')'
|
|
43
|
-
* @see https://github.github.com/gfm/#inline-link
|
|
44
|
-
*
|
|
45
|
-
* @override
|
|
46
|
-
* @see TokenizerMatchInlineHook
|
|
47
|
-
*/
|
|
48
|
-
protected _findDelimiter(startIndex: number, endIndex: number, nodePoints: ReadonlyArray<NodePoint>, api: Readonly<MatchInlinePhaseApi>): Delimiter | null;
|
|
49
|
-
/**
|
|
50
|
-
* @override
|
|
51
|
-
* @see TokenizerMatchInlineHook
|
|
52
|
-
*/
|
|
53
|
-
isDelimiterPair(openerDelimiter: Delimiter, closerDelimiter: Delimiter, internalTokens: ReadonlyArray<YastInlineToken>, nodePoints: ReadonlyArray<NodePoint>): ResultOfIsDelimiterPair;
|
|
54
|
-
/**
|
|
55
|
-
* @override
|
|
56
|
-
* @see TokenizerMatchInlineHook
|
|
57
|
-
*/
|
|
58
|
-
processDelimiterPair(openerDelimiter: Delimiter, closerDelimiter: Delimiter, internalTokens: ReadonlyArray<YastInlineToken>, nodePoints: ReadonlyArray<NodePoint>, api: Readonly<MatchInlinePhaseApi>): ResultOfProcessDelimiterPair<T, Token, Delimiter>;
|
|
59
|
-
/**
|
|
60
|
-
* @override
|
|
61
|
-
* @see TokenizerParseInlineHook
|
|
62
|
-
*/
|
|
63
|
-
processToken(token: Token, children: YastNode[] | undefined, nodePoints: ReadonlyArray<NodePoint>): Node;
|
|
9
|
+
export declare class LinkTokenizer extends BaseInlineTokenizer<T, IDelimiter, IToken, INode, IThis> implements IInlineTokenizer<T, IDelimiter, IToken, INode, IThis> {
|
|
10
|
+
constructor(props?: ITokenizerProps);
|
|
11
|
+
readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis>;
|
|
12
|
+
readonly parse: IParseInlineHookCreator<T, IToken, INode, IThis>;
|
|
64
13
|
}
|
package/lib/types/types.d.ts
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { ILink, LinkType } from '@yozora/ast';
|
|
2
|
+
import type { INodeInterval } from '@yozora/character';
|
|
3
|
+
import type { IBaseInlineTokenizerProps, IPartialYastInlineToken, ITokenizer, IYastTokenDelimiter } from '@yozora/core-tokenizer';
|
|
4
4
|
export declare type T = LinkType;
|
|
5
|
-
export declare type
|
|
5
|
+
export declare type INode = ILink;
|
|
6
6
|
export declare const uniqueName = "@yozora/tokenizer-link";
|
|
7
|
-
export interface
|
|
7
|
+
export interface IToken extends IPartialYastInlineToken<T> {
|
|
8
8
|
/**
|
|
9
9
|
* Link destination interval.
|
|
10
10
|
*/
|
|
11
|
-
destinationContent?:
|
|
11
|
+
destinationContent?: INodeInterval;
|
|
12
12
|
/**
|
|
13
13
|
* Link title interval.
|
|
14
14
|
*/
|
|
15
|
-
titleContent?:
|
|
15
|
+
titleContent?: INodeInterval;
|
|
16
16
|
}
|
|
17
|
-
export interface
|
|
17
|
+
export interface IDelimiter extends IYastTokenDelimiter {
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* IDelimiter type.
|
|
20
20
|
*/
|
|
21
21
|
type: 'opener' | 'closer';
|
|
22
22
|
/**
|
|
23
23
|
* Link destination interval.
|
|
24
24
|
*/
|
|
25
|
-
destinationContent?:
|
|
25
|
+
destinationContent?: INodeInterval;
|
|
26
26
|
/**
|
|
27
27
|
* Link title interval.
|
|
28
28
|
*/
|
|
29
|
-
titleContent?:
|
|
29
|
+
titleContent?: INodeInterval;
|
|
30
30
|
}
|
|
31
|
-
export declare type
|
|
31
|
+
export declare type IThis = ITokenizer;
|
|
32
|
+
export declare type ITokenizerProps = Partial<IBaseInlineTokenizerProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { INodePoint } from '@yozora/character';
|
|
2
|
+
import type { IYastInlineToken } from '@yozora/core-tokenizer';
|
|
3
3
|
/**
|
|
4
4
|
* The link text may contain balanced brackets, but not unbalanced ones,
|
|
5
5
|
* unless they are escaped
|
|
@@ -9,4 +9,4 @@ import type { YastInlineToken } from '@yozora/core-tokenizer';
|
|
|
9
9
|
* @see https://github.github.com/gfm/#example-522
|
|
10
10
|
* @see https://github.github.com/gfm/#example-523
|
|
11
11
|
*/
|
|
12
|
-
export declare const checkBalancedBracketsStatus: (startIndex: number, endIndex: number, internalTokens: ReadonlyArray<
|
|
12
|
+
export declare const checkBalancedBracketsStatus: (startIndex: number, endIndex: number, internalTokens: ReadonlyArray<IYastInlineToken>, nodePoints: ReadonlyArray<INodePoint>) => -1 | 0 | 1;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { INodePoint } from '@yozora/character';
|
|
2
2
|
/**
|
|
3
3
|
* A link destination consists of either
|
|
4
4
|
* - a sequence of zero or more characters between an opening '<' and a closing '>'
|
|
@@ -12,4 +12,4 @@ import type { NodePoint } from '@yozora/character';
|
|
|
12
12
|
* @see https://github.github.com/gfm/#link-destination
|
|
13
13
|
* @return position at next iteration
|
|
14
14
|
*/
|
|
15
|
-
export declare function eatLinkDestination(nodePoints: ReadonlyArray<
|
|
15
|
+
export declare function eatLinkDestination(nodePoints: ReadonlyArray<INodePoint>, startIndex: number, endIndex: number): number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { INodePoint } from '@yozora/character';
|
|
2
2
|
/**
|
|
3
3
|
* A link title consists of either
|
|
4
4
|
*
|
|
@@ -11,4 +11,4 @@ import type { NodePoint } from '@yozora/character';
|
|
|
11
11
|
* - a sequence of zero or more characters between matching parentheses '(...)',
|
|
12
12
|
* including a '(' or ')' character only if it is backslash-escaped.
|
|
13
13
|
*/
|
|
14
|
-
export declare function eatLinkTitle(nodePoints: ReadonlyArray<
|
|
14
|
+
export declare function eatLinkTitle(nodePoints: ReadonlyArray<INodePoint>, startIndex: number, endIndex: number): number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yozora/tokenizer-link",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha.2",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "guanghechen",
|
|
6
6
|
"url": "https://github.com/guanghechen/"
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"test": "cross-env TS_NODE_FILES=true jest --config ../../jest.config.js --rootDir ."
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@yozora/ast": "^
|
|
39
|
-
"@yozora/character": "^
|
|
40
|
-
"@yozora/core-tokenizer": "^
|
|
38
|
+
"@yozora/ast": "^2.0.0-alpha.2",
|
|
39
|
+
"@yozora/character": "^2.0.0-alpha.2",
|
|
40
|
+
"@yozora/core-tokenizer": "^2.0.0-alpha.2"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "da59d85520455c59a117a35032ef1a035c10ea21"
|
|
43
43
|
}
|