@santi020k/lumen-core 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.
@@ -1 +1 @@
1
- {"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../src/code.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEhG,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,wBAAwB;;;;;;;CAOkB,CAAA;AA0EvD,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,WAc9C,CAAA;AAoBD,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,iBAAa,KAAG,cAAc,EA0B7E,CAAA;AAgBD,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,iBAAa,WACW,CAAA"}
1
+ {"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../src/code.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEhG,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,wBAAwB;;;;;;;CAOkB,CAAA;AA+NvD,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,WAc9C,CAAA;AAuKD,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,iBAAa,KAAG,cAAc,EA0B7E,CAAA;AAgBD,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,iBAAa,WACW,CAAA"}
package/dist/code.js CHANGED
@@ -6,7 +6,20 @@ export const lumenCodeTokenClassNames = {
6
6
  symbol: 'ui-code__token--symbol',
7
7
  type: 'ui-code__token--type'
8
8
  };
9
- const jsLikeLanguages = new Set([
9
+ const bashLikeLanguages = new Set([
10
+ 'bash',
11
+ 'console',
12
+ 'shell',
13
+ 'sh',
14
+ 'terminal',
15
+ 'zsh'
16
+ ]);
17
+ const jsonLikeLanguages = new Set([
18
+ 'json',
19
+ 'json5',
20
+ 'jsonc'
21
+ ]);
22
+ const javascriptLikeLanguages = new Set([
10
23
  'js',
11
24
  'jsx',
12
25
  'javascript',
@@ -15,7 +28,30 @@ const jsLikeLanguages = new Set([
15
28
  'tsx',
16
29
  'typescript'
17
30
  ]);
18
- const jsKeywords = new Set([
31
+ const luaLikeLanguages = new Set([
32
+ 'lua'
33
+ ]);
34
+ const markdownLikeLanguages = new Set([
35
+ 'md',
36
+ 'markdown',
37
+ 'mdx'
38
+ ]);
39
+ const markupLikeLanguages = new Set([
40
+ 'astro',
41
+ 'html',
42
+ 'markup',
43
+ 'svg',
44
+ 'vue',
45
+ 'xml'
46
+ ]);
47
+ const sqlLikeLanguages = new Set([
48
+ 'sql'
49
+ ]);
50
+ const yamlLikeLanguages = new Set([
51
+ 'yaml',
52
+ 'yml'
53
+ ]);
54
+ const javascriptKeywords = new Set([
19
55
  'as',
20
56
  'async',
21
57
  'await',
@@ -51,7 +87,7 @@ const jsKeywords = new Set([
51
87
  'var',
52
88
  'while'
53
89
  ]);
54
- const jsTypes = new Set([
90
+ const javascriptTypes = new Set([
55
91
  'Array',
56
92
  'Boolean',
57
93
  'Date',
@@ -67,12 +103,108 @@ const jsTypes = new Set([
67
103
  'unknown',
68
104
  'void'
69
105
  ]);
70
- const jsTokenPattern = /\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\b\d[\d._]*\b|\b[A-Za-z_$][\w$]*\b|[=+\-*%<>!?:.,;()[\]{}|&/]+/g;
106
+ const bashKeywords = new Set([
107
+ 'case',
108
+ 'do',
109
+ 'done',
110
+ 'elif',
111
+ 'else',
112
+ 'esac', // cspell:ignore esac
113
+ 'export',
114
+ 'fi',
115
+ 'for',
116
+ 'function',
117
+ 'if',
118
+ 'in',
119
+ 'local',
120
+ 'readonly',
121
+ 'set',
122
+ 'then',
123
+ 'unset',
124
+ 'while'
125
+ ]);
126
+ const jsonKeywords = new Set([
127
+ 'false',
128
+ 'null',
129
+ 'true'
130
+ ]);
131
+ const luaKeywords = new Set([
132
+ 'and',
133
+ 'break',
134
+ 'do',
135
+ 'else',
136
+ 'elseif',
137
+ 'end',
138
+ 'false',
139
+ 'for',
140
+ 'function',
141
+ 'goto',
142
+ 'if',
143
+ 'in',
144
+ 'local',
145
+ 'nil',
146
+ 'not',
147
+ 'or',
148
+ 'repeat',
149
+ 'return',
150
+ 'then',
151
+ 'true',
152
+ 'until',
153
+ 'while'
154
+ ]);
155
+ const sqlKeywords = new Set([
156
+ 'alter',
157
+ 'and',
158
+ 'as',
159
+ 'asc',
160
+ 'by',
161
+ 'create',
162
+ 'delete',
163
+ 'desc',
164
+ 'distinct',
165
+ 'drop',
166
+ 'from',
167
+ 'group',
168
+ 'having',
169
+ 'insert',
170
+ 'into',
171
+ 'join',
172
+ 'limit',
173
+ 'not',
174
+ 'null',
175
+ 'on',
176
+ 'or',
177
+ 'order',
178
+ 'select',
179
+ 'set',
180
+ 'table',
181
+ 'union',
182
+ 'update',
183
+ 'values',
184
+ 'where'
185
+ ]);
186
+ const yamlKeywords = new Set([
187
+ 'false',
188
+ 'no',
189
+ 'null',
190
+ 'off',
191
+ 'on',
192
+ 'true',
193
+ 'yes'
194
+ ]);
195
+ const bashTokenPattern = /#[^\n]*|"(?:\\.|[^"\\])*"|'[^']*'|\$\{?[A-Za-z_][\w]*\}?|--?[A-Za-z][\w-]*|\b[A-Za-z_][\w]*\b|\b\d+(?:\.\d+)?\b|[|&;<>()[\]{}=]+/g;
196
+ const javascriptTokenPattern = /\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\b\d[\d._]*\b|\b[A-Za-z_$][\w$]*\b|[=+\-*%<>!?:.,;()[\]{}|&/]+/g;
197
+ const jsonTokenPattern = /\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|\b(?:false|null|true)\b|-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b|[{},:]|\[|\]/gi;
198
+ const luaTokenPattern = /--\[\[[\s\S]*?\]\]|--[^\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\b[A-Za-z_][\w]*\b|\b\d+(?:\.\d+)?\b|[=+\-*%<>~#.,:;()[\]{}]+/g;
199
+ const markdownTokenPattern = /```[\s\S]*?```|`[^`\n]+`|<!--[\s\S]*?-->|^#{1,6}(?=\s)|^>\s?|^\s*(?:[-+*]|\d+\.)\s+|\*\*|__|\*|_|\[[^\]]+\]\([^)]+\)/gm;
200
+ const markupTokenPattern = /<!--[\s\S]*?-->|---|<\/?|\/?>|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\b[A-Za-z_][\w:.-]*\b|[{}=]/g;
201
+ const sqlTokenPattern = /--[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:''|[^'])*'|\b[A-Za-z_][\w$]*\b|\b\d+(?:\.\d+)?\b|[=+\-*%<>!.,;()[\]]+/g;
202
+ const yamlTokenPattern = /#[^\n]*|"(?:\\.|[^"\\])*"|'(?:''|[^'])*'|\b[A-Za-z_][\w.-]*(?=\s*:)|\b(?:false|no|null|off|on|true|yes)\b|\b\d+(?:\.\d+)?\b|[{},:&*!?|>@`~-]+|\[|\]/gi;
71
203
  const leadingWhitespacePattern = /^[\t ]*/;
72
204
  const normalizeLanguage = (language = '') => language.trim().toLowerCase();
73
205
  const startsWithIdentifierPattern = /^[A-Za-z_$]/;
74
206
  const startsWithNumberPattern = /^\d/;
75
- const startsWithCommentPattern = /^\/[/*]/;
207
+ const startsWithCommentPattern = /^(?:#|--|\/[/*]|<!--)/;
76
208
  const startsWithStringPattern = /^["'`]/;
77
209
  export const normalizeLumenCode = (code) => {
78
210
  const lines = code.replaceAll(/\r\n?/g, '\n').split('\n');
@@ -86,7 +218,7 @@ export const normalizeLumenCode = (code) => {
86
218
  const trimBy = indentation.length > 0 ? Math.min(...indentation) : 0;
87
219
  return lines.map(line => line.slice(trimBy)).join('\n');
88
220
  };
89
- const getTokenKind = (value) => {
221
+ const getJavascriptTokenKind = (value) => {
90
222
  if (startsWithCommentPattern.exec(value))
91
223
  return 'comment';
92
224
  if (startsWithStringPattern.exec(value))
@@ -94,30 +226,155 @@ const getTokenKind = (value) => {
94
226
  if (startsWithNumberPattern.exec(value))
95
227
  return 'accent';
96
228
  if (startsWithIdentifierPattern.exec(value)) {
97
- if (jsKeywords.has(value))
229
+ if (javascriptKeywords.has(value))
98
230
  return 'keyword';
99
- if (jsTypes.has(value))
231
+ if (javascriptTypes.has(value))
100
232
  return 'type';
101
233
  return undefined;
102
234
  }
103
235
  return 'symbol';
104
236
  };
237
+ const getBashTokenKind = (value) => {
238
+ if (value.startsWith('#'))
239
+ return 'comment';
240
+ if (startsWithStringPattern.exec(value))
241
+ return 'string';
242
+ if (value.startsWith('$'))
243
+ return 'accent';
244
+ if (value.startsWith('-'))
245
+ return 'type';
246
+ if (startsWithNumberPattern.exec(value))
247
+ return 'accent';
248
+ if (bashKeywords.has(value))
249
+ return 'keyword';
250
+ if (startsWithIdentifierPattern.exec(value))
251
+ return undefined;
252
+ return 'symbol';
253
+ };
254
+ const getJsonTokenKind = (value, source, start) => {
255
+ if (startsWithCommentPattern.exec(value))
256
+ return 'comment';
257
+ if (value.startsWith('"')) {
258
+ const trailingSource = source.slice(start + value.length);
259
+ return /^\s*:/.exec(trailingSource) ? 'keyword' : 'string';
260
+ }
261
+ if (jsonKeywords.has(value.toLowerCase()))
262
+ return 'type';
263
+ if (/^-?\d/.exec(value))
264
+ return 'accent';
265
+ return 'symbol';
266
+ };
267
+ const getLuaTokenKind = (value) => {
268
+ if (value.startsWith('--'))
269
+ return 'comment';
270
+ if (startsWithStringPattern.exec(value))
271
+ return 'string';
272
+ if (startsWithNumberPattern.exec(value))
273
+ return 'accent';
274
+ if (luaKeywords.has(value))
275
+ return 'keyword';
276
+ if (startsWithIdentifierPattern.exec(value))
277
+ return undefined;
278
+ return 'symbol';
279
+ };
280
+ const getMarkdownTokenKind = (value) => {
281
+ if (value.startsWith('<!--'))
282
+ return 'comment';
283
+ if (value.startsWith('`'))
284
+ return 'string';
285
+ if (value.startsWith('['))
286
+ return 'accent';
287
+ if (value.trimStart().startsWith('#'))
288
+ return 'keyword';
289
+ return 'symbol';
290
+ };
291
+ const getMarkupTokenKind = (value, source, start) => {
292
+ if (value.startsWith('<!--'))
293
+ return 'comment';
294
+ if (startsWithStringPattern.exec(value))
295
+ return 'string';
296
+ if (value === '---')
297
+ return 'comment';
298
+ if (/^(?:<\/?|\/?>|[{}=])$/.exec(value))
299
+ return 'symbol';
300
+ const openingTagIndex = source.lastIndexOf('<', start);
301
+ const closingTagIndex = source.lastIndexOf('>', start);
302
+ if (openingTagIndex < closingTagIndex)
303
+ return undefined;
304
+ const beforeValue = source.slice(openingTagIndex + 1, start).replace('/', '').trim();
305
+ return beforeValue === '' ? 'keyword' : 'type';
306
+ };
307
+ const getSqlTokenKind = (value) => {
308
+ if (startsWithCommentPattern.exec(value))
309
+ return 'comment';
310
+ if (startsWithStringPattern.exec(value))
311
+ return 'string';
312
+ if (/^\d/.exec(value))
313
+ return 'accent';
314
+ if (sqlKeywords.has(value.toLowerCase()))
315
+ return 'keyword';
316
+ if (startsWithIdentifierPattern.exec(value))
317
+ return undefined;
318
+ return 'symbol';
319
+ };
320
+ const getYamlTokenKind = (value, source, start) => {
321
+ if (value.startsWith('#'))
322
+ return 'comment';
323
+ if (startsWithStringPattern.exec(value))
324
+ return 'string';
325
+ if (startsWithNumberPattern.exec(value))
326
+ return 'accent';
327
+ if (yamlKeywords.has(value.toLowerCase()))
328
+ return 'type';
329
+ if (startsWithIdentifierPattern.exec(value)) {
330
+ const trailingSource = source.slice(start + value.length);
331
+ return /^\s*:/.exec(trailingSource) ? 'keyword' : undefined;
332
+ }
333
+ return 'symbol';
334
+ };
335
+ const getLumenCodeTokenizer = (language) => {
336
+ if (javascriptLikeLanguages.has(language)) {
337
+ return { getKind: getJavascriptTokenKind, pattern: javascriptTokenPattern };
338
+ }
339
+ if (bashLikeLanguages.has(language)) {
340
+ return { getKind: getBashTokenKind, pattern: bashTokenPattern };
341
+ }
342
+ if (jsonLikeLanguages.has(language)) {
343
+ return { getKind: getJsonTokenKind, pattern: jsonTokenPattern };
344
+ }
345
+ if (luaLikeLanguages.has(language)) {
346
+ return { getKind: getLuaTokenKind, pattern: luaTokenPattern };
347
+ }
348
+ if (markdownLikeLanguages.has(language)) {
349
+ return { getKind: getMarkdownTokenKind, pattern: markdownTokenPattern };
350
+ }
351
+ if (markupLikeLanguages.has(language)) {
352
+ return { getKind: getMarkupTokenKind, pattern: markupTokenPattern };
353
+ }
354
+ if (sqlLikeLanguages.has(language)) {
355
+ return { getKind: getSqlTokenKind, pattern: sqlTokenPattern };
356
+ }
357
+ if (yamlLikeLanguages.has(language)) {
358
+ return { getKind: getYamlTokenKind, pattern: yamlTokenPattern };
359
+ }
360
+ return undefined;
361
+ };
105
362
  export const tokenizeLumenCode = (code, language = '') => {
106
363
  const source = normalizeLumenCode(code);
107
364
  const tokens = [];
108
- const shouldTokenizeJs = jsLikeLanguages.has(normalizeLanguage(language));
365
+ const tokenizer = getLumenCodeTokenizer(normalizeLanguage(language));
109
366
  let offset = 0;
110
367
  const push = (value, start, kind) => {
111
368
  if (value)
112
369
  tokens.push(kind ? { kind, start, value } : { start, value });
113
370
  };
114
- if (!shouldTokenizeJs)
371
+ if (!tokenizer)
115
372
  return source ? [{ start: 0, value: source }] : [];
116
- for (const match of source.matchAll(jsTokenPattern)) {
373
+ for (const match of source.matchAll(tokenizer.pattern)) {
117
374
  const index = match.index;
118
375
  const value = match[0];
119
376
  push(source.slice(offset, index), offset);
120
- push(value, index, getTokenKind(value));
377
+ push(value, index, tokenizer.getKind(value, source, index));
121
378
  offset = index + value.length;
122
379
  }
123
380
  push(source.slice(offset), offset);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@santi020k/lumen-core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -68,7 +68,7 @@
68
68
  "vitest": "^4.1.10"
69
69
  },
70
70
  "engines": {
71
- "node": ">=22.18.0"
71
+ "node": ">=22.12.0"
72
72
  },
73
73
  "repository": {
74
74
  "type": "git",