@peaceroad/markdown-it-renderer-fence 0.7.0 → 0.9.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.
Files changed (36) hide show
  1. package/README.md +179 -470
  2. package/docs/README.md +37 -0
  3. package/docs/code-highlighting-design.md +321 -0
  4. package/docs/custom-highlight-styling-guide.md +210 -0
  5. package/package.json +25 -13
  6. package/src/custom-highlight/option-validator.js +5 -5
  7. package/src/custom-highlight/payload-utils.js +4 -9
  8. package/src/custom-highlight/{shiki-keyword-rules.js → shiki-role-rules.js} +249 -54
  9. package/src/custom-highlight/{shiki-keyword.js → shiki-role.js} +107 -99
  10. package/src/custom-highlight/shiki-theme-role.js +176 -0
  11. package/src/fence/line-notes.js +27 -9
  12. package/src/fence/render-api-constants.js +1 -1
  13. package/src/fence/render-api-provider.js +61 -53
  14. package/src/fence/render-api-renderer.js +26 -10
  15. package/src/fence/render-api-runtime.js +29 -10
  16. package/src/fence/render-api.js +20 -12
  17. package/src/fence/render-markup.js +34 -24
  18. package/src/fence/render-shared.js +150 -30
  19. package/src/utils/attr-utils.js +10 -0
  20. package/theme/_shared/rf-core.css +170 -0
  21. package/theme/line-notes.css +94 -0
  22. package/theme/line-number.css +64 -0
  23. package/theme/rf-basic/README.md +117 -0
  24. package/theme/rf-basic/api/highlightjs.css +71 -0
  25. package/theme/rf-basic/api/shiki.css +67 -0
  26. package/theme/rf-basic/base.css +5 -0
  27. package/theme/rf-basic/index.css +7 -0
  28. package/theme/rf-basic/index.js +164 -0
  29. package/theme/rf-basic/markup/highlightjs.css +77 -0
  30. package/theme/rf-basic/markup/shiki.css +11 -0
  31. package/theme/rf-monochrome/README.md +84 -0
  32. package/theme/rf-monochrome/base.css +5 -0
  33. package/theme/rf-monochrome/index.css +5 -0
  34. package/theme/rf-monochrome/index.js +71 -0
  35. package/theme/rf-monochrome/markup/highlightjs.css +150 -0
  36. package/theme/rf-monochrome/markup/shiki.css +38 -0
@@ -1,3 +1,7 @@
1
+ import {
2
+ escapeHtmlAttr,
3
+ } from '../utils/attr-utils.js'
4
+
1
5
  const escapeJsonForScript = (data) => {
2
6
  return JSON.stringify(data)
3
7
  .replace(/</g, '\\u003C')
@@ -7,15 +11,6 @@ const escapeJsonForScript = (data) => {
7
11
  .replace(/\u2029/g, '\\u2029')
8
12
  }
9
13
 
10
- const escapeHtmlAttr = (value) => {
11
- return String(value)
12
- .replace(/&/g, '&amp;')
13
- .replace(/"/g, '&quot;')
14
- .replace(/'/g, '&#39;')
15
- .replace(/</g, '&lt;')
16
- .replace(/>/g, '&gt;')
17
- }
18
-
19
14
  const getCustomHighlightPayloadMap = (env, envKey = 'rendererFenceCustomHighlights') => {
20
15
  if (!env || typeof env !== 'object') return {}
21
16
  const map = env[envKey]
@@ -4,12 +4,85 @@ const shikiFunctionLikeIdentifierReg = /^[A-Za-z_$][\w$]*[!?]?$/
4
4
  const shikiShellOptionTokenReg = /^-[A-Za-z0-9][A-Za-z0-9-]*$/
5
5
  const shikiShellTestOperatorSet = new Set(['-n', '-z', '-gt', '-lt', '-ge', '-le', '-eq', '-ne'])
6
6
 
7
- const keywordV4GlobalRules = [
7
+ const roleV4GlobalRules = [
8
8
  {
9
- id: 'css-color-name-to-number',
9
+ id: 'string-delimiter-punctuation',
10
+ priority: 2300,
11
+ scopeIncludesAny: ['punctuation.definition.string'],
12
+ tokenRegex: /^(?:\$?['"`]+|[<>])$/,
13
+ setBucket: 'punctuation',
14
+ },
15
+ {
16
+ id: 'string-interpolation-punctuation',
17
+ priority: 2295,
18
+ baseIn: ['string', 'string-unquoted'],
19
+ scopeIncludesAny: [
20
+ 'punctuation.definition.interpolation',
21
+ 'punctuation.section.embedded',
22
+ 'punctuation.accessor',
23
+ ],
24
+ tokenKind: 'punctuation',
25
+ setBucket: 'punctuation',
26
+ },
27
+ {
28
+ id: 'variable-prefix-punctuation',
29
+ priority: 2292,
30
+ scopeIncludesAny: ['punctuation.definition.variable'],
31
+ tokenKind: 'punctuation',
32
+ setBucket: 'punctuation',
33
+ },
34
+ {
35
+ id: 'generic-definition-punctuation',
36
+ priority: 2291,
37
+ scopeIncludesAny: ['punctuation.definition.'],
38
+ tokenKind: 'punctuation',
39
+ setBucket: 'punctuation',
40
+ },
41
+ {
42
+ id: 'generic-section-punctuation',
43
+ priority: 2290,
44
+ scopeIncludesAny: ['punctuation.section.'],
45
+ tokenKind: 'punctuation',
46
+ setBucket: 'punctuation',
47
+ },
48
+ {
49
+ id: 'object-literal-key-variable',
50
+ priority: 2289,
51
+ scopeIncludesAny: ['meta.object-literal.key'],
52
+ tokenKind: 'identifier',
53
+ setBucket: 'variable',
54
+ },
55
+ {
56
+ id: 'symbolic-operator-punctuation',
57
+ priority: 2280,
58
+ scopeIncludesAny: [
59
+ 'keyword.operator.accessor',
60
+ 'keyword.operator.arithmetic',
61
+ 'keyword.operator.assignment',
62
+ 'keyword.operator.bitwise',
63
+ 'keyword.operator.comparison',
64
+ 'keyword.operator.expression',
65
+ 'keyword.operator.logical',
66
+ 'keyword.operator.nullish',
67
+ 'keyword.operator.optional',
68
+ 'keyword.operator.spread',
69
+ 'keyword.operator.ternary',
70
+ ],
71
+ tokenKind: 'punctuation',
72
+ setBucket: 'punctuation',
73
+ },
74
+ {
75
+ id: 'json-property-name-delimiter-punctuation',
76
+ priority: 2270,
77
+ scopeIncludesAny: ['punctuation.support.type.property-name'],
78
+ tokenKind: 'punctuation',
79
+ setBucket: 'punctuation',
80
+ },
81
+ {
82
+ id: 'css-color-name-to-literal',
10
83
  priority: 2100,
11
84
  scopeIncludesAny: ['support.constant.color.w3c-standard-color-name.css'],
12
- setBucket: 'number',
85
+ setBucket: 'literal',
13
86
  },
14
87
  {
15
88
  id: 'rust-lifetime-to-type-name',
@@ -19,30 +92,45 @@ const keywordV4GlobalRules = [
19
92
  setBucket: 'type-name',
20
93
  },
21
94
  {
22
- id: 'regex-alternative-operator-keyword',
95
+ id: 'regex-alternative-operator-punctuation',
23
96
  priority: 2040,
24
97
  scopeIncludesAny: ['keyword.operator.or.regexp'],
25
98
  tokenEquals: ['|'],
26
- setBucket: 'keyword',
99
+ setBucket: 'punctuation',
27
100
  },
28
101
  ]
29
102
 
30
- const keywordV4LangRules = {
103
+ const roleV4LangRules = {
31
104
  sql: [
32
105
  {
33
- id: 'sql-window-function-blue',
106
+ id: 'sql-plain-source-punctuation-text',
107
+ priority: 2010,
108
+ scopeIncludesAny: ['source.sql'],
109
+ scopeExcludesAny: ['keyword.operator', 'punctuation.definition.string'],
110
+ tokenKind: 'punctuation',
111
+ setBucket: 'text',
112
+ },
113
+ {
114
+ id: 'sql-window-function-title',
34
115
  priority: 2000,
35
116
  scopeIncludesAny: ['support.function.ranking.sql'],
36
- setBucket: 'type',
117
+ setBucket: 'title-function',
37
118
  },
38
119
  {
39
- id: 'sql-table-database-name-blue',
120
+ id: 'sql-table-database-name-text',
40
121
  priority: 1980,
41
122
  scopeIncludesAny: ['constant.other.table-name.sql', 'constant.other.database-name.sql'],
42
- setBucket: 'type',
123
+ setBucket: 'text',
43
124
  },
44
125
  ],
45
126
  java: [
127
+ {
128
+ id: 'java-storage-modifier-keyword',
129
+ priority: 2000,
130
+ scopeIncludesAny: ['storage.modifier.java', 'storage.modifier.import.java'],
131
+ tokenKind: 'identifier',
132
+ setBucket: 'keyword',
133
+ },
46
134
  {
47
135
  id: 'java-record-signature-neutral',
48
136
  priority: 1995,
@@ -51,16 +139,16 @@ const keywordV4LangRules = {
51
139
  setBucket: 'text',
52
140
  },
53
141
  {
54
- id: 'java-package-separator-neutral',
142
+ id: 'java-package-separator-punctuation',
55
143
  priority: 1980,
56
144
  scopeIncludesAny: ['punctuation.separator.java'],
57
- setBucket: 'text',
145
+ setBucket: 'punctuation',
58
146
  },
59
147
  {
60
- id: 'java-generic-bracket-neutral',
148
+ id: 'java-generic-bracket-punctuation',
61
149
  priority: 1970,
62
150
  scopeIncludesAny: ['punctuation.bracket.angle.java'],
63
- setBucket: 'text',
151
+ setBucket: 'punctuation',
64
152
  },
65
153
  {
66
154
  id: 'java-record-keyword',
@@ -93,16 +181,22 @@ const keywordV4LangRules = {
93
181
  setBucket: 'title-function-builtin',
94
182
  },
95
183
  {
96
- id: 'php-core-const-blue',
184
+ id: 'php-file-and-declare-meta-text',
185
+ priority: 1990,
186
+ scopeIncludesAny: ['constant.other.php'],
187
+ setBucket: 'text',
188
+ },
189
+ {
190
+ id: 'php-core-const-literal',
97
191
  priority: 1980,
98
- scopeIncludesAny: ['support.constant.core.php', 'constant.other.php'],
99
- setBucket: 'variable-const',
192
+ scopeIncludesAny: ['support.constant.core.php'],
193
+ setBucket: 'literal',
100
194
  },
101
195
  {
102
- id: 'php-enum-const-blue',
196
+ id: 'php-enum-const-text',
103
197
  priority: 1970,
104
198
  scopeIncludesAny: ['constant.enum.php', 'constant.other.class.php'],
105
- setBucket: 'variable-const',
199
+ setBucket: 'text',
106
200
  },
107
201
  ],
108
202
  ruby: [
@@ -112,6 +206,20 @@ const keywordV4LangRules = {
112
206
  scopeIncludesAny: ['entity.name.function.ruby'],
113
207
  setBucket: 'title-function',
114
208
  },
209
+ {
210
+ id: 'ruby-instance-variable-token',
211
+ priority: 1990,
212
+ scopeIncludesAny: ['variable.other.readwrite.instance.ruby', 'variable.other.block.ruby'],
213
+ tokenKind: 'identifier',
214
+ setBucket: 'variable',
215
+ },
216
+ {
217
+ id: 'ruby-variable-separator-punctuation',
218
+ priority: 1985,
219
+ scopeIncludesAny: ['punctuation.separator.variable.ruby'],
220
+ tokenKind: 'punctuation',
221
+ setBucket: 'punctuation',
222
+ },
115
223
  {
116
224
  id: 'ruby-variable-accent',
117
225
  priority: 1980,
@@ -152,12 +260,35 @@ const keywordV4LangRules = {
152
260
  },
153
261
  ],
154
262
  csharp: [
263
+ {
264
+ id: 'csharp-new-expression-punctuation',
265
+ priority: 1970,
266
+ scopeIncludesAny: ['keyword.operator.expression.new.cs', 'punctuation.parenthesis.open.cs'],
267
+ tokenRegex: /^new\(?$/,
268
+ setBucket: 'punctuation',
269
+ },
155
270
  {
156
271
  id: 'csharp-keyword-type-keyword',
157
272
  priority: 1960,
158
273
  scopeIncludesAny: ['keyword.type.string.cs'],
159
274
  setBucket: 'keyword',
160
275
  },
276
+ {
277
+ id: 'csharp-record-parameter-name-text',
278
+ priority: 1955,
279
+ scopeIncludesAny: ['entity.name.variable.parameter.cs'],
280
+ tokenKind: 'identifier',
281
+ setBucket: 'text',
282
+ },
283
+ {
284
+ id: 'csharp-plain-source-identifier-text',
285
+ priority: 1950,
286
+ baseIn: ['type-name', 'type', 'variable-plain'],
287
+ scopeIncludesAny: ['source.cs'],
288
+ scopeExcludesAny: ['entity.name.', 'support.', 'storage.', 'keyword.', 'variable.'],
289
+ tokenKind: 'identifier',
290
+ setBucket: 'text',
291
+ },
161
292
  ],
162
293
  c: [
163
294
  {
@@ -177,10 +308,42 @@ const keywordV4LangRules = {
177
308
  id: 'c-placeholder-blue',
178
309
  priority: 1950,
179
310
  scopeIncludesAny: ['constant.other.placeholder.c'],
180
- setBucket: 'literal',
311
+ setBucket: 'string',
312
+ },
313
+ {
314
+ id: 'c-plain-source-identifier-text',
315
+ priority: 1940,
316
+ baseIn: ['variable-plain'],
317
+ scopeIncludesAny: ['source.c'],
318
+ scopeExcludesAny: ['variable.', 'entity.name.', 'support.', 'storage.', 'keyword.', 'constant.'],
319
+ tokenKind: 'identifier',
320
+ setBucket: 'text',
181
321
  },
182
322
  ],
183
323
  cpp: [
324
+ {
325
+ id: 'cpp-plain-function-body-fragment-text',
326
+ priority: 1985,
327
+ scopeIncludesAny: ['meta.body.function.definition.cpp'],
328
+ scopeExcludesAny: ['entity.name.', 'support.', 'storage.', 'keyword.', 'variable.', 'constant.', 'string.'],
329
+ tokenRegex: /[A-Za-z_]/,
330
+ setBucket: 'text',
331
+ },
332
+ {
333
+ id: 'cpp-plain-function-body-identifier-text',
334
+ priority: 1980,
335
+ scopeIncludesAny: ['meta.body.function.definition.cpp'],
336
+ scopeExcludesAny: ['entity.name.', 'support.', 'storage.', 'keyword.', 'variable.', 'constant.', 'string.'],
337
+ tokenKind: 'identifier',
338
+ setBucket: 'text',
339
+ },
340
+ {
341
+ id: 'cpp-scope-resolution-name-text',
342
+ priority: 1970,
343
+ scopeIncludesAny: ['entity.name.scope-resolution.cpp', 'entity.name.scope-resolution.parameter.cpp'],
344
+ tokenKind: 'identifier',
345
+ setBucket: 'text',
346
+ },
184
347
  {
185
348
  id: 'cpp-reference-modifier-keyword',
186
349
  priority: 1960,
@@ -189,6 +352,20 @@ const keywordV4LangRules = {
189
352
  },
190
353
  ],
191
354
  python: [
355
+ {
356
+ id: 'python-fstring-period-punctuation',
357
+ priority: 1920,
358
+ scopeIncludesAny: ['meta.fstring.python', 'punctuation.separator.period.python'],
359
+ tokenEquals: ['.'],
360
+ setBucket: 'punctuation',
361
+ },
362
+ {
363
+ id: 'python-meta-attribute',
364
+ priority: 1910,
365
+ scopeIncludesAny: ['meta.attribute.python'],
366
+ tokenKind: 'identifier',
367
+ setBucket: 'attribute',
368
+ },
192
369
  {
193
370
  id: 'python-fstring-conversion-neutral',
194
371
  priority: 1900,
@@ -208,24 +385,30 @@ const keywordV4LangRules = {
208
385
  ],
209
386
  css: [
210
387
  {
211
- id: 'css-function-type-blue',
388
+ id: 'css-function-title',
212
389
  priority: 1940,
213
390
  scopeIncludesAny: ['support.function.calc.css', 'support.function.gradient.css'],
214
- setBucket: 'type',
391
+ setBucket: 'title-function',
392
+ },
393
+ {
394
+ id: 'css-property-value-literal',
395
+ priority: 1930,
396
+ scopeIncludesAny: ['support.constant.property-value.css'],
397
+ setBucket: 'literal',
215
398
  },
216
399
  ],
217
400
  }
218
401
 
219
- const keywordV4SortedGlobalRules = keywordV4GlobalRules.slice().sort((a, b) => (b.priority || 0) - (a.priority || 0))
220
- const keywordV4SortedLangRules = new Map(
221
- Object.keys(keywordV4LangRules).map((lang) => [
402
+ const roleV4SortedGlobalRules = roleV4GlobalRules.slice().sort((a, b) => (b.priority || 0) - (a.priority || 0))
403
+ const roleV4SortedLangRules = new Map(
404
+ Object.keys(roleV4LangRules).map((lang) => [
222
405
  lang,
223
- keywordV4LangRules[lang].slice().sort((a, b) => (b.priority || 0) - (a.priority || 0)),
406
+ roleV4LangRules[lang].slice().sort((a, b) => (b.priority || 0) - (a.priority || 0)),
224
407
  ]),
225
408
  )
226
409
 
227
- const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
228
- const postHelper = helper && typeof helper === 'object' ? helper : {}
410
+ const applyShikiRoleLegacyPostRules = (currentBucket, ctx, helper) => {
411
+ const postHelper = helper && typeof helper === 'object' ? helper : (ctx || {})
229
412
  const hasAnyScopePattern = typeof postHelper.hasAnyScopePattern === 'function'
230
413
  ? postHelper.hasAnyScopePattern
231
414
  : () => false
@@ -234,7 +417,7 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
234
417
  : (pattern) => hasAnyScopePattern([pattern])
235
418
  const classifyToken = typeof postHelper.classifyToken === 'function'
236
419
  ? postHelper.classifyToken
237
- : () => null
420
+ : null
238
421
 
239
422
  const bucket = String(currentBucket || 'text')
240
423
  const langKey = String(ctx && ctx.langKey || '')
@@ -242,10 +425,16 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
242
425
  const tokenContent = String(ctx && ctx.tokenContent || '')
243
426
  const trimmed = String(ctx && ctx.tokenTrim || '')
244
427
  const tokenLower = (ctx && typeof ctx.tokenLower === 'string') ? ctx.tokenLower : trimmed.toLowerCase()
428
+ const isIdentifier = (ctx && typeof ctx.isIdentifier === 'boolean')
429
+ ? ctx.isIdentifier
430
+ : shikiSimpleIdentifierReg.test(trimmed)
431
+ const isPunctuation = (ctx && typeof ctx.isPunctuation === 'boolean')
432
+ ? ctx.isPunctuation
433
+ : shikiPunctuationTokenReg.test(trimmed)
245
434
  if (!trimmed) return 'text'
246
435
 
247
436
  if ((langKey === 'bash' || langKey === 'shellscript') && shikiShellOptionTokenReg.test(trimmed)) {
248
- return shikiShellTestOperatorSet.has(tokenLower) ? 'keyword' : 'literal'
437
+ return shikiShellTestOperatorSet.has(tokenLower) ? 'punctuation' : 'string'
249
438
  }
250
439
  if ((langKey === 'hcl' || langKey === 'terraform') && trimmed === '=') return 'keyword'
251
440
  if (bucket === 'comment' && trimmed.startsWith('#!')) return 'meta-shebang'
@@ -262,15 +451,16 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
262
451
  trimmed.startsWith('${') ||
263
452
  trimmed === '}'
264
453
  )
265
- ) return 'literal'
454
+ ) return hasAnyScopePattern(['variable.parameter.positional.shell', 'variable.language.special.shell'])
455
+ ? 'variable-plain'
456
+ : 'string'
266
457
  if (
267
458
  (langKey === 'bash' || langKey === 'shellscript') &&
268
459
  hasAnyScopePattern(['constant.other.option'])
269
- ) return shikiShellTestOperatorSet.has(tokenLower) ? 'keyword' : 'literal'
460
+ ) return shikiShellTestOperatorSet.has(tokenLower) ? 'punctuation' : 'string'
270
461
  if (langKey === 'python' && hasAnyScopePattern(['storage.type.string.python'])) return 'keyword'
271
- if (langKey === 'go' && hasAnyScopePattern(['entity.name.import.go'])) return 'type-name'
272
462
  if (hasAnyScopePattern(['keyword.operator.string'])) return 'keyword'
273
- if (hasAnyScopePattern(['constant.character.escape', 'constant.character.format.placeholder'])) return 'number'
463
+ if (hasAnyScopePattern(['constant.character.escape', 'constant.character.format.placeholder'])) return 'literal'
274
464
  if (hasAnyScopePattern(['variable.other.', 'variable.ruby', 'meta.attribute.python'])) return 'variable-plain'
275
465
  }
276
466
  if (bucket === 'string-unquoted') {
@@ -286,23 +476,24 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
286
476
  trimmed.startsWith('${') ||
287
477
  trimmed === '}'
288
478
  )
289
- ) return 'literal'
479
+ ) return hasAnyScopePattern(['variable.parameter.positional.shell', 'variable.language.special.shell'])
480
+ ? 'variable-plain'
481
+ : 'string'
290
482
  if (
291
483
  (langKey === 'bash' || langKey === 'shellscript') &&
292
484
  hasAnyScopePattern(['constant.other.option'])
293
- ) return shikiShellTestOperatorSet.has(tokenLower) ? 'keyword' : 'literal'
485
+ ) return shikiShellTestOperatorSet.has(tokenLower) ? 'punctuation' : 'string'
294
486
  if (hasAnyScopePattern(['entity.name.tag.yaml'])) return 'tag'
295
487
  return 'string'
296
488
  }
297
489
  if (bucket === 'title-function') {
298
- if (langKey === 'css' && hasAnyScopePattern(['support.function.misc.css'])) return 'type'
299
490
  if (hasAnyScopePattern(['support.function.builtin', 'support.function.kernel', 'support.function.construct'])) return 'title-function-builtin'
300
491
  if (hasAnyScopePattern(['storage.type.function.arrow', 'keyword.operator'])) return 'keyword'
301
492
  if (hasAnyScopePattern(['punctuation.section.function', 'punctuation.definition.arguments', 'meta.function-call.arguments'])) return 'punctuation'
302
493
  if (hasAnyScopePattern(['meta.function']) && !hasAnyScopePattern(['entity.name.function', 'support.function'])) return 'meta'
303
494
  if (hasAnyScopePattern(['punctuation.accessor'])) return 'text'
304
495
  if (!shikiFunctionLikeIdentifierReg.test(trimmed)) {
305
- if (shikiPunctuationTokenReg.test(trimmed)) return 'punctuation'
496
+ if (isPunctuation) return 'punctuation'
306
497
  if (/[.\[\](){}:]/.test(trimmed)) return 'text'
307
498
  }
308
499
  }
@@ -320,7 +511,7 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
320
511
  if (bucket === 'variable') {
321
512
  if (
322
513
  hasAnyScopePattern(['meta.type.annotation']) &&
323
- shikiPunctuationTokenReg.test(trimmed)
514
+ isPunctuation
324
515
  ) return 'punctuation'
325
516
  if (hasAnyScopePattern(['variable.language.this'])) return 'variable-this'
326
517
  if (hasAnyScopePattern(['variable.other.constant', 'constant.other.php', 'variable.other.enummember'])) return 'variable-const'
@@ -330,9 +521,9 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
330
521
  }
331
522
  if (bucket === 'variable-plain') {
332
523
  if (hasAnyScopePattern(['variable.other.constant', 'constant.other.php', 'variable.other.enummember'])) return 'variable-const'
333
- if (hasAnyScopePattern(['entity.name.variable.local.cs'])) return 'type-name'
524
+ if (langKey === 'csharp' && hasAnyScopePattern(['entity.name.variable.local.cs'])) return 'text'
334
525
  if (hasAnyScopePattern(['source.sql', 'source.python', 'source.ruby'])) return 'text'
335
- if (!shikiSimpleIdentifierReg.test(trimmed) && hasAnyScopePattern(['punctuation.'])) return 'punctuation'
526
+ if (!isIdentifier && hasAnyScopePattern(['punctuation.'])) return 'punctuation'
336
527
  }
337
528
  if (bucket === 'variable-member') {
338
529
  if (hasAnyScopePattern(['variable.object.property.ts', 'variable-object-property-ts', 'variable.object.property.js', 'variable-object-property-js'])) return 'variable-property'
@@ -345,7 +536,7 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
345
536
  if (hasAnyScopePattern(['variable.other.readwrite.hcl', 'variable.other.normal.shell', 'meta.block.hcl'])) return 'variable-plain'
346
537
  if (hasAnyScopePattern(['storage.type.built-in.primitive', 'keyword.operator.type.annotation', 'keyword.operator.type'])) return 'keyword'
347
538
  if (hasAnyScopePattern(['entity.name.type', 'support.type'])) return 'type-name'
348
- if (!shikiSimpleIdentifierReg.test(trimmed)) return 'punctuation'
539
+ if (!isIdentifier) return 'punctuation'
349
540
  }
350
541
  if (bucket === 'variable-property') {
351
542
  if (hasAnyScopePattern(['variable.object.property', 'variable.other.property'])) return 'variable-parameter'
@@ -354,18 +545,23 @@ const applyShikiKeywordLegacyPostRules = (currentBucket, ctx, helper) => {
354
545
  if (bucket === 'keyword' && hasAnyScopePattern(['variable.language.this'])) return 'variable-this'
355
546
  if (bucket === 'literal' && langKey === 'sql') return 'text'
356
547
  if (bucket === 'text') {
357
- const tokenBucket = classifyToken(tokenContent, langKey)
548
+ const tokenBucket = classifyToken
549
+ ? classifyToken(tokenContent, langKey)
550
+ : ((ctx && ctx.tokenBucket) || null)
358
551
  if (tokenBucket) return tokenBucket
359
- if (shikiSimpleIdentifierReg.test(trimmed)) return 'variable-plain'
552
+ if (hasAnyScopePattern(['source.sql', 'source.python', 'source.ruby', 'text.html.basic'])) return 'text'
553
+ if (isIdentifier) return 'variable-plain'
360
554
  }
361
- if (!shikiSimpleIdentifierReg.test(trimmed) && (bucket === 'text' || bucket === 'meta')) {
362
- const tokenBucket = classifyToken(tokenContent, langKey)
555
+ if (!isIdentifier && (bucket === 'text' || bucket === 'meta')) {
556
+ const tokenBucket = classifyToken
557
+ ? classifyToken(tokenContent, langKey)
558
+ : ((ctx && ctx.tokenBucket) || null)
363
559
  if (tokenBucket) return tokenBucket
364
560
  }
365
561
  return bucket
366
562
  }
367
563
 
368
- const matchKeywordV4Rule = (rule, currentBucket, ctx) => {
564
+ const matchRoleV4Rule = (rule, currentBucket, ctx) => {
369
565
  const hasAnyScopePattern = (ctx && typeof ctx.hasAnyScopePattern === 'function')
370
566
  ? ctx.hasAnyScopePattern
371
567
  : (() => false)
@@ -386,22 +582,21 @@ const applyRuleSet = (currentBucket, rules, ctx) => {
386
582
  let next = currentBucket
387
583
  for (let i = 0; i < rules.length; i++) {
388
584
  const rule = rules[i]
389
- if (!matchKeywordV4Rule(rule, next, ctx)) continue
585
+ if (!matchRoleV4Rule(rule, next, ctx)) continue
390
586
  next = rule.setBucket || next
391
587
  if (rule.stop !== false) break
392
588
  }
393
589
  return next
394
590
  }
395
591
 
396
- const applyKeywordV4Rules = (currentBucket, ctx) => {
397
- let next = applyRuleSet(currentBucket, keywordV4SortedGlobalRules, ctx)
398
- const langRules = keywordV4SortedLangRules.get(ctx.langKey)
592
+ const applyRoleV4Rules = (currentBucket, ctx) => {
593
+ let next = applyRuleSet(currentBucket, roleV4SortedGlobalRules, ctx)
594
+ const langRules = roleV4SortedLangRules.get(ctx.langKey)
399
595
  next = applyRuleSet(next, langRules, ctx)
400
596
  return next
401
597
  }
402
598
 
403
599
  export {
404
- applyKeywordV4Rules,
405
- applyShikiKeywordLegacyPostRules,
600
+ applyRoleV4Rules,
601
+ applyShikiRoleLegacyPostRules,
406
602
  }
407
-