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 +63 -1
- package/assets/marigolds.webp +0 -0
- package/package.json +2 -2
- package/src/generator/generate.ts +15 -0
- package/src/generator/types.ts +2 -0
- package/src/tokenizer/constants.ts +65 -29
- package/src/tokenizer/tokenize.ts +5 -3
- package/src/tokenizer/types.ts +49 -2
package/README.md
CHANGED
|
@@ -1 +1,63 @@
|
|
|
1
|
-
# <p align='center'> **
|
|
1
|
+
# <p align='center'> **ts-highlight** </p>
|
|
2
|
+
|
|
3
|
+
<div align='center'>
|
|
4
|
+
|
|
5
|
+
[](https://github.com/a-marigold/ts-highlight/actions) [](https://npmjs.com/package/ts-highlight)
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div align='center'>
|
|
10
|
+
|
|
11
|
+

|
|
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.
|
|
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/
|
|
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 +=
|
package/src/generator/types.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
DoubleOperators,
|
|
5
5
|
TripleOperators,
|
|
6
6
|
QuadrupleOperator,
|
|
7
|
-
|
|
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
|
-
//
|
|
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
|
-
*
|
|
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
|
|
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
|
-
|
|
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:
|
|
90
|
+
type:
|
|
91
|
+
identifierLikeMap[identifier as IdentifierLike] ??
|
|
92
|
+
'Identifier',
|
|
91
93
|
value: identifier,
|
|
92
94
|
start: startPos,
|
|
93
95
|
end: pos,
|
package/src/tokenizer/types.ts
CHANGED
|
@@ -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.
|