@yozora/tokenizer-fenced-code 2.0.3 → 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} +10 -12
- package/lib/esm/{index.js → index.mjs} +8 -6
- package/lib/types/index.d.ts +5 -5
- package/package.json +19 -15
- package/src/index.ts +9 -0
- package/src/match.ts +19 -0
- package/src/parse.ts +58 -0
- package/src/tokenizer.ts +52 -0
- package/src/types.ts +13 -0
|
@@ -7,13 +7,12 @@ var ast = require('@yozora/ast');
|
|
|
7
7
|
var character = require('@yozora/character');
|
|
8
8
|
var coreTokenizer = require('@yozora/core-tokenizer');
|
|
9
9
|
|
|
10
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
|
-
|
|
12
|
-
var FencedBlockTokenizer__default = /*#__PURE__*/_interopDefaultLegacy(FencedBlockTokenizer);
|
|
13
|
-
|
|
14
10
|
const match = function (api) {
|
|
15
11
|
const hook = FencedBlockTokenizer.fencedBlockMatch.call(this, api);
|
|
16
|
-
return
|
|
12
|
+
return {
|
|
13
|
+
...hook,
|
|
14
|
+
isContainingBlock: false,
|
|
15
|
+
};
|
|
17
16
|
};
|
|
18
17
|
|
|
19
18
|
const parse = function (api) {
|
|
@@ -56,12 +55,11 @@ const parse = function (api) {
|
|
|
56
55
|
|
|
57
56
|
const uniqueName = '@yozora/tokenizer-fenced-code';
|
|
58
57
|
|
|
59
|
-
class FencedCodeTokenizer extends
|
|
58
|
+
class FencedCodeTokenizer extends FencedBlockTokenizer {
|
|
60
59
|
constructor(props = {}) {
|
|
61
|
-
var _a, _b;
|
|
62
60
|
super({
|
|
63
|
-
name:
|
|
64
|
-
priority:
|
|
61
|
+
name: props.name ?? uniqueName,
|
|
62
|
+
priority: props.priority ?? coreTokenizer.TokenizerPriority.FENCED_BLOCK,
|
|
65
63
|
nodeType: ast.CodeType,
|
|
66
64
|
markers: [character.AsciiCodePoint.BACKTICK, character.AsciiCodePoint.TILDE],
|
|
67
65
|
markersRequired: 3,
|
|
@@ -75,13 +73,13 @@ class FencedCodeTokenizer extends FencedBlockTokenizer__default["default"] {
|
|
|
75
73
|
return true;
|
|
76
74
|
},
|
|
77
75
|
});
|
|
78
|
-
this.match = match;
|
|
79
|
-
this.parse = parse;
|
|
80
76
|
}
|
|
77
|
+
match = match;
|
|
78
|
+
parse = parse;
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
exports.FencedCodeTokenizer = FencedCodeTokenizer;
|
|
84
82
|
exports.FencedCodeTokenizerName = uniqueName;
|
|
85
|
-
exports
|
|
83
|
+
exports.default = FencedCodeTokenizer;
|
|
86
84
|
exports.fencedCodeMatch = match;
|
|
87
85
|
exports.fencedCodeParse = parse;
|
|
@@ -5,7 +5,10 @@ import { eatOptionalWhitespaces, mergeContentLinesFaithfully, TokenizerPriority
|
|
|
5
5
|
|
|
6
6
|
const match = function (api) {
|
|
7
7
|
const hook = fencedBlockMatch.call(this, api);
|
|
8
|
-
return
|
|
8
|
+
return {
|
|
9
|
+
...hook,
|
|
10
|
+
isContainingBlock: false,
|
|
11
|
+
};
|
|
9
12
|
};
|
|
10
13
|
|
|
11
14
|
const parse = function (api) {
|
|
@@ -50,10 +53,9 @@ const uniqueName = '@yozora/tokenizer-fenced-code';
|
|
|
50
53
|
|
|
51
54
|
class FencedCodeTokenizer extends FencedBlockTokenizer {
|
|
52
55
|
constructor(props = {}) {
|
|
53
|
-
var _a, _b;
|
|
54
56
|
super({
|
|
55
|
-
name:
|
|
56
|
-
priority:
|
|
57
|
+
name: props.name ?? uniqueName,
|
|
58
|
+
priority: props.priority ?? TokenizerPriority.FENCED_BLOCK,
|
|
57
59
|
nodeType: CodeType,
|
|
58
60
|
markers: [AsciiCodePoint.BACKTICK, AsciiCodePoint.TILDE],
|
|
59
61
|
markersRequired: 3,
|
|
@@ -67,9 +69,9 @@ class FencedCodeTokenizer extends FencedBlockTokenizer {
|
|
|
67
69
|
return true;
|
|
68
70
|
},
|
|
69
71
|
});
|
|
70
|
-
this.match = match;
|
|
71
|
-
this.parse = parse;
|
|
72
72
|
}
|
|
73
|
+
match = match;
|
|
74
|
+
parse = parse;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export { FencedCodeTokenizer, uniqueName as FencedCodeTokenizerName, FencedCodeTokenizer as default, match as fencedCodeMatch, parse as fencedCodeParse };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { IBaseBlockTokenizerProps, IMatchBlockHookCreator, IParseBlockHookCreato
|
|
|
2
2
|
import { CodeType, Code } from '@yozora/ast';
|
|
3
3
|
import FencedBlockTokenizer, { IFencedBlockToken, IFencedBlockHookContext } from '@yozora/tokenizer-fenced-block';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
type T = CodeType;
|
|
6
|
+
type INode = Code;
|
|
7
7
|
declare const uniqueName = "@yozora/tokenizer-fenced-code";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
type IToken = IFencedBlockToken<T>;
|
|
9
|
+
type IThis = IFencedBlockHookContext<T>;
|
|
10
|
+
type ITokenizerProps = Partial<IBaseBlockTokenizerProps>;
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* A code fence is a sequence of at least three consecutive backtick characters
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yozora/tokenizer-fenced-code",
|
|
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,34 +11,38 @@
|
|
|
11
11
|
"directory": "tokenizers/fenced-code"
|
|
12
12
|
},
|
|
13
13
|
"homepage": "https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/fenced-code",
|
|
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.
|
|
41
|
-
"@yozora/tokenizer-fenced-block": "^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",
|
|
45
|
+
"@yozora/tokenizer-fenced-block": "^2.0.5-alpha.0"
|
|
42
46
|
},
|
|
43
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "8bf941fe4ef82947165b0f3cc123cd493665e13b"
|
|
44
48
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { match as fencedCodeMatch } from './match'
|
|
2
|
+
export { parse as fencedCodeParse } from './parse'
|
|
3
|
+
export { FencedCodeTokenizer, FencedCodeTokenizer as default } from './tokenizer'
|
|
4
|
+
export { uniqueName as FencedCodeTokenizerName } from './types'
|
|
5
|
+
export type {
|
|
6
|
+
IThis as IFencedCodeHookContext,
|
|
7
|
+
IToken as IFencedCodeToken,
|
|
8
|
+
ITokenizerProps as IFencedCodeTokenizerProps,
|
|
9
|
+
} from './types'
|
package/src/match.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IMatchBlockHook, IMatchBlockHookCreator } from '@yozora/core-tokenizer'
|
|
2
|
+
import { fencedBlockMatch } from '@yozora/tokenizer-fenced-block'
|
|
3
|
+
import type { IThis, IToken, T } from './types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A code fence is a sequence of at least three consecutive backtick characters
|
|
7
|
+
* (`) or tildes (~). (Tildes and backticks cannot be mixed.) A fenced code
|
|
8
|
+
* block begins with a code fence, indented no more than three spaces.
|
|
9
|
+
*
|
|
10
|
+
* @see https://github.com/syntax-tree/mdast#code
|
|
11
|
+
* @see https://github.github.com/gfm/#code-fence
|
|
12
|
+
*/
|
|
13
|
+
export const match: IMatchBlockHookCreator<T, IToken, IThis> = function (api) {
|
|
14
|
+
const hook = fencedBlockMatch.call(this, api) as IMatchBlockHook<T, IToken>
|
|
15
|
+
return {
|
|
16
|
+
...hook,
|
|
17
|
+
isContainingBlock: false,
|
|
18
|
+
}
|
|
19
|
+
}
|
package/src/parse.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { CodeType } from '@yozora/ast'
|
|
2
|
+
import type { INodePoint } from '@yozora/character'
|
|
3
|
+
import {
|
|
4
|
+
calcEscapedStringFromNodePoints,
|
|
5
|
+
calcStringFromNodePoints,
|
|
6
|
+
isUnicodeWhitespaceCharacter,
|
|
7
|
+
} from '@yozora/character'
|
|
8
|
+
import type { IParseBlockHookCreator } from '@yozora/core-tokenizer'
|
|
9
|
+
import { eatOptionalWhitespaces, mergeContentLinesFaithfully } from '@yozora/core-tokenizer'
|
|
10
|
+
import type { INode, IThis, IToken, T } from './types'
|
|
11
|
+
|
|
12
|
+
export const parse: IParseBlockHookCreator<T, IToken, INode, IThis> = function (api) {
|
|
13
|
+
return {
|
|
14
|
+
parse: tokens =>
|
|
15
|
+
tokens.map(token => {
|
|
16
|
+
const infoString = token.infoString
|
|
17
|
+
|
|
18
|
+
// match lang
|
|
19
|
+
let i = 0
|
|
20
|
+
const langInfo: INodePoint[] = []
|
|
21
|
+
for (; i < infoString.length; ++i) {
|
|
22
|
+
const p = infoString[i]
|
|
23
|
+
if (isUnicodeWhitespaceCharacter(p.codePoint)) break
|
|
24
|
+
langInfo.push(p)
|
|
25
|
+
}
|
|
26
|
+
const lang: string = calcEscapedStringFromNodePoints(langInfo, 0, langInfo.length, true)
|
|
27
|
+
|
|
28
|
+
// match meta
|
|
29
|
+
i = eatOptionalWhitespaces(infoString, i, infoString.length)
|
|
30
|
+
const meta: string = calcEscapedStringFromNodePoints(infoString, i, infoString.length, true)
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* match content
|
|
34
|
+
* Backslash escape works in info strings in fenced code blocks.
|
|
35
|
+
* @see https://github.github.com/gfm/#example-320
|
|
36
|
+
*/
|
|
37
|
+
const contents: INodePoint[] = mergeContentLinesFaithfully(token.lines)
|
|
38
|
+
let value: string = calcStringFromNodePoints(contents)
|
|
39
|
+
if (!/\n$/.test(value)) value += '\n'
|
|
40
|
+
|
|
41
|
+
const node: INode = api.shouldReservePosition
|
|
42
|
+
? {
|
|
43
|
+
type: CodeType,
|
|
44
|
+
position: token.position,
|
|
45
|
+
lang: lang.length > 0 ? lang : null,
|
|
46
|
+
meta: meta.length > 0 ? meta : null,
|
|
47
|
+
value,
|
|
48
|
+
}
|
|
49
|
+
: {
|
|
50
|
+
type: CodeType,
|
|
51
|
+
lang: lang.length > 0 ? lang : null,
|
|
52
|
+
meta: meta.length > 0 ? meta : null,
|
|
53
|
+
value,
|
|
54
|
+
}
|
|
55
|
+
return node
|
|
56
|
+
}),
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/tokenizer.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { CodeType } from '@yozora/ast'
|
|
2
|
+
import { AsciiCodePoint } from '@yozora/character'
|
|
3
|
+
import type {
|
|
4
|
+
IBlockTokenizer,
|
|
5
|
+
IMatchBlockHookCreator,
|
|
6
|
+
IParseBlockHookCreator,
|
|
7
|
+
} from '@yozora/core-tokenizer'
|
|
8
|
+
import { TokenizerPriority } from '@yozora/core-tokenizer'
|
|
9
|
+
import FencedBlockTokenizer from '@yozora/tokenizer-fenced-block'
|
|
10
|
+
import { match } from './match'
|
|
11
|
+
import { parse } from './parse'
|
|
12
|
+
import type { INode, IThis, IToken, ITokenizerProps, T } from './types'
|
|
13
|
+
import { uniqueName } from './types'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Lexical Analyzer for FencedCode.
|
|
17
|
+
* @see https://github.com/syntax-tree/mdast#code
|
|
18
|
+
* @see https://github.github.com/gfm/#code-fence
|
|
19
|
+
*/
|
|
20
|
+
export class FencedCodeTokenizer
|
|
21
|
+
extends FencedBlockTokenizer<T, INode, IThis>
|
|
22
|
+
implements IBlockTokenizer<T, IToken, INode, IThis>
|
|
23
|
+
{
|
|
24
|
+
/* istanbul ignore next */
|
|
25
|
+
constructor(props: ITokenizerProps = {}) {
|
|
26
|
+
super({
|
|
27
|
+
name: props.name ?? uniqueName,
|
|
28
|
+
priority: props.priority ?? TokenizerPriority.FENCED_BLOCK,
|
|
29
|
+
nodeType: CodeType,
|
|
30
|
+
markers: [AsciiCodePoint.BACKTICK, AsciiCodePoint.TILDE],
|
|
31
|
+
markersRequired: 3,
|
|
32
|
+
checkInfoString: (infoString, marker): boolean => {
|
|
33
|
+
/**
|
|
34
|
+
* Info strings for backtick code blocks cannot contain backticks:
|
|
35
|
+
* Info strings for tilde code blocks can contain backticks and tildes
|
|
36
|
+
* @see https://github.github.com/gfm/#example-115
|
|
37
|
+
* @see https://github.github.com/gfm/#example-116
|
|
38
|
+
*/
|
|
39
|
+
if (marker === AsciiCodePoint.BACKTICK) {
|
|
40
|
+
for (const p of infoString) {
|
|
41
|
+
if (p.codePoint === AsciiCodePoint.BACKTICK) return false
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return true
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public override readonly match: IMatchBlockHookCreator<T, IToken, IThis> = match
|
|
50
|
+
|
|
51
|
+
public override readonly parse: IParseBlockHookCreator<T, IToken, INode, IThis> = parse
|
|
52
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Code, CodeType } from '@yozora/ast'
|
|
2
|
+
import type { IBaseBlockTokenizerProps } from '@yozora/core-tokenizer'
|
|
3
|
+
import type { IFencedBlockHookContext, IFencedBlockToken } from '@yozora/tokenizer-fenced-block'
|
|
4
|
+
|
|
5
|
+
export type T = CodeType
|
|
6
|
+
export type INode = Code
|
|
7
|
+
export const uniqueName = '@yozora/tokenizer-fenced-code'
|
|
8
|
+
|
|
9
|
+
export type IToken = IFencedBlockToken<T>
|
|
10
|
+
|
|
11
|
+
export type IThis = IFencedBlockHookContext<T>
|
|
12
|
+
|
|
13
|
+
export type ITokenizerProps = Partial<IBaseBlockTokenizerProps>
|