Skip to content

Plugin API

ExpressiveCodePlugin

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.

Properties

name

Type: string

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.

baseStyles?

Type: string | BaseStylesResolverFn

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 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.

hooks?

A set of functions that should be called by the engine at specific points in the rendering process. See ExpressiveCodePluginHooks for a list of available hooks.

jsModules?

Type: string[] | JsModulesResolverFn

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 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.

styleSettings?

An instance of PluginStyleSettings that is used to define the plugin’s CSS variables.

PluginStyleSettings

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 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.

If you want to provide descriptive names for your style settings, but keep the generated CSS variable names short, you can pass an array of search and replace string pairs to the cssVarReplacements property of the object passed to the constructor. The replacements will be applied to all generated CSS variable names.

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']

Constructors

new PluginStyleSettings(options)

Arguments
ParameterType
optionsObject
options.defaultValuesPartial<UnresolvedStyleSettings>
options.cssVarExclusions?StyleSettingPath[]
options.cssVarReplacements?[string, string][]

Properties

cssVarExclusions

Type: readonly StyleSettingPath[]

cssVarReplacements

Type: readonly [string, string][]

defaultValues

Type: readonly Partial<UnresolvedStyleSettings>

AttachedPluginData

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.

Usage example

pluginDataExample.ts
import { AttachedPluginData, ExpressiveCodePlugin } from '@expressive-code/core'
export function pluginDataExample(): ExpressiveCodePlugin {
return {
name: 'AttachedPluginDataExample',
hooks: {
preprocessMetadata: ({ codeBlock }) => {
// Get a reference to the block's data object
const blockData = pluginFramesData.getOrCreateFor(codeBlock)
// Example: Store the meta string in the data object
// and remove it from the block
blockData.extractedMeta = codeBlock.meta
codeBlock.meta = ''
},
postprocessRenderedBlock: ({ codeBlock }) => {
// Try to retrieve the stored title from the block's data object
const blockData = pluginFramesData.getOrCreateFor(codeBlock)
// Log the extracted data
console.dir(blockData)
},
},
}
}
// Define the data object type
export interface PluginFramesData {
extractedMeta?: string
}
// Create a singleton instance that allows attaching this type of data
// to any object and to retrieve it later.
// Note: Exporting is optional. This can be useful if multiple plugins
// need to work together.
export const pluginFramesData = new AttachedPluginData<PluginFramesData>(
// This function initializes the attached data
// in case nothing was attached to an object yet
() => ({})
)

Type parameters

Parameter
PluginDataType

Constructors

new AttachedPluginData(getInitialValueFn)

  • new AttachedPluginData<PluginDataType>(getInitialValueFn): AttachedPluginData<PluginDataType>
Arguments
ParameterType
getInitialValueFn() => PluginDataType

Methods

getOrCreateFor()

  • getOrCreateFor(target): PluginDataType
Arguments
ParameterType
targetPluginDataTarget

setFor()

  • setFor(target, data): void
Arguments
ParameterType
targetPluginDataTarget
dataPluginDataType

Referenced types

BaseStylesResolverFn

Type: (context) => string | Promise<string>

A function that you can assign to the baseStyles property of an ExpressiveCodePlugin.

The engine will call it when going through all registered plugins and collecting their base styles.

Arguments

ParameterType
contextResolverContext

JsModulesResolverFn

Type: (context) => string[] | Promise<string[]>

A function that you can assign to the jsModules property of an ExpressiveCodePlugin.

The engine will call it when going through all registered plugins and collecting their JS modules.

Arguments

ParameterType
contextResolverContext

ResolverContext

Type: Object

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.

Object properties

cssVar
Type: (styleSetting, fallbackValue?) => string
cssVarName
Type: (styleSetting) => string
styleVariants
Type: StyleVariant[]

ResolvedStyleSettingsByPath

Type: Map<StyleSettingPath, string>

StyleResolverFn

Type: (context) => StyleValueOrValues

A function that resolves a single style setting to a 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.

Arguments

ParameterTypeDescription
contextObject-
context.resolveSetting(settingPath) => string-
context.styleVariantIndexnumberThe index in the engine’s styleVariants array that’s currently being resolved.
context.themeExpressiveCodeTheme-

StyleSettingPath

Type: FlattenKeys<StyleSettings>

StyleValueOrValues

Type: string | [string, string]

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.

StyleVariant

Type: Object

Object properties

cssVarDeclarations
Type: Map<string, string>
resolvedStyleSettings
theme

UnresolvedPluginStyleSettings

Type: { [SettingName in keyof T]: UnresolvedStyleValue }

Type parameters

Parameter
T

UnresolvedStyleValue

This is the value type for all style overrides. It allows either static style values or a resolver function.

UnresolvedStyleSettings

Type: { [K in keyof StyleSettings]: StyleSettings[K] extends object ? UnresolvedPluginStyleSettings<StyleSettings[K]> : UnresolvedStyleValue }