ts-highlight 0.1.0 → 0.2.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/README.md CHANGED
@@ -1 +1,63 @@
1
- # <p align='center'> **es-highlight** </p>
1
+ # <p align='center'> **ts-highlight** </p>
2
+
3
+ <div align='center'>
4
+
5
+ [![CI](https://github.com/a-marigold/crumb/actions/workflows/ci.yaml/badge.svg)](https://github.com/a-marigold/ts-highlight/actions) [![npm](https://img.shields.io/npm/v/ts-highlight)](https://npmjs.com/package/ts-highlight)
6
+
7
+ </div>
8
+
9
+ <div align='center'>
10
+
11
+ ![marigolds](assets/marigolds.webp)
12
+
13
+ </div>
14
+
15
+ ### Usage
16
+
17
+ ```typescript
18
+ import { higlight, type HighlightCSSClasses } from 'ts-higlight';
19
+
20
+ // styles of generated code are extensible
21
+ const cssClasses: HiglightCSSClasses = {
22
+ pre: 'pre-class second-pre-class', // classes can be divided as if they are in HTML `class` attribute
23
+ code: 'code-class',
24
+ line: 'Example-module-css-module__m3Y3uq__line', // classes can be CSS module strings
25
+
26
+ token: 'token-class', // `token` class is the class of every token of generated code
27
+
28
+ // Every token has its own class for fine grained configuration
29
+ operator: 'operator-class',
30
+
31
+ identifier: 'identifier',
32
+ keyword: 'keyword',
33
+
34
+ bigintChar: 'bigint-class', // class of bigint character (`10n` - `n` is `bigintChar`)
35
+ stringLiteral: 'string',
36
+
37
+ whitespace: 'whitespace', // even whitespace has its own class
38
+
39
+
40
+ ...
41
+ };
42
+
43
+ highlight(`let a = 'hello';`, cssClasses);
44
+ ```
45
+
46
+ Real output will be:
47
+
48
+ ```html
49
+ <pre class="pre-class second-pre-class">
50
+ <code class="code-class">
51
+ <div class="Example-module-css-module__m3Y3uq__line">
52
+ <span class="token-class keyword">let</span>
53
+ <span class="token-class whitespace"> </span>
54
+ <span class="token-class identifier">a</span>
55
+ <span class="token-class whitespace"> </span>
56
+ <span class="token-class operator-class">=</span>
57
+ <span class="token-class whitespace"> </span>
58
+ <span class="token-class string">'hello'</span>
59
+ <span class="token-class operator">;</span>
60
+ </div>
61
+ </code>
62
+ </pre>
63
+ ```
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-highlight",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "module": "./dist/index.js",
5
5
  "type": "module",
6
6
  "private": false,
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "repository": {
13
13
  "type": "github",
14
- "url": "https://github.com/a-marigold/es-higрlight"
14
+ "url": "https://github.com/a-marigold/ts-highlight"
15
15
  },
16
16
  "scripts": {
17
17
  "lint": "biome check",
@@ -108,6 +108,21 @@ export const generate = (
108
108
  continue;
109
109
  }
110
110
 
111
+ if (currentToken.type === 'Instruction') {
112
+ generated +=
113
+ OPENED_SPAN_WITH_CLASS +
114
+ cssClasses.token +
115
+ ' ' +
116
+ cssClasses.instruction +
117
+ '>' +
118
+ currentToken.value +
119
+ CLOSED_SPAN;
120
+
121
+ tokenPos++;
122
+
123
+ continue;
124
+ }
125
+
111
126
  // literals
112
127
  if (currentToken.type === 'StringLiteral') {
113
128
  generated +=
@@ -56,7 +56,9 @@ export type HighlightCSSClasses = Partial<{
56
56
  whitespace: string;
57
57
  comment: string;
58
58
 
59
+ // identifier like token types ('Keyword', 'Instruction')
59
60
  keyword: string;
61
+ instruction: string;
60
62
 
61
63
  operator: string;
62
64
 
@@ -4,7 +4,7 @@ import type {
4
4
  DoubleOperators,
5
5
  TripleOperators,
6
6
  QuadrupleOperator,
7
- Keywords,
7
+ IdentifierLikeMap,
8
8
  } from './types';
9
9
 
10
10
  // operators
@@ -99,36 +99,72 @@ export const tripleOperators: TokenSet = new Set(tripleOperatorsInit);
99
99
  */
100
100
  export const quadrupleOperator: QuadrupleOperator = '>>>=';
101
101
 
102
- // keywords
103
-
104
- const keywordsInit: Keywords = [
105
- 'var',
106
- 'let',
107
- 'const',
108
- 'typeof',
109
- 'class',
110
-
111
- 'in',
112
-
113
- 'new',
114
-
115
- 'instanceof',
116
- 'function',
117
-
118
- 'void',
119
- 'delete',
120
- 'keyof',
121
- 'abstract',
122
- 'interface',
123
- 'enum',
124
- 'type',
125
- 'implements',
126
- ];
127
-
102
+ // identifier like token types
128
103
  /**
129
- * `Set` with javascript and typescript keywords
104
+ * Object with Identifier like literals and their TokenType.
105
+ *
106
+ * Used to determine correct TokenType.
107
+ *
108
+ *
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const unknownIdentifier = 'function';
113
+ *
114
+ * const tokenTypeOfUnknownIdentifier = identifierLikeMap[unknownIdentifier as IdentifierLike];
115
+ *
116
+ * // Output:
117
+ *
118
+ * 'Keyword';
119
+ *
120
+ * ```
130
121
  */
131
- export const keywords: TokenSet = new Set(keywordsInit);
122
+ export const identifierLikeMap: IdentifierLikeMap = {
123
+ NaN: 'NaNLiteral',
124
+ abstract: 'Keyword',
125
+ as: 'Instruction',
126
+ assert: 'Instruction',
127
+ asserts: 'Instruction',
128
+ async: 'Instruction',
129
+ await: 'Instruction',
130
+ break: 'Instruction',
131
+ catch: 'Instruction',
132
+ class: 'Keyword',
133
+ const: 'Keyword',
134
+ continue: 'Instruction',
135
+ debugger: 'Keyword',
136
+ declare: 'Keyword',
137
+ default: 'Instruction',
138
+ delete: 'Keyword',
139
+ do: 'Instruction',
140
+ enum: 'Keyword',
141
+ export: 'Instruction',
142
+ false: 'BooleanLiteral',
143
+ finally: 'Instruction',
144
+ for: 'Instruction',
145
+ function: 'Keyword',
146
+ implements: 'Keyword',
147
+ import: 'Instruction',
148
+ in: 'Keyword',
149
+ instanceof: 'Keyword',
150
+ interface: 'Keyword',
151
+ is: 'Instruction',
152
+ keyof: 'Keyword',
153
+ let: 'Keyword',
154
+ new: 'Keyword',
155
+ package: 'Instruction',
156
+ this: 'Keyword',
157
+ throw: 'Instruction',
158
+ true: 'BooleanLiteral',
159
+ try: 'Instruction',
160
+ type: 'Keyword',
161
+ typeof: 'Keyword',
162
+ var: 'Keyword',
163
+ void: 'Keyword',
164
+ while: 'Instruction',
165
+ with: 'Instruction',
166
+ yield: 'Instruction',
167
+ };
132
168
 
133
169
  // regular expresions (RegExp)
134
170
 
@@ -6,10 +6,10 @@ import {
6
6
  doubleOperators,
7
7
  tripleOperators,
8
8
  quadrupleOperator,
9
- keywords,
9
+ identifierLikeMap,
10
10
  } from './constants';
11
11
 
12
- import type { Token } from './types';
12
+ import type { Token, IdentifierLike } from './types';
13
13
 
14
14
  /**
15
15
  *
@@ -87,7 +87,9 @@ export const tokenize = (source: string): Token[] => {
87
87
  const identifier = source.slice(startPos, pos);
88
88
 
89
89
  tokens[tokens.length] = {
90
- type: keywords.has(identifier) ? 'Keyword' : 'Identifier',
90
+ type:
91
+ identifierLikeMap[identifier as IdentifierLike] ??
92
+ 'Identifier',
91
93
  value: identifier,
92
94
  start: startPos,
93
95
  end: pos,
@@ -14,6 +14,7 @@ export type TokenType =
14
14
  | 'WhiteSpace'
15
15
  | 'Comment'
16
16
  | 'LineDivision'
17
+ | 'Instruction'
17
18
  | LiteralTokenType;
18
19
 
19
20
  /**
@@ -119,7 +120,11 @@ export type JSKeywords = [
119
120
 
120
121
  'function',
121
122
  'void',
122
- 'delete'
123
+ 'delete',
124
+
125
+ 'this',
126
+
127
+ 'debugger'
123
128
  ];
124
129
  export type JSKeyword = JSKeywords[number];
125
130
  export type TSKeywords = [
@@ -128,13 +133,55 @@ export type TSKeywords = [
128
133
  'interface',
129
134
  'enum',
130
135
  'type',
131
- 'implements'
136
+ 'implements',
137
+ 'declare'
132
138
  ];
133
139
  export type TSKeyword = TSKeywords[number];
134
140
 
135
141
  export type Keywords = [...JSKeywords, ...TSKeywords];
136
142
  export type Keyword = Keywords[number];
137
143
 
144
+ type JSInstruction =
145
+ | 'for'
146
+ | 'do'
147
+ | 'while'
148
+ | 'continue'
149
+ | 'break'
150
+ | 'import'
151
+ | 'export'
152
+ | 'package'
153
+ | 'try'
154
+ | 'catch'
155
+ | 'finally'
156
+ | 'async'
157
+ | 'await'
158
+ | 'yield'
159
+ | 'with'
160
+ | 'assert'
161
+ | 'default'
162
+ | 'throw';
163
+
164
+ type TSInstruction = 'as' | 'asserts' | 'is';
165
+ export type Instruction = JSInstruction | TSInstruction;
166
+
167
+ type Literal = 'true' | 'false' | 'NaN';
168
+
169
+ /**
170
+ * Token Types that are like `Identifier` TokenType
171
+ */
172
+ export type IdentifierLike = Keyword | Instruction | Literal;
173
+
174
+ /**
175
+ * Record with Token Types that are like `Identifier` TokenType.
176
+ * Used to determine correct TokenType
177
+ */
178
+ export type IdentifierLikeMap = {
179
+ [K in IdentifierLike]: Extract<
180
+ TokenType,
181
+ 'Keyword' | 'Instruction' | 'BooleanLiteral' | 'NaNLiteral'
182
+ >;
183
+ };
184
+
138
185
  /**
139
186
  *
140
187
  * Type that contains `TokenType` values to be checked in tokenizer.