@yozora/tokenizer-image-reference 2.0.4 → 2.0.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.
@@ -157,18 +157,17 @@ const uniqueName = '@yozora/tokenizer-image-reference';
157
157
 
158
158
  class ImageReferenceTokenizer extends coreTokenizer.BaseInlineTokenizer {
159
159
  constructor(props = {}) {
160
- var _a, _b;
161
160
  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,
161
+ name: props.name ?? uniqueName,
162
+ priority: props.priority ?? coreTokenizer.TokenizerPriority.LINKS,
164
163
  });
165
- this.match = match;
166
- this.parse = parse;
167
164
  }
165
+ match = match;
166
+ parse = parse;
168
167
  }
169
168
 
170
169
  exports.ImageReferenceTokenizer = ImageReferenceTokenizer;
171
170
  exports.ImageReferenceTokenizerName = uniqueName;
172
- exports["default"] = ImageReferenceTokenizer;
171
+ exports.default = ImageReferenceTokenizer;
173
172
  exports.imageReferenceMatch = match;
174
173
  exports.imageReferenceParse = parse;
@@ -153,14 +153,13 @@ const uniqueName = '@yozora/tokenizer-image-reference';
153
153
 
154
154
  class ImageReferenceTokenizer extends BaseInlineTokenizer {
155
155
  constructor(props = {}) {
156
- var _a, _b;
157
156
  super({
158
- name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
159
- priority: (_b = props.priority) !== null && _b !== void 0 ? _b : TokenizerPriority.LINKS,
157
+ name: props.name ?? uniqueName,
158
+ priority: props.priority ?? TokenizerPriority.LINKS,
160
159
  });
161
- this.match = match;
162
- this.parse = parse;
163
160
  }
161
+ match = match;
162
+ parse = parse;
164
163
  }
165
164
 
166
165
  export { ImageReferenceTokenizer, uniqueName as ImageReferenceTokenizerName, ImageReferenceTokenizer as default, match as imageReferenceMatch, parse as imageReferenceParse };
@@ -3,15 +3,15 @@ import { Association, Reference, ImageReferenceType, ImageReference } from '@yoz
3
3
  import { ILinkReferenceDelimiterBracket } from '@yozora/tokenizer-link-reference';
4
4
 
5
5
  declare const uniqueName = "@yozora/tokenizer-image-reference";
6
- declare type T = ImageReferenceType;
7
- declare type INode = ImageReference;
6
+ type T = ImageReferenceType;
7
+ type INode = ImageReference;
8
8
  interface IToken extends IPartialYastInlineToken<T>, Association, Reference {
9
9
  }
10
10
  interface IDelimiter extends IYastTokenDelimiter {
11
11
  brackets: ILinkReferenceDelimiterBracket[];
12
12
  }
13
- declare type IThis = ITokenizer;
14
- declare type ITokenizerProps = Partial<IBaseInlineTokenizerProps>;
13
+ type IThis = ITokenizer;
14
+ type ITokenizerProps = Partial<IBaseInlineTokenizerProps>;
15
15
 
16
16
  /**
17
17
  * Syntax for image-references is like the syntax for link-references, with one
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yozora/tokenizer-image-reference",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "author": {
5
5
  "name": "guanghechen",
6
6
  "url": "https://github.com/guanghechen/"
@@ -11,36 +11,40 @@
11
11
  "directory": "tokenizers/image-reference"
12
12
  },
13
13
  "homepage": "https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/image-reference",
14
- "main": "lib/cjs/index.js",
15
- "module": "lib/esm/index.js",
16
- "types": "lib/types/index.d.ts",
17
- "source": "src/index.ts",
14
+ "type": "module",
15
+ "exports": {
16
+ "types": "./lib/types/index.d.ts",
17
+ "import": "./lib/esm/index.mjs",
18
+ "require": "./lib/cjs/index.cjs"
19
+ },
20
+ "source": "./src/index.ts",
21
+ "types": "./lib/types/index.d.ts",
22
+ "main": "./lib/cjs/index.cjs",
23
+ "module": "./lib/esm/index.mjs",
18
24
  "license": "MIT",
19
25
  "engines": {
20
26
  "node": ">= 16.0.0"
21
27
  },
22
28
  "files": [
23
29
  "lib/",
24
- "!lib/**/*.js.map",
25
- "!lib/**/*.d.ts.map",
30
+ "src/",
26
31
  "package.json",
27
32
  "CHANGELOG.md",
28
33
  "LICENSE",
29
34
  "README.md"
30
35
  ],
31
36
  "scripts": {
32
- "build": "cross-env NODE_ENV=production rollup -c ../../rollup.config.js",
33
- "prebuild": "rimraf lib/",
37
+ "build": "rimraf lib/ && cross-env NODE_ENV=production rollup -c ../../rollup.config.mjs",
34
38
  "prepublishOnly": "cross-env ROLLUP_SHOULD_SOURCEMAP=false yarn build",
35
- "test": "cross-env TS_NODE_FILES=true jest --config ../../jest.config.js --rootDir ."
39
+ "test": "cross-env TS_NODE_FILES=true NODE_OPTIONS=--experimental-vm-modules jest --config ../../jest.config.mjs --rootDir ."
36
40
  },
37
41
  "dependencies": {
38
- "@yozora/ast": "^2.0.4",
39
- "@yozora/character": "^2.0.4",
40
- "@yozora/core-tokenizer": "^2.0.4",
41
- "@yozora/tokenizer-image": "^2.0.4",
42
- "@yozora/tokenizer-link": "^2.0.4",
43
- "@yozora/tokenizer-link-reference": "^2.0.4"
42
+ "@yozora/ast": "^2.0.5",
43
+ "@yozora/character": "^2.0.5",
44
+ "@yozora/core-tokenizer": "^2.0.5",
45
+ "@yozora/tokenizer-image": "^2.0.5",
46
+ "@yozora/tokenizer-link": "^2.0.5",
47
+ "@yozora/tokenizer-link-reference": "^2.0.5"
44
48
  },
45
- "gitHead": "c980b95254394dcacba0cbb4bea251350b09397c"
49
+ "gitHead": "7ba3bab49fe65cf2f57082c0503af73da9356cf0"
46
50
  }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { match as imageReferenceMatch } from './match'
2
+ export { parse as imageReferenceParse } from './parse'
3
+ export { ImageReferenceTokenizer, ImageReferenceTokenizer as default } from './tokenizer'
4
+ export { uniqueName as ImageReferenceTokenizerName } from './types'
5
+ export type {
6
+ IThis as IImageReferenceHookContext,
7
+ IToken as IImageReferenceToken,
8
+ ITokenizerProps as IImageReferenceTokenizerProps,
9
+ } from './types'
package/src/match.ts ADDED
@@ -0,0 +1,206 @@
1
+ import { ImageReferenceType } from '@yozora/ast'
2
+ import type { INodePoint } from '@yozora/character'
3
+ import { AsciiCodePoint } from '@yozora/character'
4
+ import type {
5
+ IMatchInlineHookCreator,
6
+ IResultOfIsDelimiterPair,
7
+ IResultOfProcessDelimiterPair,
8
+ IYastInlineToken,
9
+ } from '@yozora/core-tokenizer'
10
+ import { eatLinkLabel, genFindDelimiter } from '@yozora/core-tokenizer'
11
+ import { checkBalancedBracketsStatus } from '@yozora/tokenizer-link'
12
+ import type { IDelimiter, IThis, IToken, T } from './types'
13
+
14
+ /**
15
+ * Syntax for image-references is like the syntax for link-references, with one
16
+ * difference. Instead of link text, we have an image description. The rules for
17
+ * this are the same as for link text, except that
18
+ *
19
+ * a) an image description starts with '![' rather than '[', and
20
+ * b) an image description may contain links.
21
+ *
22
+ * An image description has inline elements as its contents. When an image is
23
+ * rendered to HTML, this is standardly used as the image’s alt attribute.
24
+ *
25
+ * One type of opener delimiter: '!['
26
+ *
27
+ * Three types of closer delimiter: ']', '][]' something like '][bar]'
28
+ *
29
+ * ------
30
+ *
31
+ * A 'opener' type delimiter is one of the following forms:
32
+ *
33
+ * - '!['
34
+ *
35
+ * A 'closer' type delimiter is one of the following forms:
36
+ *
37
+ * - ']'
38
+ * - '][]'
39
+ * - '][identifier]'
40
+ *
41
+ * @see https://github.com/syntax-tree/mdast#imagereference
42
+ * @see https://github.github.com/gfm/#images
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
+ function _findDelimiter(startIndex: number, endIndex: number): IDelimiter | null {
52
+ const nodePoints: ReadonlyArray<INodePoint> = api.getNodePoints()
53
+
54
+ for (let i = startIndex; i < endIndex; ++i) {
55
+ const c = nodePoints[i].codePoint
56
+ switch (c) {
57
+ case AsciiCodePoint.BACKSLASH:
58
+ i += 1
59
+ break
60
+ case AsciiCodePoint.EXCLAMATION_MARK: {
61
+ if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_BRACKET) {
62
+ break
63
+ }
64
+
65
+ return {
66
+ type: 'opener',
67
+ startIndex: i,
68
+ endIndex: i + 2,
69
+ brackets: [],
70
+ }
71
+ }
72
+ case AsciiCodePoint.CLOSE_BRACKET: {
73
+ const delimiter: IDelimiter = {
74
+ type: 'closer',
75
+ startIndex: i,
76
+ endIndex: i + 1,
77
+ brackets: [],
78
+ }
79
+
80
+ if (i + 1 >= endIndex || nodePoints[i + 1].codePoint !== AsciiCodePoint.OPEN_BRACKET) {
81
+ return delimiter
82
+ }
83
+
84
+ const result = eatLinkLabel(nodePoints, i + 1, endIndex)
85
+
86
+ // It's something like ']['
87
+ if (result.nextIndex < 0) return delimiter
88
+
89
+ // It's something like '][]'
90
+ if (result.labelAndIdentifier == null) {
91
+ return {
92
+ type: 'closer',
93
+ startIndex: i,
94
+ endIndex: result.nextIndex,
95
+ brackets: [
96
+ {
97
+ startIndex: i + 1,
98
+ endIndex: result.nextIndex,
99
+ },
100
+ ],
101
+ }
102
+ }
103
+
104
+ return {
105
+ type: 'closer',
106
+ startIndex: i,
107
+ endIndex: result.nextIndex,
108
+ brackets: [
109
+ {
110
+ startIndex: i + 1,
111
+ endIndex: result.nextIndex,
112
+ label: result.labelAndIdentifier.label,
113
+ identifier: result.labelAndIdentifier.identifier,
114
+ },
115
+ ],
116
+ }
117
+ }
118
+ }
119
+ }
120
+ return null
121
+ }
122
+
123
+ function isDelimiterPair(
124
+ openerDelimiter: IDelimiter,
125
+ closerDelimiter: IDelimiter,
126
+ internalTokens: ReadonlyArray<IYastInlineToken>,
127
+ ): IResultOfIsDelimiterPair {
128
+ const nodePoints: ReadonlyArray<INodePoint> = api.getNodePoints()
129
+ const balancedBracketsStatus: -1 | 0 | 1 = checkBalancedBracketsStatus(
130
+ openerDelimiter.endIndex,
131
+ closerDelimiter.startIndex,
132
+ internalTokens,
133
+ nodePoints,
134
+ )
135
+ switch (balancedBracketsStatus) {
136
+ case -1:
137
+ return { paired: false, opener: false, closer: true }
138
+ case 0:
139
+ return { paired: true }
140
+ case 1:
141
+ return { paired: false, opener: true, closer: false }
142
+ }
143
+ }
144
+
145
+ function processDelimiterPair(
146
+ openerDelimiter: IDelimiter,
147
+ closerDelimiter: IDelimiter,
148
+ internalTokens: ReadonlyArray<IYastInlineToken>,
149
+ ): IResultOfProcessDelimiterPair<T, IToken, IDelimiter> {
150
+ const nodePoints: ReadonlyArray<INodePoint> = api.getNodePoints()
151
+ const bracket = closerDelimiter.brackets[0]
152
+ if (bracket != null && bracket.identifier != null) {
153
+ if (api.hasDefinition(bracket.identifier)) {
154
+ const token: IToken = {
155
+ nodeType: ImageReferenceType,
156
+ startIndex: openerDelimiter.startIndex,
157
+ endIndex: bracket.endIndex,
158
+ referenceType: 'full',
159
+ label: bracket.label!,
160
+ identifier: bracket.identifier,
161
+ children: api.resolveInternalTokens(
162
+ internalTokens,
163
+ openerDelimiter.endIndex,
164
+ closerDelimiter.startIndex,
165
+ ),
166
+ }
167
+ return { tokens: [token] }
168
+ }
169
+
170
+ /**
171
+ * A shortcut type of link-reference / image-reference could not followed
172
+ * by a link label (even though it is not defined).
173
+ * @see https://github.github.com/gfm/#example-579
174
+ */
175
+ return { tokens: internalTokens }
176
+ }
177
+
178
+ const { nextIndex, labelAndIdentifier } = eatLinkLabel(
179
+ nodePoints,
180
+ openerDelimiter.endIndex - 1,
181
+ closerDelimiter.startIndex + 1,
182
+ )
183
+ if (
184
+ nextIndex === closerDelimiter.startIndex + 1 &&
185
+ labelAndIdentifier != null &&
186
+ api.hasDefinition(labelAndIdentifier.identifier)
187
+ ) {
188
+ const token: IToken = {
189
+ nodeType: ImageReferenceType,
190
+ startIndex: openerDelimiter.startIndex,
191
+ endIndex: closerDelimiter.endIndex,
192
+ referenceType: bracket == null ? 'shortcut' : 'collapsed',
193
+ label: labelAndIdentifier.label,
194
+ identifier: labelAndIdentifier.identifier,
195
+ children: api.resolveInternalTokens(
196
+ internalTokens,
197
+ openerDelimiter.endIndex,
198
+ closerDelimiter.startIndex,
199
+ ),
200
+ }
201
+ return { tokens: [token] }
202
+ }
203
+
204
+ return { tokens: internalTokens }
205
+ }
206
+ }
package/src/parse.ts ADDED
@@ -0,0 +1,36 @@
1
+ import type { Node } from '@yozora/ast'
2
+ import { ImageReferenceType } from '@yozora/ast'
3
+ import type { IParseInlineHookCreator } from '@yozora/core-tokenizer'
4
+ import { calcImageAlt } from '@yozora/tokenizer-image'
5
+ import type { INode, IThis, IToken, T } from './types'
6
+
7
+ export const parse: IParseInlineHookCreator<T, IToken, INode, IThis> = function (api) {
8
+ return {
9
+ parse: tokens =>
10
+ tokens.map(token => {
11
+ const { identifier, label, referenceType } = token
12
+
13
+ // calc alt
14
+ const children: Node[] = api.parseInlineTokens(token.children)
15
+ const alt = calcImageAlt(children)
16
+
17
+ const node: INode = api.shouldReservePosition
18
+ ? {
19
+ type: ImageReferenceType,
20
+ position: api.calcPosition(token),
21
+ identifier,
22
+ label,
23
+ referenceType,
24
+ alt,
25
+ }
26
+ : {
27
+ type: ImageReferenceType,
28
+ identifier,
29
+ label,
30
+ referenceType,
31
+ alt,
32
+ }
33
+ return node
34
+ }),
35
+ }
36
+ }
@@ -0,0 +1,32 @@
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 ImageReference.
14
+ * @see https://github.com/syntax-tree/mdast#imagereference
15
+ * @see https://github.github.com/gfm/#images
16
+ */
17
+ export class ImageReferenceTokenizer
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 ADDED
@@ -0,0 +1,23 @@
1
+ import type { Association, ImageReference, ImageReferenceType, Reference } from '@yozora/ast'
2
+ import type {
3
+ IBaseInlineTokenizerProps,
4
+ IPartialYastInlineToken,
5
+ ITokenizer,
6
+ IYastTokenDelimiter,
7
+ } from '@yozora/core-tokenizer'
8
+ import type { ILinkReferenceDelimiterBracket } from '@yozora/tokenizer-link-reference'
9
+
10
+ export const uniqueName = '@yozora/tokenizer-image-reference'
11
+
12
+ export type T = ImageReferenceType
13
+ export type INode = ImageReference
14
+
15
+ export interface IToken extends IPartialYastInlineToken<T>, Association, Reference {}
16
+
17
+ export interface IDelimiter extends IYastTokenDelimiter {
18
+ brackets: ILinkReferenceDelimiterBracket[]
19
+ }
20
+
21
+ export type IThis = ITokenizer
22
+
23
+ export type ITokenizerProps = Partial<IBaseInlineTokenizerProps>