@yozora/tokenizer-indented-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.
@@ -103,18 +103,17 @@ const uniqueName = '@yozora/tokenizer-indented-code';
103
103
 
104
104
  class IndentedCodeTokenizer extends coreTokenizer.BaseBlockTokenizer {
105
105
  constructor(props = {}) {
106
- var _a, _b;
107
106
  super({
108
- name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
109
- priority: (_b = props.priority) !== null && _b !== void 0 ? _b : coreTokenizer.TokenizerPriority.ATOMIC,
107
+ name: props.name ?? uniqueName,
108
+ priority: props.priority ?? coreTokenizer.TokenizerPriority.ATOMIC,
110
109
  });
111
- this.match = match;
112
- this.parse = parse;
113
110
  }
111
+ match = match;
112
+ parse = parse;
114
113
  }
115
114
 
116
115
  exports.IndentedCodeTokenizer = IndentedCodeTokenizer;
117
116
  exports.IndentedCodeTokenizerName = uniqueName;
118
- exports["default"] = IndentedCodeTokenizer;
117
+ exports.default = IndentedCodeTokenizer;
119
118
  exports.indentedCodeMatch = match;
120
119
  exports.indentedCodeParse = parse;
@@ -99,14 +99,13 @@ const uniqueName = '@yozora/tokenizer-indented-code';
99
99
 
100
100
  class IndentedCodeTokenizer extends BaseBlockTokenizer {
101
101
  constructor(props = {}) {
102
- var _a, _b;
103
102
  super({
104
- name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
105
- priority: (_b = props.priority) !== null && _b !== void 0 ? _b : TokenizerPriority.ATOMIC,
103
+ name: props.name ?? uniqueName,
104
+ priority: props.priority ?? TokenizerPriority.ATOMIC,
106
105
  });
107
- this.match = match;
108
- this.parse = parse;
109
106
  }
107
+ match = match;
108
+ parse = parse;
110
109
  }
111
110
 
112
111
  export { IndentedCodeTokenizer, uniqueName as IndentedCodeTokenizerName, IndentedCodeTokenizer as default, match as indentedCodeMatch, parse as indentedCodeParse };
@@ -1,8 +1,8 @@
1
1
  import { IPartialYastBlockToken, IPhrasingContentLine, ITokenizer, IBaseBlockTokenizerProps, IMatchBlockHookCreator, IParseBlockHookCreator, BaseBlockTokenizer, IBlockTokenizer } from '@yozora/core-tokenizer';
2
2
  import { CodeType, Code } from '@yozora/ast';
3
3
 
4
- declare type T = CodeType;
5
- declare type INode = Code;
4
+ type T = CodeType;
5
+ type INode = Code;
6
6
  declare const uniqueName = "@yozora/tokenizer-indented-code";
7
7
  interface IToken extends IPartialYastBlockToken<T> {
8
8
  /**
@@ -10,8 +10,8 @@ interface IToken extends IPartialYastBlockToken<T> {
10
10
  */
11
11
  lines: IPhrasingContentLine[];
12
12
  }
13
- declare type IThis = ITokenizer;
14
- declare type ITokenizerProps = Partial<IBaseBlockTokenizerProps>;
13
+ type IThis = ITokenizer;
14
+ type ITokenizerProps = Partial<IBaseBlockTokenizerProps>;
15
15
 
16
16
  /**
17
17
  * An indented code block is composed of one or more indented chunks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yozora/tokenizer-indented-code",
3
- "version": "2.0.3",
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/indented-code"
12
12
  },
13
13
  "homepage": "https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/indented-code",
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.3",
39
- "@yozora/character": "^2.0.3",
40
- "@yozora/core-tokenizer": "^2.0.3"
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": "8cc8f95cfebc8d752bc3272cdd24965f540c130b"
46
+ "gitHead": "8bf941fe4ef82947165b0f3cc123cd493665e13b"
43
47
  }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
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 ADDED
@@ -0,0 +1,94 @@
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 ADDED
@@ -0,0 +1,54 @@
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
+ }
@@ -0,0 +1,31 @@
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 ADDED
@@ -0,0 +1,22 @@
1
+ import type { Code, CodeType } from '@yozora/ast'
2
+ import type {
3
+ IBaseBlockTokenizerProps,
4
+ IPartialYastBlockToken,
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 IPartialYastBlockToken<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>