summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHippo2023-11-20 22:42:56 +0100
committerGitHub2023-11-20 22:42:56 +0100
commitc6a4bcb7982c54c513f20c96a9b2aaf9ac09094b (patch)
tree17cc0c2d13a566cfb9c73c3a025bb70bc0c3d64e
parent6d14b4f51fcbc3e82c71fb786903083013f11e05 (diff)
downloadIT.starlight-c6a4bcb7982c54c513f20c96a9b2aaf9ac09094b.tar.gz
IT.starlight-c6a4bcb7982c54c513f20c96a9b2aaf9ac09094b.tar.bz2
IT.starlight-c6a4bcb7982c54c513f20c96a9b2aaf9ac09094b.zip
Add Expressive Code to Starlight (#742)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> Co-authored-by: HiDeoo <494699+HiDeoo@users.noreply.github.com> Co-authored-by: Kevin Zuniga Cuellar <46791833+kevinzunigacuellar@users.noreply.github.com> Co-authored-by: Lorenzo Lewis <15347255+lorenzolewis@users.noreply.github.com> Co-authored-by: Genteure <11240579+Genteure@users.noreply.github.com> Co-authored-by: trueberryless <99918022+trueberryless@users.noreply.github.com>
-rw-r--r--.changeset/sweet-berries-begin.md38
-rw-r--r--docs/src/content/docs/guides/authoring-content.md145
-rw-r--r--docs/src/content/docs/guides/i18n.mdx11
-rw-r--r--docs/src/content/docs/reference/configuration.mdx66
-rw-r--r--packages/starlight/index.ts10
-rw-r--r--packages/starlight/integrations/asides.ts30
-rw-r--r--packages/starlight/integrations/expressive-code/exports.ts36
-rw-r--r--packages/starlight/integrations/expressive-code/index.ts152
-rw-r--r--packages/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc1834
-rw-r--r--packages/starlight/integrations/expressive-code/themes/night-owl-light.jsonc1730
-rw-r--r--packages/starlight/integrations/expressive-code/theming.ts109
-rw-r--r--packages/starlight/integrations/expressive-code/translations.ts26
-rw-r--r--packages/starlight/integrations/shared/pathToLocale.ts32
-rw-r--r--packages/starlight/package.json2
-rw-r--r--packages/starlight/schemas/expressiveCode.ts11
-rw-r--r--packages/starlight/schemas/i18n.ts26
-rw-r--r--packages/starlight/utils/user-config.ts7
-rw-r--r--pnpm-lock.yaml66
18 files changed, 4298 insertions, 33 deletions
diff --git a/.changeset/sweet-berries-begin.md b/.changeset/sweet-berries-begin.md
new file mode 100644
index 00000000..2f9ffab8
--- /dev/null
+++ b/.changeset/sweet-berries-begin.md
@@ -0,0 +1,38 @@
+---
+'@astrojs/starlight': minor
+---
+
+Adds Expressive Code as Starlight’s default code block renderer
+
+⚠️ **Potentially breaking change:**
+This addition changes how Markdown code blocks are rendered. By default, Starlight will now use [Expressive Code](https://github.com/expressive-code/expressive-code/tree/main/packages/astro-expressive-code).
+If you were already customizing how code blocks are rendered and don't want to use the [features provided by Expressive Code](https://starlight.astro.build/guides/authoring-content/#expressive-code-features), you can preserve the previous behavior by setting the new config option `expressiveCode` to `false`.
+
+If you had previously added Expressive Code manually to your Starlight project, you can now remove the manual set-up in `astro.config.mjs`:
+
+- Move your configuration to Starlight’s new `expressiveCode` option.
+- Remove the `astro-expressive-code` integration.
+
+For example:
+
+```diff
+import starlight from '@astrojs/starlight';
+import { defineConfig } from 'astro/config';
+- import expressiveCode from 'astro-expressive-code';
+
+export default defineConfig({
+ integrations: [
+- expressiveCode({
+- themes: ['rose-pine'],
+- }),
+ starlight({
+ title: 'My docs',
++ expressiveCode: {
++ themes: ['rose-pine'],
++ },
+ }),
+ ],
+});
+```
+
+Note that the built-in Starlight version of Expressive Code sets some opinionated defaults that are different from the `astro-expressive-code` defaults. You may need to set some `styleOverrides` if you wish to keep styles exactly the same.
diff --git a/docs/src/content/docs/guides/authoring-content.md b/docs/src/content/docs/guides/authoring-content.md
index 52f2b8b3..37ddc2ba 100644
--- a/docs/src/content/docs/guides/authoring-content.md
+++ b/docs/src/content/docs/guides/authoring-content.md
@@ -202,9 +202,148 @@ var fun = function lang(l) {
```
````
-```md
-Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
-```
+### Expressive Code features
+
+Starlight uses [Expressive Code](https://github.com/expressive-code/expressive-code/tree/main/packages/astro-expressive-code) to extend formatting possibilities for code blocks.
+Expressive Code’s text markers and window frames plugins are enabled by default.
+Code block rendering can be configured using Starlight’s [`expressiveCode` configuration option](/reference/configuration/#expressivecode).
+
+#### Text markers
+
+You can highlight specific lines or parts of your code blocks using [Expressive Code text markers](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#usage-in-markdown--mdx-documents) on the opening line of your code block.
+Use curly braces (`{ }`) to highlight entire lines, and quotation marks to highlight strings of text.
+
+There are three highlighting styles: neutral for calling attention to code, green for indicating inserted code, and red for indicating deleted code.
+Both text and entire lines can be marked using the default marker, or in combination with `ins=` and `del=` to produce the desired highlighting.
+
+Expressive Code provides several options for customizing the visual appearance of your code samples.
+Many of these can be combined, for highly illustrative code samples.
+Please explore the [Expressive Code documentation](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md) for the extensive options available.
+Some of the most common examples are shown below:
+
+- [Mark entire lines & line ranges using the `{ }` marker](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#marking-entire-lines--line-ranges):
+
+ ```js {2-3}
+ function demo() {
+ // This line (#2) and the next one are highlighted
+ return 'This is line #3 of this snippet';
+ }
+ ```
+
+ ````md
+ ```js {2-3}
+ function demo() {
+ // This line (#2) and the next one are highlighted
+ return 'This is line #3 of this snippet';
+ }
+ ```
+ ````
+
+- [Mark selections of text using the `" "` marker or regular expressions](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#marking-entire-lines--line-ranges):
+
+ ```js "Individual terms" /Even.*supported/
+ // Individual terms can be highlighted, too
+ function demo() {
+ return 'Even regular expressions are supported';
+ }
+ ```
+
+ ````md
+ ```js "Individual terms" /Even.*supported/
+ // Individual terms can be highlighted, too
+ function demo() {
+ return 'Even regular expressions are supported';
+ }
+ ```
+ ````
+
+- [Mark text or lines as inserted or deleted with `ins` or `del`](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#selecting-marker-types-mark-ins-del):
+
+ ```js "return true;" ins="inserted" del="deleted"
+ function demo() {
+ console.log('These are inserted and deleted marker types');
+ // The return statement uses the default marker type
+ return true;
+ }
+ ```
+
+ ````md
+ ```js "return true;" ins="inserted" del="deleted"
+ function demo() {
+ console.log('These are inserted and deleted marker types');
+ // The return statement uses the default marker type
+ return true;
+ }
+ ```
+ ````
+
+- [Combine syntax highlighting with `diff`-like syntax](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#combining-syntax-highlighting-with-diff-like-syntax):
+
+ ```diff lang="js"
+ function thisIsJavaScript() {
+ // This entire block gets highlighted as JavaScript,
+ // and we can still add diff markers to it!
+ - console.log('Old code to be removed')
+ + console.log('New and shiny code!')
+ }
+ ```
+
+ ````md
+ ```diff lang="js"
+ function thisIsJavaScript() {
+ // This entire block gets highlighted as JavaScript,
+ // and we can still add diff markers to it!
+ - console.log('Old code to be removed')
+ + console.log('New and shiny code!')
+ }
+ ```
+ ````
+
+#### Frames and titles
+
+Code blocks can be rendered inside a window-like frame.
+A frame that looks like a terminal window will be used for shell scripting languages (e.g. `bash` or `sh`).
+Other languages display inside a code editor-style frame if they include a title.
+
+A code block’s optional title can be set either with a `title="..."` attribute following the code block's opening backticks and language identifier, or with a file name comment in the first lines of the code.
+
+- [Add a file name tab with a comment](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-frames/README.md#code-editor-window-frames)
+
+ ```js
+ // my-test-file.js
+ console.log('Hello World!');
+ ```
+
+ ````md
+ ```js
+ // my-test-file.js
+ console.log('Hello World!');
+ ```
+ ````
+
+- [Add a title to a Terminal window](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-frames/README.md#terminal-window-frames)
+
+ ```bash title="Installing dependencies…"
+ npm install
+ ```
+
+ ````md
+ ```bash title="Installing dependencies…"
+ npm install
+ ```
+ ````
+
+- [Disable window frames with `frame="none"`](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-frames/README.md#overriding-frame-types)
+
+ ```bash frame="none"
+ echo "This is not rendered as a terminal despite using the bash language"
+ ```
+
+ ````md
+ ```bash frame="none"
+ echo "This is not rendered as a terminal despite using the bash language"
+ ```
+ ````
## Other common Markdown features
diff --git a/docs/src/content/docs/guides/i18n.mdx b/docs/src/content/docs/guides/i18n.mdx
index 587e034b..42166c7a 100644
--- a/docs/src/content/docs/guides/i18n.mdx
+++ b/docs/src/content/docs/guides/i18n.mdx
@@ -205,6 +205,17 @@ You can provide translations for additional languages you support — or overrid
}
```
+ Starlight’s code blocks are powered by the [Expressive Code](https://github.com/expressive-code/expressive-code) library.
+ You can set translations for its UI strings in the same JSON file using `expressiveCode` keys:
+
+ ```json
+ {
+ "expressiveCode.copyButtonCopied": "Copied!",
+ "expressiveCode.copyButtonTooltip": "Copy to clipboard",
+ "expressiveCode.terminalWindowFallbackTitle": "Terminal window"
+ }
+ ```
+
Starlight’s search modal is powered by the [Pagefind](https://pagefind.app/) library.
You can set translations for Pagefind’s UI in the same JSON file using `pagefind` keys:
diff --git a/docs/src/content/docs/reference/configuration.mdx b/docs/src/content/docs/reference/configuration.mdx
index 8d1dfe6a..9f27bf36 100644
--- a/docs/src/content/docs/reference/configuration.mdx
+++ b/docs/src/content/docs/reference/configuration.mdx
@@ -346,6 +346,72 @@ starlight({
});
```
+### `expressiveCode`
+
+**type:** `StarlightExpressiveCodeOptions | boolean`
+**default:** `true`
+
+Starlight uses [Expressive Code](https://github.com/expressive-code/expressive-code/tree/main/packages/astro-expressive-code) to render code blocks and add support for highlighting parts of code examples, adding filenames to code blocks, and more.
+See the [“Code blocks” guide](/guides/authoring-content/#code-blocks) to learn how to use Expressive Code syntax in your Markdown and MDX content.
+
+You can use any of the standard [Expressive Code configuration options](https://github.com/expressive-code/expressive-code/blob/main/packages/astro-expressive-code/README.md#configuration) as well as some Starlight-specific properties, by setting them in Starlight’s `expressiveCode` option.
+For example, set Expressive Code’s `styleOverrides` option to override the default CSS. This enables customizations like giving your code blocks rounded corners:
+
+```js ins={2-4}
+starlight({
+ expressiveCode: {
+ styleOverrides: { borderRadius: '0.5rem' },
+ },
+});
+```
+
+If you want to disable Expressive Code, set `expressiveCode: false` in your Starlight config:
+
+```js ins={2}
+starlight({
+ expressiveCode: false,
+});
+```
+
+In addition to the standard Expressive Code options, you can also set the following Starlight-specific properties in your `expressiveCode` config to further customize theme behavior for your code blocks :
+
+#### `themes`
+
+**type:** `Array<string | ThemeObject | ExpressiveCodeTheme>`
+**default:** `['starlight-dark', 'starlight-light']`
+
+Set the themes used to style code blocks.
+See the [Expressive Code `themes` documentation](https://github.com/expressive-code/expressive-code/blob/main/packages/astro-expressive-code/README.md#themes) for details of the supported theme formats.
+
+Starlight uses the dark and light variants of Sarah Drasner’s [Night Owl theme](https://github.com/sdras/night-owl-vscode-theme) by default.
+
+If you provide at least one dark and one light theme, Starlight will automatically keep the active code block theme in sync with the current site theme.
+Configure this behavior with the [`useStarlightDarkModeSwitch`](#usestarlightdarkmodeswitch) option.
+
+#### `useStarlightDarkModeSwitch`
+
+**type:** `boolean`
+**default:** `true`
+
+When `true`, code blocks automatically switch between light and dark themes when the site theme changes.
+When `false`, you must manually add CSS to handle switching between multiple themes.
+
+:::note
+When setting `themes`, you must provide at least one dark and one light theme for the Starlight dark mode switch to work.
+:::
+
+#### `useStarlightUiThemeColors`
+
+**type:** `boolean`
+**default:** `true` if `themes` is not set, otherwise `false`
+
+When `true`, Starlight's CSS variables are used for the colors of code block UI elements (backgrounds, buttons, shadows etc.), matching the [site color theme](/guides/css-and-tailwind/#theming).
+When `false`, the colors provided by the active syntax highlighting theme are used for these elements.
+
+:::note
+When using custom themes and setting this to `true`, you must provide at least one dark and one light theme to ensure proper color contrast.
+:::
+
### `head`
**type:** [`HeadConfig[]`](#headconfig)
diff --git a/packages/starlight/index.ts b/packages/starlight/index.ts
index 01dc25f1..64567b38 100644
--- a/packages/starlight/index.ts
+++ b/packages/starlight/index.ts
@@ -4,6 +4,7 @@ import { spawn } from 'node:child_process';
import { dirname, relative } from 'node:path';
import { fileURLToPath } from 'node:url';
import { starlightAsides } from './integrations/asides';
+import { starlightExpressiveCode } from './integrations/expressive-code';
import { starlightSitemap } from './integrations/sitemap';
import { vitePluginStarlightUserConfig } from './integrations/virtual-user-config';
import { errorMap } from './utils/error-map';
@@ -37,6 +38,15 @@ export default function StarlightIntegration(opts: StarlightUserConfig): AstroIn
entryPoint: '@astrojs/starlight/index.astro',
});
const integrations: AstroIntegration[] = [];
+ if (!config.integrations.find(({ name }) => name === 'astro-expressive-code')) {
+ integrations.push(
+ ...starlightExpressiveCode({
+ starlightConfig: userConfig,
+ astroConfig: config,
+ useTranslations,
+ })
+ );
+ }
if (!config.integrations.find(({ name }) => name === '@astrojs/sitemap')) {
integrations.push(starlightSitemap(userConfig));
}
diff --git a/packages/starlight/integrations/asides.ts b/packages/starlight/integrations/asides.ts
index a97a610a..9d0c9bf7 100644
--- a/packages/starlight/integrations/asides.ts
+++ b/packages/starlight/integrations/asides.ts
@@ -7,6 +7,7 @@ import { remove } from 'unist-util-remove';
import { visit } from 'unist-util-visit';
import type { StarlightConfig } from '../types';
import type { createTranslationSystemFromFs } from '../utils/translations-fs';
+import { pathToLocale } from './shared/pathToLocale';
interface AsidesOptions {
starlightConfig: { locales: StarlightConfig['locales'] };
@@ -14,33 +15,6 @@ interface AsidesOptions {
useTranslations: ReturnType<typeof createTranslationSystemFromFs>;
}
-function pathToLocale(
- slug: string | undefined,
- config: AsidesOptions['starlightConfig']
-): string | undefined {
- const locales = Object.keys(config.locales || {});
- const baseSegment = slug?.split('/')[0];
- if (baseSegment && locales.includes(baseSegment)) return baseSegment;
- return undefined;
-}
-
-/** get current lang from file full path */
-function getLocaleFromPath(
- unformattedPath: string | undefined,
- { starlightConfig, astroConfig }: AsidesOptions
-): string | undefined {
- const srcDir = new URL(astroConfig.srcDir, astroConfig.root);
- const docsDir = new URL('content/docs/', srcDir);
- const path = unformattedPath
- // Format path to unix style path.
- ?.replace(/\\/g, '/')
- // Strip docs path leaving only content collection file ID.
- // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md
- .replace(docsDir.pathname, '');
- const locale = pathToLocale(path, starlightConfig);
- return locale;
-}
-
/** Hacky function that generates an mdast HTML tree ready for conversion to HTML by rehype. */
function h(el: string, attrs: Properties = {}, children: any[] = []): P {
const { tagName, properties } = _h(el, attrs);
@@ -123,7 +97,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
};
const transformer: Transformer<Root> = (tree, file) => {
- const locale = getLocaleFromPath(file.history[0], options);
+ const locale = pathToLocale(file.history[0], options);
const t = options.useTranslations(locale);
visit(tree, (node, index, parent) => {
if (!parent || index === null || node.type !== 'containerDirective') {
diff --git a/packages/starlight/integrations/expressive-code/exports.ts b/packages/starlight/integrations/expressive-code/exports.ts
new file mode 100644
index 00000000..9955b8e0
--- /dev/null
+++ b/packages/starlight/integrations/expressive-code/exports.ts
@@ -0,0 +1,36 @@
+/**
+ * @file This file is exported by Starlight as `@astrojs/starlight/expressive-code`
+ * and can be used in your site's configuration to customize Expressive Code.
+ *
+ * It provides access to all of the Expressive Code classes and functions without having
+ * to install `astro-expressive-code` as an additional dependency into your project
+ * (and thereby risiking version conflicts).
+ *
+ * For example, you can use this to load custom themes from a JSONC file (JSON with comments)
+ * that would otherwise be difficult to import, and pass them to the `themes` option:
+ *
+ * @example
+ * ```js
+ * // astro.config.mjs
+ * import fs from 'node:fs';
+ * import { defineConfig } from 'astro/config';
+ * import starlight from '@astrojs/starlight';
+ * import { ExpressiveCodeTheme } from '@astrojs/starlight/expressive-code';
+ *
+ * const jsoncString = fs.readFileSync(new URL(`./my-theme.jsonc`, import.meta.url), 'utf-8');
+ * const myTheme = ExpressiveCodeTheme.fromJSONString(jsoncString);
+ *
+ * export default defineConfig({
+ * integrations: [
+ * starlight({
+ * title: 'My Starlight site',
+ * expressiveCode: {
+ * themes: [myTheme],
+ * },
+ * }),
+ * ],
+ * });
+ * ```
+ */
+
+export * from 'astro-expressive-code';
diff --git a/packages/starlight/integrations/expressive-code/index.ts b/packages/starlight/integrations/expressive-code/index.ts
new file mode 100644
index 00000000..bbe2fdf6
--- /dev/null
+++ b/packages/starlight/integrations/expressive-code/index.ts
@@ -0,0 +1,152 @@
+import {
+ astroExpressiveCode,
+ type AstroExpressiveCodeOptions,
+ addClassName,
+} from 'astro-expressive-code';
+import type { AstroConfig, AstroIntegration } from 'astro';
+import type { StarlightConfig } from '../../types';
+import type { createTranslationSystemFromFs } from '../../utils/translations-fs';
+import { pathToLocale } from '../shared/pathToLocale';
+import { applyStarlightUiThemeColors, preprocessThemes, type ThemeObjectOrBundledThemeName } from './theming';
+import { addTranslations } from './translations';
+
+export type StarlightExpressiveCodeOptions = Omit<AstroExpressiveCodeOptions, 'themes'> & {
+ /**
+ * Set the themes used to style code blocks.
+ *
+ * See the [Expressive Code `themes` documentation](https://github.com/expressive-code/expressive-code/blob/main/packages/astro-expressive-code/README.md#themes)
+ * for details of the supported theme formats.
+ *
+ * Starlight uses the dark and light variants of Sarah Drasner’s
+ * [Night Owl theme](https://github.com/sdras/night-owl-vscode-theme) by default.
+ *
+ * If you provide at least one dark and one light theme, Starlight will automatically keep
+ * the active code block theme in sync with the current site theme. Configure this behavior
+ * with the [`useStarlightDarkModeSwitch`](#usestarlightdarkmodeswitch) option.
+ *
+ * Defaults to `['starlight-dark', 'starlight-light']`.
+ */
+ themes?: ThemeObjectOrBundledThemeName[] | undefined
+ /**
+ * When `true`, code blocks automatically switch between light and dark themes when the
+ * site theme changes.
+ *
+ * When `false`, you must manually add CSS to handle switching between multiple themes.
+ *
+ * **Note**: When setting `themes`, you must provide at least one dark and one light theme
+ * for the Starlight dark mode switch to work.
+ *
+ * Defaults to `true`.
+ */
+ useStarlightDarkModeSwitch?: boolean | undefined;
+ /**
+ * When `true`, Starlight's CSS variables are used for the colors of code block UI elements
+ * (backgrounds, buttons, shadows etc.), matching the
+ * [site color theme](/guides/css-and-tailwind/#theming).
+ *
+ * When `false`, the colors provided by the active syntax highlighting theme are used for
+ * these elements.
+ *
+ * Defaults to `true` if the `themes` option is not set (= you are using Starlight's
+ * default themes), and `false` otherwise.
+ *
+ * **Note**: When manually setting this to `true` with your custom set of `themes`, you must
+ * provide at least one dark and one light theme to ensure proper color contrast.
+ */
+ useStarlightUiThemeColors?: boolean | undefined;
+};
+
+export const starlightExpressiveCode = ({
+ astroConfig,
+ starlightConfig,
+ useTranslations,
+}: {
+ astroConfig: Pick<AstroConfig, 'root' | 'srcDir'>;
+ starlightConfig: StarlightConfig;
+ useTranslations: ReturnType<typeof createTranslationSystemFromFs>;
+}): AstroIntegration[] => {
+ const { locales, expressiveCode } = starlightConfig;
+ if (expressiveCode === false) return [];
+ const config: StarlightExpressiveCodeOptions =
+ typeof expressiveCode === 'object' ? expressiveCode : {};
+
+ const {
+ themes: themesInput,
+ customizeTheme,
+ styleOverrides: { textMarkers: textMarkersStyleOverrides, ...otherStyleOverrides } = {},
+ useStarlightDarkModeSwitch,
+ useStarlightUiThemeColors = config.themes === undefined,
+ plugins = [],
+ ...rest
+ } = config;
+
+ // Handle the `themes` option
+ const themes = preprocessThemes(themesInput);
+ if (useStarlightUiThemeColors === true && themes.length < 2) {
+ console.warn(
+ `*** Warning: Using the config option "useStarlightUiThemeColors: true" ` +
+ `with a single theme is not recommended. For better color contrast, ` +
+ `please provide at least one dark and one light theme.\n`
+ );
+ }
+
+ // Add the `not-content` class to all rendered blocks to prevent them from being affected
+ // by Starlight's default content styles
+ plugins.push({
+ name: 'Starlight Plugin',
+ hooks: {
+ postprocessRenderedBlock: ({ renderData }) => {
+ addClassName(renderData.blockAst, 'not-content');
+ },
+ },
+ });
+
+ // Add Expressive Code UI translations (if any) for all defined locales
+ addTranslations(locales, useTranslations);
+
+ return [
+ astroExpressiveCode({
+ themes,
+ customizeTheme: (theme) => {
+ if (useStarlightUiThemeColors) {
+ applyStarlightUiThemeColors(theme);
+ }
+ if (customizeTheme) {
+ theme = customizeTheme(theme) ?? theme;
+ }
+ return theme;
+ },
+ themeCssSelector: (theme, { styleVariants }) => {
+ // If one dark and one light theme are available, and the user has not disabled it,
+ // generate theme CSS selectors compatible with Starlight's dark mode switch
+ if (useStarlightDarkModeSwitch !== false && styleVariants.length >= 2) {
+ const baseTheme = styleVariants[0]?.theme;
+ const altTheme = styleVariants.find((v) => v.theme.type !== baseTheme?.type)?.theme;
+ if (theme === baseTheme || theme === altTheme) return `[data-theme='${theme.type}']`;
+ }
+ // Return the default selector
+ return `[data-theme='${theme.name}']`;
+ },
+ styleOverrides: {
+ borderRadius: '0px',
+ borderWidth: '1px',
+ codePaddingBlock: '0.75rem',
+ codePaddingInline: '1rem',
+ codeFontFamily: 'var(--__sl-font-mono)',
+ codeFontSize: 'var(--sl-text-code)',
+ codeLineHeight: 'var(--sl-line-height)',
+ uiFontFamily: 'var(--__sl-font)',
+ textMarkers: {
+ lineDiffIndicatorMarginLeft: '0.25rem',
+ defaultChroma: '45',
+ backgroundOpacity: '60%',
+ ...textMarkersStyleOverrides,
+ },
+ ...otherStyleOverrides,
+ },
+ getBlockLocale: ({ file }) => pathToLocale(file.path, { starlightConfig, astroConfig }),
+ plugins,
+ ...rest,
+ }),
+ ];
+};
diff --git a/packages/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc b/packages/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc
new file mode 100644
index 00000000..a1b87a5c
--- /dev/null
+++ b/packages/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc
@@ -0,0 +1,1834 @@
+/**
+ * Night Owl VS Code Theme - https://github.com/sdras/night-owl-vscode-theme
+ *
+ * MIT License
+ *
+ * Copyright (c) 2018 Sarah Drasner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+{
+ "name": "Night Owl No Italics",
+ "type": "dark",
+ "semanticHighlighting": false,
+ "colors": {
+ "contrastBorder": "#122d42",
+ "focusBorder": "#122d42",
+ "foreground": "#d6deeb",
+ "widget.shadow": "#011627",
+ "selection.background": "#4373c2",
+ "errorForeground": "#EF5350",
+ "button.background": "#7e57c2cc",
+ "button.foreground": "#ffffffcc",
+ "button.hoverBackground": "#7e57c2",
+ "dropdown.background": "#011627",
+ "dropdown.border": "#5f7e97",
+ "dropdown.foreground": "#ffffffcc",
+ "input.background": "#0b253a",
+ "input.border": "#5f7e97",
+ "input.foreground": "#ffffffcc",
+ "input.placeholderForeground": "#5f7e97",
+ "inputOption.activeBorder": "#ffffffcc",
+ "punctuation.definition.generic.begin.html": "#ef5350f2",
+ "inputValidation.errorBackground": "#AB0300F2",
+ "inputValidation.errorBorder": "#EF5350",
+ "inputValidation.infoBackground": "#00589EF2",
+ "inputValidation.infoBorder": "#64B5F6",
+ "inputValidation.warningBackground": "#675700F2",
+ "inputValidation.warningBorder": "#FFCA28",
+ "scrollbar.shadow": "#010b14",
+ "scrollbarSlider.activeBackground": "#084d8180",
+ "scrollbarSlider.background": "#084d8180",
+ "scrollbarSlider.hoverBackground": "#084d8180",
+ "badge.background": "#5f7e97",
+ "badge.foreground": "#ffffff",
+ "progress.background": "#7e57c2",
+ "breadcrumb.foreground": "#A599E9",
+ "breadcrumb.focusForeground": "#ffffff",
+ "breadcrumb.activeSelectionForeground": "#FFFFFF",
+ "breadcrumbPicker.background": "#001122",
+ "list.activeSelectionBackground": "#234d708c",
+ "list.activeSelectionForeground": "#ffffff",
+ "list.invalidItemForeground": "#975f94",
+ "list.dropBackground": "#011627",
+ "list.focusBackground": "#010d18",
+ "list.focusForeground": "#ffffff",
+ "list.highlightForeground": "#ffffff",
+ "list.hoverBackground": "#011627",
+ "list.hoverForeground": "#ffffff",
+ "list.inactiveSelectionBackground": "#0e293f",
+ "list.inactiveSelectionForeground": "#5f7e97",
+ "activityBar.background": "#011627",
+ "activityBar.dropBackground": "#5f7e97",
+ "activityBar.foreground": "#5f7e97",
+ "activityBar.border": "#011627",
+ "activityBarBadge.background": "#44596b",
+ "activityBarBadge.foreground": "#ffffff",
+ "sideBar.background": "#011627",
+ "sideBar.foreground": "#89a4bb",
+ "sideBar.border": "#011627",
+ "sideBarTitle.foreground": "#5f7e97",
+ "sideBarSectionHeader.background": "#011627",
+ "sideBarSectionHeader.foreground": "#5f7e97",
+ "editorGroup.emptyBackground": "#011627",
+ "editorGroup.border": "#011627",
+ "editorGroup.dropBackground": "#7e57c273",
+ "editorGroupHeader.noTabsBackground": "#011627",
+ "editorGroupHeader.tabsBackground": "#011627",
+ "editorGroupHeader.tabsBorder": "#262A39",
+ "tab.activeBackground": "#0b2942",
+ "tab.activeForeground": "#d2dee7",
+ "tab.border": "#272B3B",
+ "tab.activeBorder": "#262A39",
+ "tab.unfocusedActiveBorder": "#262A39",
+ "tab.inactiveBackground": "#01111d",
+ "tab.inactiveForeground": "#5f7e97",
+ "tab.unfocusedActiveForeground": "#5f7e97",
+ "tab.unfocusedInactiveForeground": "#5f7e97",
+ "editor.background": "#011627",
+ "editor.foreground": "#d6deeb",
+ "editorLineNumber.foreground": "#4b6479",
+ "editorLineNumber.activeForeground": "#C5E4FD",
+ "editorCursor.foreground": "#80a4c2",
+ "editor.selectionBackground": "#1d3b53",
+ "editor.selectionHighlightBackground": "#5f7e9779",
+ "editor.inactiveSelectionBackground": "#7e57c25a",
+ "editor.wordHighlightBackground": "#f6bbe533",
+ "editor.wordHighlightStrongBackground": "#e2a2f433",
+ "editor.findMatchBackground": "#5f7e9779",
+ "editor.findMatchHighlightBackground": "#1085bb5d",
+ "editor.findRangeHighlightBackground": null,
+ "editor.hoverHighlightBackground": "#7e57c25a",
+ "editor.lineHighlightBackground": "#0003",
+ "editor.lineHighlightBorder": null,
+ "editorLink.activeForeground": null,
+ "editor.rangeHighlightBackground": "#7e57c25a",
+ "editorWhitespace.foreground": null,
+ "editorIndentGuide.background": "#5e81ce52",
+ "editorIndentGuide.activeBackground": "#7E97AC",
+ "editorRuler.foreground": "#5e81ce52",
+ "editorCodeLens.foreground": "#5e82ceb4",
+ "editorBracketMatch.background": "#5f7e974d",
+ "editorBracketMatch.border": null,
+ "editorOverviewRuler.currentContentForeground": "#7e57c2",
+ "editorOverviewRuler.incomingContentForeground": "#7e57c2",
+ "editorOverviewRuler.commonContentForeground": "#7e57c2",
+ "editorError.foreground": "#EF5350",
+ "editorError.border": null,
+ "editorWarning.foreground": "#b39554",
+ "editorWarning.border": null,
+ "editorGutter.background": "#011627",
+ "editorGutter.modifiedBackground": "#e2b93d",
+ "editorGutter.addedBackground": "#9CCC65",
+ "editorGutter.deletedBackground": "#EF5350",
+ "diffEditor.insertedTextBackground": "#99b76d23",
+ "diffEditor.insertedTextBorder": "#c5e47833",
+ "diffEditor.removedTextBackground": "#ef535033",
+ "diffEditor.removedTextBorder": "#ef53504d",
+ "editorWidget.background": "#021320",
+ "editorWidget.border": "#5f7e97",
+ "editorSuggestWidget.background": "#2C3043",
+ "editorSuggestWidget.border": "#2B2F40",
+ "editorSuggestWidget.foreground": "#d6deeb",
+ "editorSuggestWidget.highlightForeground": "#ffffff",
+ "editorSuggestWidget.selectedBackground": "#5f7e97",
+ "editorHoverWidget.background": "#011627",
+ "editorHoverWidget.border": "#5f7e97",
+ "debugExceptionWidget.background": "#011627",
+ "debugExceptionWidget.border": "#5f7e97",
+ "editorMarkerNavigation.background": "#0b2942",
+ "editorMarkerNavigationError.background": "#EF5350",
+ "editorMarkerNavigationWarning.background": "#FFCA28",
+ "peekView.border": "#5f7e97",
+ "peekViewEditor.background": "#011627",
+ "peekViewEditor.matchHighlightBackground": "#7e57c25a",
+ "peekViewResult.background": "#011627",
+ "peekViewResult.fileForeground": "#5f7e97",
+ "peekViewResult.lineForeground": "#5f7e97",
+ "peekViewResult.matchHighlightBackground": "#ffffffcc",
+ "peekViewResult.selectionBackground": "#2E3250",
+ "peekViewResult.selectionForeground": "#5f7e97",
+ "peekViewTitle.background": "#011627",
+ "peekViewTitleDescription.foreground": "#697098",
+ "peekViewTitleLabel.foreground": "#5f7e97",
+ "merge.currentHeaderBackground": "#5f7e97",
+ "merge.currentContentBackground": null,
+ "merge.incomingHeaderBackground": "#7e57c25a",
+ "merge.incomingContentBackground": null,
+ "merge.border": null,
+ "panel.background": "#011627",
+ "panel.border": "#5f7e97",
+ "panelTitle.activeBorder": "#5f7e97",
+ "panelTitle.activeForeground": "#ffffffcc",
+ "panelTitle.inactiveForeground": "#d6deeb80",
+ "statusBar.background": "#011627",
+ "statusBar.foreground": "#5f7e97",
+ "statusBar.border": "#262A39",
+ "statusBar.debuggingBackground": "#202431",
+ "statusBar.debuggingForeground": null,
+ "statusBar.debuggingBorder": "#1F2330",
+ "statusBar.noFolderForeground": null,
+ "statusBar.noFolderBackground": "#011627",
+ "statusBar.noFolderBorder": "#25293A",
+ "statusBarItem.activeBackground": "#202431",
+ "statusBarItem.hoverBackground": "#202431",
+ "statusBarItem.prominentBackground": "#202431",
+ "statusBarItem.prominentHoverBackground": "#202431",
+ "titleBar.activeBackground": "#011627",
+ "titleBar.activeForeground": "#eeefff",
+ "titleBar.inactiveBackground": "#010e1a",
+ "titleBar.inactiveForeground": null,
+ "notifications.background": "#01111d",
+ "notifications.border": "#262a39",
+ "notificationCenter.border": "#262a39",
+ "notificationToast.border": "#262a39",
+ "notifications.foreground": "#ffffffcc",
+ "notificationLink.foreground": "#80CBC4",
+ "extensionButton.prominentForeground": "#ffffffcc",
+ "extensionButton.prominentBackground": "#7e57c2cc",
+ "extensionButton.prominentHoverBackground": "#7e57c2",
+ "pickerGroup.foreground": "#d1aaff",
+ "pickerGroup.border": "#011627",
+ "terminal.ansiWhite": "#ffffff",
+ "terminal.ansiBlack": "#011627",
+ "terminal.ansiBlue": "#82AAFF",
+ "terminal.ansiCyan": "#21c7a8",
+ "terminal.ansiGreen": "#22da6e",
+ "terminal.ansiMagenta": "#C792EA",
+ "terminal.ansiRed": "#EF5350",
+ "terminal.ansiYellow": "#c5e478",
+ "terminal.ansiBrightWhite": "#ffffff",
+ "terminal.ansiBrightBlack": "#575656",
+ "terminal.ansiBrightBlue": "#82AAFF",
+ "terminal.ansiBrightCyan": "#7fdbca",
+ "terminal.ansiBrightGreen": "#22da6e",
+ "terminal.ansiBrightMagenta": "#C792EA",
+ "terminal.ansiBrightRed": "#EF5350",
+ "terminal.ansiBrightYellow": "#ffeb95",
+ "terminal.selectionBackground": "#1b90dd4d",
+ "terminalCursor.background": "#234d70",
+ "textCodeBlock.background": "#4f4f4f",
+ "debugToolBar.background": "#011627",
+ "welcomePage.buttonBackground": "#011627",
+ "welcomePage.buttonHoverBackground": "#011627",
+ "walkThrough.embeddedEditorBackground": "#011627",
+ "gitDecoration.modifiedResourceForeground": "#a2bffc",
+ "gitDecoration.deletedResourceForeground": "#EF535090",
+ "gitDecoration.untrackedResourceForeground": "#c5e478ff",
+ "gitDecoration.ignoredResourceForeground": "#395a75",
+ "gitDecoration.conflictingResourceForeground": "#ffeb95cc",
+ "source.elm": "#5f7e97",
+ "string.quoted.single.js": "#ffffff",
+ "meta.objectliteral.js": "#82AAFF"
+ },
+ "tokenColors": [
+ {
+ "name": "Changed",
+ "scope": [
+ "markup.changed",
+ "meta.diff.header.git",
+ "meta.diff.header.from-file",
+ "meta.diff.header.to-file"
+ ],
+ "settings": {
+ "foreground": "#a2bffc"
+ }
+ },
+ {
+ "name": "Deleted",
+ "scope": "markup.deleted.diff",
+ "settings": {
+ "foreground": "#EF535090"
+ }
+ },
+ {
+ "name": "Inserted",
+ "scope": "markup.inserted.diff",
+ "settings": {
+ "foreground": "#c5e478ff"
+ }
+ },
+ {
+ "name": "Global settings",
+ "settings": {
+ "background": "#011627",
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "Comment",
+ "scope": "comment",
+ "settings": {
+ "foreground": "#637777",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "String",
+ "scope": "string",
+ "settings": {
+ "foreground": "#ecc48d"
+ }
+ },
+ {
+ "name": "String Quoted",
+ "scope": ["string.quoted", "variable.other.readwrite.js"],
+ "settings": {
+ "foreground": "#ecc48d"
+ }
+ },
+ {
+ "name": "Support Constant Math",
+ "scope": "support.constant.math",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Number",
+ "scope": ["constant.numeric", "constant.character.numeric"],
+ "settings": {
+ "foreground": "#F78C6C",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Built-in constant",
+ "scope": [
+ "constant.language",
+ "punctuation.definition.constant",
+ "variable.other.constant"
+ ],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "User-defined constant",
+ "scope": ["constant.character", "constant.other"],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Constant Character Escape",
+ "scope": "constant.character.escape",
+ "settings": {
+ "foreground": "#F78C6C"
+ }
+ },
+ {
+ "name": "RegExp String",
+ "scope": ["string.regexp", "string.regexp keyword.other"],
+ "settings": {
+ "foreground": "#5ca7e4"
+ }
+ },
+ {
+ "name": "Comma in functions",
+ "scope": "meta.function punctuation.separator.comma",
+ "settings": {
+ "foreground": "#5f7e97"
+ }
+ },
+ {
+ "name": "Variable",
+ "scope": "variable",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Keyword",
+ "scope": ["punctuation.accessor", "keyword"],
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Storage",
+ "scope": [
+ "storage",
+ "meta.var.expr",
+ "meta.class meta.method.declaration meta.var.expr storage.type.js",
+ "storage.type.property.js",
+ "storage.type.property.ts",
+ "storage.type.property.tsx"
+ ],
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Storage type",
+ "scope": "storage.type",
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "Storage type",
+ "scope": "storage.type.function.arrow.js",
+ "settings": {
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Class name",
+ "scope": ["entity.name.class", "meta.class entity.name.type.class"],
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "Inherited class",
+ "scope": "entity.other.inherited-class",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Function name",
+ "scope": "entity.name.function",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Meta Tag",
+ "scope": ["punctuation.definition.tag", "meta.tag"],
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "HTML Tag names",
+ "scope": [
+ "entity.name.tag",
+ "meta.tag.other.html",
+ "meta.tag.other.js",
+ "meta.tag.other.tsx",
+ "entity.name.tag.tsx",
+ "entity.name.tag.js",
+ "entity.name.tag",
+ "meta.tag.js",
+ "meta.tag.tsx",
+ "meta.tag.html"
+ ],
+ "settings": {
+ "foreground": "#caece6",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Tag attribute",
+ "scope": "entity.other.attribute-name",
+ "settings": {
+ "fontStyle": "",
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Entity Name Tag Custom",
+ "scope": "entity.name.tag.custom",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Library (function & constant)",
+ "scope": ["support.function", "support.constant"],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Support Constant Property Value meta",
+ "scope": "support.constant.meta.property-value",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Library class/type",
+ "scope": ["support.type", "support.class"],
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Support Variable DOM",
+ "scope": "support.variable.dom",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Invalid",
+ "scope": "invalid",
+ "settings": {
+ "background": "#ff2c83",
+ "foreground": "#ffffff"
+ }
+ },
+ {
+ "name": "Invalid deprecated",
+ "scope": "invalid.deprecated",
+ "settings": {
+ "foreground": "#ffffff",
+ "background": "#d3423e"
+ }
+ },
+ {
+ "name": "Keyword Operator",
+ "scope": "keyword.operator",
+ "settings": {
+ "foreground": "#7fdbca",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Keyword Operator Relational",
+ "scope": "keyword.operator.relational",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Keyword Operator Assignment",
+ "scope": "keyword.operator.assignment",
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "Keyword Operator Arithmetic",
+ "scope": "keyword.operator.arithmetic",
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "Keyword Operator Bitwise",
+ "scope": "keyword.operator.bitwise",
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "Keyword Operator Increment",
+ "scope": "keyword.operator.increment",
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "Keyword Operator Ternary",
+ "scope": "keyword.operator.ternary",
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "Double-Slashed Comment",
+ "scope": "comment.line.double-slash",
+ "settings": {
+ "foreground": "#637777"
+ }
+ },
+ {
+ "name": "Object",
+ "scope": "object",
+ "settings": {
+ "foreground": "#cdebf7"
+ }
+ },
+ {
+ "name": "Null",
+ "scope": "constant.language.null",
+ "settings": {
+ "foreground": "#ff5874"
+ }
+ },
+ {
+ "name": "Meta Brace",
+ "scope": "meta.brace",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "Meta Delimiter Period",
+ "scope": "meta.delimiter.period",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Punctuation Definition String",
+ "scope": "punctuation.definition.string",
+ "settings": {
+ "foreground": "#d9f5dd"
+ }
+ },
+ {
+ "name": "Punctuation Definition String Markdown",
+ "scope": "punctuation.definition.string.begin.markdown",
+ "settings": {
+ "foreground": "#ff5874"
+ }
+ },
+ {
+ "name": "Boolean",
+ "scope": "constant.language.boolean",
+ "settings": {
+ "foreground": "#ff5874"
+ }
+ },
+ {
+ "name": "Object Comma",
+ "scope": "object.comma",
+ "settings": {
+ "foreground": "#ffffff"
+ }
+ },
+ {
+ "name": "Variable Parameter Function",
+ "scope": "variable.parameter.function",
+ "settings": {
+ "foreground": "#7fdbca",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Support Type Property Name & entity name tags",
+ "scope": [
+ "support.type.vendor.property-name",
+ "support.constant.vendor.property-value",
+ "support.type.property-name",
+ "meta.property-list entity.name.tag"
+ ],
+ "settings": {
+ "foreground": "#80CBC4",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Entity Name tag reference in stylesheets",
+ "scope": "meta.property-list entity.name.tag.reference",
+ "settings": {
+ "foreground": "#57eaf1"
+ }
+ },
+ {
+ "name": "Constant Other Color RGB Value Punctuation Definition Constant",
+ "scope": "constant.other.color.rgb-value punctuation.definition.constant",
+ "settings": {
+ "foreground": "#F78C6C"
+ }
+ },
+ {
+ "name": "Constant Other Color",
+ "scope": "constant.other.color",
+ "settings": {
+ "foreground": "#FFEB95"
+ }
+ },
+ {
+ "name": "Keyword Other Unit",
+ "scope": "keyword.other.unit",
+ "settings": {
+ "foreground": "#FFEB95"
+ }
+ },
+ {
+ "name": "Meta Selector",
+ "scope": "meta.selector",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Entity Other Attribute Name Id",
+ "scope": "entity.other.attribute-name.id",
+ "settings": {
+ "foreground": "#FAD430"
+ }
+ },
+ {
+ "name": "Meta Property Name",
+ "scope": "meta.property-name",
+ "settings": {
+ "foreground": "#80CBC4"
+ }
+ },
+ {
+ "name": "Doctypes",
+ "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Punctuation Definition Parameters",
+ "scope": "punctuation.definition.parameters",
+ "settings": {
+ "foreground": "#d9f5dd"
+ }
+ },
+ {
+ "name": "Keyword Control Operator",
+ "scope": "keyword.control.operator",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Keyword Operator Logical",
+ "scope": "keyword.operator.logical",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Variable Instances",
+ "scope": [
+ "variable.instance",
+ "variable.other.instance",
+ "variable.readwrite.instance",
+ "variable.other.readwrite.instance",
+ "variable.other.property"
+ ],
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Variable Property Other object property",
+ "scope": ["variable.other.object.property"],
+ "settings": {
+ "foreground": "#faf39f",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Variable Property Other object",
+ "scope": ["variable.other.object.js"],
+ "settings": {
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Entity Name Function",
+ "scope": ["entity.name.function"],
+ "settings": {
+ "foreground": "#82AAFF",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby",
+ "scope": [
+ "keyword.control.conditional.js",
+ "keyword.operator.comparison",
+ "keyword.control.flow.js",
+ "keyword.control.flow.ts",
+ "keyword.control.flow.tsx",
+ "keyword.control.ruby",
+ "keyword.control.def.ruby",
+ "keyword.control.loop.js",
+ "keyword.control.loop.ts",
+ "keyword.control.import.js",
+ "keyword.control.import.ts",
+ "keyword.control.import.tsx",
+ "keyword.control.from.js",
+ "keyword.control.from.ts",
+ "keyword.control.from.tsx",
+ "keyword.control.conditional.js",
+ "keyword.control.conditional.ts",
+ "keyword.control.switch.js",
+ "keyword.control.switch.ts",
+ "keyword.operator.instanceof.js",
+ "keyword.operator.expression.instanceof.ts",
+ "keyword.operator.expression.instanceof.tsx"
+ ],
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords",
+ "scope": [
+ "support.constant",
+ "keyword.other.special-method",
+ "keyword.other.new",
+ "keyword.other.debugger",
+ "keyword.control"
+ ],
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Support Function",
+ "scope": "support.function",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Invalid Broken",
+ "scope": "invalid.broken",
+ "settings": {
+ "foreground": "#020e14",
+ "background": "#F78C6C"
+ }
+ },
+ {
+ "name": "Invalid Unimplemented",
+ "scope": "invalid.unimplemented",
+ "settings": {
+ "background": "#8BD649",
+ "foreground": "#ffffff"
+ }
+ },
+ {
+ "name": "Invalid Illegal",
+ "scope": "invalid.illegal",
+ "settings": {
+ "foreground": "#ffffff",
+ "background": "#ec5f67"
+ }
+ },
+ {
+ "name": "Language Variable",
+ "scope": "variable.language",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Support Variable Property",
+ "scope": "support.variable.property",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Variable Function",
+ "scope": "variable.function",
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Variable Interpolation",
+ "scope": "variable.interpolation",
+ "settings": {
+ "foreground": "#ec5f67"
+ }
+ },
+ {
+ "name": "Meta Function Call",
+ "scope": "meta.function-call",
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Punctuation Section Embedded",
+ "scope": "punctuation.section.embedded",
+ "settings": {
+ "foreground": "#d3423e"
+ }
+ },
+ {
+ "name": "Punctuation Tweaks",
+ "scope": [
+ "punctuation.terminator.expression",
+ "punctuation.definition.arguments",
+ "punctuation.definition.array",
+ "punctuation.section.array",
+ "meta.array"
+ ],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "More Punctuation Tweaks",
+ "scope": [
+ "punctuation.definition.list.begin",
+ "punctuation.definition.list.end",
+ "punctuation.separator.arguments",
+ "punctuation.definition.list"
+ ],
+ "settings": {
+ "foreground": "#d9f5dd"
+ }
+ },
+ {
+ "name": "Template Strings",
+ "scope": "string.template meta.template.expression",
+ "settings": {
+ "foreground": "#d3423e"
+ }
+ },
+ {
+ "name": "Backtics(``) in Template Strings",
+ "scope": "string.template punctuation.definition.string",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "Italics",
+ "scope": "italic",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": "italic"
+ }
+ },
+ {
+ "name": "Bold",
+ "scope": "bold",
+ "settings": {
+ "foreground": "#c5e478",
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "Quote",
+ "scope": "quote",
+ "settings": {
+ "foreground": "#697098",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Raw Code",
+ "scope": "raw",
+ "settings": {
+ "foreground": "#80CBC4"
+ }
+ },
+ {
+ "name": "CoffeScript Variable Assignment",
+ "scope": "variable.assignment.coffee",
+ "settings": {
+ "foreground": "#31e1eb"
+ }
+ },
+ {
+ "name": "CoffeScript Parameter Function",
+ "scope": "variable.parameter.function.coffee",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "CoffeeScript Assignments",
+ "scope": "variable.assignment.coffee",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "C# Readwrite Variables",
+ "scope": "variable.other.readwrite.cs",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "C# Classes & Storage types",
+ "scope": ["entity.name.type.class.cs", "storage.type.cs"],
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "C# Namespaces",
+ "scope": "entity.name.type.namespace.cs",
+ "settings": {
+ "foreground": "#B2CCD6"
+ }
+ },
+ {
+ "name": "C# Unquoted String Zone",
+ "scope": "string.unquoted.preprocessor.message.cs",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "C# Region",
+ "scope": [
+ "punctuation.separator.hash.cs",
+ "keyword.preprocessor.region.cs",
+ "keyword.preprocessor.endregion.cs"
+ ],
+ "settings": {
+ "foreground": "#ffcb8b",
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "C# Other Variables",
+ "scope": "variable.other.object.cs",
+ "settings": {
+ "foreground": "#B2CCD6"
+ }
+ },
+ {
+ "name": "C# Enum",
+ "scope": "entity.name.type.enum.cs",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Dart String",
+ "scope": [
+ "string.interpolated.single.dart",
+ "string.interpolated.double.dart"
+ ],
+ "settings": {
+ "foreground": "#FFCB8B"
+ }
+ },
+ {
+ "name": "Dart Class",
+ "scope": "support.class.dart",
+ "settings": {
+ "foreground": "#FFCB8B"
+ }
+ },
+ {
+ "name": "Tag names in Stylesheets",
+ "scope": [
+ "entity.name.tag.css",
+ "entity.name.tag.less",
+ "entity.name.tag.custom.css",
+ "support.constant.property-value.css"
+ ],
+ "settings": {
+ "foreground": "#ff6363",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Wildcard(*) selector in Stylesheets",
+ "scope": [
+ "entity.name.tag.wildcard.css",
+ "entity.name.tag.wildcard.less",
+ "entity.name.tag.wildcard.scss",
+ "entity.name.tag.wildcard.sass"
+ ],
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "CSS Keyword Other Unit",
+ "scope": "keyword.other.unit.css",
+ "settings": {
+ "foreground": "#FFEB95"
+ }
+ },
+ {
+ "name": "Attribute Name for CSS",
+ "scope": [
+ "meta.attribute-selector.css entity.other.attribute-name.attribute",
+ "variable.other.readwrite.js"
+ ],
+ "settings": {
+ "foreground": "#F78C6C"
+ }
+ },
+ {
+ "name": "Elixir Classes",
+ "scope": [
+ "source.elixir support.type.elixir",
+ "source.elixir meta.module.elixir entity.name.class.elixir"
+ ],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Elixir Functions",
+ "scope": "source.elixir entity.name.function",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Elixir Constants",
+ "scope": [
+ "source.elixir constant.other.symbol.elixir",
+ "source.elixir constant.other.keywords.elixir"
+ ],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Elixir String Punctuations",
+ "scope": "source.elixir punctuation.definition.string",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Elixir",
+ "scope": [
+ "source.elixir variable.other.readwrite.module.elixir",
+ "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"
+ ],
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Elixir Binary Punctuations",
+ "scope": "source.elixir .punctuation.binary.elixir",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Closure Constant Keyword",
+ "scope": "constant.keyword.clojure",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Go Function Calls",
+ "scope": "source.go meta.function-call.go",
+ "settings": {
+ "foreground": "#DDDDDD"
+ }
+ },
+ {
+ "name": "Go Keywords",
+ "scope": [
+ "source.go keyword.package.go",
+ "source.go keyword.import.go",
+ "source.go keyword.function.go",
+ "source.go keyword.type.go",
+ "source.go keyword.struct.go",
+ "source.go keyword.interface.go",
+ "source.go keyword.const.go",
+ "source.go keyword.var.go",
+ "source.go keyword.map.go",
+ "source.go keyword.channel.go",
+ "source.go keyword.control.go"
+ ],
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "Go Constants e.g. nil, string format (%s, %d, etc.)",
+ "scope": [
+ "source.go constant.language.go",
+ "source.go constant.other.placeholder.go"
+ ],
+ "settings": {
+ "foreground": "#ff5874"
+ }
+ },
+ {
+ "name": "C++ Functions",
+ "scope": [
+ "entity.name.function.preprocessor.cpp",
+ "entity.scope.name.cpp"
+ ],
+ "settings": {
+ "foreground": "#7fdbcaff"
+ }
+ },
+ {
+ "name": "C++ Meta Namespace",
+ "scope": ["meta.namespace-block.cpp"],
+ "settings": {
+ "foreground": "#e0dec6"
+ }
+ },
+ {
+ "name": "C++ Language Primitive Storage",
+ "scope": ["storage.type.language.primitive.cpp"],
+ "settings": {
+ "foreground": "#ff5874"
+ }
+ },
+ {
+ "name": "C++ Preprocessor Macro",
+ "scope": ["meta.preprocessor.macro.cpp"],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "C++ Variable Parameter",
+ "scope": ["variable.parameter"],
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "Powershell Variables",
+ "scope": ["variable.other.readwrite.powershell"],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Powershell Function",
+ "scope": ["support.function.powershell"],
+ "settings": {
+ "foreground": "#7fdbcaff"
+ }
+ },
+ {
+ "name": "ID Attribute Name in HTML",
+ "scope": "entity.other.attribute-name.id.html",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "HTML Punctuation Definition Tag",
+ "scope": "punctuation.definition.tag.html",
+ "settings": {
+ "foreground": "#6ae9f0"
+ }
+ },
+ {
+ "name": "HTML Doctype",
+ "scope": "meta.tag.sgml.doctype.html",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "JavaScript Classes",
+ "scope": "meta.class entity.name.type.class.js",
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "JavaScript Method Declaration e.g. `constructor`",
+ "scope": "meta.method.declaration storage.type.js",
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "JavaScript Terminator",
+ "scope": "terminator.js",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "JavaScript Meta Punctuation Definition",
+ "scope": "meta.js punctuation.definition.js",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "Entity Names in Code Documentations",
+ "scope": [
+ "entity.name.type.instance.jsdoc",
+ "entity.name.type.instance.phpdoc"
+ ],
+ "settings": {
+ "foreground": "#5f7e97"
+ }
+ },
+ {
+ "name": "Other Variables in Code Documentations",
+ "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],
+ "settings": {
+ "foreground": "#78ccf0"
+ }
+ },
+ {
+ "name": "JavaScript module imports and exports",
+ "scope": [
+ "variable.other.meta.import.js",
+ "meta.import.js variable.other",
+ "variable.other.meta.export.js",
+ "meta.export.js variable.other"
+ ],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "JavaScript Variable Parameter Function",
+ "scope": "variable.parameter.function.js",
+ "settings": {
+ "foreground": "#7986E7"
+ }
+ },
+ {
+ "name": "JavaScript[React] Variable Other Object",
+ "scope": [
+ "variable.other.object.js",
+ "variable.other.object.jsx",
+ "variable.object.property.js",
+ "variable.object.property.jsx"
+ ],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "JavaScript Variables",
+ "scope": ["variable.js", "variable.other.js"],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "JavaScript Entity Name Type",
+ "scope": ["entity.name.type.js", "entity.name.type.module.js"],
+ "settings": {
+ "foreground": "#ffcb8b",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "JavaScript Support Classes",
+ "scope": "support.class.js",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "JSON Property Names",
+ "scope": "support.type.property-name.json",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "JSON Support Constants",
+ "scope": "support.constant.json",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "JSON Property values (string)",
+ "scope": "meta.structure.dictionary.value.json string.quoted.double",
+ "settings": {
+ "foreground": "#c789d6"
+ }
+ },
+ {
+ "name": "Strings in JSON values",
+ "scope": "string.quoted.double.json punctuation.definition.string.json",
+ "settings": {
+ "foreground": "#80CBC4"
+ }
+ },
+ {
+ "name": "Specific JSON Property values like null",
+ "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",
+ "settings": {
+ "foreground": "#ff5874"
+ }
+ },
+ {
+ "name": "JavaScript Other Variable",
+ "scope": "variable.other.object.js",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Ruby Variables",
+ "scope": ["variable.other.ruby"],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "Ruby Class",
+ "scope": ["entity.name.type.class.ruby"],
+ "settings": {
+ "foreground": "#ecc48d"
+ }
+ },
+ {
+ "name": "Ruby Hashkeys",
+ "scope": "constant.language.symbol.hashkey.ruby",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "LESS Tag names",
+ "scope": "entity.name.tag.less",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "LESS Keyword Other Unit",
+ "scope": "keyword.other.unit.css",
+ "settings": {
+ "foreground": "#FFEB95"
+ }
+ },
+ {
+ "name": "Attribute Name for LESS",
+ "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",
+ "settings": {
+ "foreground": "#F78C6C"
+ }
+ },
+ {
+ "name": "Markdown Headings",
+ "scope": [
+ "markup.heading.markdown",
+ "markup.heading.setext.1.markdown",
+ "markup.heading.setext.2.markdown"
+ ],
+ "settings": {
+ "foreground": "#82b1ff"
+ }
+ },
+ {
+ "name": "Markdown Italics",
+ "scope": "markup.italic.markdown",
+ "settings": {
+ "foreground": "#c792ea",
+ "fontStyle": "italic"
+ }
+ },
+ {
+ "name": "Markdown Bold",
+ "scope": "markup.bold.markdown",
+ "settings": {
+ "foreground": "#c5e478",
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "Markdown Quote + others",
+ "scope": "markup.quote.markdown",
+ "settings": {
+ "foreground": "#697098",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Markdown Raw Code + others",
+ "scope": "markup.inline.raw.markdown",
+ "settings": {
+ "foreground": "#80CBC4"
+ }
+ },
+ {
+ "name": "Markdown Links",
+ "scope": [
+ "markup.underline.link.markdown",
+ "markup.underline.link.image.markdown"
+ ],
+ "settings": {
+ "foreground": "#ff869a"
+ }
+ },
+ {
+ "name": "Markdown Link Title and Description",
+ "scope": [
+ "string.other.link.title.markdown",
+ "string.other.link.description.markdown"
+ ],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "Markdown Punctuation",
+ "scope": [
+ "punctuation.definition.string.markdown",
+ "punctuation.definition.string.begin.markdown",
+ "punctuation.definition.string.end.markdown",
+ "meta.link.inline.markdown punctuation.definition.string"
+ ],
+ "settings": {
+ "foreground": "#82b1ff"
+ }
+ },
+ {
+ "name": "Markdown MetaData Punctuation",
+ "scope": ["punctuation.definition.metadata.markdown"],
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "Markdown List Punctuation",
+ "scope": ["beginning.punctuation.definition.list.markdown"],
+ "settings": {
+ "foreground": "#82b1ff"
+ }
+ },
+ {
+ "name": "Markdown Inline Raw String",
+ "scope": "markup.inline.raw.string.markdown",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "PHP Variables",
+ "scope": "variable.other.php",
+ "settings": {
+ "foreground": "#bec5d4"
+ }
+ },
+ {
+ "name": "Support Classes in PHP",
+ "scope": "support.class.php",
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "Punctuations in PHP function calls",
+ "scope": "meta.function-call.php punctuation",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "PHP Global Variables",
+ "scope": "variable.other.global.php",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Declaration Punctuation in PHP Global Variables",
+ "scope": "variable.other.global.php punctuation.definition.variable",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Language Constants in Python",
+ "scope": "constant.language.python",
+ "settings": {
+ "foreground": "#ff5874"
+ }
+ },
+ {
+ "name": "Python Function Parameter and Arguments",
+ "scope": [
+ "variable.parameter.function.python",
+ "meta.function-call.arguments.python"
+ ],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Python Function Call",
+ "scope": [
+ "meta.function-call.python",
+ "meta.function-call.generic.python"
+ ],
+ "settings": {
+ "foreground": "#B2CCD6"
+ }
+ },
+ {
+ "name": "Punctuations in Python",
+ "scope": "punctuation.python",
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "Decorator Functions in Python",
+ "scope": "entity.name.function.decorator.python",
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Python Language Variable",
+ "scope": "source.python variable.language.special",
+ "settings": {
+ "foreground": "#8EACE3"
+ }
+ },
+ {
+ "name": "Python import control keyword",
+ "scope": "keyword.control",
+ "settings": {
+ "foreground": "#c792ea"
+ }
+ },
+ {
+ "name": "SCSS Variable",
+ "scope": [
+ "variable.scss",
+ "variable.sass",
+ "variable.parameter.url.scss",
+ "variable.parameter.url.sass"
+ ],
+ "settings": {
+ "foreground": "#c5e478"
+ }
+ },
+ {
+ "name": "Variables in SASS At-Rules",
+ "scope": [
+ "source.css.scss meta.at-rule variable",
+ "source.css.sass meta.at-rule variable"
+ ],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "Variables in SASS At-Rules",
+ "scope": [
+ "source.css.scss meta.at-rule variable",
+ "source.css.sass meta.at-rule variable"
+ ],
+ "settings": {
+ "foreground": "#bec5d4"
+ }
+ },
+ {
+ "name": "Attribute Name for SASS",
+ "scope": [
+ "meta.attribute-selector.scss entity.other.attribute-name.attribute",
+ "meta.attribute-selector.sass entity.other.attribute-name.attribute"
+ ],
+ "settings": {
+ "foreground": "#F78C6C"
+ }
+ },
+ {
+ "name": "Tag names in SASS",
+ "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "SASS Keyword Other Unit",
+ "scope": ["keyword.other.unit.scss", "keyword.other.unit.sass"],
+ "settings": {
+ "foreground": "#FFEB95"
+ }
+ },
+ {
+ "name": "TypeScript[React] Variables and Object Properties",
+ "scope": [
+ "variable.other.readwrite.alias.ts",
+ "variable.other.readwrite.alias.tsx",
+ "variable.other.readwrite.ts",
+ "variable.other.readwrite.tsx",
+ "variable.other.object.ts",
+ "variable.other.object.tsx",
+ "variable.object.property.ts",
+ "variable.object.property.tsx",
+ "variable.other.ts",
+ "variable.other.tsx",
+ "variable.tsx",
+ "variable.ts"
+ ],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "TypeScript[React] Entity Name Types",
+ "scope": ["entity.name.type.ts", "entity.name.type.tsx"],
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "TypeScript[React] Node Classes",
+ "scope": ["support.class.node.ts", "support.class.node.tsx"],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "TypeScript[React] Entity Name Types as Parameters",
+ "scope": [
+ "meta.type.parameters.ts entity.name.type",
+ "meta.type.parameters.tsx entity.name.type"
+ ],
+ "settings": {
+ "foreground": "#5f7e97"
+ }
+ },
+ {
+ "name": "TypeScript[React] Import/Export Punctuations",
+ "scope": [
+ "meta.import.ts punctuation.definition.block",
+ "meta.import.tsx punctuation.definition.block",
+ "meta.export.ts punctuation.definition.block",
+ "meta.export.tsx punctuation.definition.block"
+ ],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "TypeScript[React] Punctuation Decorators",
+ "scope": [
+ "meta.decorator punctuation.decorator.ts",
+ "meta.decorator punctuation.decorator.tsx"
+ ],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "TypeScript[React] Punctuation Decorators",
+ "scope": "meta.tag.js meta.jsx.children.tsx",
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "YAML Entity Name Tags",
+ "scope": "entity.name.tag.yaml",
+ "settings": {
+ "foreground": "#7fdbca"
+ }
+ },
+ {
+ "name": "JavaScript Variable Other ReadWrite",
+ "scope": ["variable.other.readwrite.js", "variable.parameter"],
+ "settings": {
+ "foreground": "#d7dbe0"
+ }
+ },
+ {
+ "name": "Support Class Component",
+ "scope": ["support.class.component.js", "support.class.component.tsx"],
+ "settings": {
+ "foreground": "#f78c6c",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Text nested in React tags",
+ "scope": [
+ "meta.jsx.children",
+ "meta.jsx.children.js",
+ "meta.jsx.children.tsx"
+ ],
+ "settings": {
+ "foreground": "#d6deeb"
+ }
+ },
+ {
+ "name": "TypeScript Classes",
+ "scope": "meta.class entity.name.type.class.tsx",
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "TypeScript Entity Name Type",
+ "scope": ["entity.name.type.tsx", "entity.name.type.module.tsx"],
+ "settings": {
+ "foreground": "#ffcb8b"
+ }
+ },
+ {
+ "name": "TypeScript Class Variable Keyword",
+ "scope": [
+ "meta.class.ts meta.var.expr.ts storage.type.ts",
+ "meta.class.tsx meta.var.expr.tsx storage.type.tsx"
+ ],
+ "settings": {
+ "foreground": "#C792EA"
+ }
+ },
+ {
+ "name": "TypeScript Method Declaration e.g. `constructor`",
+ "scope": [
+ "meta.method.declaration storage.type.ts",
+ "meta.method.declaration storage.type.tsx"
+ ],
+ "settings": {
+ "foreground": "#82AAFF"
+ }
+ },
+ {
+ "name": "normalize font style of certain components",
+ "scope": [
+ "meta.property-list.css meta.property-value.css variable.other.less",
+ "meta.property-list.scss variable.scss",
+ "meta.property-list.sass variable.sass",
+ "meta.brace",
+ "keyword.operator.operator",
+ "keyword.operator.or.regexp",
+ "keyword.operator.expression.in",
+ "keyword.operator.relational",
+ "keyword.operator.assignment",
+ "keyword.operator.comparison",
+ "keyword.operator.type",
+ "keyword.operator",
+ "keyword",
+ "punctuation.definintion.string",
+ "punctuation",
+ "variable.other.readwrite.js",
+ "storage.type",
+ "source.css",
+ "string.quoted"
+ ],
+ "settings": {
+ "fontStyle": ""
+ }
+ }
+ ]
+}
diff --git a/packages/starlight/integrations/expressive-code/themes/night-owl-light.jsonc b/packages/starlight/integrations/expressive-code/themes/night-owl-light.jsonc
new file mode 100644
index 00000000..f35155b6
--- /dev/null
+++ b/packages/starlight/integrations/expressive-code/themes/night-owl-light.jsonc
@@ -0,0 +1,1730 @@
+/**
+ * Night Owl VS Code Theme - https://github.com/sdras/night-owl-vscode-theme
+ *
+ * MIT License
+ *
+ * Copyright (c) 2018 Sarah Drasner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+{
+ "name": "Night Owl Light",
+ "type": "light",
+ "semanticHighlighting": false,
+ "colors": {
+ "foreground": "#403f53",
+ "focusBorder": "#93A1A1",
+ "errorForeground": "#403f53",
+ "selection.background": "#7a8181ad",
+ "descriptionForeground": "#403f53",
+ "widget.shadow": "#d9d9d9",
+ "titleBar.activeBackground": "#F0F0F0",
+ "notifications.background": "#F0F0F0",
+ "notifications.foreground": "#403f53",
+ "notificationLink.foreground": "#994cc3",
+ "notifications.border": "#CCCCCC",
+ "notificationCenter.border": "#CCCCCC",
+ "notificationToast.border": "#CCCCCC",
+ "notificationCenterHeader.foreground": "#403f53",
+ "notificationCenterHeader.background": "#F0F0F0",
+ "button.background": "#2AA298",
+ "button.foreground": "#F0F0F0",
+ "dropdown.background": "#F0F0F0",
+ "dropdown.foreground": "#403f53",
+ "dropdown.border": "#d9d9d9",
+ "input.background": "#F0F0F0",
+ "input.foreground": "#403f53",
+ "input.border": "#d9d9d9",
+ "input.placeholderForeground": "#93A1A1",
+ "inputOption.activeBorder": "#2AA298",
+ "inputValidation.infoBorder": "#D0D0D0",
+ "inputValidation.infoBackground": "#F0F0F0",
+ "inputValidation.warningBackground": "#daaa01",
+ "inputValidation.warningBorder": "#E0AF02",
+ "inputValidation.errorBackground": "#f76e6e",
+ "inputValidation.errorBorder": "#de3d3b",
+ "badge.background": "#2AA298",
+ "badge.foreground": "#F0F0F0",
+ "progressBar.background": "#2AA298",
+ "list.activeSelectionBackground": "#d3e8f8",
+ "list.activeSelectionForeground": "#403f53",
+ "list.inactiveSelectionBackground": "#E0E7EA",
+ "list.inactiveSelectionForeground": "#403f53",
+ "list.focusBackground": "#d3e8f8",
+ "list.hoverBackground": "#d3e8f8",
+ "list.focusForeground": "#403f53",
+ "list.hoverForeground": "#403f53",
+ "list.highlightForeground": "#403f53",
+ "list.errorForeground": "#E64D49",
+ "list.warningForeground": "#daaa01",
+ "activityBar.background": "#F0F0F0",
+ "activityBar.foreground": "#403f53",
+ "activityBar.dropBackground": "#D0D0D0",
+ "activityBarBadge.background": "#403f53",
+ "activityBarBadge.foreground": "#F0F0F0",
+ "activityBar.border": "#F0F0F0",
+ "sideBar.background": "#F0F0F0",
+ "sideBar.foreground": "#403f53",
+ "sideBarTitle.foreground": "#403f53",
+ "sideBar.border": "#F0F0F0",
+ "scrollbar.shadow": "#CCCCCC",
+ "tab.border": "#F0F0F0",
+ "tab.activeBackground": "#F6F6F6",
+ "tab.activeForeground": "#403f53",
+ "tab.inactiveForeground": "#403f53",
+ "tab.inactiveBackground": "#F0F0F0",
+ "editorGroup.border": "#F0F0F0",
+ "editorGroup.background": "#F6F6F6",
+ "editorGroupHeader.tabsBackground": "#F0F0F0",
+ "editorGroupHeader.tabsBorder": "#F0F0F0",
+ "editorGroupHeader.noTabsBackground": "#F0F0F0",
+ "tab.activeModifiedBorder": "#2AA298",
+ "tab.inactiveModifiedBorder": "#93A1A1",
+ "tab.unfocusedActiveModifiedBorder": "#93A1A1",
+ "tab.unfocusedInactiveModifiedBorder": "#93A1A1",
+ "editor.background": "#FBFBFB",
+ "editor.foreground": "#403f53",
+ "editorCursor.foreground": "#90A7B2",
+ "editorLineNumber.foreground": "#90A7B2",
+ "editorLineNumber.activeForeground": "#403f53",
+ "editor.selectionBackground": "#E0E0E0",
+ "editor.selectionHighlightBackground": "#339cec33",
+ "editor.wordHighlightBackground": "#339cec33",
+ "editor.wordHighlightStrongBackground": "#007dd659",
+ "editor.findMatchBackground": "#93A1A16c",
+ "editor.findMatchHighlightBackground": "#93a1a16c",
+ "editor.findRangeHighlightBackground": "#7497a633",
+ "editor.hoverHighlightBackground": "#339cec33",
+ "editor.lineHighlightBackground": "#F0F0F0",
+ "editor.rangeHighlightBackground": "#7497a633",
+ "editorWhitespace.foreground": "#d9d9d9",
+ "editorIndentGuide.background": "#d9d9d9",
+ "editorCodeLens.foreground": "#403f53",
+ "editorBracketMatch.background": "#d3e8f8",
+ "editorBracketMatch.border": "#2AA298",
+ "editorError.foreground": "#E64D49",
+ "editorError.border": "#FBFBFB",
+ "editorWarning.foreground": "#daaa01",
+ "editorWarning.border": "#daaa01",
+ "editorGutter.addedBackground": "#49d0c5",
+ "editorGutter.modifiedBackground": "#6fbef6",
+ "editorGutter.deletedBackground": "#f76e6e",
+ "editorRuler.foreground": "#d9d9d9",
+ "editorOverviewRuler.errorForeground": "#E64D49",
+ "editorOverviewRuler.warningForeground": "#daaa01",
+ "editorWidget.background": "#F0F0F0",
+ "editorWidget.border": "#d9d9d9",
+ "editorSuggestWidget.background": "#F0F0F0",
+ "editorSuggestWidget.foreground": "#403f53",
+ "editorSuggestWidget.highlightForeground": "#403f53",
+ "editorSuggestWidget.selectedBackground": "#d3e8f8",
+ "editorSuggestWidget.border": "#d9d9d9",
+ "editorHoverWidget.background": "#F0F0F0",
+ "editorHoverWidget.border": "#d9d9d9",
+ "debugExceptionWidget.background": "#F0F0F0",
+ "debugExceptionWidget.border": "#d9d9d9",
+ "editorMarkerNavigation.background": "#D0D0D0",
+ "editorMarkerNavigationError.background": "#f76e6e",
+ "editorMarkerNavigationWarning.background": "#daaa01",
+ "debugToolBar.background": "#F0F0F0",
+ "pickerGroup.border": "#d9d9d9",
+ "pickerGroup.foreground": "#403f53",
+ "extensionButton.prominentBackground": "#2AA298",
+ "extensionButton.prominentForeground": "#F0F0F0",
+ "statusBar.background": "#F0F0F0",
+ "statusBar.border": "#F0F0F0",
+ "statusBar.debuggingBackground": "#F0F0F0",
+ "statusBar.debuggingForeground": "#403f53",
+ "statusBar.foreground": "#403f53",
+ "statusBar.noFolderBackground": "#F0F0F0",
+ "statusBar.noFolderForeground": "#403f53",
+ "panel.background": "#F0F0F0",
+ "panel.border": "#d9d9d9",
+ "peekView.border": "#d9d9d9",
+ "peekViewEditor.background": "#F6F6F6",
+ "peekViewEditorGutter.background": "#F6F6F6",
+ "peekViewEditor.matchHighlightBackground": "#49d0c5",
+ "peekViewResult.background": "#F0F0F0",
+ "peekViewResult.fileForeground": "#403f53",
+ "peekViewResult.lineForeground": "#403f53",
+ "peekViewResult.matchHighlightBackground": "#49d0c5",
+ "peekViewResult.selectionBackground": "#E0E7EA",
+ "peekViewResult.selectionForeground": "#403f53",
+ "peekViewTitle.background": "#F0F0F0",
+ "peekViewTitleLabel.foreground": "#403f53",
+ "peekViewTitleDescription.foreground": "#403f53",
+ "terminal.ansiBrightBlack": "#403f53",
+ "terminal.ansiBlack": "#403f53",
+ "terminal.ansiBrightBlue": "#288ed7",
+ "terminal.ansiBlue": "#288ed7",
+ "terminal.ansiBrightCyan": "#2AA298",
+ "terminal.ansiCyan": "#2AA298",
+ "terminal.ansiBrightGreen": "#08916a",
+ "terminal.ansiGreen": "#08916a",
+ "terminal.ansiBrightMagenta": "#d6438a",
+ "terminal.ansiMagenta": "#d6438a",
+ "terminal.ansiBrightRed": "#de3d3b",
+ "terminal.ansiRed": "#de3d3b",
+ "terminal.ansiBrightWhite": "#F0F0F0",
+ "terminal.ansiWhite": "#F0F0F0",
+ "terminal.ansiBrightYellow": "#daaa01",
+ "terminal.ansiYellow": "#E0AF02",
+ "terminal.background": "#F6F6F6",
+ "terminal.foreground": "#403f53"
+ },
+ "tokenColors": [
+ {
+ "name": "Changed",
+ "scope": [
+ "markup.changed",
+ "meta.diff.header.git",
+ "meta.diff.header.from-file",
+ "meta.diff.header.to-file"
+ ],
+ "settings": {
+ "foreground": "#a2bffc"
+ }
+ },
+ {
+ "name": "Deleted",
+ "scope": "markup.deleted.diff",
+ "settings": {
+ "foreground": "#EF535090"
+ }
+ },
+ {
+ "name": "Inserted",
+ "scope": "markup.inserted.diff",
+ "settings": {
+ "foreground": "#4876d6ff"
+ }
+ },
+ {
+ "name": "Global settings",
+ "settings": {
+ "background": "#011627",
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Comment",
+ "scope": "comment",
+ "settings": {
+ "foreground": "#989fb1"
+ }
+ },
+ {
+ "name": "String",
+ "scope": "string",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "String Quoted",
+ "scope": ["string.quoted", "variable.other.readwrite.js"],
+ "settings": {
+ "foreground": "#c96765"
+ }
+ },
+ {
+ "name": "Support Constant Math",
+ "scope": "support.constant.math",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Number",
+ "scope": ["constant.numeric", "constant.character.numeric"],
+ "settings": {
+ "foreground": "#aa0982",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Built-in constant",
+ "scope": [
+ "constant.language",
+ "punctuation.definition.constant",
+ "variable.other.constant"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "User-defined constant",
+ "scope": ["constant.character", "constant.other"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Constant Character Escape",
+ "scope": "constant.character.escape",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "RegExp String",
+ "scope": ["string.regexp", "string.regexp keyword.other"],
+ "settings": {
+ "foreground": "#5ca7e4"
+ }
+ },
+ {
+ "name": "Comma in functions",
+ "scope": "meta.function punctuation.separator.comma",
+ "settings": {
+ "foreground": "#5f7e97"
+ }
+ },
+ {
+ "name": "Variable",
+ "scope": "variable",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Keyword",
+ "scope": ["punctuation.accessor", "keyword"],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Storage",
+ "scope": [
+ "storage",
+ "meta.var.expr",
+ "meta.class meta.method.declaration meta.var.expr storage.type.js",
+ "storage.type.property.js",
+ "storage.type.property.ts",
+ "storage.type.property.tsx"
+ ],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Storage type",
+ "scope": "storage.type",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Storage type",
+ "scope": "storage.type.function.arrow.js",
+ "settings": {
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Class name",
+ "scope": ["entity.name.class", "meta.class entity.name.type.class"],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Inherited class",
+ "scope": "entity.other.inherited-class",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Function name",
+ "scope": "entity.name.function",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Meta Tag",
+ "scope": ["punctuation.definition.tag", "meta.tag"],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "HTML Tag names",
+ "scope": [
+ "entity.name.tag",
+ "meta.tag.other.html",
+ "meta.tag.other.js",
+ "meta.tag.other.tsx",
+ "entity.name.tag.tsx",
+ "entity.name.tag.js",
+ "entity.name.tag",
+ "meta.tag.js",
+ "meta.tag.tsx",
+ "meta.tag.html"
+ ],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Tag attribute",
+ "scope": "entity.other.attribute-name",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Entity Name Tag Custom",
+ "scope": "entity.name.tag.custom",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Library (function & constant)",
+ "scope": ["support.function", "support.constant"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Support Constant Property Value meta",
+ "scope": "support.constant.meta.property-value",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Library class/type",
+ "scope": ["support.type", "support.class"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Support Variable DOM",
+ "scope": "support.variable.dom",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Invalid",
+ "scope": "invalid",
+ "settings": {
+ "foreground": "#ff2c83"
+ }
+ },
+ {
+ "name": "Invalid deprecated",
+ "scope": "invalid.deprecated",
+ "settings": {
+ "foreground": "#d3423e"
+ }
+ },
+ {
+ "name": "Keyword Operator",
+ "scope": "keyword.operator",
+ "settings": {
+ "foreground": "#0c969b",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Keyword Operator Relational",
+ "scope": "keyword.operator.relational",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Keyword Operator Assignment",
+ "scope": "keyword.operator.assignment",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Keyword Operator Arithmetic",
+ "scope": "keyword.operator.arithmetic",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Keyword Operator Bitwise",
+ "scope": "keyword.operator.bitwise",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Keyword Operator Increment",
+ "scope": "keyword.operator.increment",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Keyword Operator Ternary",
+ "scope": "keyword.operator.ternary",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Double-Slashed Comment",
+ "scope": "comment.line.double-slash",
+ "settings": {
+ "foreground": "#939dbb"
+ }
+ },
+ {
+ "name": "Object",
+ "scope": "object",
+ "settings": {
+ "foreground": "#cdebf7"
+ }
+ },
+ {
+ "name": "Null",
+ "scope": "constant.language.null",
+ "settings": {
+ "foreground": "#bc5454"
+ }
+ },
+ {
+ "name": "Meta Brace",
+ "scope": "meta.brace",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Meta Delimiter Period",
+ "scope": "meta.delimiter.period",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Punctuation Definition String",
+ "scope": "punctuation.definition.string",
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Punctuation Definition String Markdown",
+ "scope": "punctuation.definition.string.begin.markdown",
+ "settings": {
+ "foreground": "#bc5454"
+ }
+ },
+ {
+ "name": "Boolean",
+ "scope": "constant.language.boolean",
+ "settings": {
+ "foreground": "#bc5454"
+ }
+ },
+ {
+ "name": "Object Comma",
+ "scope": "object.comma",
+ "settings": {
+ "foreground": "#ffffff"
+ }
+ },
+ {
+ "name": "Variable Parameter Function",
+ "scope": "variable.parameter.function",
+ "settings": {
+ "foreground": "#0c969b",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Support Type Property Name & entity name tags",
+ "scope": [
+ "support.type.vendor.property-name",
+ "support.constant.vendor.property-value",
+ "support.type.property-name",
+ "meta.property-list entity.name.tag"
+ ],
+ "settings": {
+ "foreground": "#0c969b",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Entity Name tag reference in stylesheets",
+ "scope": "meta.property-list entity.name.tag.reference",
+ "settings": {
+ "foreground": "#57eaf1"
+ }
+ },
+ {
+ "name": "Constant Other Color RGB Value Punctuation Definition Constant",
+ "scope": "constant.other.color.rgb-value punctuation.definition.constant",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Constant Other Color",
+ "scope": "constant.other.color",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Keyword Other Unit",
+ "scope": "keyword.other.unit",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Meta Selector",
+ "scope": "meta.selector",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Entity Other Attribute Name Id",
+ "scope": "entity.other.attribute-name.id",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Meta Property Name",
+ "scope": "meta.property-name",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Doctypes",
+ "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Punctuation Definition Parameters",
+ "scope": "punctuation.definition.parameters",
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Keyword Control Operator",
+ "scope": "keyword.control.operator",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Keyword Operator Logical",
+ "scope": "keyword.operator.logical",
+ "settings": {
+ "foreground": "#994cc3",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Variable Instances",
+ "scope": [
+ "variable.instance",
+ "variable.other.instance",
+ "variable.readwrite.instance",
+ "variable.other.readwrite.instance",
+ "variable.other.property"
+ ],
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Variable Property Other object property",
+ "scope": ["variable.other.object.property"],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Variable Property Other object",
+ "scope": ["variable.other.object.js"],
+ "settings": {
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Entity Name Function",
+ "scope": ["entity.name.function"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Keyword Operator Comparison, imports, returns and Keyword Operator Ruby",
+ "scope": [
+ "keyword.operator.comparison",
+ "keyword.control.flow.js",
+ "keyword.control.flow.ts",
+ "keyword.control.flow.tsx",
+ "keyword.control.ruby",
+ "keyword.control.module.ruby",
+ "keyword.control.class.ruby",
+ "keyword.control.def.ruby",
+ "keyword.control.loop.js",
+ "keyword.control.loop.ts",
+ "keyword.control.import.js",
+ "keyword.control.import.ts",
+ "keyword.control.import.tsx",
+ "keyword.control.from.js",
+ "keyword.control.from.ts",
+ "keyword.control.from.tsx",
+ "keyword.operator.instanceof.js",
+ "keyword.operator.expression.instanceof.ts",
+ "keyword.operator.expression.instanceof.tsx"
+ ],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Keyword Control Conditional",
+ "scope": [
+ "keyword.control.conditional.js",
+ "keyword.control.conditional.ts",
+ "keyword.control.switch.js",
+ "keyword.control.switch.ts"
+ ],
+ "settings": {
+ "foreground": "#994cc3",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords",
+ "scope": [
+ "support.constant",
+ "keyword.other.special-method",
+ "keyword.other.new",
+ "keyword.other.debugger",
+ "keyword.control"
+ ],
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Support Function",
+ "scope": "support.function",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Invalid Broken",
+ "scope": "invalid.broken",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Invalid Unimplemented",
+ "scope": "invalid.unimplemented",
+ "settings": {
+ "foreground": "#8BD649"
+ }
+ },
+ {
+ "name": "Invalid Illegal",
+ "scope": "invalid.illegal",
+ "settings": {
+ "foreground": "#c96765"
+ }
+ },
+ {
+ "name": "Language Variable",
+ "scope": "variable.language",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Support Variable Property",
+ "scope": "support.variable.property",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Variable Function",
+ "scope": "variable.function",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Variable Interpolation",
+ "scope": "variable.interpolation",
+ "settings": {
+ "foreground": "#ec5f67"
+ }
+ },
+ {
+ "name": "Meta Function Call",
+ "scope": "meta.function-call",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Punctuation Section Embedded",
+ "scope": "punctuation.section.embedded",
+ "settings": {
+ "foreground": "#d3423e"
+ }
+ },
+ {
+ "name": "Punctuation Tweaks",
+ "scope": [
+ "punctuation.terminator.expression",
+ "punctuation.definition.arguments",
+ "punctuation.definition.array",
+ "punctuation.section.array",
+ "meta.array"
+ ],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "More Punctuation Tweaks",
+ "scope": [
+ "punctuation.definition.list.begin",
+ "punctuation.definition.list.end",
+ "punctuation.separator.arguments",
+ "punctuation.definition.list"
+ ],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Template Strings",
+ "scope": "string.template meta.template.expression",
+ "settings": {
+ "foreground": "#d3423e"
+ }
+ },
+ {
+ "name": "Backtics(``) in Template Strings",
+ "scope": "string.template punctuation.definition.string",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Italics",
+ "scope": "italic",
+ "settings": {
+ "foreground": "#994cc3",
+ "fontStyle": "italic"
+ }
+ },
+ {
+ "name": "Bold",
+ "scope": "bold",
+ "settings": {
+ "foreground": "#4876d6",
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "Quote",
+ "scope": "quote",
+ "settings": {
+ "foreground": "#697098"
+ }
+ },
+ {
+ "name": "Raw Code",
+ "scope": "raw",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "CoffeScript Variable Assignment",
+ "scope": "variable.assignment.coffee",
+ "settings": {
+ "foreground": "#31e1eb"
+ }
+ },
+ {
+ "name": "CoffeScript Parameter Function",
+ "scope": "variable.parameter.function.coffee",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "CoffeeScript Assignments",
+ "scope": "variable.assignment.coffee",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "C# Readwrite Variables",
+ "scope": "variable.other.readwrite.cs",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "C# Classes & Storage types",
+ "scope": ["entity.name.type.class.cs", "storage.type.cs"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "C# Namespaces",
+ "scope": "entity.name.type.namespace.cs",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Tag names in Stylesheets",
+ "scope": [
+ "entity.name.tag.css",
+ "entity.name.tag.less",
+ "entity.name.tag.custom.css",
+ "support.constant.property-value.css"
+ ],
+ "settings": {
+ "foreground": "#c96765",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Wildcard(*) selector in Stylesheets",
+ "scope": [
+ "entity.name.tag.wildcard.css",
+ "entity.name.tag.wildcard.less",
+ "entity.name.tag.wildcard.scss",
+ "entity.name.tag.wildcard.sass"
+ ],
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "CSS Keyword Other Unit",
+ "scope": "keyword.other.unit.css",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Attribute Name for CSS",
+ "scope": [
+ "meta.attribute-selector.css entity.other.attribute-name.attribute",
+ "variable.other.readwrite.js"
+ ],
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Elixir Classes",
+ "scope": [
+ "source.elixir support.type.elixir",
+ "source.elixir meta.module.elixir entity.name.class.elixir"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Elixir Functions",
+ "scope": "source.elixir entity.name.function",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Elixir Constants",
+ "scope": [
+ "source.elixir constant.other.symbol.elixir",
+ "source.elixir constant.other.keywords.elixir"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Elixir String Punctuations",
+ "scope": "source.elixir punctuation.definition.string",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Elixir",
+ "scope": [
+ "source.elixir variable.other.readwrite.module.elixir",
+ "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Elixir Binary Punctuations",
+ "scope": "source.elixir .punctuation.binary.elixir",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Closure Constant Keyword",
+ "scope": "constant.keyword.clojure",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Go Function Calls",
+ "scope": "source.go meta.function-call.go",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Go Keywords",
+ "scope": [
+ "source.go keyword.package.go",
+ "source.go keyword.import.go",
+ "source.go keyword.function.go",
+ "source.go keyword.type.go",
+ "source.go keyword.struct.go",
+ "source.go keyword.interface.go",
+ "source.go keyword.const.go",
+ "source.go keyword.var.go",
+ "source.go keyword.map.go",
+ "source.go keyword.channel.go",
+ "source.go keyword.control.go"
+ ],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "Go Constants e.g. nil, string format (%s, %d, etc.)",
+ "scope": [
+ "source.go constant.language.go",
+ "source.go constant.other.placeholder.go"
+ ],
+ "settings": {
+ "foreground": "#bc5454"
+ }
+ },
+ {
+ "name": "C++ Functions",
+ "scope": [
+ "entity.name.function.preprocessor.cpp",
+ "entity.scope.name.cpp"
+ ],
+ "settings": {
+ "foreground": "#0c969bff"
+ }
+ },
+ {
+ "name": "C++ Meta Namespace",
+ "scope": ["meta.namespace-block.cpp"],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "C++ Language Primitive Storage",
+ "scope": ["storage.type.language.primitive.cpp"],
+ "settings": {
+ "foreground": "#bc5454"
+ }
+ },
+ {
+ "name": "C++ Preprocessor Macro",
+ "scope": ["meta.preprocessor.macro.cpp"],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "C++ Variable Parameter",
+ "scope": ["variable.parameter"],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Powershell Variables",
+ "scope": ["variable.other.readwrite.powershell"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Powershell Function",
+ "scope": ["support.function.powershell"],
+ "settings": {
+ "foreground": "#0c969bff"
+ }
+ },
+ {
+ "name": "ID Attribute Name in HTML",
+ "scope": "entity.other.attribute-name.id.html",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "HTML Punctuation Definition Tag",
+ "scope": "punctuation.definition.tag.html",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "HTML Doctype",
+ "scope": "meta.tag.sgml.doctype.html",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "JavaScript Classes",
+ "scope": "meta.class entity.name.type.class.js",
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "JavaScript Method Declaration e.g. `constructor`",
+ "scope": "meta.method.declaration storage.type.js",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "JavaScript Terminator",
+ "scope": "terminator.js",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "JavaScript Meta Punctuation Definition",
+ "scope": "meta.js punctuation.definition.js",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Entity Names in Code Documentations",
+ "scope": [
+ "entity.name.type.instance.jsdoc",
+ "entity.name.type.instance.phpdoc"
+ ],
+ "settings": {
+ "foreground": "#5f7e97"
+ }
+ },
+ {
+ "name": "Other Variables in Code Documentations",
+ "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],
+ "settings": {
+ "foreground": "#78ccf0"
+ }
+ },
+ {
+ "name": "JavaScript module imports and exports",
+ "scope": [
+ "variable.other.meta.import.js",
+ "meta.import.js variable.other",
+ "variable.other.meta.export.js",
+ "meta.export.js variable.other"
+ ],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "JavaScript Variable Parameter Function",
+ "scope": "variable.parameter.function.js",
+ "settings": {
+ "foreground": "#7986E7"
+ }
+ },
+ {
+ "name": "JavaScript[React] Variable Other Object",
+ "scope": [
+ "variable.other.object.js",
+ "variable.other.object.jsx",
+ "variable.object.property.js",
+ "variable.object.property.jsx"
+ ],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "JavaScript Variables",
+ "scope": ["variable.js", "variable.other.js"],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "JavaScript Entity Name Type",
+ "scope": ["entity.name.type.js", "entity.name.type.module.js"],
+ "settings": {
+ "foreground": "#111111",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "JavaScript Support Classes",
+ "scope": "support.class.js",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "JSON Property Names",
+ "scope": "support.type.property-name.json",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "JSON Support Constants",
+ "scope": "support.constant.json",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "JSON Property values (string)",
+ "scope": "meta.structure.dictionary.value.json string.quoted.double",
+ "settings": {
+ "foreground": "#c789d6"
+ }
+ },
+ {
+ "name": "Strings in JSON values",
+ "scope": "string.quoted.double.json punctuation.definition.string.json",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Specific JSON Property values like null",
+ "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",
+ "settings": {
+ "foreground": "#bc5454"
+ }
+ },
+ {
+ "name": "JavaScript Other Variable",
+ "scope": "variable.other.object.js",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Ruby Variables",
+ "scope": ["variable.other.ruby"],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Ruby Class",
+ "scope": ["entity.name.type.class.ruby"],
+ "settings": {
+ "foreground": "#c96765"
+ }
+ },
+ {
+ "name": "Ruby Hashkeys",
+ "scope": "constant.language.symbol.hashkey.ruby",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Ruby Symbols",
+ "scope": "constant.language.symbol.ruby",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "LESS Tag names",
+ "scope": "entity.name.tag.less",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "LESS Keyword Other Unit",
+ "scope": "keyword.other.unit.css",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Attribute Name for LESS",
+ "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Markdown Headings",
+ "scope": [
+ "markup.heading.markdown",
+ "markup.heading.setext.1.markdown",
+ "markup.heading.setext.2.markdown"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Markdown Italics",
+ "scope": "markup.italic.markdown",
+ "settings": {
+ "foreground": "#994cc3",
+ "fontStyle": "italic"
+ }
+ },
+ {
+ "name": "Markdown Bold",
+ "scope": "markup.bold.markdown",
+ "settings": {
+ "foreground": "#4876d6",
+ "fontStyle": "bold"
+ }
+ },
+ {
+ "name": "Markdown Quote + others",
+ "scope": "markup.quote.markdown",
+ "settings": {
+ "foreground": "#697098"
+ }
+ },
+ {
+ "name": "Markdown Raw Code + others",
+ "scope": "markup.inline.raw.markdown",
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Markdown Links",
+ "scope": [
+ "markup.underline.link.markdown",
+ "markup.underline.link.image.markdown"
+ ],
+ "settings": {
+ "foreground": "#ff869a"
+ }
+ },
+ {
+ "name": "Markdown Link Title and Description",
+ "scope": [
+ "string.other.link.title.markdown",
+ "string.other.link.description.markdown"
+ ],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Markdown Punctuation",
+ "scope": [
+ "punctuation.definition.string.markdown",
+ "punctuation.definition.string.begin.markdown",
+ "punctuation.definition.string.end.markdown",
+ "meta.link.inline.markdown punctuation.definition.string"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Markdown MetaData Punctuation",
+ "scope": ["punctuation.definition.metadata.markdown"],
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Markdown List Punctuation",
+ "scope": ["beginning.punctuation.definition.list.markdown"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Markdown Inline Raw String",
+ "scope": "markup.inline.raw.string.markdown",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "PHP Variables",
+ "scope": ["variable.other.php", "variable.other.property.php"],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Support Classes in PHP",
+ "scope": "support.class.php",
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Punctuations in PHP function calls",
+ "scope": "meta.function-call.php punctuation",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "PHP Global Variables",
+ "scope": "variable.other.global.php",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Declaration Punctuation in PHP Global Variables",
+ "scope": "variable.other.global.php punctuation.definition.variable",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Language Constants in Python",
+ "scope": "constant.language.python",
+ "settings": {
+ "foreground": "#bc5454"
+ }
+ },
+ {
+ "name": "Python Function Parameter and Arguments",
+ "scope": [
+ "variable.parameter.function.python",
+ "meta.function-call.arguments.python"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Python Function Call",
+ "scope": [
+ "meta.function-call.python",
+ "meta.function-call.generic.python"
+ ],
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "Punctuations in Python",
+ "scope": "punctuation.python",
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Decorator Functions in Python",
+ "scope": "entity.name.function.decorator.python",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Python Language Variable",
+ "scope": "source.python variable.language.special",
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Python import control keyword",
+ "scope": "keyword.control",
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "SCSS Variable",
+ "scope": [
+ "variable.scss",
+ "variable.sass",
+ "variable.parameter.url.scss",
+ "variable.parameter.url.sass"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Variables in SASS At-Rules",
+ "scope": [
+ "source.css.scss meta.at-rule variable",
+ "source.css.sass meta.at-rule variable"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "Variables in SASS At-Rules",
+ "scope": [
+ "source.css.scss meta.at-rule variable",
+ "source.css.sass meta.at-rule variable"
+ ],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "Attribute Name for SASS",
+ "scope": [
+ "meta.attribute-selector.scss entity.other.attribute-name.attribute",
+ "meta.attribute-selector.sass entity.other.attribute-name.attribute"
+ ],
+ "settings": {
+ "foreground": "#aa0982"
+ }
+ },
+ {
+ "name": "Tag names in SASS",
+ "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],
+ "settings": {
+ "foreground": "#0c969b"
+ }
+ },
+ {
+ "name": "SASS Keyword Other Unit",
+ "scope": ["keyword.other.unit.scss", "keyword.other.unit.sass"],
+ "settings": {
+ "foreground": "#994cc3"
+ }
+ },
+ {
+ "name": "TypeScript[React] Variables and Object Properties",
+ "scope": [
+ "variable.other.readwrite.alias.ts",
+ "variable.other.readwrite.alias.tsx",
+ "variable.other.readwrite.ts",
+ "variable.other.readwrite.tsx",
+ "variable.other.object.ts",
+ "variable.other.object.tsx",
+ "variable.object.property.ts",
+ "variable.object.property.tsx",
+ "variable.other.ts",
+ "variable.other.tsx",
+ "variable.tsx",
+ "variable.ts"
+ ],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "TypeScript[React] Entity Name Types",
+ "scope": ["entity.name.type.ts", "entity.name.type.tsx"],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "TypeScript[React] Node Classes",
+ "scope": ["support.class.node.ts", "support.class.node.tsx"],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "TypeScript[React] Entity Name Types as Parameters",
+ "scope": [
+ "meta.type.parameters.ts entity.name.type",
+ "meta.type.parameters.tsx entity.name.type"
+ ],
+ "settings": {
+ "foreground": "#5f7e97"
+ }
+ },
+ {
+ "name": "TypeScript[React] Import/Export Punctuations",
+ "scope": [
+ "meta.import.ts punctuation.definition.block",
+ "meta.import.tsx punctuation.definition.block",
+ "meta.export.ts punctuation.definition.block",
+ "meta.export.tsx punctuation.definition.block"
+ ],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "TypeScript[React] Punctuation Decorators",
+ "scope": [
+ "meta.decorator punctuation.decorator.ts",
+ "meta.decorator punctuation.decorator.tsx"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "TypeScript[React] Punctuation Decorators",
+ "scope": "meta.tag.js meta.jsx.children.tsx",
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "YAML Entity Name Tags",
+ "scope": "entity.name.tag.yaml",
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "JavaScript Variable Other ReadWrite",
+ "scope": ["variable.other.readwrite.js", "variable.parameter"],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "Support Class Component",
+ "scope": ["support.class.component.js", "support.class.component.tsx"],
+ "settings": {
+ "foreground": "#aa0982",
+ "fontStyle": ""
+ }
+ },
+ {
+ "name": "Text nested in React tags",
+ "scope": [
+ "meta.jsx.children",
+ "meta.jsx.children.js",
+ "meta.jsx.children.tsx"
+ ],
+ "settings": {
+ "foreground": "#403f53"
+ }
+ },
+ {
+ "name": "TypeScript Classes",
+ "scope": "meta.class entity.name.type.class.tsx",
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "TypeScript Entity Name Type",
+ "scope": ["entity.name.type.tsx", "entity.name.type.module.tsx"],
+ "settings": {
+ "foreground": "#111111"
+ }
+ },
+ {
+ "name": "TypeScript Class Variable Keyword",
+ "scope": [
+ "meta.class.ts meta.var.expr.ts storage.type.ts",
+ "meta.class.tsx meta.var.expr.tsx storage.type.tsx"
+ ],
+ "settings": {
+ "foreground": "#C792EA"
+ }
+ },
+ {
+ "name": "TypeScript Method Declaration e.g. `constructor`",
+ "scope": [
+ "meta.method.declaration storage.type.ts",
+ "meta.method.declaration storage.type.tsx"
+ ],
+ "settings": {
+ "foreground": "#4876d6"
+ }
+ },
+ {
+ "name": "normalize font style of certain components",
+ "scope": [
+ "meta.property-list.css meta.property-value.css variable.other.less",
+ "meta.property-list.scss variable.scss",
+ "meta.property-list.sass variable.sass",
+ "meta.brace",
+ "keyword.operator.operator",
+ "keyword.operator.or.regexp",
+ "keyword.operator.expression.in",
+ "keyword.operator.relational",
+ "keyword.operator.assignment",
+ "keyword.operator.comparison",
+ "keyword.operator.type",
+ "keyword.operator",
+ "keyword",
+ "punctuation.definintion.string",
+ "punctuation",
+ "variable.other.readwrite.js",
+ "storage.type",
+ "source.css",
+ "string.quoted"
+ ],
+ "settings": {
+ "fontStyle": ""
+ }
+ }
+ ]
+}
diff --git a/packages/starlight/integrations/expressive-code/theming.ts b/packages/starlight/integrations/expressive-code/theming.ts
new file mode 100644
index 00000000..d132afb2
--- /dev/null
+++ b/packages/starlight/integrations/expressive-code/theming.ts
@@ -0,0 +1,109 @@
+import fs from 'node:fs';
+import {
+ ExpressiveCodeTheme,
+ type ThemeObjectOrShikiThemeName,
+} from 'astro-expressive-code';
+
+export type BundledThemeName = 'starlight-dark' | 'starlight-light';
+
+export type ThemeObjectOrBundledThemeName = ThemeObjectOrShikiThemeName | BundledThemeName;
+
+/**
+ * Converts the Starlight `themes` config option into a format understood by Expressive Code,
+ * loading any bundled themes and using the Starlight defaults if no themes were provided.
+ */
+export function preprocessThemes(
+ themes: ThemeObjectOrBundledThemeName[] | undefined
+): ThemeObjectOrShikiThemeName[] {
+ // Try to gracefully handle cases where the user forgot to use an array in the config
+ themes = themes && !Array.isArray(themes) ? [themes] : themes;
+ // If no themes were provided, use our bundled default themes
+ if (!themes || !themes.length) themes = ['starlight-dark', 'starlight-light'];
+
+ return themes.map((theme) => {
+ // If the current entry is the name of a bundled theme, load it
+ if (theme === 'starlight-dark' || theme === 'starlight-light') {
+ const bundledThemeFile =
+ theme === 'starlight-dark' ? 'night-owl-dark.jsonc' : 'night-owl-light.jsonc';
+ return customizeBundledTheme(ExpressiveCodeTheme.fromJSONString(
+ fs.readFileSync(new URL(`./themes/${bundledThemeFile}`, import.meta.url), 'utf-8')
+ ));
+ }
+ // Otherwise, just pass it through
+ return theme;
+ });
+}
+
+/**
+ * Customizes some settings of the bundled theme to make it fit better with Starlight.
+ */
+function customizeBundledTheme(theme: ExpressiveCodeTheme) {
+ theme.colors['titleBar.border'] = theme.colors['tab.activeBackground'];
+ theme.colors['editorGroupHeader.tabsBorder'] = theme.colors['tab.activeBackground'];
+
+ // Add underline font style to link syntax highlighting tokens
+ // to match the new GitHub theme link style
+ theme.settings.forEach((s) => {
+ if (s.name?.includes('Link')) s.settings.fontStyle = 'underline';
+ });
+
+ return theme;
+}
+
+/**
+ * Modifies the given theme by applying Starlight's CSS variables to the colors of UI elements
+ * (backgrounds, buttons, shadows etc.). This ensures that code blocks match the site's theme.
+ */
+export function applyStarlightUiThemeColors(theme: ExpressiveCodeTheme) {
+ const isDark = theme.type === 'dark';
+ const neutralMinimal = isDark ? '#ffffff17' : '#0000001a';
+ const neutralDimmed = isDark ? '#ffffff40' : '#00000055';
+
+ // Make borders slightly transparent
+ const borderColor = 'color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)';
+ theme.colors['titleBar.border'] = borderColor;
+ theme.colors['editorGroupHeader.tabsBorder'] = borderColor;
+
+ // Use the same color for terminal title bar background and editor tab bar background
+ const backgroundColor = isDark ? 'var(--sl-color-black)' : 'var(--sl-color-gray-6)';
+ theme.colors['titleBar.activeBackground'] = backgroundColor;
+ theme.colors['editorGroupHeader.tabsBackground'] = backgroundColor;
+
+ // Use the same color for terminal titles and tab titles
+ theme.colors['titleBar.activeForeground'] = 'var(--sl-color-text)';
+ theme.colors['tab.activeForeground'] = 'var(--sl-color-text)';
+
+ // Set tab border colors
+ const activeBorderColor = isDark ? 'var(--sl-color-accent-high)' : 'var(--sl-color-accent)';
+ theme.colors['tab.activeBorder'] = 'transparent';
+ theme.colors['tab.activeBorderTop'] = activeBorderColor;
+
+ // Use neutral colors for scrollbars
+ theme.colors['scrollbarSlider.background'] = neutralMinimal;
+ theme.colors['scrollbarSlider.hoverBackground'] = neutralDimmed;
+
+ // Set theme `bg` color property for contrast calculations
+ theme.bg = isDark ? '#23262f' : '#f6f7f9';
+ // Set actual background color to the appropriate Starlight CSS variable
+ const editorBackgroundColor = isDark ? 'var(--sl-color-gray-6)' : 'var(--sl-color-gray-7)';
+
+ theme.styleOverrides.frames = {
+ // Use the same color for editor background, terminal background and active tab background
+ editorBackground: editorBackgroundColor,
+ terminalBackground: editorBackgroundColor,
+ editorActiveTabBackground: editorBackgroundColor,
+ terminalTitlebarDotsForeground: borderColor,
+ terminalTitlebarDotsOpacity: '0.75',
+ inlineButtonForeground: 'var(--sl-color-text)',
+ frameBoxShadowCssValue: 'none',
+ };
+
+ // Use neutral, semi-transparent colors for default text markers
+ // to avoid conflicts with the user's chosen background color
+ theme.styleOverrides.textMarkers = {
+ markBackground: neutralMinimal,
+ markBorderColor: neutralDimmed,
+ };
+
+ return theme;
+}
diff --git a/packages/starlight/integrations/expressive-code/translations.ts b/packages/starlight/integrations/expressive-code/translations.ts
new file mode 100644
index 00000000..1ff1c286
--- /dev/null
+++ b/packages/starlight/integrations/expressive-code/translations.ts
@@ -0,0 +1,26 @@
+import { pluginFramesTexts } from 'astro-expressive-code';
+import type { StarlightConfig } from '../../types';
+import type { createTranslationSystemFromFs } from '../../utils/translations-fs';
+
+export function addTranslations(
+ locales: StarlightConfig['locales'],
+ useTranslations: ReturnType<typeof createTranslationSystemFromFs>
+) {
+ for (const locale in locales) {
+ const lang = locales[locale]?.lang;
+ if (!lang) continue;
+
+ const t = useTranslations(locale);
+ const translationKeys = [
+ 'expressiveCode.copyButtonCopied',
+ 'expressiveCode.copyButtonTooltip',
+ 'expressiveCode.terminalWindowFallbackTitle',
+ ] as const;
+ translationKeys.forEach((key) => {
+ const translation = t(key);
+ if (!translation) return;
+ const ecId = key.replace(/^expressiveCode\./, '');
+ pluginFramesTexts.overrideTexts(lang, { [ecId]: translation });
+ });
+ }
+}
diff --git a/packages/starlight/integrations/shared/pathToLocale.ts b/packages/starlight/integrations/shared/pathToLocale.ts
new file mode 100644
index 00000000..34673891
--- /dev/null
+++ b/packages/starlight/integrations/shared/pathToLocale.ts
@@ -0,0 +1,32 @@
+import type { StarlightConfig } from '../../types';
+
+function slugToLocale(
+ slug: string | undefined,
+ localesConfig: StarlightConfig['locales']
+): string | undefined {
+ const locales = Object.keys(localesConfig || {});
+ const baseSegment = slug?.split('/')[0];
+ return baseSegment && locales.includes(baseSegment) ? baseSegment : undefined;
+}
+
+/** Get current locale from the full file path. */
+export function pathToLocale(
+ path: string | undefined,
+ {
+ starlightConfig,
+ astroConfig,
+ }: {
+ starlightConfig: { locales: StarlightConfig['locales'] };
+ astroConfig: { root: URL; srcDir: URL };
+ }
+): string | undefined {
+ const srcDir = new URL(astroConfig.srcDir, astroConfig.root);
+ const docsDir = new URL('content/docs/', srcDir);
+ const slug = path
+ // Format path to unix style path.
+ ?.replace(/\\/g, '/')
+ // Strip docs path leaving only content collection file ID.
+ // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md
+ .replace(docsDir.pathname, '');
+ return slugToLocale(slug, starlightConfig.locales);
+}
diff --git a/packages/starlight/package.json b/packages/starlight/package.json
index 3ff8403e..4ad3c200 100644
--- a/packages/starlight/package.json
+++ b/packages/starlight/package.json
@@ -157,6 +157,7 @@
"./props": "./props.ts",
"./schema": "./schema.ts",
"./types": "./types.ts",
+ "./expressive-code": "./integrations/expressive-code/exports.ts",
"./index.astro": "./index.astro",
"./404.astro": "./404.astro",
"./style/markdown.css": "./style/markdown.css"
@@ -176,6 +177,7 @@
"@astrojs/sitemap": "^3.0.0",
"@pagefind/default-ui": "^1.0.3",
"@types/mdast": "^3.0.11",
+ "astro-expressive-code": "^0.29.0",
"bcp-47": "^2.1.0",
"execa": "^8.0.1",
"hast-util-select": "^5.0.5",
diff --git a/packages/starlight/schemas/expressiveCode.ts b/packages/starlight/schemas/expressiveCode.ts
new file mode 100644
index 00000000..fc4490a9
--- /dev/null
+++ b/packages/starlight/schemas/expressiveCode.ts
@@ -0,0 +1,11 @@
+import { z } from 'astro/zod';
+import type { StarlightExpressiveCodeOptions } from '../integrations/expressive-code';
+
+export const ExpressiveCodeSchema = () =>
+ z
+ .union([
+ z.custom<StarlightExpressiveCodeOptions>((value) => typeof value === 'object' && value),
+ z.boolean(),
+ ])
+ .describe('Define how code blocks are rendered by passing options to Expressive Code, or disable the integration by passing `false`.')
+ .optional();
diff --git a/packages/starlight/schemas/i18n.ts b/packages/starlight/schemas/i18n.ts
index d1cd3975..0cf6496c 100644
--- a/packages/starlight/schemas/i18n.ts
+++ b/packages/starlight/schemas/i18n.ts
@@ -1,12 +1,16 @@
import { z } from 'astro/zod';
export function i18nSchema() {
- return starlightI18nSchema().merge(pagefindI18nSchema());
+ return starlightI18nSchema().merge(pagefindI18nSchema()).merge(expressiveCodeI18nSchema());
}
export type i18nSchemaOutput = z.output<ReturnType<typeof i18nSchema>>;
export function builtinI18nSchema() {
- return starlightI18nSchema().required().strict().merge(pagefindI18nSchema());
+ return starlightI18nSchema()
+ .required()
+ .strict()
+ .merge(pagefindI18nSchema())
+ .merge(expressiveCodeI18nSchema());
}
function starlightI18nSchema() {
@@ -162,3 +166,21 @@ function pagefindI18nSchema() {
})
.partial();
}
+
+function expressiveCodeI18nSchema() {
+ return z
+ .object({
+ 'expressiveCode.copyButtonCopied': z
+ .string()
+ .describe('Expressive Code UI translation. English default value: `"Copied!"`'),
+
+ 'expressiveCode.copyButtonTooltip': z
+ .string()
+ .describe('Expressive Code UI translation. English default value: `"Copy to clipboard"`'),
+
+ 'expressiveCode.terminalWindowFallbackTitle': z
+ .string()
+ .describe('Expressive Code UI translation. English default value: `"Terminal window"`'),
+ })
+ .partial();
+}
diff --git a/packages/starlight/utils/user-config.ts b/packages/starlight/utils/user-config.ts
index ad1afdcd..a026c216 100644
--- a/packages/starlight/utils/user-config.ts
+++ b/packages/starlight/utils/user-config.ts
@@ -1,6 +1,7 @@
import { z } from 'astro/zod';
import { parse as bcpParse, stringify as bcpStringify } from 'bcp-47';
import { ComponentConfigSchema } from '../schemas/components';
+import { ExpressiveCodeSchema } from '../schemas/expressiveCode';
import { FaviconSchema } from '../schemas/favicon';
import { HeadConfigSchema } from '../schemas/head';
import { LogoConfigSchema } from '../schemas/logo';
@@ -183,6 +184,12 @@ const UserConfigSchema = z.object({
/** The default favicon for your site which should be a path to an image in the `public/` directory. */
favicon: FaviconSchema(),
+ /**
+ * Define how code blocks are rendered by passing options to Expressive Code,
+ * or disable the integration by passing `false`.
+ */
+ expressiveCode: ExpressiveCodeSchema(),
+
/** Specify paths to components that should override Starlight’s default components */
components: ComponentConfigSchema(),
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9946589d..b712ee18 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -147,6 +147,9 @@ importers:
'@types/mdast':
specifier: ^3.0.11
version: 3.0.11
+ astro-expressive-code:
+ specifier: ^0.29.0
+ version: 0.29.0(astro@3.2.3)
bcp-47:
specifier: ^2.1.0
version: 2.1.0
@@ -774,6 +777,11 @@ packages:
prettier: 2.8.8
dev: true
+ /@ctrl/tinycolor@3.6.1:
+ resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==}
+ engines: {node: '>=10'}
+ dev: false
+
/@esbuild/android-arm64@0.18.17:
resolution: {integrity: sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==}
engines: {node: '>=12'}
@@ -1144,6 +1152,38 @@ packages:
requiresBuild: true
optional: true
+ /@expressive-code/core@0.29.0:
+ resolution: {integrity: sha512-AGFPSKMEA3J6gdFOuuN+7AESmRESSMypC9twqe+hq2nYWXXtp95Nv6pK+qV3o7doYqEWgWBJ9Mivb19CK+HW0Q==}
+ dependencies:
+ '@ctrl/tinycolor': 3.6.1
+ hast-util-to-html: 8.0.4
+ hastscript: 7.2.0
+ postcss: 8.4.29
+ postcss-nested: 6.0.1(postcss@8.4.29)
+ dev: false
+
+ /@expressive-code/plugin-frames@0.29.0:
+ resolution: {integrity: sha512-4wgua53ah9nBDKjHyhW8bDNEsXWjm5WvqznARmahn58CwTqjOdn44stc/56x0haL98wHpZTyksgyuiOdPzJ5eg==}
+ dependencies:
+ '@expressive-code/core': 0.29.0
+ hastscript: 7.2.0
+ dev: false
+
+ /@expressive-code/plugin-shiki@0.29.0:
+ resolution: {integrity: sha512-+mS1rkW1E5yhUUMBxOQB8HJbFlf3lWen0Hm7mi14K0Q+PQru/G5PqKaa5Du9Ut+/bWSevTNc1up5UiF8fhS/9A==}
+ dependencies:
+ '@expressive-code/core': 0.29.0
+ shiki: 0.14.4
+ dev: false
+
+ /@expressive-code/plugin-text-markers@0.29.0:
+ resolution: {integrity: sha512-9TwA91Zcjw3lyiVvsuh5MfcP9QRcg4/GJ2tZgLnNAmsCwPzbFM6iP1ZZJfigeeSD8bBqhfxyws7rydI2lGEVFA==}
+ dependencies:
+ '@expressive-code/core': 0.29.0
+ hastscript: 7.2.0
+ unist-util-visit-parents: 5.1.3
+ dev: false
+
/@hapi/hoek@9.3.0:
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
dev: true
@@ -1699,6 +1739,15 @@ packages:
hasBin: true
dev: false
+ /astro-expressive-code@0.29.0(astro@3.2.3):
+ resolution: {integrity: sha512-14DINm8EJYrusewcJumO3IsmTeqQYESCYZ3tVn0Wxup8hehYqy4I7HzT3XNKufRIo883ikDmTljbpAVhj8ls+g==}
+ peerDependencies:
+ astro: ^3.0.0-beta
+ dependencies:
+ astro: 3.2.3(@types/node@18.16.19)
+ remark-expressive-code: 0.29.0
+ dev: false
+
/astro@3.2.3(@types/node@18.16.19):
resolution: {integrity: sha512-1epnxQhTbfzgdmLP1yu51E8zjIOKYxZyA8hMTD4S2E+F5gMp/D81H4hekPbbq89GDxNJiHDRNZDHtS5vrU5E5w==}
engines: {node: '>=18.14.1', npm: '>=6.14.0'}
@@ -2938,6 +2987,15 @@ packages:
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
engines: {node: '>=6'}
+ /expressive-code@0.29.0:
+ resolution: {integrity: sha512-Gl27zUVizrzjp1sLPDMJwyVQ4mws7JRkxQOiFjCWiUv2jvugM0Jhjr56337docIk7oZaKbL1IPdCq1yDNfMm5A==}
+ dependencies:
+ '@expressive-code/core': 0.29.0
+ '@expressive-code/plugin-frames': 0.29.0
+ '@expressive-code/plugin-shiki': 0.29.0
+ '@expressive-code/plugin-text-markers': 0.29.0
+ dev: false
+
/extend-shallow@2.0.1:
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
engines: {node: '>=0.10.0'}
@@ -5439,6 +5497,14 @@ packages:
- supports-color
dev: false
+ /remark-expressive-code@0.29.0:
+ resolution: {integrity: sha512-T36DPLBalqFDwIcExs2WCgy0SSCf99RNtuCQunrHQT0NE4aKiD4k8X+tPWDeCmI6dy4lX+yJO1xgV3IG54pnnA==}
+ dependencies:
+ expressive-code: 0.29.0
+ hast-util-to-html: 8.0.4
+ unist-util-visit: 4.1.2
+ dev: false
+
/remark-gfm@3.0.1:
resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==}
dependencies: