Skip to content

Commit 94cc6d8

Browse files
authoredNov 14, 2024··
feat: port @michael-makes/shiki-colorized-brackets JSR package (#831)
* feat: port @michael-makes/shiki-colorized-brackets JSR package * fix: colorized-brackets tests fail to find fixtures * fix: colorized-brackets test fails to find lang on Windows * fix: colorized-brackets test fails to find lang on Windows (again) * feat: add explicitTrigger option for transformerColorizedBrackets * docs: enable @shikijs/colorized-brackets in its own docs page
1 parent 48d6c57 commit 94cc6d8

39 files changed

+1384
-1
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ logs
1111
node_modules
1212
temp
1313
tmp
14+
packages/colorized-brackets/src/themes.ts
1415
packages/shiki/src/langs
1516
packages/shiki/src/themes
1617
packages/shiki/src/*.json

‎docs/.vitepress/config.ts

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { defineConfig } from 'vitepress'
44
import { withMermaid } from 'vitepress-plugin-mermaid'
55

66
import { version } from '../../package.json'
7+
import { transformerColorizedBrackets } from '../../packages/colorized-brackets/src'
78
import { transformerMetaWordHighlight, transformerNotationWordHighlight, transformerRemoveNotationEscape } from '../../packages/transformers/src'
89
import { defaultHoverInfoProcessor, transformerTwoslash } from '../../packages/vitepress-twoslash/src/index'
910
import vite from './vite.config'
@@ -41,6 +42,7 @@ const INTEGRATIONS: DefaultTheme.NavItemWithLink[] = [
4142
{ text: 'Next', link: '/packages/next' },
4243
{ text: 'Astro', link: '/packages/astro' },
4344
{ text: 'Common Transformers', link: '/packages/transformers' },
45+
{ text: 'Colorized Brackets', link: '/packages/colorized-brackets' },
4446
{ text: 'CLI', link: '/packages/cli' },
4547
]
4648

@@ -125,6 +127,7 @@ export default withMermaid(defineConfig({
125127
},
126128
}),
127129
transformerRemoveNotationEscape(),
130+
transformerColorizedBrackets({ explicitTrigger: true }),
128131
],
129132
},
130133

‎docs/guide/transformers.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const code = await codeToHtml('foo\bar', {
2828
})
2929
```
3030

31-
We also provide some common transformers for you to use, see [`@shikijs/transforms`](/packages/transformers) for more details.
31+
We also provide some common transformers for you to use, see [`@shikijs/transforms`](/packages/transformers) and [`@shikijs/colorized-brackets](/packages/colorized-brackets) for more details.
3232

3333
## Transformer Hooks
3434

‎docs/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
},
1313
"devDependencies": {
1414
"@iconify-json/svg-spinners": "catalog:",
15+
"@shikijs/colorized-brackets": "workspace:*",
1516
"@shikijs/transformers": "workspace:*",
1617
"@shikijs/twoslash": "workspace:*",
1718
"@unocss/reset": "catalog:",

‎docs/packages/colorized-brackets.md

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# @shikijs/colorized-brackets
6+
7+
<Badges name="@shikijs/colorized-brackets" />
8+
9+
VSCode-style colorized brackets transformer for Shiki.
10+
11+
## Install
12+
13+
```bash
14+
npm i -D @shikijs/colorized-brackets
15+
```
16+
17+
## Usage
18+
19+
Add to your Shiki transformers:
20+
21+
```ts colorize-brackets
22+
import { transformerColorizedBrackets } from '@shikijs/colorized-brackets'
23+
import { codeToHtml } from 'shiki'
24+
25+
const html = await codeToHtml('let values: number[] = [];', {
26+
lang: 'ts',
27+
theme: 'dark-plus',
28+
transformers: [transformerColorizedBrackets()],
29+
})
30+
```
31+
32+
### Colors
33+
34+
Brackets are automatically colored according to your Shiki theme (or themes if using [dual themes](https://shiki.style/guide/dual-themes)), with support for all of Shiki's built-in themes. However, you can customize colors if you've added custom themes to Shiki, or if you want to override the colors of a built-in theme:
35+
36+
```ts colorize-brackets
37+
const html = await codeToHtml('let values: number[] = [];', {
38+
lang: 'ts',
39+
theme: myCustomTheme,
40+
transformers: [transformerColorizedBrackets({
41+
themes: {
42+
'my-custom-theme': ['goldenrod', 'blueviolet', 'dodgerblue', 'crimson'],
43+
},
44+
})],
45+
})
46+
```
47+
48+
The final color is the mismatched bracket color. The other colors are for each "level" of bracket pair. Any valid CSS color can be used.
49+
50+
If no bracket colors are found for a theme, it falls back to the default `dark-plus` theme.
51+
52+
### Brackets
53+
54+
You can customize the bracket pairs:
55+
56+
```ts colorize-brackets
57+
const transformer = transformerColorizedBrackets({
58+
bracketPairs: [{ opener: '{', closer: '}' }],
59+
})
60+
```
61+
62+
The above would only colorize `{}` curly brackets. The default config colorizes `[]` square brackets, `{}` curly brackets, `()` parentheses, and `<>` angle brackets (only in TS type annotations).
63+
64+
For advanced usage, you can specify which TextMate scopes a bracket pair is allowed or denied in, using `scopesAllowList` and `scopesDenyList`. For example, the default config for `<>` angle brackets is:
65+
66+
```ts colorize-brackets
67+
const bracketPair = {
68+
opener: '<',
69+
closer: '>',
70+
scopesAllowList: [
71+
'punctuation.definition.typeparameters.begin.ts',
72+
'punctuation.definition.typeparameters.end.ts',
73+
],
74+
}
75+
```
76+
77+
### Language-specific Overrides
78+
79+
All settings can be overridden for specific languages using the `langs` option:
80+
81+
```ts colorize-brackets
82+
const transformer = transformerColorizedBrackets({
83+
langs: { ts: myCustomTypescriptConfig },
84+
})
85+
```
86+
87+
### Explicit Trigger
88+
89+
If you do not want colorized brackets for all code blocks, you can enable the `explicitTrigger` option:
90+
91+
```ts colorize-brackets
92+
const transformer = transformerColorizedBrackets({
93+
explicitTrigger: true,
94+
})
95+
```
96+
97+
Then, only code blocks with the `colorize-brackets` [meta string](/guide/transformers#meta) will have bracket colorizing enabled.
98+
99+
````md
100+
```ts
101+
// no bracket colorizing
102+
```
103+
104+
```ts colorize-brackets
105+
// brackets will be colorized
106+
```
107+
````

‎packages/colorized-brackets/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# @shikijs/colorized-brackets
2+
3+
VSCode-style colorized brackets transformer for [Shiki](https://github.com/shikijs/shiki).
4+
5+
[Documentation](https://shiki.style/packages/colorized-brackets)
6+
7+
## License
8+
9+
MIT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { defineBuildConfig } from 'unbuild'
2+
3+
export default defineBuildConfig({
4+
entries: [
5+
'src/index.ts',
6+
],
7+
declaration: true,
8+
rollup: {
9+
emitCJS: false,
10+
dts: {
11+
compilerOptions: {
12+
paths: {},
13+
},
14+
},
15+
},
16+
externals: [
17+
'hast',
18+
],
19+
})
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "@shikijs/colorized-brackets",
3+
"type": "module",
4+
"version": "1.22.2",
5+
"description": "Collective of common transformers transformers for Shiki",
6+
"author": "Michael Moore <mscottmoore@pm.me>",
7+
"license": "MIT",
8+
"homepage": "https://github.com/shikijs/shiki#readme",
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/shikijs/shiki.git",
12+
"directory": "packages/colorized-brackets"
13+
},
14+
"bugs": "https://github.com/shikijs/shiki/issues",
15+
"keywords": [
16+
"shiki",
17+
"@shikijs/colorized-brackets"
18+
],
19+
"sideEffects": false,
20+
"exports": {
21+
".": {
22+
"types": "./dist/index.d.mts",
23+
"default": "./dist/index.mjs"
24+
}
25+
},
26+
"main": "./dist/index.mjs",
27+
"module": "./dist/index.mjs",
28+
"types": "./dist/index.d.mts",
29+
"files": [
30+
"dist"
31+
],
32+
"scripts": {
33+
"build": "unbuild",
34+
"dev": "unbuild --stub",
35+
"prepare": "esno scripts/prepare.ts",
36+
"prepublishOnly": "nr build",
37+
"test": "vitest"
38+
},
39+
"dependencies": {
40+
"shiki": "workspace:*"
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import fs from 'fs-extra'
2+
import { themes as allThemes } from 'tm-themes'
3+
4+
async function main() {
5+
// if a theme doesn't define bracket colors, it falls back to these
6+
// from vscode /src/vs/editor/common/core/editorColorRegistry.ts
7+
const vsCodeBaseThemes: Record<string, Record<string, string>> = {
8+
light: {
9+
'editorBracketHighlight.foreground1': '#0431FA',
10+
'editorBracketHighlight.foreground2': '#319331',
11+
'editorBracketHighlight.foreground3': '#7B3814',
12+
'editorBracketHighlight.unexpectedBracket.foreground':
13+
'rgba(255, 18, 18, 0.8)',
14+
},
15+
dark: {
16+
'editorBracketHighlight.foreground1': '#FFD700',
17+
'editorBracketHighlight.foreground2': '#DA70D6',
18+
'editorBracketHighlight.foreground3': '#179FFF',
19+
'editorBracketHighlight.unexpectedBracket.foreground':
20+
'rgba(255, 18, 18, 0.8)',
21+
},
22+
lightHighContrast: {
23+
'editorBracketHighlight.foreground1': '#0431FA',
24+
'editorBracketHighlight.foreground2': '#319331',
25+
'editorBracketHighlight.foreground3': '#7B3814',
26+
'editorBracketHighlight.unexpectedBracket.foreground': '#B5200D',
27+
},
28+
darkHighContrast: {
29+
'editorBracketHighlight.foreground1': '#FFD700',
30+
'editorBracketHighlight.foreground2': '#DA70D6',
31+
'editorBracketHighlight.foreground3': '#87CEFA',
32+
'editorBracketHighlight.unexpectedBracket.foreground':
33+
'rgba(255, 50, 50, 1)',
34+
},
35+
}
36+
37+
const themes: Record<string, string[]> = {}
38+
for (const t of allThemes) {
39+
const theme = await fs.readJSON(`./node_modules/shiki/node_modules/tm-themes/themes/${t.name}.json`)
40+
const isHighContrast = t.name.includes('high-contrast')
41+
const themeType = theme.type ?? 'dark'
42+
const baseTheme = isHighContrast ? `${themeType}HighContrast` : themeType
43+
const colors: Record<string, string> = {
44+
...vsCodeBaseThemes[baseTheme],
45+
...theme.colors,
46+
}
47+
const bracketTheme = [
48+
colors['editorBracketHighlight.foreground1'],
49+
colors['editorBracketHighlight.foreground2'],
50+
colors['editorBracketHighlight.foreground3'],
51+
colors['editorBracketHighlight.foreground4'],
52+
colors['editorBracketHighlight.foreground5'],
53+
colors['editorBracketHighlight.foreground6'],
54+
colors['editorBracketHighlight.unexpectedBracket.foreground'],
55+
].filter(Boolean)
56+
themes[t.name] = bracketTheme
57+
}
58+
59+
const sorted = Object.fromEntries(
60+
Object.entries(themes).sort((a, b) => a[0].localeCompare(b[0])),
61+
)
62+
63+
await fs.writeFile(
64+
'./src/themes.ts',
65+
`// Generated by scripts/prepare.ts
66+
export default ${JSON.stringify(sorted, undefined, 2)} as Record<string, string[]>
67+
`,
68+
{ encoding: 'utf-8' },
69+
)
70+
}
71+
72+
main()

0 commit comments

Comments
 (0)
Please sign in to comment.