@yozora/tokenizer-autolink 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 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 { DefaultYastParser } from '@yozora/core-parser'
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 AutolinkTokenizer from '@yozora/tokenizer-autolink'
91
91
 
92
- const parser = new DefaultYastParser()
93
- .useBlockFallbackTokenizer(new ParagraphTokenizer())
94
- .useInlineFallbackTokenizer(new TextTokenizer())
92
+ const parser = new DefaultParser()
93
+ .useFallbackTokenizer(new ParagraphTokenizer())
94
+ .useFallbackTokenizer(new TextTokenizer())
95
95
  .useTokenizer(new AutolinkTokenizer())
96
96
 
97
97
  // parse source markdown content
@@ -241,7 +241,6 @@ Name | Type | Required | Default
241
241
  [@yozora/tokenizer-link]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link#readme
242
242
  [@yozora/tokenizer-link-reference]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link-reference#readme
243
243
  [@yozora/tokenizer-list]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list#readme
244
- [@yozora/tokenizer-list-item]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list-item#readme
245
244
  [@yozora/tokenizer-math]: https://github.com/yozorajs/yozora/tree/main/tokenizers/math#readme
246
245
  [@yozora/tokenizer-paragraph]: https://github.com/yozorajs/yozora/tree/main/tokenizers/paragraph#readme
247
246
  [@yozora/tokenizer-setext-heading]: https://github.com/yozorajs/yozora/tree/main/tokenizers/setext-heading#readme
@@ -301,7 +300,6 @@ Name | Type | Required | Default
301
300
  [doc-@yozora/tokenizer-definition]: https://yozora.guanghechen.com/docs/package/tokenizer-definition
302
301
  [doc-@yozora/tokenizer-link-reference]: https://yozora.guanghechen.com/docs/package/tokenizer-link-reference
303
302
  [doc-@yozora/tokenizer-list]: https://yozora.guanghechen.com/docs/package/tokenizer-list
304
- [doc-@yozora/tokenizer-list-item]: https://yozora.guanghechen.com/docs/package/tokenizer-list-item
305
303
  [doc-@yozora/tokenizer-math]: https://yozora.guanghechen.com/docs/package/tokenizer-math
306
304
  [doc-@yozora/tokenizer-paragraph]: https://yozora.guanghechen.com/docs/package/tokenizer-paragraph
307
305
  [doc-@yozora/tokenizer-setext-heading]: https://yozora.guanghechen.com/docs/package/tokenizer-setext-heading
package/lib/cjs/index.js CHANGED
@@ -103,12 +103,79 @@ function eatAutolinkSchema(nodePoints, startIndex, endIndex) {
103
103
  return { valid: true, nextIndex: i };
104
104
  }
105
105
 
106
- const uniqueName = '@yozora/tokenizer-autolink';
107
-
108
106
  const helpers = [
109
107
  { contentType: 'uri', eat: eatAbsoluteUri },
110
108
  { contentType: 'email', eat: eatEmailAddress },
111
109
  ];
110
+ const match = function (api) {
111
+ return {
112
+ findDelimiter: () => coreTokenizer.genFindDelimiter(_findDelimiter),
113
+ processSingleDelimiter,
114
+ };
115
+ function _findDelimiter(startIndex, endIndex) {
116
+ const nodePoints = api.getNodePoints();
117
+ for (let i = startIndex; i < endIndex; ++i) {
118
+ if (nodePoints[i].codePoint !== character.AsciiCodePoint.OPEN_ANGLE)
119
+ continue;
120
+ let nextIndex = endIndex;
121
+ let contentType = null;
122
+ for (const helper of helpers) {
123
+ const eatResult = helper.eat(nodePoints, i + 1, endIndex);
124
+ nextIndex = Math.min(nextIndex, eatResult.nextIndex);
125
+ if (eatResult.valid) {
126
+ contentType = helper.contentType;
127
+ nextIndex = eatResult.nextIndex;
128
+ break;
129
+ }
130
+ }
131
+ if (contentType == null) {
132
+ i = Math.max(i, nextIndex - 1);
133
+ continue;
134
+ }
135
+ if (nextIndex < endIndex && nodePoints[nextIndex].codePoint === character.AsciiCodePoint.CLOSE_ANGLE) {
136
+ return {
137
+ type: 'full',
138
+ startIndex: i,
139
+ endIndex: nextIndex + 1,
140
+ contentType,
141
+ };
142
+ }
143
+ i = nextIndex - 1;
144
+ }
145
+ return null;
146
+ }
147
+ function processSingleDelimiter(delimiter) {
148
+ const token = {
149
+ nodeType: ast.LinkType,
150
+ startIndex: delimiter.startIndex,
151
+ endIndex: delimiter.endIndex,
152
+ contentType: delimiter.contentType,
153
+ children: api.resolveFallbackTokens([], delimiter.startIndex + 1, delimiter.endIndex - 1),
154
+ };
155
+ return [token];
156
+ }
157
+ };
158
+
159
+ const parse = function (api) {
160
+ return {
161
+ parse: tokens => tokens.map(token => {
162
+ const nodePoints = api.getNodePoints();
163
+ let url = character.calcStringFromNodePoints(nodePoints, token.startIndex + 1, token.endIndex - 1);
164
+ if (token.contentType === 'email') {
165
+ url = 'mailto:' + url;
166
+ }
167
+ const encodedUrl = coreTokenizer.encodeLinkDestination(url);
168
+ const children = api.parseInlineTokens(token.children);
169
+ const node = api.shouldReservePosition
170
+ ? { type: ast.LinkType, position: api.calcPosition(token), url: encodedUrl, children }
171
+ : { type: ast.LinkType, url: encodedUrl, children };
172
+ return node;
173
+ }),
174
+ };
175
+ };
176
+
177
+ const uniqueName = '@yozora/tokenizer-autolink';
178
+
112
179
  class AutolinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
113
180
  constructor(props = {}) {
114
181
  var _a, _b;
@@ -116,76 +183,15 @@ class AutolinkTokenizer extends coreTokenizer.BaseInlineTokenizer {
116
183
  name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
117
184
  priority: (_b = props.priority) !== null && _b !== void 0 ? _b : coreTokenizer.TokenizerPriority.ATOMIC,
118
185
  });
119
- this.match = api => {
120
- return {
121
- findDelimiter: () => coreTokenizer.genFindDelimiter(_findDelimiter),
122
- processSingleDelimiter,
123
- };
124
- function _findDelimiter(startIndex, endIndex) {
125
- const nodePoints = api.getNodePoints();
126
- for (let i = startIndex; i < endIndex; ++i) {
127
- if (nodePoints[i].codePoint !== character.AsciiCodePoint.OPEN_ANGLE)
128
- continue;
129
- let nextIndex = endIndex;
130
- let contentType = null;
131
- for (const helper of helpers) {
132
- const eatResult = helper.eat(nodePoints, i + 1, endIndex);
133
- nextIndex = Math.min(nextIndex, eatResult.nextIndex);
134
- if (eatResult.valid) {
135
- contentType = helper.contentType;
136
- nextIndex = eatResult.nextIndex;
137
- break;
138
- }
139
- }
140
- if (contentType == null) {
141
- i = Math.max(i, nextIndex - 1);
142
- continue;
143
- }
144
- if (nextIndex < endIndex &&
145
- nodePoints[nextIndex].codePoint === character.AsciiCodePoint.CLOSE_ANGLE) {
146
- return {
147
- type: 'full',
148
- startIndex: i,
149
- endIndex: nextIndex + 1,
150
- contentType,
151
- };
152
- }
153
- i = nextIndex - 1;
154
- }
155
- return null;
156
- }
157
- function processSingleDelimiter(delimiter) {
158
- const token = {
159
- nodeType: ast.LinkType,
160
- startIndex: delimiter.startIndex,
161
- endIndex: delimiter.endIndex,
162
- contentType: delimiter.contentType,
163
- children: api.resolveFallbackTokens([], delimiter.startIndex + 1, delimiter.endIndex - 1),
164
- };
165
- return [token];
166
- }
167
- };
168
- this.parse = api => ({
169
- parse: (token, children) => {
170
- const nodePoints = api.getNodePoints();
171
- let url = character.calcStringFromNodePoints(nodePoints, token.startIndex + 1, token.endIndex - 1);
172
- if (token.contentType === 'email') {
173
- url = 'mailto:' + url;
174
- }
175
- const encodedUrl = coreTokenizer.encodeLinkDestination(url);
176
- const result = {
177
- type: ast.LinkType,
178
- url: encodedUrl,
179
- children,
180
- };
181
- return result;
182
- },
183
- });
186
+ this.match = match;
187
+ this.parse = parse;
184
188
  }
185
189
  }
186
190
 
187
191
  exports.AutolinkTokenizer = AutolinkTokenizer;
188
192
  exports.AutolinkTokenizerName = uniqueName;
193
+ exports.autolinkMatch = match;
194
+ exports.autolinkParse = parse;
189
195
  exports["default"] = AutolinkTokenizer;
190
196
  exports.eatAbsoluteUri = eatAbsoluteUri;
191
197
  exports.eatAutolinkSchema = eatAutolinkSchema;
package/lib/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isAsciiLetter, isAsciiDigitCharacter, AsciiCodePoint, isAlphanumeric, isAsciiCharacter, isWhitespaceCharacter, isAsciiControlCharacter, calcStringFromNodePoints } from '@yozora/character';
2
2
  import { LinkType } from '@yozora/ast';
3
- import { BaseInlineTokenizer, TokenizerPriority, genFindDelimiter, encodeLinkDestination } from '@yozora/core-tokenizer';
3
+ import { genFindDelimiter, encodeLinkDestination, BaseInlineTokenizer, TokenizerPriority } from '@yozora/core-tokenizer';
4
4
 
5
5
  function eatEmailAddress(nodePoints, startIndex, endIndex) {
6
6
  let i = startIndex;
@@ -99,12 +99,79 @@ function eatAutolinkSchema(nodePoints, startIndex, endIndex) {
99
99
  return { valid: true, nextIndex: i };
100
100
  }
101
101
 
102
- const uniqueName = '@yozora/tokenizer-autolink';
103
-
104
102
  const helpers = [
105
103
  { contentType: 'uri', eat: eatAbsoluteUri },
106
104
  { contentType: 'email', eat: eatEmailAddress },
107
105
  ];
106
+ const match = function (api) {
107
+ return {
108
+ findDelimiter: () => genFindDelimiter(_findDelimiter),
109
+ processSingleDelimiter,
110
+ };
111
+ function _findDelimiter(startIndex, endIndex) {
112
+ const nodePoints = api.getNodePoints();
113
+ for (let i = startIndex; i < endIndex; ++i) {
114
+ if (nodePoints[i].codePoint !== AsciiCodePoint.OPEN_ANGLE)
115
+ continue;
116
+ let nextIndex = endIndex;
117
+ let contentType = null;
118
+ for (const helper of helpers) {
119
+ const eatResult = helper.eat(nodePoints, i + 1, endIndex);
120
+ nextIndex = Math.min(nextIndex, eatResult.nextIndex);
121
+ if (eatResult.valid) {
122
+ contentType = helper.contentType;
123
+ nextIndex = eatResult.nextIndex;
124
+ break;
125
+ }
126
+ }
127
+ if (contentType == null) {
128
+ i = Math.max(i, nextIndex - 1);
129
+ continue;
130
+ }
131
+ if (nextIndex < endIndex && nodePoints[nextIndex].codePoint === AsciiCodePoint.CLOSE_ANGLE) {
132
+ return {
133
+ type: 'full',
134
+ startIndex: i,
135
+ endIndex: nextIndex + 1,
136
+ contentType,
137
+ };
138
+ }
139
+ i = nextIndex - 1;
140
+ }
141
+ return null;
142
+ }
143
+ function processSingleDelimiter(delimiter) {
144
+ const token = {
145
+ nodeType: LinkType,
146
+ startIndex: delimiter.startIndex,
147
+ endIndex: delimiter.endIndex,
148
+ contentType: delimiter.contentType,
149
+ children: api.resolveFallbackTokens([], delimiter.startIndex + 1, delimiter.endIndex - 1),
150
+ };
151
+ return [token];
152
+ }
153
+ };
154
+
155
+ const parse = function (api) {
156
+ return {
157
+ parse: tokens => tokens.map(token => {
158
+ const nodePoints = api.getNodePoints();
159
+ let url = calcStringFromNodePoints(nodePoints, token.startIndex + 1, token.endIndex - 1);
160
+ if (token.contentType === 'email') {
161
+ url = 'mailto:' + url;
162
+ }
163
+ const encodedUrl = encodeLinkDestination(url);
164
+ const children = api.parseInlineTokens(token.children);
165
+ const node = api.shouldReservePosition
166
+ ? { type: LinkType, position: api.calcPosition(token), url: encodedUrl, children }
167
+ : { type: LinkType, url: encodedUrl, children };
168
+ return node;
169
+ }),
170
+ };
171
+ };
172
+
173
+ const uniqueName = '@yozora/tokenizer-autolink';
174
+
108
175
  class AutolinkTokenizer extends BaseInlineTokenizer {
109
176
  constructor(props = {}) {
110
177
  var _a, _b;
@@ -112,72 +179,9 @@ class AutolinkTokenizer extends BaseInlineTokenizer {
112
179
  name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
113
180
  priority: (_b = props.priority) !== null && _b !== void 0 ? _b : TokenizerPriority.ATOMIC,
114
181
  });
115
- this.match = api => {
116
- return {
117
- findDelimiter: () => genFindDelimiter(_findDelimiter),
118
- processSingleDelimiter,
119
- };
120
- function _findDelimiter(startIndex, endIndex) {
121
- const nodePoints = api.getNodePoints();
122
- for (let i = startIndex; i < endIndex; ++i) {
123
- if (nodePoints[i].codePoint !== AsciiCodePoint.OPEN_ANGLE)
124
- continue;
125
- let nextIndex = endIndex;
126
- let contentType = null;
127
- for (const helper of helpers) {
128
- const eatResult = helper.eat(nodePoints, i + 1, endIndex);
129
- nextIndex = Math.min(nextIndex, eatResult.nextIndex);
130
- if (eatResult.valid) {
131
- contentType = helper.contentType;
132
- nextIndex = eatResult.nextIndex;
133
- break;
134
- }
135
- }
136
- if (contentType == null) {
137
- i = Math.max(i, nextIndex - 1);
138
- continue;
139
- }
140
- if (nextIndex < endIndex &&
141
- nodePoints[nextIndex].codePoint === AsciiCodePoint.CLOSE_ANGLE) {
142
- return {
143
- type: 'full',
144
- startIndex: i,
145
- endIndex: nextIndex + 1,
146
- contentType,
147
- };
148
- }
149
- i = nextIndex - 1;
150
- }
151
- return null;
152
- }
153
- function processSingleDelimiter(delimiter) {
154
- const token = {
155
- nodeType: LinkType,
156
- startIndex: delimiter.startIndex,
157
- endIndex: delimiter.endIndex,
158
- contentType: delimiter.contentType,
159
- children: api.resolveFallbackTokens([], delimiter.startIndex + 1, delimiter.endIndex - 1),
160
- };
161
- return [token];
162
- }
163
- };
164
- this.parse = api => ({
165
- parse: (token, children) => {
166
- const nodePoints = api.getNodePoints();
167
- let url = calcStringFromNodePoints(nodePoints, token.startIndex + 1, token.endIndex - 1);
168
- if (token.contentType === 'email') {
169
- url = 'mailto:' + url;
170
- }
171
- const encodedUrl = encodeLinkDestination(url);
172
- const result = {
173
- type: LinkType,
174
- url: encodedUrl,
175
- children,
176
- };
177
- return result;
178
- },
179
- });
182
+ this.match = match;
183
+ this.parse = parse;
180
184
  }
181
185
  }
182
186
 
183
- export { AutolinkTokenizer, uniqueName as AutolinkTokenizerName, AutolinkTokenizer as default, eatAbsoluteUri, eatAutolinkSchema, eatEmailAddress };
187
+ export { AutolinkTokenizer, uniqueName as AutolinkTokenizerName, match as autolinkMatch, parse as autolinkParse, AutolinkTokenizer as default, eatAbsoluteUri, eatAutolinkSchema, eatEmailAddress };
@@ -1,5 +1,7 @@
1
1
  export * from './util/email';
2
2
  export * from './util/uri';
3
+ export { match as autolinkMatch } from './match';
4
+ export { parse as autolinkParse } from './parse';
3
5
  export { AutolinkTokenizer, AutolinkTokenizer as default } from './tokenizer';
4
6
  export { uniqueName as AutolinkTokenizerName } from './types';
5
- export type { IToken as IAutolinkToken, ITokenizerProps as IAutolinkTokenizerProps, AutolinkContentType, } from './types';
7
+ export type { IThis as IAutolinkHookContext, IToken as IAutolinkToken, ITokenizerProps as IAutolinkTokenizerProps, AutolinkContentType, } from './types';
@@ -0,0 +1,9 @@
1
+ import type { IMatchInlineHookCreator } from '@yozora/core-tokenizer';
2
+ import type { IDelimiter, IThis, IToken, T } from './types';
3
+ /**
4
+ * Autolinks are absolute URIs and email addresses inside '<' and '>'.
5
+ * They are parsed as links, with the URL or email address as the link label.
6
+ *
7
+ * @see https://github.github.com/gfm/#autolink
8
+ */
9
+ export declare const match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis>;
@@ -0,0 +1,3 @@
1
+ import type { IParseInlineHookCreator } from '@yozora/core-tokenizer';
2
+ import type { INode, IThis, IToken, T } from './types';
3
+ export declare const parse: IParseInlineHookCreator<T, IToken, INode, IThis>;
@@ -1,16 +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 Autolink.
6
- *
7
- * Autolinks are absolute URIs and email addresses inside '<' and '>'.
8
- * They are parsed as links, with the URL or email address as the link label.
9
- *
10
6
  * @see https://github.github.com/gfm/#autolink
11
7
  */
12
- export declare class AutolinkTokenizer extends BaseInlineTokenizer<T, IDelimiter, IToken, INode> implements IInlineTokenizer<T, IDelimiter, IToken, INode> {
8
+ export declare class AutolinkTokenizer extends BaseInlineTokenizer<T, IDelimiter, IToken, INode, IThis> implements IInlineTokenizer<T, IDelimiter, IToken, INode, IThis> {
13
9
  constructor(props?: ITokenizerProps);
14
- readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken>;
15
- readonly parse: IParseInlineHookCreator<T, IToken, INode>;
10
+ readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis>;
11
+ readonly parse: IParseInlineHookCreator<T, IToken, INode, IThis>;
16
12
  }
@@ -1,9 +1,9 @@
1
- import type { ILink, LinkType } from '@yozora/ast';
1
+ import type { Link, LinkType } from '@yozora/ast';
2
2
  import type { INodePoint } from '@yozora/character';
3
- import type { IBaseInlineTokenizerProps, IPartialYastInlineToken, IResultOfRequiredEater, IYastTokenDelimiter } from '@yozora/core-tokenizer';
3
+ import type { IBaseInlineTokenizerProps, IPartialYastInlineToken, IResultOfRequiredEater, ITokenizer, IYastTokenDelimiter } from '@yozora/core-tokenizer';
4
4
  export declare type AutolinkContentType = 'uri' | 'email';
5
5
  export declare type T = LinkType;
6
- export declare type INode = ILink;
6
+ export declare type INode = Link;
7
7
  export declare const uniqueName = "@yozora/tokenizer-autolink";
8
8
  export interface IToken extends IPartialYastInlineToken<T> {
9
9
  /**
@@ -18,6 +18,7 @@ export interface IDelimiter extends IYastTokenDelimiter {
18
18
  */
19
19
  contentType: AutolinkContentType;
20
20
  }
21
+ export declare type IThis = ITokenizer;
21
22
  export declare type ITokenizerProps = Partial<IBaseInlineTokenizerProps>;
22
23
  export declare type ContentEater = (nodePoints: ReadonlyArray<INodePoint>, startIndex: number, endIndex: number) => IResultOfRequiredEater;
23
24
  export interface IContentHelper {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yozora/tokenizer-autolink",
3
- "version": "2.0.0-alpha.0",
3
+ "version": "2.0.0",
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": "^2.0.0-alpha.0",
39
- "@yozora/character": "^2.0.0-alpha.0",
40
- "@yozora/core-tokenizer": "^2.0.0-alpha.0"
38
+ "@yozora/ast": "^2.0.0",
39
+ "@yozora/character": "^2.0.0",
40
+ "@yozora/core-tokenizer": "^2.0.0"
41
41
  },
42
- "gitHead": "0171501339c49ffd02ed16a63447fa20a47a29a7"
42
+ "gitHead": "65e99d1709fdd1c918465dce6b1e91de96bdab5e"
43
43
  }