import * as hast from 'hast'; import { Element, Parents } from 'hast'; import { ThemeRegistration } from 'shiki'; import { TinyColor } from '@ctrl/tinycolor'; import { addClassName as addClassName$1, getClassNames as getClassNames$1, getInlineStyles as getInlineStyles$1, removeClassName as removeClassName$1, setInlineStyle as setInlineStyle$1, setInlineStyles as setInlineStyles$1, setProperty as setProperty$1 } from './hast.js'; import 'hast-util-to-html'; import 'hast-util-to-text'; import 'hast-util-select'; import 'unist-util-visit'; import 'unist-util-visit-parents'; import 'hastscript'; declare class MetaOptions { #private; constructor(input: string); /** * A list of error messages that occurred when parsing the meta string, * or `undefined` if no errors occurred. */ get errors(): string[] | undefined; /** * Returns a list of meta options, optionally filtered by their key and/or {@link MetaOptionKind}. * * @param keyOrKeys * Allows to filter the options by key. An empty string will return options without a key. * A non-empty string will return options with a matching key (case-insensitive). * An array of strings will return options with any of the matching keys. * If omitted, no key-based filtering will be applied. * * @param kind * Allows to filter the options by {@link MetaOptionKind}. * If omitted, no kind-based filtering will be applied. */ list(keyOrKeys?: string | string[], kind?: K): K extends "string" | "boolean" | "range" | "regexp" ? (Extract | Extract | Extract | Extract)[] : MetaOption[]; value(key: string, kind?: K): (K extends "string" | "boolean" | "range" | "regexp" ? Extract | Extract | Extract | Extract : MetaOption)["value"] | undefined; /** * Returns the last string value with the given key (case-insensitive), * or without a key by passing an empty string. */ getString(key: string): string | undefined; /** * Returns an array of all string values with the given keys (case-insensitive), * or without a key by passing an empty string. */ getStrings(keyOrKeys?: string | string[]): string[]; /** * Returns the last range value (`{value}`) with the given key (case-insensitive), * or without a key by passing an empty string. */ getRange(key: string): string | undefined; /** * Returns an array of all range values (`{value}`) with the given keys (case-insensitive), * or without a key by passing an empty string. */ getRanges(keyOrKeys?: string | string[]): string[]; /** * Returns the last integer value with the given key (case-insensitive), * or without a key by passing an empty string. */ getInteger(key: string): number | undefined; /** * Returns an array of all integer values with the given keys (case-insensitive), * or without a key by passing an empty string. */ getIntegers(keyOrKeys?: string | string[]): number[]; /** * Returns the last RegExp value (`/value/`) with the given key (case-insensitive), * or without a key by passing an empty string. */ getRegExp(key: string): RegExp | undefined; /** * Returns an array of all RegExp values (`/value/`) with the given keys (case-insensitive), * or without a key by passing an empty string. */ getRegExps(keyOrKeys?: string | string[]): RegExp[]; /** * Returns the last boolean value with the given key (case-insensitive). */ getBoolean(key: string): boolean | undefined; } type MetaOptionBase = { index: number; raw: string; key: string | undefined; valueStartDelimiter: string; valueEndDelimiter: string; }; type MetaOptionString = MetaOptionBase & { kind: 'string'; value: string; }; type MetaOptionRange = MetaOptionBase & { kind: 'range'; value: string; }; type MetaOptionRegExp = MetaOptionBase & { kind: 'regexp'; value: RegExp; }; type MetaOptionBoolean = MetaOptionBase & { kind: 'boolean'; value: boolean; }; type MetaOption = MetaOptionString | MetaOptionRange | MetaOptionRegExp | MetaOptionBoolean; type MetaOptionKind = MetaOption['kind']; type PluginStyles = { pluginName: string; styles: string; }; /** * A union of VS Code colors that we know the default values for. The default values are required * because VS Code themes do not need to define all colors, only the ones they want to change. * * This is not an exhaustive list of all VS Code colors and does not need to be. If a color is * missing here, it can still be set by themes and used by plugins - it will just have no defaults. */ type VSCodeDefaultColorKey = 'focusBorder' | 'foreground' | 'disabledForeground' | 'descriptionForeground' | 'errorForeground' | 'icon.foreground' | 'contrastActiveBorder' | 'contrastBorder' | 'textBlockQuote.background' | 'textBlockQuote.border' | 'textCodeBlock.background' | 'textLink.activeForeground' | 'textLink.foreground' | 'textPreformat.foreground' | 'textSeparator.foreground' | 'editor.background' | 'editor.foreground' | 'editorLineNumber.foreground' | 'editorLineNumber.activeForeground' | 'editorActiveLineNumber.foreground' | 'editor.selectionBackground' | 'editor.inactiveSelectionBackground' | 'editor.selectionHighlightBackground' | 'editorError.foreground' | 'editorWarning.foreground' | 'editorInfo.foreground' | 'editorHint.foreground' | 'problemsErrorIcon.foreground' | 'problemsWarningIcon.foreground' | 'problemsInfoIcon.foreground' | 'editor.findMatchBackground' | 'editor.findMatchHighlightBackground' | 'editor.findRangeHighlightBackground' | 'editorLink.activeForeground' | 'editorLightBulb.foreground' | 'editorLightBulbAutoFix.foreground' | 'diffEditor.insertedTextBackground' | 'diffEditor.insertedTextBorder' | 'diffEditor.removedTextBackground' | 'diffEditor.removedTextBorder' | 'diffEditor.insertedLineBackground' | 'diffEditor.removedLineBackground' | 'editorStickyScroll.background' | 'editorStickyScrollHover.background' | 'editorInlayHint.background' | 'editorInlayHint.foreground' | 'editorInlayHint.typeForeground' | 'editorInlayHint.typeBackground' | 'editorInlayHint.parameterForeground' | 'editorInlayHint.parameterBackground' | 'editorPane.background' | 'editorGroup.emptyBackground' | 'editorGroup.focusedEmptyBorder' | 'editorGroupHeader.tabsBackground' | 'editorGroupHeader.tabsBorder' | 'editorGroupHeader.noTabsBackground' | 'editorGroupHeader.border' | 'editorGroup.border' | 'editorGroup.dropBackground' | 'editorGroup.dropIntoPromptForeground' | 'editorGroup.dropIntoPromptBackground' | 'editorGroup.dropIntoPromptBorder' | 'sideBySideEditor.horizontalBorder' | 'sideBySideEditor.verticalBorder' | 'scrollbar.shadow' | 'scrollbarSlider.background' | 'scrollbarSlider.hoverBackground' | 'scrollbarSlider.activeBackground' | 'panel.background' | 'panel.border' | 'panelTitle.activeBorder' | 'panelTitle.activeForeground' | 'panelTitle.inactiveForeground' | 'panelSectionHeader.background' | 'terminal.background' | 'widget.shadow' | 'editorWidget.background' | 'editorWidget.foreground' | 'editorWidget.border' | 'quickInput.background' | 'quickInput.foreground' | 'quickInputTitle.background' | 'pickerGroup.foreground' | 'pickerGroup.border' | 'editor.hoverHighlightBackground' | 'editorHoverWidget.background' | 'editorHoverWidget.foreground' | 'editorHoverWidget.border' | 'editorHoverWidget.statusBarBackground' | 'titleBar.activeBackground' | 'titleBar.activeForeground' | 'titleBar.inactiveBackground' | 'titleBar.inactiveForeground' | 'titleBar.border' | 'toolbar.hoverBackground' | 'toolbar.activeBackground' | 'tab.activeBackground' | 'tab.unfocusedActiveBackground' | 'tab.inactiveBackground' | 'tab.unfocusedInactiveBackground' | 'tab.activeForeground' | 'tab.inactiveForeground' | 'tab.unfocusedActiveForeground' | 'tab.unfocusedInactiveForeground' | 'tab.hoverBackground' | 'tab.unfocusedHoverBackground' | 'tab.hoverForeground' | 'tab.unfocusedHoverForeground' | 'tab.border' | 'tab.lastPinnedBorder' | 'tab.activeBorder' | 'tab.unfocusedActiveBorder' | 'tab.activeBorderTop' | 'tab.unfocusedActiveBorderTop' | 'tab.hoverBorder' | 'tab.unfocusedHoverBorder' | 'tab.activeModifiedBorder' | 'tab.inactiveModifiedBorder' | 'tab.unfocusedActiveModifiedBorder' | 'tab.unfocusedInactiveModifiedBorder' | 'badge.background' | 'badge.foreground' | 'button.background' | 'button.foreground' | 'button.border' | 'button.separator' | 'button.hoverBackground' | 'button.secondaryBackground' | 'button.secondaryForeground' | 'button.secondaryHoverBackground' | 'dropdown.background' | 'dropdown.foreground' | 'dropdown.border' | 'list.activeSelectionBackground' | 'list.activeSelectionForeground' | 'tree.indentGuidesStroke' | 'input.background' | 'input.foreground' | 'input.placeholderForeground' | 'inputOption.activeBorder' | 'inputOption.hoverBackground' | 'inputOption.activeBackground' | 'inputOption.activeForeground' | 'inputValidation.infoBackground' | 'inputValidation.infoBorder' | 'inputValidation.warningBackground' | 'inputValidation.warningBorder' | 'inputValidation.errorBackground' | 'inputValidation.errorBorder' | 'keybindingLabel.background' | 'keybindingLabel.foreground' | 'keybindingLabel.border' | 'keybindingLabel.bottomBorder' | 'menu.foreground' | 'menu.background' | 'menu.selectionForeground' | 'menu.selectionBackground' | 'menu.separatorBackground' | 'editor.snippetTabstopHighlightBackground' | 'editor.snippetFinalTabstopHighlightBorder' | 'terminal.ansiBlack' | 'terminal.ansiRed' | 'terminal.ansiGreen' | 'terminal.ansiYellow' | 'terminal.ansiBlue' | 'terminal.ansiMagenta' | 'terminal.ansiCyan' | 'terminal.ansiWhite' | 'terminal.ansiBrightBlack' | 'terminal.ansiBrightRed' | 'terminal.ansiBrightGreen' | 'terminal.ansiBrightYellow' | 'terminal.ansiBrightBlue' | 'terminal.ansiBrightMagenta' | 'terminal.ansiBrightCyan' | 'terminal.ansiBrightWhite'; type VSCodeThemeType = 'dark' | 'light'; type VSCodeWorkbenchColors = { [key in VSCodeDefaultColorKey]: string; } & { [key: string]: string; }; /** * Represents a strongly typed set of style settings provided by a plugin (or core). * * The constructor expects an object with a `defaultSettings` property. This property must contain * the default values for all settings and will be made available as a public instance property. * Allowed default value types are plain values (e.g. strings), an array of two values * to provide a dark and light variant, or resolver functions that return one of these types. * * If you are writing a plugin that provides style overrides, please merge your style overrides * into the `StyleOverrides` interface declaration provided by the `@expressive-code/core` module. * You can see an example of this below. * * As a plugin author, you should also assign an instance of this class to your plugin's * `styleSettings` property. This allows the engine to automatically declare CSS variables * for your style settings in all theme variants defined in the config. * * To consume the CSS variables in your plugin's `baseStyles` or anywhere else, see the * {@link cssVar} method to get a CSS variable reference to any style setting. * * If CSS variables should not be generated for some of your style settings, you can exclude them * using the `cssVarExclusions` property of the object passed to the constructor. * * @example * // When using TypeScript: Declare the types of your style settings * interface FramesStyleSettings { * fontFamily: string * fontSize: string * minContrast: string * titleBarForeground: string * } * * // When using TypeScript: Merge your style settings into the core module's `StyleSettings` * declare module '@expressive-code/core' { * export interface StyleSettings { * frames: FramesStyleSettings * } * } * * const framesStyleSettings = new PluginStyleSettings({ * defaultValues: { * frames: { * fontFamily: 'sans-serif', * fontSize: '1rem', * minContrast: '5', * titleBarForeground: ({ theme }) => theme.colors['editor.foreground'], * } * }, * cssVarExclusions: ['frames.minContrast'], * }) * * // ↓↓↓ * * framesStyleSettings.defaultValues.frames.fontFamily // 'sans-serif' * framesStyleSettings.defaultValues.frames.fontSize // '1rem' * framesStyleSettings.defaultValues.frames.minContrast // '5' * framesStyleSettings.defaultValues.frames.titleBarForeground // ({ theme }) => theme.colors['editor.foreground'] */ declare class PluginStyleSettings { readonly defaultValues: Partial; readonly cssVarExclusions: StyleSettingPath[]; constructor({ defaultValues, cssVarExclusions }: { defaultValues: Partial; cssVarExclusions?: StyleSettingPath[] | undefined; }); } interface CoreStyleSettings { /** * Border radius of code blocks. * @default '0.3rem' */ borderRadius: string; /** * Border width of code blocks. * @default '1.5px' */ borderWidth: string; /** * Border color of code blocks. * @default * ({ theme }) => theme.colors['titleBar.border'] || lighten(theme.colors['editor.background'], theme.type === 'dark' ? 0.5 : -0.15) || 'transparent' */ borderColor: string; /** * Font family of code content. * @default "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace" */ codeFontFamily: string; /** * Font size of code content. * @default '0.85rem' */ codeFontSize: string; /** * Font weight of code content. * @default '400' */ codeFontWeight: string; /** * Font line height of code content. * @default '1.65' */ codeLineHeight: string; /** * Block-level padding (= top and bottom padding in horizontal writing mode) * around the code content inside code blocks. * @default '1rem' */ codePaddingBlock: string; /** * Inline-level padding (= left and right padding in horizontal writing mode) * around the code content inside code blocks. * @default '1.35rem' */ codePaddingInline: string; /** * Background color of code blocks. * @default * ({ theme }) => theme.colors['editor.background'] */ codeBackground: string; /** * Foreground color of code, unless overwritten by syntax highlighting. * @default * ({ theme }) => theme.colors['editor.foreground'] */ codeForeground: string; /** * Background color of selected code, unless selection color customization is disabled * by the option `useThemedSelectionColors`. * @default * ({ theme }) => theme.colors['editor.selectionBackground'] */ codeSelectionBackground: string; /** * Default color of the border between the gutter and code content, * unless overwritten by a line-level annotation. * * Only visible if a gutter is present (e.g. to display line numbers). * * @default * ({ theme }) => lighten(theme.colors['editor.background'], theme.type === 'dark' ? 0.2 : -0.15) */ gutterBorderColor: string; /** * Width of the border between the gutter and code content. * * @default '1.5px' */ gutterBorderWidth: string; /** * Default foreground color of gutter elements. * * @default * ({ theme, resolveSetting }) => ensureColorContrastOnBackground(theme.colors['editorLineNumber.foreground'] || resolveSetting('codeForeground'), resolveSetting('codeBackground'), 3.3, 3.6) */ gutterForeground: string; /** * Default foreground color of gutter elements in highlighted lines. * * @default * ({ theme, resolveSetting }) => ensureColorContrastOnBackground(theme.colors['editorLineNumber.activeForeground'] || theme.colors['editorLineNumber.foreground'] || resolveSetting('codeForeground'), resolveSetting('codeBackground'), 4.5, 5) */ gutterHighlightForeground: string; /** * Font family of UI elements. * @default "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'" */ uiFontFamily: string; /** * Font size of UI elements. * @default '0.9rem' */ uiFontSize: string; /** * Font weight of UI elements. * @default '400' */ uiFontWeight: string; /** * Font line height of UI elements. * @default '1.65' */ uiLineHeight: string; /** * Block-level padding (= top and bottom padding in horizontal writing mode) * of UI elements like tabs, buttons etc. * @default '0.25rem' */ uiPaddingBlock: string; /** * Inline-level padding (= left and right padding in horizontal writing mode) * of UI elements like tabs, buttons etc. * @default '1rem' */ uiPaddingInline: string; /** * Background color of selected UI elements, unless selection color customization is disabled * by the option `useThemedSelectionColors`. * @default * ({ theme }) => theme.colors['menu.selectionBackground'] */ uiSelectionBackground: string; /** * Foreground color of selected UI elements, unless selection color customization is disabled * by the option `useThemedSelectionColors`. * @default * ({ theme }) => theme.colors['menu.selectionForeground'] */ uiSelectionForeground: string; /** * Color of the focus border around focused elements. * @default * ({ theme }) => theme.colors['focusBorder'] */ focusBorder: string; /** * Color of the scrollbar thumb, unless scrollbar color customization is disabled * by the option `useThemedScrollbars`. * @default * ({ theme }) => theme.colors['scrollbarSlider.background'] */ scrollbarThumbColor: string; /** * Color of the scrollbar thumb when hovered, unless scrollbar color customization is disabled * by the option `useThemedScrollbars`. * @default * ({ theme }) => theme.colors['scrollbarSlider.hoverBackground'] */ scrollbarThumbHoverColor: string; } interface StyleSettings extends CoreStyleSettings { } /** * The value of a single style setting. You can either set it to a string, * or an array of two strings. * * If you use the array form, the first value will be used for dark themes, * and the second value for light themes. */ type StyleValueOrValues = string | [dark: string, light: string]; /** * A function that resolves a single style setting to a {@link StyleValueOrValues}. * * You can assign this to any style setting to dynamically generate style values * based on the current theme. * * This function is called once for each style variant in the engine's `styleVariants` array, * which includes one entry per theme in the engine's `themes` configuration option. */ type StyleResolverFn = (context: { theme: ExpressiveCodeTheme; /** The index in the engine's `styleVariants` array that's currently being resolved. */ styleVariantIndex: number; resolveSetting: (settingPath: StyleSettingPath) => string; }) => StyleValueOrValues; /** * This is the value type for all style overrides. * It allows either static style values or a resolver function. */ type UnresolvedStyleValue = StyleValueOrValues | StyleResolverFn; type UnresolvedPluginStyleSettings = { [SettingName in keyof T]: UnresolvedStyleValue; }; type Keys = Exclude; type FlattenKeys = { [K in Keys]: T[K] extends object ? `${K}.${Keys}` : K; }[Keys]; type StyleSettingPath = FlattenKeys; type UnresolvedStyleSettings = { [K in keyof StyleSettings]: StyleSettings[K] extends object ? UnresolvedPluginStyleSettings : UnresolvedStyleValue; }; type StyleOverrides = Partial<{ [K in keyof StyleSettings]: StyleSettings[K] extends object ? Partial> : UnresolvedStyleValue; }>; type ResolvedStyleSettingsByPath = Map; /** * A map of long terms commonly found in style setting paths to shorter alternatives that are * still human-readable. These replacements are automatically applied by {@link getCssVarName} * when generating CSS variable names to keep them fairly short. * * Plugins can add their own replacements to this map by importing this constant and calling * `cssVarReplacements.set('myLongTerm', 'myLt')` inside their plugin initialization function. */ declare const cssVarReplacements: Map; /** * Generates a CSS variable name for a given style setting path. * * Performs the following transformations on the path: * - To avoid name collisions, the name is prefixed with `--ec-`. * - All dots in the path are replaced with dashes. * - Various common terms are replaced with shorter alternatives to reduce CSS size * (see {@link cssVarReplacements}). */ declare function getCssVarName(styleSetting: StyleSettingPath): string; declare const codeLineClass = "ec-line"; type StyleVariant = { theme: ExpressiveCodeTheme; resolvedStyleSettings: ResolvedStyleSettingsByPath; cssVarDeclarations: Map; }; /** * Maps the given `themes` to an array of {@link StyleVariant `StyleVariant`} objects, * doing the following per theme: * - Resolving all style settings contributed by core & plugins, * respecting both theme and global `styleOverrides` (theme overrides take precedence) * - Generating CSS variable declarations for the resolved style settings */ declare function resolveStyleVariants({ themes, plugins, styleOverrides, cssVarName, }: { themes: ExpressiveCodeTheme[]; plugins: readonly ExpressiveCodePlugin[]; styleOverrides: StyleOverrides; cssVarName: ResolverContext['cssVarName']; }): StyleVariant[]; /** * Overrides the alpha value of a color with the given value. * Values should be between 0 and 1. */ declare function setAlpha(input: string, newAlpha: number): string; /** * Multiplies the existing alpha value of a color with the given factor. * Automatically limits the resulting alpha value to the range 0 to 1. */ declare function multiplyAlpha(input: string, factor: number): string; /** * Returns the luminance of a color. * Luminance values are between 0 and 1. */ declare function getLuminance(input: string): number; /** * Mixes a color with white or black to achieve the desired luminance. * Luminance values should be between 0 and 1. */ declare function setLuminance(input: string, targetLuminance: number): string; /** * Lightens a color by the given amount. * Automatically limits the resulting lightness value to the range 0 to 1. */ declare function lighten(input: string, amount: number): string; /** * Darkens a color by the given amount. * Automatically limits the resulting lightness value to the range 0 to 1. */ declare function darken(input: string, amount: number): string; /** * Mixes the second color into the first color by the given amount. * Amount should be between 0 and 1. */ declare function mix(input: string, mixinInput: string, amount: number): string; /** * Computes how the first color would look on top of the second color. */ declare function onBackground(input: string, background: string): string; declare function getColorContrast(color1: string, color2: string): number; declare function getColorContrastOnBackground(input: string, background: string): number; /** * Modifies the luminance and/or the alpha value of a color to ensure its color contrast * on the given background color is within the given range. * * - If the contrast is too low, the luminance is either increased or decreased first, * and then the alpha value is increased (if required). * - If the contrast is too high, only the alpha value is decreased. * * If the target contrast cannot be reached, the function will try to get as close as possible. */ declare function ensureColorContrastOnBackground(input: string, background: string, minContrast?: number, maxContrast?: number): string; declare function changeLuminanceToReachColorContrast(input1: string, input2: string, minContrast?: number): string; declare function changeAlphaToReachColorContrast(input: string, background: string, minContrast?: number, maxContrast?: number): string; /** * Given any number of input colors, which may include CSS variables with optional fallbacks, * returns the first static color. * * Returns `undefined` if no parseable static color can be found. */ declare function getFirstStaticColor(...inputs: (string | undefined)[]): string | undefined; /** * Determine a static background color based on the given style variant, * trying to resolve fallback values of CSS variables if necessary. * * This color is intended to be used for contrast calculations, not as an actual background color. */ declare function getStaticBackgroundColor(styleVariant: StyleVariant): string; type ChromaticRecolorTarget = { /** * The target hue in degrees (0 – 360). */ hue: number; /** * The target chroma (0 – 0.4). * * If the input color's lightness is very high, the resulting chroma may be lower * than this value. This avoids results that appear too saturated in comparison * to the input color. */ chroma: number; /** * The lightness (0 – 1) that the target chroma was measured at. * * If given, the chroma will be adjusted relative to this lightness * before applying it to the input color. */ chromaMeasuredAtLightness?: number | undefined; }; /** * Adjusts the input color based on the given target color while keeping * the input lightness unchanged. Uses the OKLCH color space to ensure * the resulting color is perceptually similar to the input color. * * The target color can either be defined as a string (e.g. a hex color), * or as an object with `hue` and `chroma`. * * Note that the resulting color's chroma may be lower than the target value * for input colors with very high lightness. This avoids results * that appear too saturated in comparison to the input color. */ declare function chromaticRecolor(input: string, target: string | ChromaticRecolorTarget): string; declare function toHexColor(input: TinyColor | string): string; declare function toRgbaString(input: string): string; declare class ExpressiveCodeTheme implements Omit { name: string; type: VSCodeThemeType; colors: VSCodeWorkbenchColors; fg: string; bg: string; semanticHighlighting: boolean; settings: ThemeSetting[]; styleOverrides: StyleOverrides; /** * Loads the given theme for use with Expressive Code. Supports both Shiki and VS Code themes. * * You can also pass an existing `ExpressiveCodeTheme` instance to create a copy of it. * * Note: To save on bundle size, this constructor does not support loading themes * bundled with Shiki by name (e.g. `dracula`). Instead, import Shiki's `loadTheme` * function yourself, use it to load its bundled theme (e.g. `themes/dracula.json`), * and pass the result to this constructor. */ constructor(theme: ExpressiveCodeThemeInput); /** * Applies chromatic adjustments to entire groups of theme colors while keeping their * relative lightness and alpha components intact. This can be used to quickly create * theme variants that fit the color scheme of any website or brand. * * Adjustments can either be defined as hue and chroma values in the OKLCH color space * (range 0–360 for hue, 0–0.4 for chroma), or these values can be extracted from * hex color strings (e.g. `#3b82f6`). * * You can target predefined groups of theme colors (e.g. `backgrounds`, `accents`) * and/or use the `custom` property to define your own groups of theme colors to be adjusted. * Each custom group must contain a `themeColorKeys` property with an array of VS Code * theme color keys (e.g. `['panel.background', 'panel.border']`) and a `targetHueAndChroma` * property that accepts the same adjustment target values as `backgrounds` and `accents`. * Custom groups will be applied in the order they are defined. * * Returns the same `ExpressiveCodeTheme` instance to allow chaining. */ applyHueAndChromaAdjustments(adjustments: { backgrounds?: string | ChromaticRecolorTarget | undefined; accents?: string | ChromaticRecolorTarget | undefined; custom?: { themeColorKeys: string[]; targetHueAndChroma: string | ChromaticRecolorTarget; }[] | undefined; }): this; /** * Processes the theme's syntax highlighting colors to ensure a minimum contrast ratio * between foreground and background colors. * * The default value of 5.5 ensures optimal accessibility with a contrast ratio of 5.5:1. * * You can optionally pass a custom background color to use for the contrast checks. * By default, the theme's background color will be used. * * Returns the same `ExpressiveCodeTheme` instance to allow chaining. */ ensureMinSyntaxHighlightingColorContrast(minContrast?: number, backgroundColor?: string): this; /** * Parses the given theme settings into a properly typed format * that can be used by both Expressive Code and Shiki. * * As theme scopes can be defined as either a comma-separated string, or an array of strings, * they will always be converted to their array form to simplify further processing. * * Also recreates known object properties to prevent accidental mutation * of the original settings when copying a theme. */ private parseThemeSettings; /** * Attempts to parse the given JSON string as a theme. * * As some themes follow the JSONC format and may contain comments and trailing commas, * this method will attempt to strip them before parsing the result. */ static fromJSONString(json: string): ExpressiveCodeTheme; } type ExpressiveCodeThemeInput = Partial> & { type?: VSCodeThemeType | string | undefined; tokenColors?: unknown | undefined; semanticHighlighting?: boolean | undefined; styleOverrides?: StyleOverrides | undefined; }; type ThemeSetting = { name?: string | undefined; scope?: string[] | undefined; settings: { foreground?: string | undefined; fontStyle?: string | undefined; }; }; interface ExpressiveCodeLoggerOptions { label: string; debug(message: string): void; info(message: string): void; warn(message: string): void; error(message: string): void; } declare class ExpressiveCodeLogger implements ExpressiveCodeLoggerOptions { readonly label: string; readonly logger: Partial; constructor(logger?: Partial); debug(message: string): void; info(message: string): void; warn(message: string): void; error(message: string): void; } interface ExpressiveCodeEngineConfig { /** * The color themes that should be available for your code blocks. * * CSS variables will be generated for all themes, allowing to select the theme to display * using CSS. If you specify one dark and one light theme, a `prefers-color-scheme` media query * will also be generated by default. You can customize this to match your site's needs * through the `useDarkModeMediaQuery` and `themeCssSelector` options. * * Defaults to the `github-dark` and `github-light` themes. */ themes?: ExpressiveCodeTheme[] | undefined; /** * Determines if Expressive Code should process the syntax highlighting colors of all themes * to ensure an accessible minimum contrast ratio between foreground and background colors. * * Defaults to `5.5`, which ensures a contrast ratio of at least 5.5:1. * You can change the desired contrast ratio by providing another value, * or turn the feature off by setting this option to `0`. */ minSyntaxHighlightingColorContrast?: number | undefined; /** * Determines if CSS code is generated that uses a `prefers-color-scheme` media query * to automatically switch between light and dark themes based on the user's system preferences. * * Defaults to `true` if your `themes` option is set to one dark and one light theme * (which is the default), and `false` otherwise. */ useDarkModeMediaQuery?: boolean | undefined; /** * Allows to customize the base selector used to scope theme-dependent CSS styles. * * By default, this selector is `:root`, which ensures that all required CSS variables * are globally available. */ themeCssRoot?: string | undefined; /** * Allows to customize the selectors used to manually switch between multiple themes. * * These selectors are useful if you want to allow your users to choose a theme * instead of relying solely on the media query generated by `useDarkModeMediaQuery`. * * Default value: * ```js * (theme) => `[data-theme='${theme.name}']` * ``` * * You can add a theme selector either to your `` element (which is targeted * by the `themeCssRoot` default value of `:root`), and/or any individual code block wrapper. * * For example, when using the default settings, selecting the theme `github-light` * for the entire page would look like this: * ```html * * ``` * * If your site's theme switcher requires a different approach, you can customize the selectors * using this option. For example, if you want to use class names instead of a data attribute, * you could set this option to a function that returns `.theme-${theme.name}` instead. * * If you want to prevent the generation of theme-specific CSS rules altogether, * you can set this to `false` or return it from the function. */ themeCssSelector?: ((theme: ExpressiveCodeTheme, context: { styleVariants: StyleVariant[]; }) => string | false) | false | undefined; /** * Allows to specify a CSS cascade layer name that should be used for all generated CSS. * * If you are using [cascade layers](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers) * on your site to control the order in which CSS rules are applied, set this option to * a non-empty string, and Expressive Code will wrap all of its generated CSS styles * in a `@layer` rule with the given name. */ cascadeLayer?: string | undefined; /** * Determines if code blocks should be protected against influence from site-wide styles. * * Defaults to `true`, which causes Expressive Code to use the declaration `all: revert` * to revert all CSS properties to the values they would have had without any site-wide styles. * This ensures the most predictable results out of the box. * * You can set this to `false` if you want your site-wide styles to influence the code blocks. */ useStyleReset?: boolean | undefined; /** * This optional function is called once per theme during engine initialization * with the loaded theme as its only argument. * * It allows customizing the loaded theme and can be used for various purposes: * - You can change a theme's `name` property to influence the CSS needed to select it * (e.g., when using the default settings for `themeCssRoot` and `themeCssSelector`, * setting `theme.name = 'dark'` will allow theme selection using ``). * - You can create color variations of themes by using `theme.applyHueAndChromaAdjustments()`. * * You can optionally return an `ExpressiveCodeTheme` instance from this function to replace * the theme provided in the configuration. This allows you to create a copy of the theme * and modify it without affecting the original instance. */ customizeTheme?: ((theme: ExpressiveCodeTheme) => ExpressiveCodeTheme | void) | undefined; /** * Whether the themes are allowed to style the scrollbars. Defaults to `true`. * * If set to `false`, scrollbars will be rendered using the browser's default style. * * Note that you can override the individual scrollbar colors defined by the theme * using the `styleOverrides` option. */ useThemedScrollbars?: boolean | undefined; /** * Whether the themes are allowed to style selected text. Defaults to `false`. * * By default, Expressive Code renders selected text in code blocks using the browser's * default style to maximize accessibility. If you want your selections to be more colorful, * you can set this option to `true` to allow using theme selection colors instead. * * Note that you can override the individual selection colors defined by the theme * using the `styleOverrides` option. */ useThemedSelectionColors?: boolean | undefined; /** * An optional set of style overrides that can be used to customize the appearance of * the rendered code blocks without having to write custom CSS. * * The root level of this nested object contains core styles like colors, fonts, paddings * and more. Plugins can contribute their own style settings to this object as well. * For example, if the `frames` plugin is enabled, you can override its `shadowColor` by * setting `styleOverrides.frames.shadowColor` to a color value. * * If any of the settings are not given, default values will be used or derived from the theme. * * **Tip:** If your site uses CSS variables for styling, you can also use these overrides * to replace any core style with a CSS variable reference, e.g. `var(--your-css-var)`. */ styleOverrides?: StyleOverrides | undefined; /** * The locale that should be used for text content. Defaults to `en-US`. */ defaultLocale?: string | undefined; /** * An optional set of default props for all code blocks in your project. * * For example, setting this to `{ wrap: true }` enables word wrapping on all code blocks * by default, saving you from having to manually set this option on every single code block. */ defaultProps?: (ExpressiveCodeBlock['props'] & { /** * Allows to override the default props based on a code block's * syntax highlighting language. * * Use the language IDs as keys and an object containing the props as values. * The keys also support specifying multiple language IDs separated by commas * to apply the same props to multiple languages. * * @example * ```js * defaultProps: { * wrap: true, * overridesByLang: { * 'bash,sh,zsh': { wrap: false } * } * } * ``` */ overridesByLang?: Record | undefined; }) | undefined; /** * An optional array of plugins that should be used when rendering code blocks. * * To add a plugin, import its initialization function and call it inside this array. * * If the plugin has any configuration options, you can pass them to the initialization * function as an object containing your desired property values. * * If any nested arrays are found inside the `plugins` array, they will be flattened * before processing. */ plugins?: (ExpressiveCodePlugin | ExpressiveCodePlugin[])[] | undefined; logger?: Partial | undefined; /** * @deprecated Efficient multi-theme support is now a core feature, so the `theme` option * was deprecated in favor of the new array `themes`. Please migrate your existing config * to use `themes` and ensure it is an array. If you only need a single theme, your `themes` * array can contain just this one theme. However, please consider the benefits of providing * multiple themes. See the `themes` option for more details. */ theme?: ExpressiveCodeTheme | undefined; } type ResolvedExpressiveCodeEngineConfig = { [P in keyof Omit]-?: Exclude; } & { customizeTheme: ExpressiveCodeEngineConfig['customizeTheme']; plugins: readonly ExpressiveCodePlugin[]; logger: ExpressiveCodeLogger; }; /** * The Expressive Code engine is responsible for rendering code blocks to a * [Hypertext Abstract Syntax Tree (HAST)](https://github.com/syntax-tree/hast) * that can be serialized to HTML, as well as generating the required CSS styles * and JS modules. * * It also provides read-only access to all resolved configuration options * through its public properties. */ declare class ExpressiveCodeEngine implements ResolvedExpressiveCodeEngineConfig { /** * Creates a new instance of the Expressive Code engine. * * To minimize overhead caused by loading plugins, you can create a single instance * for your application and keep using it to render all your code blocks. */ constructor(config: ExpressiveCodeEngineConfig); /** * Renders the given code block(s) and returns the rendered group & block ASTs, * the rendered code block contents after all transformations have been applied, * and a set of non-global CSS styles required by the rendered code blocks. * * In Expressive Code, all processing of your code blocks and their metadata * is performed by plugins. To render markup around lines or inline ranges of characters, * the `render` method calls the hook functions registered by all added plugins. * * @param input * The code block(s) to render. Can either be an `ExpressiveCodeBlockOptions` object * containing the properties required to create a new `ExpressiveCodeBlock` internally, * an existing `ExpressiveCodeBlock`, or an array containing any combination of these. * * @param options * Optional configuration options for the rendering process. */ render(input: RenderInput, options?: RenderOptions): Promise<{ renderedGroupAst: hast.Element; renderedGroupContents: RenderedGroupContents; styles: Set; }>; /** * Returns a string containing all CSS styles that should be added to every page * using Expressive Code. These styles are static base styles which do not depend * on the configured theme(s). * * The calling code must take care of actually adding the returned styles to the page. * * Please note that the styles contain references to CSS variables, which must also * be added to the page. These can be obtained by calling {@link getThemeStyles}. */ getBaseStyles(): Promise; /** * Returns a string containing theme-dependent styles that should be added to every page * using Expressive Code. These styles contain CSS variable declarations that are generated * automatically based on the configured {@link ExpressiveCodeEngineConfig.themes themes}, * {@link ExpressiveCodeEngineConfig.useDarkModeMediaQuery useDarkModeMediaQuery} and * {@link ExpressiveCodeEngineConfig.themeCssSelector themeCssSelector} config options. * * The first theme defined in the `themes` option is considered the "base theme", * for which a full set of CSS variables is declared and scoped to the selector * defined by the `themeCssRoot` option (defaults to `:root`). * * For all alternate themes, a differential set of CSS variables is declared for cases where * their values differ from the base theme, and scoped to theme-specific selectors that are * generated by combining `themeCssRoot` with the theme selector specified by this option. * * The calling code must take care of actually adding the returned styles to the page. * * Please note that these styles must be added to the page together with the base styles * returned by {@link getBaseStyles}. */ getThemeStyles(): Promise; /** * Returns an array of JavaScript modules (pure code without any wrapping `script` tags) * that should be added to every page containing code blocks. * * The contents are collected from the `jsModules` property of all registered plugins. * Any duplicates are removed. * * The calling code must take care of actually adding the collected scripts to the page. * For example, it could create site-wide JavaScript files from the returned modules * and refer to them in a script tag with `type="module"`, or it could insert them * into inline `