@yozora/tokenizer-thematic-break 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.
@@ -89,18 +89,17 @@ const uniqueName = '@yozora/tokenizer-thematic-break';
89
89
 
90
90
  class ThematicBreakTokenizer extends coreTokenizer.BaseBlockTokenizer {
91
91
  constructor(props = {}) {
92
- var _a, _b;
93
92
  super({
94
- name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
95
- priority: (_b = props.priority) !== null && _b !== void 0 ? _b : coreTokenizer.TokenizerPriority.ATOMIC,
93
+ name: props.name ?? uniqueName,
94
+ priority: props.priority ?? coreTokenizer.TokenizerPriority.ATOMIC,
96
95
  });
97
- this.match = match;
98
- this.parse = parse;
99
96
  }
97
+ match = match;
98
+ parse = parse;
100
99
  }
101
100
 
102
101
  exports.ThematicBreakTokenizer = ThematicBreakTokenizer;
103
102
  exports.ThematicBreakTokenizerName = uniqueName;
104
- exports["default"] = ThematicBreakTokenizer;
103
+ exports.default = ThematicBreakTokenizer;
105
104
  exports.thematicBreakMatch = match;
106
105
  exports.thematicBreakParse = parse;
@@ -85,14 +85,13 @@ const uniqueName = '@yozora/tokenizer-thematic-break';
85
85
 
86
86
  class ThematicBreakTokenizer extends BaseBlockTokenizer {
87
87
  constructor(props = {}) {
88
- var _a, _b;
89
88
  super({
90
- name: (_a = props.name) !== null && _a !== void 0 ? _a : uniqueName,
91
- priority: (_b = props.priority) !== null && _b !== void 0 ? _b : TokenizerPriority.ATOMIC,
89
+ name: props.name ?? uniqueName,
90
+ priority: props.priority ?? TokenizerPriority.ATOMIC,
92
91
  });
93
- this.match = match;
94
- this.parse = parse;
95
92
  }
93
+ match = match;
94
+ parse = parse;
96
95
  }
97
96
 
98
97
  export { ThematicBreakTokenizer, uniqueName as ThematicBreakTokenizerName, ThematicBreakTokenizer as default, match as thematicBreakMatch, parse as thematicBreakParse };
@@ -1,8 +1,8 @@
1
1
  import { IPartialYastBlockToken, ITokenizer, IBaseBlockTokenizerProps, IMatchBlockHookCreator, IParseBlockHookCreator, BaseBlockTokenizer, IBlockTokenizer } from '@yozora/core-tokenizer';
2
2
  import { ThematicBreakType, ThematicBreak } from '@yozora/ast';
3
3
 
4
- declare type T = ThematicBreakType;
5
- declare type INode = ThematicBreak;
4
+ type T = ThematicBreakType;
5
+ type INode = ThematicBreak;
6
6
  declare const uniqueName = "@yozora/tokenizer-thematic-break";
7
7
  interface IToken extends IPartialYastBlockToken<T> {
8
8
  /**
@@ -14,8 +14,8 @@ interface IToken extends IPartialYastBlockToken<T> {
14
14
  */
15
15
  continuous: boolean;
16
16
  }
17
- declare type IThis = ITokenizer;
18
- declare type ITokenizerProps = Partial<IBaseBlockTokenizerProps>;
17
+ type IThis = ITokenizer;
18
+ type ITokenizerProps = Partial<IBaseBlockTokenizerProps>;
19
19
 
20
20
  /**
21
21
  * A line consisting of 0-3 spaces of indentation, followed by a sequence of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yozora/tokenizer-thematic-break",
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,33 +11,37 @@
11
11
  "directory": "tokenizers/thematic-break"
12
12
  },
13
13
  "homepage": "https://github.com/yozorajs/yozora/tree/release-2.x.x/tokenizers/thematic-break",
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"
42
+ "@yozora/ast": "^2.0.5",
43
+ "@yozora/character": "^2.0.5",
44
+ "@yozora/core-tokenizer": "^2.0.5"
41
45
  },
42
- "gitHead": "c980b95254394dcacba0cbb4bea251350b09397c"
46
+ "gitHead": "7ba3bab49fe65cf2f57082c0503af73da9356cf0"
43
47
  }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { match as thematicBreakMatch } from './match'
2
+ export { parse as thematicBreakParse } from './parse'
3
+ export { ThematicBreakTokenizer, ThematicBreakTokenizer as default } from './tokenizer'
4
+ export { uniqueName as ThematicBreakTokenizerName } from './types'
5
+ export type {
6
+ IThis as IThematicBreakHookContext,
7
+ IToken as IThematicBreakToken,
8
+ ITokenizerProps as IThematicBreakTokenizerProps,
9
+ } from './types'
package/src/match.ts ADDED
@@ -0,0 +1,127 @@
1
+ import { ThematicBreakType } from '@yozora/ast'
2
+ import { AsciiCodePoint, isUnicodeWhitespaceCharacter } from '@yozora/character'
3
+ import type {
4
+ IMatchBlockHookCreator,
5
+ IPhrasingContentLine,
6
+ IResultOfEatAndInterruptPreviousSibling,
7
+ IResultOfEatOpener,
8
+ IYastBlockToken,
9
+ } from '@yozora/core-tokenizer'
10
+ import { calcEndPoint, calcStartPoint } from '@yozora/core-tokenizer'
11
+ import type { IThis, IToken, T } from './types'
12
+
13
+ /**
14
+ * A line consisting of 0-3 spaces of indentation, followed by a sequence of
15
+ * three or more matching -, _, or * characters, each followed optionally by
16
+ * any number of spaces or tabs, forms a thematic break.
17
+ *
18
+ * @see https://github.github.com/gfm/#thematic-break
19
+ */
20
+ export const match: IMatchBlockHookCreator<T, IToken, IThis> = function () {
21
+ return {
22
+ isContainingBlock: false,
23
+ eatOpener,
24
+ eatAndInterruptPreviousSibling,
25
+ }
26
+
27
+ function eatOpener(line: Readonly<IPhrasingContentLine>): IResultOfEatOpener<T, IToken> {
28
+ /**
29
+ * Four spaces is too much
30
+ * @see https://github.github.com/gfm/#example-19
31
+ */
32
+ if (line.countOfPrecedeSpaces >= 4) return null
33
+
34
+ const { nodePoints, startIndex, endIndex, firstNonWhitespaceIndex } = line
35
+ if (firstNonWhitespaceIndex + 2 >= endIndex) return null
36
+
37
+ let marker: number
38
+ let count = 0
39
+ let continuous = true
40
+ let hasPotentialInternalSpace = false
41
+ for (let i = firstNonWhitespaceIndex; i < endIndex; ++i) {
42
+ const c = nodePoints[i]
43
+
44
+ /**
45
+ * Spaces are allowed between the characters
46
+ * Spaces are allowed at the end
47
+ * @see https://github.github.com/gfm/#example-21
48
+ * @see https://github.github.com/gfm/#example-22
49
+ * @see https://github.github.com/gfm/#example-23
50
+ * @see https://github.github.com/gfm/#example-24
51
+ */
52
+ if (isUnicodeWhitespaceCharacter(c.codePoint)) {
53
+ hasPotentialInternalSpace = true
54
+ continue
55
+ }
56
+
57
+ /**
58
+ * As it is traversed from a non-empty character, if a blank character
59
+ * has been encountered before, it means that there is an internal space
60
+ */
61
+ if (hasPotentialInternalSpace) {
62
+ continuous = false
63
+ }
64
+
65
+ switch (c.codePoint) {
66
+ /**
67
+ * A line consisting of 0-3 spaces of indentation, followed by a
68
+ * sequence of three or more matching '-', '_', or '*' characters,
69
+ * each followed optionally by any number of spaces or tabs, forms
70
+ * a thematic break
71
+ */
72
+ case AsciiCodePoint.MINUS_SIGN:
73
+ case AsciiCodePoint.UNDERSCORE:
74
+ case AsciiCodePoint.ASTERISK: {
75
+ if (count <= 0) {
76
+ marker = c.codePoint
77
+ count += 1
78
+ break
79
+ }
80
+ /**
81
+ * It is required that all of the non-whitespace characters be the same
82
+ * @see https://github.github.com/gfm/#example-26
83
+ */
84
+ if (c.codePoint !== marker!) return null
85
+ count += 1
86
+ break
87
+ }
88
+ /**
89
+ * No other characters may occur in the line
90
+ * @see https://github.github.com/gfm/#example-25
91
+ */
92
+ default:
93
+ return null
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Not enough characters
99
+ * @see https://github.github.com/gfm/#example-16
100
+ */
101
+ if (count < 3) return null
102
+
103
+ const token: IToken = {
104
+ nodeType: ThematicBreakType,
105
+ position: {
106
+ start: calcStartPoint(nodePoints, startIndex),
107
+ end: calcEndPoint(nodePoints, endIndex - 1),
108
+ },
109
+ marker: marker!,
110
+ continuous,
111
+ }
112
+ return { token, nextIndex: endIndex, saturated: true }
113
+ }
114
+
115
+ function eatAndInterruptPreviousSibling(
116
+ line: Readonly<IPhrasingContentLine>,
117
+ prevSiblingToken: Readonly<IYastBlockToken>,
118
+ ): IResultOfEatAndInterruptPreviousSibling<T, IToken> {
119
+ const result = eatOpener(line)
120
+ if (result == null) return null
121
+ return {
122
+ token: result.token,
123
+ nextIndex: result.nextIndex,
124
+ remainingSibling: prevSiblingToken,
125
+ }
126
+ }
127
+ }
package/src/parse.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { ThematicBreakType } from '@yozora/ast'
2
+ import type { IParseBlockHookCreator } from '@yozora/core-tokenizer'
3
+ import type { INode, IThis, IToken, T } from './types'
4
+
5
+ export const parse: IParseBlockHookCreator<T, IToken, INode, IThis> = function (api) {
6
+ return {
7
+ parse: tokens =>
8
+ tokens.map(token => {
9
+ const node: INode = api.shouldReservePosition
10
+ ? { type: ThematicBreakType, position: token.position }
11
+ : { type: ThematicBreakType }
12
+ return node
13
+ }),
14
+ }
15
+ }
@@ -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 ThematicBreak.
14
+ * @see https://github.github.com/gfm/#thematic-break
15
+ */
16
+ export class ThematicBreakTokenizer
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,25 @@
1
+ import type { ThematicBreak, ThematicBreakType } from '@yozora/ast'
2
+ import type {
3
+ IBaseBlockTokenizerProps,
4
+ IPartialYastBlockToken,
5
+ ITokenizer,
6
+ } from '@yozora/core-tokenizer'
7
+
8
+ export type T = ThematicBreakType
9
+ export type INode = ThematicBreak
10
+ export const uniqueName = '@yozora/tokenizer-thematic-break'
11
+
12
+ export interface IToken extends IPartialYastBlockToken<T> {
13
+ /**
14
+ * CodePoint of '-' / '_' / '*'
15
+ */
16
+ marker: number
17
+ /**
18
+ * Whether there are no internal spaces between marker characters
19
+ */
20
+ continuous: boolean
21
+ }
22
+
23
+ export type IThis = ITokenizer
24
+
25
+ export type ITokenizerProps = Partial<IBaseBlockTokenizerProps>