Files
website/node_modules/@expressive-code/core/dist/index.d.ts
2024-05-06 17:15:30 -04:00

1949 lines
91 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<K extends MetaOptionKind | undefined = undefined>(keyOrKeys?: string | string[], kind?: K): K extends "string" | "boolean" | "range" | "regexp" ? (Extract<MetaOptionString, {
kind: K;
}> | Extract<MetaOptionRange, {
kind: K;
}> | Extract<MetaOptionRegExp, {
kind: K;
}> | Extract<MetaOptionBoolean, {
kind: K;
}>)[] : MetaOption[];
value<K extends MetaOptionKind | undefined = undefined>(key: string, kind?: K): (K extends "string" | "boolean" | "range" | "regexp" ? Extract<MetaOptionString, {
kind: K;
}> | Extract<MetaOptionRange, {
kind: K;
}> | Extract<MetaOptionRegExp, {
kind: K;
}> | Extract<MetaOptionBoolean, {
kind: K;
}> : 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<UnresolvedStyleSettings>;
readonly cssVarExclusions: StyleSettingPath[];
constructor({ defaultValues, cssVarExclusions }: {
defaultValues: Partial<UnresolvedStyleSettings>;
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<T> = {
[SettingName in keyof T]: UnresolvedStyleValue;
};
type Keys<T> = Exclude<keyof T, symbol>;
type FlattenKeys<T> = {
[K in Keys<T>]: T[K] extends object ? `${K}.${Keys<T[K]>}` : K;
}[Keys<T>];
type StyleSettingPath = FlattenKeys<StyleSettings>;
type UnresolvedStyleSettings = {
[K in keyof StyleSettings]: StyleSettings[K] extends object ? UnresolvedPluginStyleSettings<StyleSettings[K]> : UnresolvedStyleValue;
};
type StyleOverrides = Partial<{
[K in keyof StyleSettings]: StyleSettings[K] extends object ? Partial<UnresolvedPluginStyleSettings<StyleSettings[K]>> : UnresolvedStyleValue;
}>;
type ResolvedStyleSettingsByPath = Map<StyleSettingPath, string>;
/**
* 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<string, string>;
/**
* 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<string, string>;
};
/**
* 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<ThemeRegistration, 'type' | 'colors' | 'settings'> {
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 0360 for hue, 00.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<Omit<ExpressiveCodeTheme | ThemeRegistration, 'type'>> & {
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<ExpressiveCodeLoggerOptions>;
constructor(logger?: Partial<ExpressiveCodeLoggerOptions>);
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 `<html>` 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
* <html data-theme="github-light">
* ```
*
* 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 `<html data-theme="dark">`).
* - 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<string, ExpressiveCodeBlock['props']> | 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<ExpressiveCodeLoggerOptions> | 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<ExpressiveCodeEngineConfig, 'customizeTheme' | 'plugins' | 'theme' | 'logger'>]-?: Exclude<ExpressiveCodeEngineConfig[P], undefined>;
} & {
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<string>;
}>;
/**
* 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<string>;
/**
* 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<string>;
/**
* 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 `<script type="module">` elements.
*/
getJsModules(): Promise<string[]>;
private cssVar;
private getResolverContext;
readonly themes: ExpressiveCodeTheme[];
readonly minSyntaxHighlightingColorContrast: number;
readonly useDarkModeMediaQuery: boolean;
readonly themeCssRoot: string;
readonly themeCssSelector: NonNullable<ExpressiveCodeEngineConfig['themeCssSelector']>;
readonly cascadeLayer: string;
readonly useStyleReset: boolean;
readonly customizeTheme: ExpressiveCodeEngineConfig['customizeTheme'];
readonly useThemedScrollbars: boolean;
readonly useThemedSelectionColors: boolean;
readonly styleOverrides: StyleOverrides;
readonly styleVariants: StyleVariant[];
readonly defaultLocale: string;
readonly defaultProps: NonNullable<ExpressiveCodeEngineConfig['defaultProps']>;
readonly plugins: readonly ExpressiveCodePlugin[];
readonly logger: ExpressiveCodeLogger;
}
type RenderInput = ExpressiveCodeBlockOptions | ExpressiveCodeBlock | (ExpressiveCodeBlockOptions | ExpressiveCodeBlock)[];
interface RenderOptions {
/**
* An optional handler function that can initialize plugin data for the
* code block group before processing starts.
*
* Plugins can provide access to their data by exporting a const
* set to a `new AttachedPluginData(...)` instance (e.g. `myPluginData`).
*
* You can then import the const and set `onInitGroup` to a function that
* calls `myPluginData.setFor(group, { ...data... })`.
*/
onInitGroup?: ((groupContents: GroupContents) => void) | undefined;
}
type GroupContents = readonly {
codeBlock: ExpressiveCodeBlock;
}[];
type RenderedGroupContents = readonly {
codeBlock: ExpressiveCodeBlock;
renderedBlockAst: Element;
}[];
interface GutterElement {
/**
* When rendering code lines, the engine goes through all gutter elements registered by
* the installed plugins and calls this function to render the gutter element for that line.
*
* It is expected to return a HAST node that represents the gutter element. For example,
* the line numbers plugin uses the `hastscript` library here to create an HTML element
* containing the current line number.
*
* After rendering all gutter elements registered by the installed plugins, the engine adds
* the returned HAST nodes as children to the line's gutter container.
*
* Please ensure (e.g. through CSS defined in your plugin's base styles) that your gutter
* element has a fixed width across all lines, even if you don't render any content inside
* your element for some lines. As each line's gutter container is immediately followed
* by the line's code contents, the combined width of all gutter elements must stay constant
* to ensure that the code contents of all lines are aligned.
*/
renderLine(context: GutterRenderContext): Element;
/**
* Some plugins may render lines that are not part of the original code, e.g. to display
* the expected output of a call right inside the code block.
*
* To properly align such lines with the original code, plugins can request an empty line
* from the engine using the `renderEmptyLine` context function.
*
* When called, the engine goes through all gutter elements registered by the installed plugins
* and calls their `renderPlaceholder` function to render the placeholder gutter contents.
*/
renderPlaceholder(): Element;
/**
* Determines the phase in which this gutter element should be rendered.
* Rendering is done in phases, from `earliest` to `latest`.
* Elements with the same phase are rendered in the order they were added.
*
* The earlier a gutter element is rendered, the further to the beginning of the line
* it will be placed. For example, the line numbers plugin renders its gutter elements
* in the `earlier` phase to ensure that they are placed before most other gutter elements.
*
* The default phase is `normal`.
*/
renderPhase?: AnnotationRenderPhase | undefined;
}
type GutterRenderContext = ExpressiveCodeHookContextBase & {
line: ExpressiveCodeLine;
lineIndex: number;
};
interface ExpressiveCodeHookContextBase extends ResolverContext {
codeBlock: ExpressiveCodeBlock;
groupContents: GroupContents;
locale: string;
/**
* The Expressive Code engine configuration, with all optional properties
* resolved to their default values.
*/
config: ResolvedExpressiveCodeEngineConfig;
}
interface ExpressiveCodeHookContext extends ExpressiveCodeHookContextBase {
/**
* Adds CSS styles to the document that contains the rendered code.
*
* All styles are scoped to Expressive Code by default, so they will not affect
* the rest of the page. SASS-like nesting is supported. If you want to add global styles,
* you can use the `@at-root` rule or target `:root`, `html` or `body` in your selectors.
*
* The engine's `render` function returns all added styles in a string array along with
* the rendered group and block ASTs. The calling code must take care of actually adding
* these styles to the page. For example, it could insert them into a `<style>` element
* before the rendered code block.
*
* **Note for integration authors:** If you are rendering multiple code block groups on the
* same HTML page, you should deduplicate the returned styles at the page level.
* Expressive Code deduplicates styles added to the same group before returning them,
* but is not aware which styles are already present on the page.
*
* **Note for plugin authors:** If you are adding the same styles to every block,
* consider using the `baseStyles` property of the plugin instead. This allows integrations
* to optionally extract these styles into a separate CSS file.
*/
addStyles: (css: string) => void;
/**
* Registers a gutter element for the current code block.
*
* The engine calls the {@link GutterElement.renderLine `renderLine`} function
* of the gutter elements registered by all plugins for every line of the code block.
* The returned elements are then added as children to the line's gutter container.
*/
addGutterElement: (element: GutterElement) => void;
}
/**
* A context object that the engine passes to the `postprocessRenderedLine` hook function.
*
* In addition to the properties made available by {@link ExpressiveCodeHookContext},
* it provides access to information about the line currently being rendered,
* and allows modifying the rendered output.
*/
interface PostprocessRenderedLineContext extends Omit<ExpressiveCodeHookContext, 'addGutterElement'> {
/**
* A reference to the line that is currently being rendered. It is read-only at this point,
* but you can access all line properties, including its source code and annotations.
*/
line: ExpressiveCodeLine;
/**
* The 0-based index of the line inside the code block.
*/
lineIndex: number;
/**
* Allows modifying the line's rendered output. The `lineAst` property of this object contains
* the [Hypertext Abstract Syntax Tree (HAST)](https://github.com/syntax-tree/hast) node
* representing the rendered line.
*
* You have full control over the `lineAst` property to modify the rendered output.
* For example, you could add a class name to the line's root element, or you could wrap
* the entire line in a custom element.
*
* There is a wide range of existing utility packages that you can use to manipulate
* HAST elements. For more information, see the
* [list of utilities](https://github.com/syntax-tree/hast#list-of-utilities) in the
* HAST documentation.
*/
renderData: {
lineAst: Element;
};
/**
* Allows rendering an empty line that is not part of the original code.
*
* Some plugins may need to render lines that are not part of the original code, e.g. to display
* the expected output of a call right inside the code block. To align such lines with the
* original code, plugins can request an empty line from the engine using this function.
*/
renderEmptyLine: RenderEmptyLineFn;
}
/**
* A context object that the engine passes to the `postprocessRenderedBlock` hook function.
*
* In addition to the properties made available by {@link ExpressiveCodeHookContext},
* it provides access to render data of the code block currently being rendered,
* and allows modifying the rendered output.
*/
interface PostprocessRenderedBlockContext extends Omit<ExpressiveCodeHookContext, 'addGutterElement'> {
/**
* Allows modifying the block's rendered output. The `blockAst` property of this object contains
* the [Hypertext Abstract Syntax Tree (HAST)](https://github.com/syntax-tree/hast) node
* representing the rendered block.
*
* You have full control over the `blockAst` property to modify the rendered output.
* For example, you could add a class name to the block's root element,
* wrap the entire block in a custom element, or traverse its children
* to find specific elements and modify them.
*
* There is a wide range of existing utility packages that you can use to manipulate
* HAST elements. For more information, see the
* [list of utilities](https://github.com/syntax-tree/hast#list-of-utilities) in the
* HAST documentation.
*/
renderData: {
blockAst: Element;
};
/**
* Allows rendering an empty line that is not part of the original code.
*
* Some plugins may need to render lines that are not part of the original code, e.g. to display
* the expected output of a call right inside the code block. To align such lines with the
* original code, plugins can request an empty line from the engine using this function.
*/
renderEmptyLine: RenderEmptyLineFn;
}
type RenderEmptyLineFn = () => {
lineAst: Element;
gutterWrapper: Element | undefined;
codeWrapper: Element;
};
/**
* A context object that the engine passes to the `postprocessRenderedBlockGroup` hook function.
*
* It provides access to information about the code block group currently being rendered,
* and allows modifying the rendered output.
*/
interface PostprocessRenderedBlockGroupContext {
/**
* An array of objects, each containing a reference to the code block,
* and its rendered HAST output. This is the same HAST element per block that is also available
* in the `renderData` property of the `postprocessRenderedBlock` hook context.
*/
renderedGroupContents: RenderedGroupContents;
/**
* A list of styles that plugins added to the current code block group using the `addStyles`
* hook context function. Each item contains the plugin name and the styles it added.
* You have full control over the styles at this point and can add, modify or remove them
* as needed.
*/
pluginStyles: PluginStyles[];
/**
* See {@link ExpressiveCodeHookContext.addStyles}.
*/
addStyles: (css: string) => void;
/**
* Allows modifying the rendered output of a group of code blocks. The `groupAst` property of this object contains
* the [Hypertext Abstract Syntax Tree (HAST)](https://github.com/syntax-tree/hast) parent node
* surrounding all rendered blocks.
*
* This is the only property that allows you to modify the wrapper element of the entire group.
* You have full control over it to modify the rendered output.
* For example, you could add a class name to the groups root element,
* or you could wrap the entire group in a custom element.
*/
renderData: {
groupAst: Element;
};
}
/**
* The base type of all hooks. It is a function that gets called by the engine
* and receives a context object. The context type defaults to {@link ExpressiveCodeHookContext},
* but can vary by hook, so see the list of available hooks for the correct type.
*/
type ExpressiveCodeHook<ContextType = ExpressiveCodeHookContext> = (context: ContextType) => void | Promise<void>;
/** @internal */
interface ExpressiveCodePluginHooks_BeforeRendering {
/**
* Allows preprocessing the code block's {@link ExpressiveCodeBlock.language language}
* identifier before loading language-specific defaults into
* {@link ExpressiveCodeBlock.props props}.
*
* The Text Markers plugin uses this hook to override the `diff` language identifier
* with the language specified in the `lang` meta option (if given) to allow using diff syntax
* to mark inserted and deleted lines while using another language for syntax highlighting.
*/
preprocessLanguage?: ExpressiveCodeHook | undefined;
/**
* Allows preprocessing the meta string and the props before any plugins can
* modify the code.
*
* Instead of accessing the raw meta string, plugins are recommended to use the parsed version
* of the contained options through the {@link ExpressiveCodeBlock.metaOptions} property.
*
* As the code still matches the plaintext in the containing Markdown/MDX document at this
* point, this hook can be used to apply annotations by line numbers.
*/
preprocessMetadata?: ExpressiveCodeHook | undefined;
/**
* Allows preprocessing the code before any language-specific hooks are run.
*
* Plugins are expected to use this hook to remove any of their syntax that could disturb
* annotation plugins like syntax highlighters. Removed information can either be stored
* internally or used to create annotations.
*
* Plugins can also use this hook to insert new code, e.g. to add type information for
* syntax highlighters, or to provide functionality to include external files into the
* code block.
*/
preprocessCode?: ExpressiveCodeHook | undefined;
/**
* Allows analyzing the preprocessed code and collecting language-specific syntax annotations.
*
* This hook is used by syntax highlighting plugins to run the code through `Shiki` or
* `Shiki-Twoslash` and to create annotations from their highlighted tokens.
*
* These annotations are then available to the following hooks and will be used during
* rendering.
*/
performSyntaxAnalysis?: ExpressiveCodeHook | undefined;
/**
* Allows postprocessing the code plaintext after collecting syntax annotations.
*
* Plugins are expected to use this hook to remove any parts from the code
* that should not be contained in the output. For example, if a plugin added declarations
* or type information during the `preprocessCode` hook to provide information to the
* syntax highlighter, the declarations could now be removed again.
*
* After this hook has finished processing, the plaintext of all code lines becomes read-only.
*/
postprocessAnalyzedCode?: ExpressiveCodeHook | undefined;
/**
* Allows annotating the final code plaintext.
*
* As the code is read-only at this point, plugins can use this hook to create annotations
* on lines or inline ranges matching a specific search term.
*/
annotateCode?: ExpressiveCodeHook | undefined;
/**
* Allows applying final changes to annotations before rendering.
*
* After this hook has finished processing, all annotations become read-only.
*/
postprocessAnnotations?: ExpressiveCodeHook | undefined;
}
/** @internal */
interface ExpressiveCodePluginHooks_Rendering {
/**
* Allows editing the AST of a single line of code after all annotations were rendered.
*/
postprocessRenderedLine?: ExpressiveCodeHook<PostprocessRenderedLineContext> | undefined;
/**
* Allows editing the AST of the entire code block after all annotations were rendered
* and all lines were postprocessed.
*/
postprocessRenderedBlock?: ExpressiveCodeHook<PostprocessRenderedBlockContext> | undefined;
/**
* Allows editing the ASTs of all code blocks that were rendered as part of the same group,
* as well as the AST of the group root element that contains all group blocks.
*
* Groups are defined by the calling code. For example, a rehype plugin using Expressive Code
* to render code blocks could provide authors with a way to group related code blocks together.
*
* This hook is used by the frames plugin to display multiple code blocks as editor file tabs.
*
* Note: Even if a code block is not part of any group, this hook will still be called.
* Standalone code blocks are treated like a group containing only a single block.
*/
postprocessRenderedBlockGroup?: ExpressiveCodeHook<PostprocessRenderedBlockGroupContext> | undefined;
}
interface ExpressiveCodePluginHooks extends ExpressiveCodePluginHooks_BeforeRendering, ExpressiveCodePluginHooks_Rendering {
}
type ExpressiveCodePluginHookName = keyof ExpressiveCodePluginHooks;
/**
* Runs the given `runner` function for every hook that was registered by plugins
* for the given hook type.
*
* The runner function is called with an object containing the hook name, the hook function
* registered by the plugin, and the plugin that registered it.
*
* Errors occuring in the runner function are caught and rethrown with information about the
* plugin and hook that caused the error.
*/
declare function runHooks<HookType extends keyof ExpressiveCodePluginHooks>(key: HookType, context: {
plugins: readonly ExpressiveCodePlugin[];
config: ResolvedExpressiveCodeEngineConfig;
}, runner: (hook: {
hookName: HookType;
hookFn: NonNullable<ExpressiveCodePluginHooks[HookType]>;
plugin: ExpressiveCodePlugin;
}) => void | Promise<void>): Promise<void>;
/**
* An interface that defines an Expressive Code plugin. To add a custom plugin,
* you pass an object matching this interface into the `plugins` array property
* of the engine configuration.
*/
interface ExpressiveCodePlugin {
/**
* The display name of the plugin. This is the only required property.
* It is used by the engine to display messages concerning the plugin,
* e.g. when it encounters an error.
*/
name: string;
/**
* An instance of `PluginStyleSettings` that is used to define the plugin's CSS variables.
*/
styleSettings?: PluginStyleSettings | undefined;
/**
* The CSS styles that should be added to every page containing code blocks.
*
* All styles are scoped to Expressive Code by default, so they will not affect
* the rest of the page. SASS-like nesting is supported. If you want to add global styles,
* you can use the `@at-root` rule or target `:root`, `html` or `body` in your selectors.
*
* The engine's `getBaseStyles` function goes through all registered plugins
* and collects their base styles.
*
* If you provide a function instead of a string, it is called with an object argument
* of type {@link ResolverContext}, and is expected to return a string or a string promise.
*
* The calling code must take care of actually adding the collected styles to the page.
* For example, it could create a site-wide CSS stylesheet from the base styles
* and insert a link to it, or it could insert the base styles into a `<style>` element.
*/
baseStyles?: string | BaseStylesResolverFn | undefined;
/**
* JavaScript modules (pure code without any wrapping `script` tags) that should be added
* to every page containing code blocks.
*
* The engine's `getJsModules` function goes through all registered plugins,
* collects their JS modules and deduplicates them.
*
* If you provide a function instead of a string, it is called with an object argument
* of type {@link ResolverContext}, and is expected to return a string or a string promise.
*
* 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 `<script type="module">` elements.
*/
jsModules?: string[] | JsModulesResolverFn | undefined;
/**
* A set of functions that should be called by the engine at specific points in the
* rendering process. See {@link ExpressiveCodePluginHooks} for a list of available hooks.
*/
hooks?: ExpressiveCodePluginHooks | undefined;
}
type BaseStylesResolverFn = (context: ResolverContext) => string | Promise<string>;
type JsModulesResolverFn = (context: ResolverContext) => string[] | Promise<string[]>;
/**
* A context object that the engine passes to most hook functions.
*
* It provides access to theme-dependent CSS variables, all resolved style variants
* based on the configured themes and settings, and the config-dependent wrapper class name.
*/
type ResolverContext = {
/**
* Returns a CSS variable reference for the given style setting. The CSS variable name is
* automatically generated based on the setting path.
*
* You can optionally pass a fallback value that will be added to the CSS `var()` function call
* (e.g. `var(--ec-xyz, fallbackValue)`) in case the referenced variable is not defined or
* unsupported. However, this should rarely be the case as the engine automatically generates
* CSS variables for all style settings if the plugin's `styleSettings` property is set.
*
* @example
* cssVar('frames.fontSize')
* // ↓↓↓
* 'var(--ec-frames-fontSize)'
*
* cssVar('frames.fontSize', '2rem')
* // ↓↓↓
* 'var(--ec-frames-fontSize, 2rem)'
*/
cssVar: (styleSetting: StyleSettingPath, fallbackValue?: string) => string;
/**
* Returns the CSS variable name for the given style setting. The CSS variable name is
* automatically generated based on the setting path.
*
* @example
* cssVarName('frames.fontSize')
* // ↓↓↓
* '--ec-frames-fontSize'
*/
cssVarName: (styleSetting: StyleSettingPath) => string;
styleVariants: StyleVariant[];
};
/**
* A utility function that helps you define an Expressive Code plugin.
*
* Using this function is recommended, but not required. It just passes through the given object,
* but it also provides type information for your editor's auto-completion and type checking.
*
* @example
* ```js
* // your-plugin.mjs
* import { definePlugin } from '@expressive-code/core'
*
* export function myCustomPlugin() {
* return definePlugin({
* name: 'My custom plugin',
* hooks: {
* // ...
* }
* })
* }
* ```
*/
declare function definePlugin(plugin: ExpressiveCodePlugin): ExpressiveCodePlugin;
interface ExpressiveCodeProcessingState {
canEditCode: boolean;
canEditLanguage: boolean;
canEditMetadata: boolean;
canEditAnnotations: boolean;
}
interface ExpressiveCodeBlockOptions {
/**
* The plaintext contents of the code block.
*/
code: string;
/**
* The code block's language.
*
* Please use a valid [language identifier](https://expressive-code.com/key-features/syntax-highlighting/#supported-languages)
* to ensure proper syntax highlighting.
*/
language: string;
/**
* An optional meta string. In markdown or MDX documents, this is the part of the
* code block's opening fence that comes after the language name.
*/
meta?: string | undefined;
/**
* Optional props that can be used to influence the rendering of this code block.
*
* Plugins can add their own props to this type. To allow users to set these props through
* the meta string, plugins can use the `preprocessMetadata` hook to read `metaOptions`
* and update the `props` object accordingly.
*/
props?: PartialAllowUndefined<ExpressiveCodeBlockProps> | undefined;
/**
* The code block's locale (e.g. `en-US` or `de-DE`). This is used by plugins to display
* localized strings depending on the language of the containing page.
*
* If no locale is defined here, most Expressive Code integrations will attempt to auto-detect
* the block locale using the configured
* [`getBlockLocale`](https://expressive-code.com/reference/configuration/#getblocklocale)
* function, and finally fall back to the configured
* [`defaultLocale`](https://expressive-code.com/reference/configuration/#defaultlocale).
*/
locale?: string | undefined;
/**
* Optional data about the parent document the code block is located in.
*
* Integrations like `rehype-expressive-code` can provide this information based on the
* source document being processed. There may be cases where no document is available,
* e.g. when the code block was created dynamically.
*/
parentDocument?: {
/**
* The full path to the source file containing the code block.
*/
sourceFilePath?: string | undefined;
/**
* A reference to the object representing the parsed source document.
* This reference will stay the same for all code blocks in the same document.
*
* For example, if you are using `rehype-expressive-code` to render code blocks
* in a Markdown file, this would be the `hast` node representing the file's
* root node.
*/
documentRoot?: unknown | undefined;
/**
* Data about the position of the code block in the parent document.
*/
positionInDocument?: {
groupIndex: number;
totalGroups?: number | undefined;
} | undefined;
} | undefined;
}
type PartialAllowUndefined<T> = {
[Key in keyof T]?: T[Key] | undefined;
};
interface ExpressiveCodeBlockProps {
/**
* If `true`, word wrapping will be enabled for the code block, causing lines that exceed
* the available width to wrap to the next line. You can use the `preserveIndent` option
* to control how wrapped lines are indented.
*
* If `false`, lines that exceed the available width will cause a horizontal scrollbar
* to appear.
*
* @note This option only affects how the code block is displayed and does not change
* the actual code. When copied to the clipboard, the code will still contain the
* original unwrapped lines.
*
* @default false
*/
wrap: boolean;
/**
* If `true`, wrapped parts of long lines will be aligned with their line's
* indentation level, making the wrapped code appear to start at the same column.
* This increases readability of the wrapped code and can be especially useful
* for languages where indentation is significant, e.g. Python.
*
* If `false`, wrapped parts of long lines will always start at column 1.
* This can be useful to reproduce terminal output.
*
* @note This option only has an effect if `wrap` is `true`. It only affects how the
* code block is displayed and does not change the actual code. When copied to the clipboard,
* the code will still contain the original unwrapped lines.
*
* @default true
*/
preserveIndent: boolean;
}
/**
* Represents a single code block that can be rendered by the Expressive Code engine.
*/
declare class ExpressiveCodeBlock {
#private;
constructor(options: ExpressiveCodeBlockOptions);
/**
* This field exists to ensure that only actual class instances are accepted
* as the type `ExpressiveCodeBlock` by TypeScript. Without this workaround,
* plain objects with the same structure would be accepted, but fail at runtime.
*/
private _requireInstance;
/**
* Provides read-only access to the code block's plaintext contents.
*/
get code(): string;
get language(): string;
/**
* Allows getting and setting the code block's language.
*
* Setting this property may throw an error if not allowed in the current {@link state}.
*/
set language(value: string);
get meta(): string;
/**
* Allows getting or setting the code block's meta string. In markdown or MDX documents,
* this is the part of the code block's opening fence that comes after the language name.
*
* Setting this property may throw an error if not allowed in the current {@link state}.
*/
set meta(value: string);
/**
* Provides read-only access to the parsed version of the block's {@link meta} string.
*/
get metaOptions(): MetaOptions;
/**
* Provides access to the code block's props.
*
* To allow users to set these props through the meta string, plugins can use the
* `preprocessMetadata` hook to read `metaOptions` and update their props accordingly.
*
* Props can be modified until rendering starts and become read-only afterwards.
*/
get props(): NonNullable<ExpressiveCodeBlockOptions['props']>;
/**
* Allows getting the code block's locale (e.g. `en-US` or `de-DE`). It is used by plugins
* to display localized strings depending on the language of the containing page.
*
* Integrations like `rehype-expressive-code` support multi-language sites by allowing you
* to provide custom logic to determine a block's locale (e.g. based on its parent document).
*
* If no locale is defined here, `ExpressiveCodeEngine` will render the code block
* using the `defaultLocale` provided in its configuration.
*/
get locale(): string | undefined;
/**
* Provides read-only access to optional data about the parent document
* the code block is located in.
*
* Integrations like `rehype-expressive-code` can provide this information based on
* the source document being processed. There may be cases where no document is available,
* e.g. when the code block was created dynamically.
*/
get parentDocument(): {
/**
* The full path to the source file containing the code block.
*/
sourceFilePath?: string | undefined;
/**
* A reference to the object representing the parsed source document.
* This reference will stay the same for all code blocks in the same document.
*
* For example, if you are using `rehype-expressive-code` to render code blocks
* in a Markdown file, this would be the `hast` node representing the file's
* root node.
*/
documentRoot?: unknown;
/**
* Data about the position of the code block in the parent document.
*/
positionInDocument?: {
groupIndex: number;
totalGroups?: number | undefined;
} | undefined;
} | undefined;
/**
* Provides read-only access to the code block's processing state.
*
* The processing state controls which properties of the code block can be modified.
* The engine updates it automatically during rendering.
*/
get state(): ExpressiveCodeProcessingState | undefined;
/**
* @internal
*/
set state(value: ExpressiveCodeProcessingState | undefined);
/**
* Returns the line at the given index, or `undefined` if the index is out of range.
*/
getLine(index: number): ExpressiveCodeLine | undefined;
/**
* Returns a readonly array of lines starting at the given index and ending before
* the given index (exclusive). The indices support the same syntax as JavaScripts
* `Array.slice` method.
*/
getLines(startIndex?: number, endIndex?: number): readonly ExpressiveCodeLine[];
/**
* Deletes the line at the given index.
*
* May throw an error if not allowed in the current {@link state}.
*/
deleteLine(index: number): void;
/**
* Deletes the lines at the given indices.
*
* This function automatically sorts the indices in descending order before deleting the lines,
* so you do not need to worry about indices shifting after deleting a line.
*
* May throw an error if not allowed in the current {@link state}.
*/
deleteLines(indices: number[]): void;
/**
* Inserts a new line at the given index.
*
* May throw an error if not allowed in the current {@link state}.
*/
insertLine(index: number, textLine: string): ExpressiveCodeLine;
/**
* Inserts multiple new lines at the given index.
*
* May throw an error if not allowed in the current {@link state}.
*/
insertLines(index: number, textLines: string[]): ExpressiveCodeLine[];
}
declare class ExpressiveCodeLine {
#private;
constructor(text: string);
get text(): string;
get parent(): ExpressiveCodeBlock | undefined;
set parent(value: ExpressiveCodeBlock | undefined);
getAnnotations(): readonly ExpressiveCodeAnnotation[];
addAnnotation(annotation: ExpressiveCodeAnnotation): void;
deleteAnnotation(annotation: ExpressiveCodeAnnotation): void;
editText(columnStart: number | undefined, columnEnd: number | undefined, newText: string): string;
}
declare function validateExpressiveCodeAnnotation(annotation: ExpressiveCodeAnnotation): void;
type ExpressiveCodeInlineRange = {
columnStart: number;
columnEnd: number;
};
type AnnotationRenderOptions = ResolverContext & {
nodesToTransform: Parents[];
line: ExpressiveCodeLine;
lineIndex: number;
};
type AnnotationRenderPhase = 'earliest' | 'earlier' | 'normal' | 'later' | 'latest';
declare const AnnotationRenderPhaseOrder: AnnotationRenderPhase[];
type AnnotationBaseOptions = {
inlineRange?: ExpressiveCodeInlineRange | undefined;
renderPhase?: AnnotationRenderPhase | undefined;
};
/**
* An abstract class representing a single annotation attached to a code line.
*
* You can develop your own annotations by extending this class and providing
* implementations for its abstract methods. See the implementation of the
* {@link InlineStyleAnnotation} class for an example.
*
* You can also define your annotations as plain objects, as long as they have
* the same properties as this class. This allows you to use annotations in a
* more functional way, without the need to extend a class.
*/
declare abstract class ExpressiveCodeAnnotation {
constructor({ inlineRange, renderPhase }: AnnotationBaseOptions);
/**
* Renders the annotation by transforming the provided nodes.
*
* This function will be called with an array of AST nodes to transform, and is expected
* to return an array containing the same number of nodes.
*
* For example, you could use the `hastscript` library to wrap the received nodes
* in HTML elements.
*/
abstract render({ nodesToTransform, line, lineIndex }: AnnotationRenderOptions): Parents[];
/**
* An optional name for the annotation. This can be used for debugging or logging purposes,
* or to allow other plugins to identify the annotation.
*/
readonly name?: string | undefined;
/**
* An optional range of columns within the line that this annotation applies to.
* If not provided, the annotation will apply to the entire line.
*/
readonly inlineRange?: ExpressiveCodeInlineRange | undefined;
/**
* Determines the phase in which this annotation should be rendered.
* Rendering is done in phases, from `earliest` to `latest`.
* Annotations with the same phase are rendered in the order they were added.
*
* The earlier an annotation is rendered, the more likely it is to be split, modified
* or wrapped by later annotations. Syntax highlighting is rendered in the `earliest` phase
* to allow other annotations to wrap and modify the highlighted code.
*
* The default phase is `normal`.
*/
readonly renderPhase?: AnnotationRenderPhase | undefined;
}
type InlineStyleAnnotationOptions = AnnotationBaseOptions & {
/**
* The color of the annotation. This is expected to be a hex color string, e.g. `#888`.
* Using CSS variables or other color formats is possible, but prevents automatic
* color contrast checks from working.
*/
color?: string | undefined;
/**
* Whether the annotation should be rendered in italics.
*/
italic?: boolean | undefined;
/**
* Whether the annotation should be rendered in bold.
*/
bold?: boolean | undefined;
/**
* Whether the annotation should be rendered with an underline.
*/
underline?: boolean | undefined;
/**
* Inline styles can be theme-dependent, which allows plugins like syntax highlighters to
* style the same code differently depending on the theme.
*
* To support this, the engine creates a style variant for each theme given in the
* configuration, and plugins can go through the engine's `styleVariants` array to
* access all the themes.
*
* When adding an inline style annotation to a range of code, you can optionally set
* this property to a `styleVariants` array index to indicate that this annotation
* only applies to a specific theme. If this property is not set, the annotation will
* apply to all themes.
*/
styleVariantIndex?: number | undefined;
};
/**
* A theme-dependent inline style annotation that allows changing colors, font styles and
* decorations of the targeted code. This annotation is used by the syntax highlighting plugin
* to apply colors and styles to syntax tokens, and you can use it in your own plugins as well.
*
* You can add as many inline style annotations to a line as you want, even targeting the same code
* with multiple fully or partially overlapping annotation ranges. During rendering, these
* annotations will be automatically optimized to avoid creating unnecessary HTML elements.
*
* @note
* If you want to publish your own plugin using the `InlineStyleAnnotation` class, import it from
* the `@expressive-code/core` package installed as a **peer dependency** of your plugin package.
* This ensures that your plugin does not cause a version conflict if the user has a different
* version of Expressive Code installed on their site.
*/
declare class InlineStyleAnnotation extends ExpressiveCodeAnnotation {
name: string;
color: string | undefined;
italic: boolean;
bold: boolean;
underline: boolean;
styleVariantIndex: number | undefined;
constructor({ color, italic, bold, underline, styleVariantIndex, ...baseOptions }: InlineStyleAnnotationOptions);
render({ nodesToTransform, styleVariants }: AnnotationRenderOptions): Parents[];
}
declare function isInlineStyleAnnotation(annotation: unknown): annotation is InlineStyleAnnotation;
type PluginDataTarget = ExpressiveCodeBlock | GroupContents | RenderedGroupContents;
/**
* A class that allows plugins to attach custom data to objects like code blocks,
* and to optionally allow external access to this data in a type-safe manner.
*/
declare class AttachedPluginData<PluginDataType> {
private readonly dataStorage;
private readonly getInitialValueFn;
constructor(getInitialValueFn: () => PluginDataType);
getOrCreateFor(target: PluginDataTarget): PluginDataType;
setFor(target: PluginDataTarget, data: PluginDataType): void;
}
type KnownTextsByKey<T extends {
[K: string]: string | (() => string);
}> = {
[K in keyof T]: T[K];
};
declare class PluginTexts<Texts extends KnownTextsByKey<Texts>> {
readonly defaultTexts: Texts;
private readonly localizedTexts;
private readonly overridesByLocale;
constructor(defaultTexts: Texts);
/**
* Adds localized texts for a specific locale. You must provide a full set of localized texts
* for the given locale.
*
* It is recommended to use two-letter language codes (e.g. `de`, `fr`, `es`) without region
* codes to make your localized texts available to all users speaking the same language.
* Region codes should only be added if regional differences must be taken into account.
*
* Plugin authors can use this to provide localized versions of their texts.
* Users can also call this function to provide their own localizations.
*
* If you only want to customize a few texts of an existing localization,
* have a look at `overrideTexts` instead.
*/
addLocale(locale: string, localizedTexts: Texts): void;
/**
* Allows you to override any defined texts. This is useful if you want to customize a few
* selected texts without having to provide a full set of localized texts.
*
* You can either override texts for a specific `locale`, or override the default texts
* by setting `locale` to `undefined`.
*
* It is recommended to use two-letter language codes (e.g. `de`, `fr`, `es`) without region
* codes to apply your overrides to all users speaking the same language.
* Region codes should only be added if regional differences must be taken into account.
*/
overrideTexts(locale: string | undefined, localeTextOverrides: Partial<Texts>): void;
/**
* Returns the best matching texts for the requested locale,
* taking any available localized texts and overrides into account.
*
* Example for locale `de-DE`:
* - If localized texts for `de-DE` are available, these will be returned.
* - If `de-DE` is not available, but `de` is, these will be returned.
* - As the final fallback, the default texts will be returned.
*/
get(locale: string): Texts;
private parseLocale;
private getLocalizedTexts;
private applyOverrides;
}
/** @deprecated Please import this function from the `/hast` entrypoint instead. */
declare const addClassName: typeof addClassName$1;
/** @deprecated Please import this function from the `/hast` entrypoint instead. */
declare const getClassNames: typeof getClassNames$1;
/** @deprecated Please import this function from the `/hast` entrypoint instead. */
declare const getInlineStyles: typeof getInlineStyles$1;
/** @deprecated Please import this function from the `/hast` entrypoint instead. */
declare const removeClassName: typeof removeClassName$1;
/** @deprecated Please import this function from the `/hast` entrypoint instead. */
declare const setInlineStyle: typeof setInlineStyle$1;
/** @deprecated Please import this function from the `/hast` entrypoint instead. */
declare const setInlineStyles: typeof setInlineStyles$1;
/** @deprecated Please import this function from the `/hast` entrypoint instead. */
declare const setProperty: typeof setProperty$1;
/**
* Formats a string template by replacing all placeholders with the given variables.
*
* Simple placeholders are written as variable names in curly brackets, e.g. `{variableName}`.
*
* You can also use conditional placeholders by separating multiple choices with semicolons
* and optionally adding a condition before each choice, e.g.
* `{itemCount;1=item;items}` or `{variableName; 0=zero; >0=positive; negative}`.
*
* The first choice that matches the condition will be used. There must always be exactly
* one catch-all choice without a condition.
*/
declare function formatTemplate(template: string, variables: {
[key: string]: string | number;
}): string;
/**
* Returns a JSON-like string representation of the given object that is stable,
* meaning that keys are sorted alphabetically. This causes objects with the same keys and values
* to always have the same string representation.
*
* Circular references are handled by replacing them with the string `[Circular]`.
*
* Functions are replaced with the string `[Function]`, unless the `includeFunctionContents`
* option is set to `true`.
*/
declare function stableStringify(obj: unknown, options?: {
includeFunctionContents?: boolean | undefined;
}): string;
/**
* Returns a simple hash of the given object.
*
* The hash is stable, meaning that if the object has the same keys and values (in any order),
* the hash will be the same. The hash is not cryptographically secure, but uses the simple
* and fast `djb2a` algorithm, which is known to produce few collisions.
*/
declare function getStableObjectHash(obj: unknown, options?: {
includeFunctionContents?: boolean | undefined;
hashLength?: number | undefined;
}): string;
export { AnnotationBaseOptions, AnnotationRenderOptions, AnnotationRenderPhase, AnnotationRenderPhaseOrder, AttachedPluginData, BaseStylesResolverFn, ChromaticRecolorTarget, ExpressiveCodeAnnotation, ExpressiveCodeBlock, ExpressiveCodeBlockOptions, ExpressiveCodeBlockProps, ExpressiveCodeEngine, ExpressiveCodeEngineConfig, ExpressiveCodeHook, ExpressiveCodeHookContext, ExpressiveCodeHookContextBase, ExpressiveCodeInlineRange, ExpressiveCodeLine, ExpressiveCodePlugin, ExpressiveCodePluginHookName, ExpressiveCodePluginHooks, ExpressiveCodePluginHooks_BeforeRendering, ExpressiveCodePluginHooks_Rendering, ExpressiveCodeTheme, ExpressiveCodeThemeInput, GutterElement, GutterRenderContext, InlineStyleAnnotation, InlineStyleAnnotationOptions, JsModulesResolverFn, MetaOption, MetaOptionBase, MetaOptionBoolean, MetaOptionKind, MetaOptionRange, MetaOptionRegExp, MetaOptionString, MetaOptions, PartialAllowUndefined, PluginDataTarget, PluginStyleSettings, PluginTexts, PostprocessRenderedBlockContext, PostprocessRenderedBlockGroupContext, PostprocessRenderedLineContext, RenderEmptyLineFn, ResolvedExpressiveCodeEngineConfig, ResolvedStyleSettingsByPath, ResolverContext, StyleOverrides, StyleResolverFn, StyleSettingPath, StyleSettings, StyleValueOrValues, StyleVariant, ThemeSetting, UnresolvedPluginStyleSettings, UnresolvedStyleSettings, UnresolvedStyleValue, addClassName, changeAlphaToReachColorContrast, changeLuminanceToReachColorContrast, chromaticRecolor, codeLineClass, cssVarReplacements, darken, definePlugin, ensureColorContrastOnBackground, formatTemplate, getClassNames, getColorContrast, getColorContrastOnBackground, getCssVarName, getFirstStaticColor, getInlineStyles, getLuminance, getStableObjectHash, getStaticBackgroundColor, isInlineStyleAnnotation, lighten, mix, multiplyAlpha, onBackground, removeClassName, resolveStyleVariants, runHooks, setAlpha, setInlineStyle, setInlineStyles, setLuminance, setProperty, stableStringify, toHexColor, toRgbaString, validateExpressiveCodeAnnotation };