@yozora/tokenizer-blockquote 2.0.4 → 2.0.5-alpha.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/lib/cjs/{index.js → index.cjs} +5 -6
- package/lib/esm/{index.js → index.mjs} +4 -5
- package/lib/types/index.d.ts +4 -4
- package/package.json +18 -14
- package/src/index.ts +9 -0
- package/src/match.ts +133 -0
- package/src/parse.ts +17 -0
- package/src/tokenizer.ts +32 -0
- package/src/types.ts +22 -0
|
@@ -81,18 +81,17 @@ const uniqueName = '@yozora/tokenizer-blockquote';
|
|
|
81
81
|
|
|
82
82
|
class BlockquoteTokenizer extends coreTokenizer.BaseBlockTokenizer {
|
|
83
83
|
constructor(props = {}) {
|
|
84
|
-
var _a, _b;
|
|
85
84
|
super({
|
|
86
|
-
name:
|
|
87
|
-
priority:
|
|
85
|
+
name: props.name ?? uniqueName,
|
|
86
|
+
priority: props.priority ?? coreTokenizer.TokenizerPriority.CONTAINING_BLOCK,
|
|
88
87
|
});
|
|
89
|
-
this.match = match;
|
|
90
|
-
this.parse = parse;
|
|
91
88
|
}
|
|
89
|
+
match = match;
|
|
90
|
+
parse = parse;
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
exports.BlockquoteTokenizer = BlockquoteTokenizer;
|
|
95
94
|
exports.BlockquoteTokenizerName = uniqueName;
|
|
96
95
|
exports.blockquoteMatch = match;
|
|
97
96
|
exports.blockquoteParse = parse;
|
|
98
|
-
exports
|
|
97
|
+
exports.default = BlockquoteTokenizer;
|
|
@@ -77,14 +77,13 @@ const uniqueName = '@yozora/tokenizer-blockquote';
|
|
|
77
77
|
|
|
78
78
|
class BlockquoteTokenizer extends BaseBlockTokenizer {
|
|
79
79
|
constructor(props = {}) {
|
|
80
|
-
var _a, _b;
|
|
81
80
|
super({
|
|
82
|
-
name:
|
|
83
|
-
priority:
|
|
81
|
+
name: props.name ?? uniqueName,
|
|
82
|
+
priority: props.priority ?? TokenizerPriority.CONTAINING_BLOCK,
|
|
84
83
|
});
|
|
85
|
-
this.match = match;
|
|
86
|
-
this.parse = parse;
|
|
87
84
|
}
|
|
85
|
+
match = match;
|
|
86
|
+
parse = parse;
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
export { BlockquoteTokenizer, uniqueName as BlockquoteTokenizerName, match as blockquoteMatch, parse as blockquoteParse, BlockquoteTokenizer as default };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IPartialYastBlockToken, IYastBlockToken, ITokenizer, IBaseBlockTokenizerProps, IMatchBlockHookCreator, IParseBlockHookCreator, BaseBlockTokenizer, IBlockTokenizer } from '@yozora/core-tokenizer';
|
|
2
2
|
import { BlockquoteType, Blockquote } from '@yozora/ast';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
type T = BlockquoteType;
|
|
5
|
+
type INode = Blockquote;
|
|
6
6
|
declare const uniqueName = "@yozora/tokenizer-blockquote";
|
|
7
7
|
interface IToken extends IPartialYastBlockToken<T> {
|
|
8
8
|
/**
|
|
@@ -10,8 +10,8 @@ interface IToken extends IPartialYastBlockToken<T> {
|
|
|
10
10
|
*/
|
|
11
11
|
children: IYastBlockToken[];
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
type IThis = ITokenizer;
|
|
14
|
+
type ITokenizerProps = Partial<IBaseBlockTokenizerProps>;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* A block quote marker consists of 0-3 spaces of initial indent, plus
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yozora/tokenizer-blockquote",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5-alpha.0",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "guanghechen",
|
|
6
6
|
"url": "https://github.com/guanghechen/"
|
|
@@ -11,33 +11,37 @@
|
|
|
11
11
|
"directory": "tokenizers/blockquote"
|
|
12
12
|
},
|
|
13
13
|
"homepage": "https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/blockquote",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
"
|
|
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.
|
|
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.
|
|
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.
|
|
39
|
-
"@yozora/character": "^2.0.
|
|
40
|
-
"@yozora/core-tokenizer": "^2.0.
|
|
42
|
+
"@yozora/ast": "^2.0.5-alpha.0",
|
|
43
|
+
"@yozora/character": "^2.0.5-alpha.0",
|
|
44
|
+
"@yozora/core-tokenizer": "^2.0.5-alpha.0"
|
|
41
45
|
},
|
|
42
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "8bf941fe4ef82947165b0f3cc123cd493665e13b"
|
|
43
47
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { match as blockquoteMatch } from './match'
|
|
2
|
+
export { parse as blockquoteParse } from './parse'
|
|
3
|
+
export { BlockquoteTokenizer, BlockquoteTokenizer as default } from './tokenizer'
|
|
4
|
+
export { uniqueName as BlockquoteTokenizerName } from './types'
|
|
5
|
+
export type {
|
|
6
|
+
IThis as IBlockquoteHookContext,
|
|
7
|
+
IToken as IBlockquoteToken,
|
|
8
|
+
ITokenizerProps as IBlockquoteTokenizerProps,
|
|
9
|
+
} from './types'
|
package/src/match.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { BlockquoteType } from '@yozora/ast'
|
|
2
|
+
import { AsciiCodePoint, VirtualCodePoint, isSpaceCharacter } from '@yozora/character'
|
|
3
|
+
import type {
|
|
4
|
+
IMatchBlockHookCreator,
|
|
5
|
+
IPhrasingContentLine,
|
|
6
|
+
IResultOfEatAndInterruptPreviousSibling,
|
|
7
|
+
IResultOfEatContinuationText,
|
|
8
|
+
IResultOfEatOpener,
|
|
9
|
+
IYastBlockToken,
|
|
10
|
+
} from '@yozora/core-tokenizer'
|
|
11
|
+
import { calcEndPoint, calcStartPoint } from '@yozora/core-tokenizer'
|
|
12
|
+
import type { IThis, IToken, T } from './types'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A block quote marker consists of 0-3 spaces of initial indent, plus
|
|
16
|
+
* (a) the character > together with a following space, or
|
|
17
|
+
* (b) a single character > not followed by a space.
|
|
18
|
+
*
|
|
19
|
+
* The following rules define block quotes:
|
|
20
|
+
* - Basic case. If a string of lines Ls constitute a sequence of blocks Bs,
|
|
21
|
+
* then the result of prepending a block quote marker to the beginning of
|
|
22
|
+
* each line in Ls is a block quote containing Bs.
|
|
23
|
+
*
|
|
24
|
+
* - Laziness. If a string of lines Ls constitute a block quote with contents
|
|
25
|
+
* Bs, then the result of deleting the initial block quote marker from one
|
|
26
|
+
* or more lines in which the next non-whitespace character after the block
|
|
27
|
+
* quote marker is paragraph continuation text is a block quote with Bs as
|
|
28
|
+
* its content. Paragraph continuation text is text that will be parsed as
|
|
29
|
+
* part of the content of a paragraph, but does not occur at the beginning
|
|
30
|
+
* of the paragraph.
|
|
31
|
+
*
|
|
32
|
+
* - Consecutiveness. A document cannot contain two block quotes in a row
|
|
33
|
+
* unless there is a blank line between them.
|
|
34
|
+
*
|
|
35
|
+
* @see https://github.com/syntax-tree/mdast#blockquote
|
|
36
|
+
* @see https://github.github.com/gfm/#block-quotes
|
|
37
|
+
*/
|
|
38
|
+
export const match: IMatchBlockHookCreator<T, IToken, IThis> = function () {
|
|
39
|
+
return {
|
|
40
|
+
isContainingBlock: true,
|
|
41
|
+
eatOpener,
|
|
42
|
+
eatAndInterruptPreviousSibling,
|
|
43
|
+
eatContinuationText,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function eatOpener(line: Readonly<IPhrasingContentLine>): IResultOfEatOpener<T, IToken> {
|
|
47
|
+
/**
|
|
48
|
+
* The '>' characters can be indented 1-3 spaces
|
|
49
|
+
* @see https://github.github.com/gfm/#example-209
|
|
50
|
+
*/
|
|
51
|
+
if (line.countOfPrecedeSpaces >= 4) return null
|
|
52
|
+
|
|
53
|
+
const { nodePoints, startIndex, endIndex, firstNonWhitespaceIndex } = line
|
|
54
|
+
if (
|
|
55
|
+
firstNonWhitespaceIndex >= endIndex ||
|
|
56
|
+
nodePoints[firstNonWhitespaceIndex].codePoint !== AsciiCodePoint.CLOSE_ANGLE
|
|
57
|
+
)
|
|
58
|
+
return null
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A block quote marker consists of 0-3 spaces of initial indent, plus
|
|
62
|
+
* (a) the character > together with a following space, or
|
|
63
|
+
* (b) a single character > not followed by a space.
|
|
64
|
+
* @see https://github.github.com/gfm/#block-quote-marker
|
|
65
|
+
*/
|
|
66
|
+
let nextIndex = firstNonWhitespaceIndex + 1
|
|
67
|
+
if (nextIndex < endIndex && isSpaceCharacter(nodePoints[nextIndex].codePoint)) {
|
|
68
|
+
nextIndex += 1
|
|
69
|
+
/**
|
|
70
|
+
* When the '>' followed by a tab, it is treated as if it were expanded
|
|
71
|
+
* into three spaces.
|
|
72
|
+
* @see https://github.github.com/gfm/#example-6
|
|
73
|
+
*/
|
|
74
|
+
if (nextIndex < endIndex && nodePoints[nextIndex].codePoint === VirtualCodePoint.SPACE) {
|
|
75
|
+
nextIndex += 1
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const token: IToken = {
|
|
80
|
+
nodeType: BlockquoteType,
|
|
81
|
+
position: {
|
|
82
|
+
start: calcStartPoint(nodePoints, startIndex),
|
|
83
|
+
end: calcEndPoint(nodePoints, nextIndex - 1),
|
|
84
|
+
},
|
|
85
|
+
children: [],
|
|
86
|
+
}
|
|
87
|
+
return { token, nextIndex }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function eatAndInterruptPreviousSibling(
|
|
91
|
+
line: Readonly<IPhrasingContentLine>,
|
|
92
|
+
prevSiblingToken: Readonly<IYastBlockToken>,
|
|
93
|
+
): IResultOfEatAndInterruptPreviousSibling<T, IToken> {
|
|
94
|
+
const result = eatOpener(line)
|
|
95
|
+
if (result == null) return null
|
|
96
|
+
return {
|
|
97
|
+
token: result.token,
|
|
98
|
+
nextIndex: result.nextIndex,
|
|
99
|
+
remainingSibling: prevSiblingToken,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function eatContinuationText(
|
|
104
|
+
line: Readonly<IPhrasingContentLine>,
|
|
105
|
+
token: IToken,
|
|
106
|
+
parentToken: Readonly<IYastBlockToken>,
|
|
107
|
+
): IResultOfEatContinuationText {
|
|
108
|
+
const { nodePoints, startIndex, endIndex, firstNonWhitespaceIndex, countOfPrecedeSpaces } = line
|
|
109
|
+
|
|
110
|
+
if (
|
|
111
|
+
countOfPrecedeSpaces >= 4 ||
|
|
112
|
+
firstNonWhitespaceIndex >= endIndex ||
|
|
113
|
+
nodePoints[firstNonWhitespaceIndex].codePoint !== AsciiCodePoint.CLOSE_ANGLE
|
|
114
|
+
) {
|
|
115
|
+
/**
|
|
116
|
+
* It is a consequence of the Laziness rule that any number of initial
|
|
117
|
+
* `>`s may be omitted on a continuation line of a nested block quote
|
|
118
|
+
* @see https://github.github.com/gfm/#example-229
|
|
119
|
+
*/
|
|
120
|
+
if (parentToken.nodeType === BlockquoteType) {
|
|
121
|
+
return { status: 'opening', nextIndex: startIndex }
|
|
122
|
+
}
|
|
123
|
+
return { status: 'notMatched' }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const nextIndex =
|
|
127
|
+
firstNonWhitespaceIndex + 1 < endIndex &&
|
|
128
|
+
isSpaceCharacter(nodePoints[firstNonWhitespaceIndex + 1].codePoint)
|
|
129
|
+
? firstNonWhitespaceIndex + 2
|
|
130
|
+
: firstNonWhitespaceIndex + 1
|
|
131
|
+
return { status: 'opening', nextIndex }
|
|
132
|
+
}
|
|
133
|
+
}
|
package/src/parse.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Node } from '@yozora/ast'
|
|
2
|
+
import { BlockquoteType } from '@yozora/ast'
|
|
3
|
+
import type { IParseBlockHookCreator } from '@yozora/core-tokenizer'
|
|
4
|
+
import type { INode, IThis, IToken, T } from './types'
|
|
5
|
+
|
|
6
|
+
export const parse: IParseBlockHookCreator<T, IToken, INode, IThis> = function (api) {
|
|
7
|
+
return {
|
|
8
|
+
parse: tokens =>
|
|
9
|
+
tokens.map(token => {
|
|
10
|
+
const children: Node[] = api.parseBlockTokens(token.children)
|
|
11
|
+
const node: INode = api.shouldReservePosition
|
|
12
|
+
? { type: BlockquoteType, position: token.position, children }
|
|
13
|
+
: { type: BlockquoteType, children }
|
|
14
|
+
return node
|
|
15
|
+
}),
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/tokenizer.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IBlockTokenizer,
|
|
3
|
+
IMatchBlockHookCreator,
|
|
4
|
+
IParseBlockHookCreator,
|
|
5
|
+
} from '@yozora/core-tokenizer'
|
|
6
|
+
import { BaseBlockTokenizer, TokenizerPriority } from '@yozora/core-tokenizer'
|
|
7
|
+
import { match } from './match'
|
|
8
|
+
import { parse } from './parse'
|
|
9
|
+
import type { INode, IThis, IToken, ITokenizerProps, T } from './types'
|
|
10
|
+
import { uniqueName } from './types'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Lexical Analyzer for Blockquote.
|
|
14
|
+
* @see https://github.com/syntax-tree/mdast#blockquote
|
|
15
|
+
* @see https://github.github.com/gfm/#block-quotes
|
|
16
|
+
*/
|
|
17
|
+
export class BlockquoteTokenizer
|
|
18
|
+
extends BaseBlockTokenizer<T, IToken, INode, IThis>
|
|
19
|
+
implements IBlockTokenizer<T, IToken, INode, IThis>
|
|
20
|
+
{
|
|
21
|
+
/* istanbul ignore next */
|
|
22
|
+
constructor(props: ITokenizerProps = {}) {
|
|
23
|
+
super({
|
|
24
|
+
name: props.name ?? uniqueName,
|
|
25
|
+
priority: props.priority ?? TokenizerPriority.CONTAINING_BLOCK,
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public override readonly match: IMatchBlockHookCreator<T, IToken, IThis> = match
|
|
30
|
+
|
|
31
|
+
public override readonly parse: IParseBlockHookCreator<T, IToken, INode, IThis> = parse
|
|
32
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Blockquote, BlockquoteType } from '@yozora/ast'
|
|
2
|
+
import type {
|
|
3
|
+
IBaseBlockTokenizerProps,
|
|
4
|
+
IPartialYastBlockToken,
|
|
5
|
+
ITokenizer,
|
|
6
|
+
IYastBlockToken,
|
|
7
|
+
} from '@yozora/core-tokenizer'
|
|
8
|
+
|
|
9
|
+
export type T = BlockquoteType
|
|
10
|
+
export type INode = Blockquote
|
|
11
|
+
export const uniqueName = '@yozora/tokenizer-blockquote'
|
|
12
|
+
|
|
13
|
+
export interface IToken extends IPartialYastBlockToken<T> {
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
children: IYastBlockToken[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type IThis = ITokenizer
|
|
21
|
+
|
|
22
|
+
export type ITokenizerProps = Partial<IBaseBlockTokenizerProps>
|