@yozora/tokenizer-indented-code 2.1.3 → 2.1.4
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/package.json +6 -6
- package/src/index.ts +0 -9
- package/src/match.ts +0 -94
- package/src/parse.ts +0 -54
- package/src/tokenizer.ts +0 -31
- package/src/types.ts +0 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yozora/tokenizer-indented-code",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
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
|
-
"
|
|
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.
|
|
43
|
-
"@yozora/character": "^2.1.
|
|
44
|
-
"@yozora/core-tokenizer": "^2.1.
|
|
42
|
+
"@yozora/ast": "^2.1.4",
|
|
43
|
+
"@yozora/character": "^2.1.4",
|
|
44
|
+
"@yozora/core-tokenizer": "^2.1.4"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "aa464ed1e3cd84892773a833910cfc53a556bf5f"
|
|
47
47
|
}
|
package/src/index.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { match as indentedCodeMatch } from './match'
|
|
2
|
-
export { parse as indentedCodeParse } from './parse'
|
|
3
|
-
export { IndentedCodeTokenizer, IndentedCodeTokenizer as default } from './tokenizer'
|
|
4
|
-
export { uniqueName as IndentedCodeTokenizerName } from './types'
|
|
5
|
-
export type {
|
|
6
|
-
IThis as IIndentedCodeHookContext,
|
|
7
|
-
IToken as IIndentedCodeToken,
|
|
8
|
-
ITokenizerProps as IIndentedCodeTokenizerProps,
|
|
9
|
-
} from './types'
|
package/src/match.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { CodeType } from '@yozora/ast'
|
|
2
|
-
import { AsciiCodePoint, VirtualCodePoint } from '@yozora/character'
|
|
3
|
-
import type {
|
|
4
|
-
IMatchBlockHookCreator,
|
|
5
|
-
IPhrasingContentLine,
|
|
6
|
-
IResultOfEatContinuationText,
|
|
7
|
-
IResultOfEatOpener,
|
|
8
|
-
} from '@yozora/core-tokenizer'
|
|
9
|
-
import { calcEndPoint, calcStartPoint } from '@yozora/core-tokenizer'
|
|
10
|
-
import type { IThis, IToken, T } from './types'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* An indented code block is composed of one or more indented chunks
|
|
14
|
-
* separated by blank lines. An indented chunk is a sequence of non-blank
|
|
15
|
-
* lines, each indented four or more spaces. The contents of the code block
|
|
16
|
-
* are the literal contents of the lines, including trailing line endings,
|
|
17
|
-
* minus four spaces of indentation.
|
|
18
|
-
*
|
|
19
|
-
* @see https://github.github.com/gfm/#indented-code-block
|
|
20
|
-
*/
|
|
21
|
-
export const match: IMatchBlockHookCreator<T, IToken, IThis> = function () {
|
|
22
|
-
return {
|
|
23
|
-
isContainingBlock: false,
|
|
24
|
-
eatOpener,
|
|
25
|
-
eatContinuationText,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function eatOpener(line: Readonly<IPhrasingContentLine>): IResultOfEatOpener<T, IToken> {
|
|
29
|
-
if (line.countOfPrecedeSpaces < 4) return null
|
|
30
|
-
const { nodePoints, startIndex, firstNonWhitespaceIndex, endIndex } = line
|
|
31
|
-
|
|
32
|
-
let firstIndex = startIndex + 4
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* If there exists 1-3 spaces before a tab forms the indent, the remain
|
|
36
|
-
* virtual spaces of the tab should not be a part of the contents.
|
|
37
|
-
* @see https://github.github.com/gfm/#example-2
|
|
38
|
-
*/
|
|
39
|
-
if (
|
|
40
|
-
nodePoints[startIndex].codePoint === AsciiCodePoint.SPACE &&
|
|
41
|
-
nodePoints[startIndex + 3].codePoint === VirtualCodePoint.SPACE
|
|
42
|
-
) {
|
|
43
|
-
let i = startIndex + 1
|
|
44
|
-
for (; i < firstNonWhitespaceIndex; ++i) {
|
|
45
|
-
if (nodePoints[i].codePoint === VirtualCodePoint.SPACE) break
|
|
46
|
-
}
|
|
47
|
-
firstIndex = i + 4
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const nextIndex = endIndex
|
|
51
|
-
const token: IToken = {
|
|
52
|
-
nodeType: CodeType,
|
|
53
|
-
position: {
|
|
54
|
-
start: calcStartPoint(nodePoints, startIndex),
|
|
55
|
-
end: calcEndPoint(nodePoints, nextIndex - 1),
|
|
56
|
-
},
|
|
57
|
-
lines: [
|
|
58
|
-
{
|
|
59
|
-
nodePoints,
|
|
60
|
-
startIndex: firstIndex,
|
|
61
|
-
endIndex,
|
|
62
|
-
firstNonWhitespaceIndex,
|
|
63
|
-
countOfPrecedeSpaces: line.countOfPrecedeSpaces - (firstIndex - startIndex),
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
}
|
|
67
|
-
return { token, nextIndex }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function eatContinuationText(
|
|
71
|
-
line: Readonly<IPhrasingContentLine>,
|
|
72
|
-
token: IToken,
|
|
73
|
-
): IResultOfEatContinuationText {
|
|
74
|
-
const { nodePoints, startIndex, endIndex, firstNonWhitespaceIndex, countOfPrecedeSpaces } = line
|
|
75
|
-
|
|
76
|
-
if (countOfPrecedeSpaces < 4 && firstNonWhitespaceIndex < endIndex)
|
|
77
|
-
return { status: 'notMatched' }
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Blank line is allowed
|
|
81
|
-
* @see https://github.github.com/gfm/#example-81
|
|
82
|
-
* @see https://github.github.com/gfm/#example-82
|
|
83
|
-
*/
|
|
84
|
-
const firstIndex = Math.min(endIndex - 1, startIndex + 4)
|
|
85
|
-
token.lines.push({
|
|
86
|
-
nodePoints,
|
|
87
|
-
startIndex: firstIndex,
|
|
88
|
-
endIndex,
|
|
89
|
-
firstNonWhitespaceIndex,
|
|
90
|
-
countOfPrecedeSpaces: countOfPrecedeSpaces - (firstIndex - startIndex),
|
|
91
|
-
})
|
|
92
|
-
return { status: 'opening', nextIndex: endIndex }
|
|
93
|
-
}
|
|
94
|
-
}
|
package/src/parse.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { CodeType } from '@yozora/ast'
|
|
2
|
-
import type { INodePoint } from '@yozora/character'
|
|
3
|
-
import { calcStringFromNodePoints } from '@yozora/character'
|
|
4
|
-
import type { IParseBlockHookCreator } from '@yozora/core-tokenizer'
|
|
5
|
-
import { mergeContentLinesFaithfully } from '@yozora/core-tokenizer'
|
|
6
|
-
import type { INode, IThis, IToken, T } from './types'
|
|
7
|
-
|
|
8
|
-
export const parse: IParseBlockHookCreator<T, IToken, INode, IThis> = function (api) {
|
|
9
|
-
return {
|
|
10
|
-
parse: tokens =>
|
|
11
|
-
tokens.map(token => {
|
|
12
|
-
/**
|
|
13
|
-
* Blank lines preceding or following an indented code block
|
|
14
|
-
* are not included in it
|
|
15
|
-
* @see https://github.github.com/gfm/#example-87
|
|
16
|
-
*/
|
|
17
|
-
const { lines } = token
|
|
18
|
-
let startLineIndex = 0,
|
|
19
|
-
endLineIndex = lines.length
|
|
20
|
-
for (; startLineIndex < endLineIndex; ++startLineIndex) {
|
|
21
|
-
const line = lines[startLineIndex]
|
|
22
|
-
if (line.firstNonWhitespaceIndex < line.endIndex) break
|
|
23
|
-
}
|
|
24
|
-
for (; startLineIndex < endLineIndex; --endLineIndex) {
|
|
25
|
-
const line = lines[endLineIndex - 1]
|
|
26
|
-
if (line.firstNonWhitespaceIndex < line.endIndex) break
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const contents: INodePoint[] = mergeContentLinesFaithfully(
|
|
30
|
-
lines,
|
|
31
|
-
startLineIndex,
|
|
32
|
-
endLineIndex,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
let value: string = calcStringFromNodePoints(contents)
|
|
36
|
-
if (!/\n$/.test(value)) value += '\n'
|
|
37
|
-
const node: INode = api.shouldReservePosition
|
|
38
|
-
? {
|
|
39
|
-
type: CodeType,
|
|
40
|
-
position: token.position,
|
|
41
|
-
lang: null,
|
|
42
|
-
meta: null,
|
|
43
|
-
value,
|
|
44
|
-
}
|
|
45
|
-
: {
|
|
46
|
-
type: CodeType,
|
|
47
|
-
lang: null,
|
|
48
|
-
meta: null,
|
|
49
|
-
value,
|
|
50
|
-
}
|
|
51
|
-
return node
|
|
52
|
-
}),
|
|
53
|
-
}
|
|
54
|
-
}
|
package/src/tokenizer.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
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 IndentedCode.
|
|
14
|
-
* @see https://github.github.com/gfm/#indented-code-block
|
|
15
|
-
*/
|
|
16
|
-
export class IndentedCodeTokenizer
|
|
17
|
-
extends BaseBlockTokenizer<T, IToken, INode, IThis>
|
|
18
|
-
implements IBlockTokenizer<T, IToken, INode, IThis>
|
|
19
|
-
{
|
|
20
|
-
/* istanbul ignore next */
|
|
21
|
-
constructor(props: ITokenizerProps = {}) {
|
|
22
|
-
super({
|
|
23
|
-
name: props.name ?? uniqueName,
|
|
24
|
-
priority: props.priority ?? TokenizerPriority.ATOMIC,
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public override readonly match: IMatchBlockHookCreator<T, IToken, IThis> = match
|
|
29
|
-
|
|
30
|
-
public override readonly parse: IParseBlockHookCreator<T, IToken, INode, IThis> = parse
|
|
31
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { Code, CodeType } from '@yozora/ast'
|
|
2
|
-
import type {
|
|
3
|
-
IBaseBlockTokenizerProps,
|
|
4
|
-
IPartialBlockToken,
|
|
5
|
-
IPhrasingContentLine,
|
|
6
|
-
ITokenizer,
|
|
7
|
-
} from '@yozora/core-tokenizer'
|
|
8
|
-
|
|
9
|
-
export type T = CodeType
|
|
10
|
-
export type INode = Code
|
|
11
|
-
export const uniqueName = '@yozora/tokenizer-indented-code'
|
|
12
|
-
|
|
13
|
-
export interface IToken extends IPartialBlockToken<T> {
|
|
14
|
-
/**
|
|
15
|
-
* Lines to construct the contents of a paragraph.
|
|
16
|
-
*/
|
|
17
|
-
lines: IPhrasingContentLine[]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type IThis = ITokenizer
|
|
21
|
-
|
|
22
|
-
export type ITokenizerProps = Partial<IBaseBlockTokenizerProps>
|