@yozora/tokenizer-link 2.1.3 → 2.1.5

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  <header>
4
4
  <h1 align="center">
5
- <a href="https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/link#readme">@yozora/tokenizer-link</a>
5
+ <a href="https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/link#readme">@yozora/tokenizer-link</a>
6
6
  </h1>
7
7
  <div align="center">
8
8
  <a href="https://www.npmjs.com/package/@yozora/tokenizer-link">
@@ -188,53 +188,53 @@ Name | Type | Required | Default
188
188
 
189
189
  [live-examples]: https://yozora.guanghechen.com/docs/package/tokenizer-link#live-examples
190
190
  [docpage]: https://yozora.guanghechen.com/docs/package/tokenizer-link
191
- [homepage]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/link#readme
191
+ [homepage]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/link#readme
192
192
  [gfm-spec]: https://github.github.com/gfm
193
193
  [mdast-homepage]: https://github.com/syntax-tree/mdast
194
194
 
195
- [@yozora/ast]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/ast#readme
196
- [@yozora/ast-util]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/ast-util#readme
197
- [@yozora/character]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/character#readme
195
+ [@yozora/ast]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/ast#readme
196
+ [@yozora/ast-util]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/ast-util#readme
197
+ [@yozora/character]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/character#readme
198
198
  [@yozora/eslint-config]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/eslint-config#readme
199
- [@yozora/core-parser]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/core-parser#readme
200
- [@yozora/core-tokenizer]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/core-tokenizer#readme
201
- [@yozora/invariant]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/invariant#readme
199
+ [@yozora/core-parser]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/core-parser#readme
200
+ [@yozora/core-tokenizer]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/core-tokenizer#readme
201
+ [@yozora/invariant]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/invariant#readme
202
202
  [@yozora/jest-for-tokenizer]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/jest-for-tokenizer#readme
203
- [@yozora/parser]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/parser#readme
204
- [@yozora/parser-gfm]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/parser-gfm#readme
205
- [@yozora/parser-gfm-ex]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/parser-gfm-ex#readme
203
+ [@yozora/parser]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/parser#readme
204
+ [@yozora/parser-gfm]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/parser-gfm#readme
205
+ [@yozora/parser-gfm-ex]: https://github.com/yozorajs/yozora/tree/v2.1.5/packages/parser-gfm-ex#readme
206
206
  [@yozora/template-tokenizer]: https://github.com/yozorajs/yozora/tree/release-2.x.x/packages/template-tokenizer#readme
207
- [@yozora/tokenizer-admonition]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/admonition#readme
208
- [@yozora/tokenizer-autolink]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/autolink#readme
209
- [@yozora/tokenizer-autolink-extension]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/autolink-extension#readme
210
- [@yozora/tokenizer-blockquote]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/blockquote#readme
211
- [@yozora/tokenizer-break]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/break#readme
212
- [@yozora/tokenizer-definition]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/definition#readme
213
- [@yozora/tokenizer-delete]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/delete#readme
214
- [@yozora/tokenizer-ecma-import]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/ecma-import#readme
215
- [@yozora/tokenizer-emphasis]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/emphasis#readme
216
- [@yozora/tokenizer-fenced-block]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/fenced-block#readme
217
- [@yozora/tokenizer-fenced-code]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/fenced-code#readme
218
- [@yozora/tokenizer-footnote]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/footnote#readme
219
- [@yozora/tokenizer-footnote-definition]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/footnote-definition#readme
220
- [@yozora/tokenizer-footnote-reference]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/footnote-reference#readme
221
- [@yozora/tokenizer-heading]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/heading#readme
222
- [@yozora/tokenizer-html-block]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/html-block#readme
223
- [@yozora/tokenizer-html-inline]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/html-inline#readme
224
- [@yozora/tokenizer-image]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/image#readme
225
- [@yozora/tokenizer-image-reference]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/image-reference#readme
226
- [@yozora/tokenizer-indented-code]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/indented-code#readme
227
- [@yozora/tokenizer-inline-code]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/inline-code#readme
228
- [@yozora/tokenizer-inline-math]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/inline-math#readme
229
- [@yozora/tokenizer-link]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/link#readme
230
- [@yozora/tokenizer-link-reference]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/link-reference#readme
231
- [@yozora/tokenizer-list]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/list#readme
232
- [@yozora/tokenizer-math]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/math#readme
233
- [@yozora/tokenizer-paragraph]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/paragraph#readme
234
- [@yozora/tokenizer-setext-heading]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/setext-heading#readme
235
- [@yozora/tokenizer-table]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/table#readme
236
- [@yozora/tokenizer-text]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/text#readme
237
- [@yozora/tokenizer-thematic-break]: https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/thematic-break#readme
207
+ [@yozora/tokenizer-admonition]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/admonition#readme
208
+ [@yozora/tokenizer-autolink]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/autolink#readme
209
+ [@yozora/tokenizer-autolink-extension]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/autolink-extension#readme
210
+ [@yozora/tokenizer-blockquote]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/blockquote#readme
211
+ [@yozora/tokenizer-break]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/break#readme
212
+ [@yozora/tokenizer-definition]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/definition#readme
213
+ [@yozora/tokenizer-delete]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/delete#readme
214
+ [@yozora/tokenizer-ecma-import]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/ecma-import#readme
215
+ [@yozora/tokenizer-emphasis]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/emphasis#readme
216
+ [@yozora/tokenizer-fenced-block]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/fenced-block#readme
217
+ [@yozora/tokenizer-fenced-code]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/fenced-code#readme
218
+ [@yozora/tokenizer-footnote]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/footnote#readme
219
+ [@yozora/tokenizer-footnote-definition]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/footnote-definition#readme
220
+ [@yozora/tokenizer-footnote-reference]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/footnote-reference#readme
221
+ [@yozora/tokenizer-heading]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/heading#readme
222
+ [@yozora/tokenizer-html-block]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/html-block#readme
223
+ [@yozora/tokenizer-html-inline]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/html-inline#readme
224
+ [@yozora/tokenizer-image]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/image#readme
225
+ [@yozora/tokenizer-image-reference]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/image-reference#readme
226
+ [@yozora/tokenizer-indented-code]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/indented-code#readme
227
+ [@yozora/tokenizer-inline-code]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/inline-code#readme
228
+ [@yozora/tokenizer-inline-math]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/inline-math#readme
229
+ [@yozora/tokenizer-link]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/link#readme
230
+ [@yozora/tokenizer-link-reference]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/link-reference#readme
231
+ [@yozora/tokenizer-list]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/list#readme
232
+ [@yozora/tokenizer-math]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/math#readme
233
+ [@yozora/tokenizer-paragraph]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/paragraph#readme
234
+ [@yozora/tokenizer-setext-heading]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/setext-heading#readme
235
+ [@yozora/tokenizer-table]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/table#readme
236
+ [@yozora/tokenizer-text]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/text#readme
237
+ [@yozora/tokenizer-thematic-break]: https://github.com/yozorajs/yozora/tree/v2.1.5/tokenizers/thematic-break#readme
238
238
 
239
239
  [@yozora/react-admonition]: https://github.com/yozorajs/yozora-react/tree/main/packages/admonition#readme
240
240
  [@yozora/react-blockquote]: https://github.com/yozorajs/yozora-react/tree/main/packages/blockquote#readme
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yozora/tokenizer-link",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "author": {
5
5
  "name": "guanghechen",
6
6
  "url": "https://github.com/guanghechen/"
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "files": [
29
29
  "lib/",
30
- "src/",
30
+ "!lib/**/*.map",
31
31
  "package.json",
32
32
  "CHANGELOG.md",
33
33
  "LICENSE",
@@ -39,9 +39,9 @@
39
39
  "test": "cross-env TS_NODE_FILES=true NODE_OPTIONS=--experimental-vm-modules jest --config ../../jest.config.mjs --rootDir ."
40
40
  },
41
41
  "dependencies": {
42
- "@yozora/ast": "^2.1.3",
43
- "@yozora/character": "^2.1.3",
44
- "@yozora/core-tokenizer": "^2.1.3"
42
+ "@yozora/ast": "^2.1.5",
43
+ "@yozora/character": "^2.1.5",
44
+ "@yozora/core-tokenizer": "^2.1.5"
45
45
  },
46
- "gitHead": "9abaaff74a12d0bae0f645813241ff947a0d828c"
46
+ "gitHead": "4f753bcf0fd921938464802462dc48c53bbd014d"
47
47
  }
package/src/index.ts DELETED
@@ -1,10 +0,0 @@
1
- export * from './util/check-brackets'
2
- export * from './util/link-destination'
3
- export * from './util/link-title'
4
- export { LinkTokenizer, LinkTokenizer as default } from './tokenizer'
5
- export { uniqueName as LinkTokenizerName } from './types'
6
- export type {
7
- IThis as ILinkHookContext,
8
- IToken as ILinkToken,
9
- ITokenizerProps as ILinkTokenizerProps,
10
- } from './types'
package/src/match.ts DELETED
@@ -1,207 +0,0 @@
1
- import { LinkType } from '@yozora/ast'
2
- import type { INodePoint } from '@yozora/character'
3
- import { AsciiCodePoint } from '@yozora/character'
4
- import type {
5
- IInlineToken,
6
- IMatchInlineHookCreator,
7
- IResultOfIsDelimiterPair,
8
- IResultOfProcessDelimiterPair,
9
- } from '@yozora/core-tokenizer'
10
- import { eatOptionalWhitespaces, genFindDelimiter, isLinkToken } from '@yozora/core-tokenizer'
11
- import type { IDelimiter, IThis, IToken, T } from './types'
12
- import { checkBalancedBracketsStatus } from './util/check-brackets'
13
- import { eatLinkDestination } from './util/link-destination'
14
- import { eatLinkTitle } from './util/link-title'
15
-
16
- /**
17
- * An inline link consists of a link text followed immediately by a left
18
- * parenthesis '(', optional whitespace, an optional link destination, an
19
- * optional link title separated from the link destination by whitespace,
20
- * optional whitespace, and a right parenthesis ')'. The link’s text consists
21
- * of the inlines contained in the link text (excluding the enclosing square
22
- * brackets).
23
- * The link’s URI consists of the link destination, excluding enclosing '<...>'
24
- * if present, with backslash-escapes in effect as described above. The link’s
25
- * title consists of the link title, excluding its enclosing delimiters, with
26
- * backslash-escapes in effect as described above.
27
- *
28
- * ------
29
- *
30
- * A 'opener' type delimiter is one of the following forms:
31
- *
32
- * - '['
33
- *
34
- * A 'closer' type delimiter is one of the following forms:
35
- *
36
- * - '](url)'
37
- * - '](url "title")'
38
- * - '](<url>)'
39
- * - '](<url> "title")'
40
- *
41
- * @see https://github.com/syntax-tree/mdast#link
42
- * @see https://github.github.com/gfm/#links
43
- */
44
- export const match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis> = function (api) {
45
- return {
46
- findDelimiter: () => genFindDelimiter<IDelimiter>(_findDelimiter),
47
- isDelimiterPair,
48
- processDelimiterPair,
49
- }
50
-
51
- /**
52
- * An inline link consists of a link text followed immediately by a left
53
- * parenthesis '(', optional whitespace, an optional link destination, an
54
- * optional link title separated from the link destination by whitespace,
55
- * optional whitespace, and a right parenthesis ')'
56
- * @see https://github.github.com/gfm/#inline-link
57
- */
58
- function _findDelimiter(startIndex: number, endIndex: number): IDelimiter | null {
59
- const nodePoints: ReadonlyArray<INodePoint> = api.getNodePoints()
60
- const blockEndIndex = api.getBlockEndIndex()
61
-
62
- /**
63
- * FIXME:
64
- *
65
- * This is a hack method to fix the situation where a higher priority token
66
- * is embedded in the delimiter, at this time, ignore the tokens that have
67
- * been parsed, and continue to match the content until the delimiter meets
68
- * its own definition or reaches the right boundary of the block content.
69
- *
70
- * This algorithm has not been strictly logically verified, but I think it
71
- * can work well in most cases. After all, it has passed many test cases.
72
- * @see https://github.github.com/gfm/#example-588
73
- */
74
- for (let i = startIndex; i < endIndex; ++i) {
75
- const p = nodePoints[i]
76
- switch (p.codePoint) {
77
- case AsciiCodePoint.BACKSLASH:
78
- i += 1
79
- break
80
- /**
81
- * A link text consists of a sequence of zero or more inline elements
82
- * enclosed by square brackets ([ and ])
83
- * @see https://github.github.com/gfm/#link-text
84
- */
85
- case AsciiCodePoint.OPEN_BRACKET: {
86
- const delimiter: IDelimiter = {
87
- type: 'opener',
88
- startIndex: i,
89
- endIndex: i + 1,
90
- }
91
- return delimiter
92
- }
93
- /**
94
- * An inline link consists of a link text followed immediately by a
95
- * left parenthesis '(', ..., and a right parenthesis ')'
96
- * @see https://github.github.com/gfm/#inline-link
97
- */
98
- case AsciiCodePoint.CLOSE_BRACKET: {
99
- if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_PARENTHESIS)
100
- break
101
-
102
- // try to match link destination
103
- const destinationStartIndex = eatOptionalWhitespaces(nodePoints, i + 2, blockEndIndex)
104
- const destinationEndIndex = eatLinkDestination(
105
- nodePoints,
106
- destinationStartIndex,
107
- blockEndIndex,
108
- )
109
- if (destinationEndIndex < 0) break // no valid destination matched
110
-
111
- // try to match link title
112
- const titleStartIndex = eatOptionalWhitespaces(
113
- nodePoints,
114
- destinationEndIndex,
115
- blockEndIndex,
116
- )
117
- const titleEndIndex = eatLinkTitle(nodePoints, titleStartIndex, blockEndIndex)
118
- if (titleEndIndex < 0) break
119
-
120
- const _startIndex = i
121
- const _endIndex = eatOptionalWhitespaces(nodePoints, titleEndIndex, blockEndIndex) + 1
122
- if (
123
- _endIndex > blockEndIndex ||
124
- nodePoints[_endIndex - 1].codePoint !== AsciiCodePoint.CLOSE_PARENTHESIS
125
- )
126
- break
127
-
128
- /**
129
- * Both the title and the destination may be omitted
130
- * @see https://github.github.com/gfm/#example-495
131
- */
132
- return {
133
- type: 'closer',
134
- startIndex: _startIndex,
135
- endIndex: _endIndex,
136
- destinationContent:
137
- destinationStartIndex < destinationEndIndex
138
- ? {
139
- startIndex: destinationStartIndex,
140
- endIndex: destinationEndIndex,
141
- }
142
- : undefined,
143
- titleContent:
144
- titleStartIndex < titleEndIndex
145
- ? { startIndex: titleStartIndex, endIndex: titleEndIndex }
146
- : undefined,
147
- }
148
- }
149
- }
150
- }
151
- return null
152
- }
153
-
154
- function isDelimiterPair(
155
- openerDelimiter: IDelimiter,
156
- closerDelimiter: IDelimiter,
157
- internalTokens: ReadonlyArray<IInlineToken>,
158
- ): IResultOfIsDelimiterPair {
159
- const nodePoints: ReadonlyArray<INodePoint> = api.getNodePoints()
160
-
161
- /**
162
- * Links may not contain other links, at any level of nesting.
163
- * @see https://github.github.com/gfm/#example-540
164
- * @see https://github.github.com/gfm/#example-541
165
- */
166
- const hasInternalLinkToken: boolean = internalTokens.find(isLinkToken) != null
167
- if (hasInternalLinkToken) {
168
- return { paired: false, opener: false, closer: false }
169
- }
170
-
171
- const balancedBracketsStatus: -1 | 0 | 1 = checkBalancedBracketsStatus(
172
- openerDelimiter.endIndex,
173
- closerDelimiter.startIndex,
174
- internalTokens,
175
- nodePoints,
176
- )
177
- switch (balancedBracketsStatus) {
178
- case -1:
179
- return { paired: false, opener: false, closer: true }
180
- case 0:
181
- return { paired: true }
182
- case 1:
183
- return { paired: false, opener: true, closer: false }
184
- }
185
- }
186
-
187
- function processDelimiterPair(
188
- openerDelimiter: IDelimiter,
189
- closerDelimiter: IDelimiter,
190
- internalTokens: ReadonlyArray<IInlineToken>,
191
- ): IResultOfProcessDelimiterPair<T, IToken, IDelimiter> {
192
- const children: ReadonlyArray<IInlineToken> = api.resolveInternalTokens(
193
- internalTokens,
194
- openerDelimiter.endIndex,
195
- closerDelimiter.startIndex,
196
- )
197
- const token: IToken = {
198
- nodeType: LinkType,
199
- startIndex: openerDelimiter.startIndex,
200
- endIndex: closerDelimiter.endIndex,
201
- destinationContent: closerDelimiter.destinationContent,
202
- titleContent: closerDelimiter.titleContent,
203
- children,
204
- }
205
- return { tokens: [token] }
206
- }
207
- }
package/src/parse.ts DELETED
@@ -1,46 +0,0 @@
1
- import type { Node } from '@yozora/ast'
2
- import { LinkType } from '@yozora/ast'
3
- import type { INodePoint } from '@yozora/character'
4
- import { AsciiCodePoint, calcEscapedStringFromNodePoints } from '@yozora/character'
5
- import type { IParseInlineHookCreator } from '@yozora/core-tokenizer'
6
- import { encodeLinkDestination } from '@yozora/core-tokenizer'
7
- import type { INode, IThis, IToken, T } from './types'
8
-
9
- export const parse: IParseInlineHookCreator<T, IToken, INode, IThis> = function (api) {
10
- return {
11
- parse: tokens =>
12
- tokens.map(token => {
13
- const nodePoints: ReadonlyArray<INodePoint> = api.getNodePoints()
14
-
15
- // calc url
16
- let url = ''
17
- if (token.destinationContent != null) {
18
- let { startIndex, endIndex } = token.destinationContent
19
- if (nodePoints[startIndex].codePoint === AsciiCodePoint.OPEN_ANGLE) {
20
- startIndex += 1
21
- endIndex -= 1
22
- }
23
- const destination = calcEscapedStringFromNodePoints(
24
- nodePoints,
25
- startIndex,
26
- endIndex,
27
- true,
28
- )
29
- url = encodeLinkDestination(destination)
30
- }
31
-
32
- // calc title
33
- let title: string | undefined
34
- if (token.titleContent != null) {
35
- const { startIndex, endIndex } = token.titleContent
36
- title = calcEscapedStringFromNodePoints(nodePoints, startIndex + 1, endIndex - 1)
37
- }
38
-
39
- const children: Node[] = api.parseInlineTokens(token.children)
40
- const node: INode = api.shouldReservePosition
41
- ? { type: LinkType, position: api.calcPosition(token), url, title, children }
42
- : { type: LinkType, url, title, children }
43
- return node
44
- }),
45
- }
46
- }
package/src/tokenizer.ts DELETED
@@ -1,32 +0,0 @@
1
- import type {
2
- IInlineTokenizer,
3
- IMatchInlineHookCreator,
4
- IParseInlineHookCreator,
5
- } from '@yozora/core-tokenizer'
6
- import { BaseInlineTokenizer, TokenizerPriority } from '@yozora/core-tokenizer'
7
- import { match } from './match'
8
- import { parse } from './parse'
9
- import type { IDelimiter, INode, IThis, IToken, ITokenizerProps, T } from './types'
10
- import { uniqueName } from './types'
11
-
12
- /**
13
- * Lexical Analyzer for InlineLink.
14
- * @see https://github.com/syntax-tree/mdast#link
15
- * @see https://github.github.com/gfm/#links
16
- */
17
- export class LinkTokenizer
18
- extends BaseInlineTokenizer<T, IDelimiter, IToken, INode, IThis>
19
- implements IInlineTokenizer<T, IDelimiter, IToken, INode, IThis>
20
- {
21
- /* istanbul ignore next */
22
- constructor(props: ITokenizerProps = {}) {
23
- super({
24
- name: props.name ?? uniqueName,
25
- priority: props.priority ?? TokenizerPriority.LINKS,
26
- })
27
- }
28
-
29
- public override readonly match: IMatchInlineHookCreator<T, IDelimiter, IToken, IThis> = match
30
-
31
- public override readonly parse: IParseInlineHookCreator<T, IToken, INode, IThis> = parse
32
- }
package/src/types.ts DELETED
@@ -1,42 +0,0 @@
1
- import type { Link, LinkType } from '@yozora/ast'
2
- import type { INodeInterval } from '@yozora/character'
3
- import type {
4
- IBaseInlineTokenizerProps,
5
- IPartialInlineToken,
6
- ITokenDelimiter,
7
- ITokenizer,
8
- } from '@yozora/core-tokenizer'
9
-
10
- export type T = LinkType
11
- export type INode = Link
12
- export const uniqueName = '@yozora/tokenizer-link'
13
-
14
- export interface IToken extends IPartialInlineToken<T> {
15
- /**
16
- * Link destination interval.
17
- */
18
- destinationContent?: INodeInterval
19
- /**
20
- * Link title interval.
21
- */
22
- titleContent?: INodeInterval
23
- }
24
-
25
- export interface IDelimiter extends ITokenDelimiter {
26
- /**
27
- * IDelimiter type.
28
- */
29
- type: 'opener' | 'closer'
30
- /**
31
- * Link destination interval.
32
- */
33
- destinationContent?: INodeInterval
34
- /**
35
- * Link title interval.
36
- */
37
- titleContent?: INodeInterval
38
- }
39
-
40
- export type IThis = ITokenizer
41
-
42
- export type ITokenizerProps = Partial<IBaseInlineTokenizerProps>
@@ -1,54 +0,0 @@
1
- import type { INodePoint } from '@yozora/character'
2
- import { AsciiCodePoint } from '@yozora/character'
3
- import type { IInlineToken } from '@yozora/core-tokenizer'
4
-
5
- /**
6
- * The link text may contain balanced brackets, but not unbalanced ones,
7
- * unless they are escaped
8
- *
9
- * @see https://github.github.com/gfm/#example-520
10
- * @see https://github.github.com/gfm/#example-521
11
- * @see https://github.github.com/gfm/#example-522
12
- * @see https://github.github.com/gfm/#example-523
13
- */
14
- export const checkBalancedBracketsStatus = (
15
- startIndex: number,
16
- endIndex: number,
17
- internalTokens: ReadonlyArray<IInlineToken>,
18
- nodePoints: ReadonlyArray<INodePoint>,
19
- ): -1 | 0 | 1 => {
20
- let i = startIndex
21
- let bracketCount = 0
22
-
23
- // update bracketCount
24
- const updateBracketCount = (): void => {
25
- const c = nodePoints[i].codePoint
26
- switch (c) {
27
- case AsciiCodePoint.BACKSLASH:
28
- i += 1
29
- break
30
- case AsciiCodePoint.OPEN_BRACKET:
31
- bracketCount += 1
32
- break
33
- case AsciiCodePoint.CLOSE_BRACKET:
34
- bracketCount -= 1
35
- break
36
- }
37
- }
38
-
39
- for (const token of internalTokens) {
40
- if (token.startIndex < startIndex) continue
41
- if (token.endIndex > endIndex) break
42
- for (; i < token.startIndex; ++i) {
43
- updateBracketCount()
44
- if (bracketCount < 0) return -1
45
- }
46
- i = token.endIndex
47
- }
48
-
49
- for (; i < endIndex; ++i) {
50
- updateBracketCount()
51
- if (bracketCount < 0) return -1
52
- }
53
- return bracketCount > 0 ? 1 : 0
54
- }
@@ -1,85 +0,0 @@
1
- import type { INodePoint } from '@yozora/character'
2
- import {
3
- AsciiCodePoint,
4
- VirtualCodePoint,
5
- isAsciiControlCharacter,
6
- isWhitespaceCharacter,
7
- } from '@yozora/character'
8
-
9
- /**
10
- * A link destination consists of either
11
- * - a sequence of zero or more characters between an opening '<' and a closing '>'
12
- * that contains no line breaks or unescaped '<' or '>' characters, or
13
- * - a nonempty sequence of characters that does not start with '<', does not include
14
- * ASCII space or control characters, and includes parentheses only if
15
- * (a) they are backslash-escaped or
16
- * (b) they are part of a balanced pair of unescaped parentheses. (Implementations
17
- * may impose limits on parentheses nesting to avoid performance issues, but
18
- * at least three levels of nesting should be supported.)
19
- * @see https://github.github.com/gfm/#link-destination
20
- * @return position at next iteration
21
- */
22
- export function eatLinkDestination(
23
- nodePoints: ReadonlyArray<INodePoint>,
24
- startIndex: number,
25
- endIndex: number,
26
- ): number {
27
- if (startIndex >= endIndex) return -1
28
-
29
- let i = startIndex
30
- switch (nodePoints[i].codePoint) {
31
- /**
32
- * In pointy brackets:
33
- * - A sequence of zero or more characters between an opening '<' and
34
- * a closing '>' that contains no line breaks or unescaped '<' or '>' characters
35
- */
36
- case AsciiCodePoint.OPEN_ANGLE: {
37
- for (i += 1; i < endIndex; ++i) {
38
- const p = nodePoints[i]
39
- switch (p.codePoint) {
40
- case AsciiCodePoint.BACKSLASH:
41
- i += 1
42
- break
43
- case AsciiCodePoint.OPEN_ANGLE:
44
- case VirtualCodePoint.LINE_END:
45
- return -1
46
- case AsciiCodePoint.CLOSE_ANGLE:
47
- return i + 1
48
- }
49
- }
50
- return -1
51
- }
52
- /**
53
- * Not in pointy brackets:
54
- * - A nonempty sequence of characters that does not start with '<', does not include
55
- * ASCII space or control characters, and includes parentheses only if
56
- *
57
- * a) they are backslash-escaped or
58
- * b) they are part of a balanced pair of unescaped parentheses. (Implementations
59
- * may impose limits on parentheses nesting to avoid performance issues,
60
- * but at least three levels of nesting should be supported.)
61
- */
62
- default: {
63
- let openParensCount = 0
64
- for (; i < endIndex; ++i) {
65
- const c = nodePoints[i].codePoint
66
- switch (c) {
67
- case AsciiCodePoint.BACKSLASH:
68
- i += 1
69
- break
70
- case AsciiCodePoint.OPEN_PARENTHESIS:
71
- openParensCount += 1
72
- break
73
- case AsciiCodePoint.CLOSE_PARENTHESIS:
74
- openParensCount -= 1
75
- if (openParensCount < 0) return i
76
- break
77
- default:
78
- if (isWhitespaceCharacter(c) || isAsciiControlCharacter(c)) return i
79
- break
80
- }
81
- }
82
- return openParensCount === 0 ? i : -1
83
- }
84
- }
85
- }