Plugin Hooks
Available plugin hooks
The engine calls the following hook functions in the order listed here:
preprocessLanguage
Allows preprocessing the code block’s language identifier before loading language-specific defaults into 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.
preprocessMetadata
Allows preprocessing the meta string and the language before any plugins can modify the code.
Plugins are expected to use this hook to remove any of their syntax from the meta string. Removed information can either be stored internally or used to create annotations.
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.
preprocessCode
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.
performSyntaxAnalysis
Allows analyzing the preprocessed code and collecting language-specific syntax annotations.
This hook is used by the syntax highlighting plugin to run the code through Shiki
and to create annotations from the returned syntax tokens.
These annotations are then available to the following hooks and will be used during rendering.
postprocessAnalyzedCode
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.
annotateCode
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.
postprocessAnnotations
Allows applying final changes to annotations before rendering.
After this hook has finished processing, all annotations become read-only and the engine starts rendering the code blocks line by line.
postprocessRenderedLine
Allows editing the AST of a single line of code after all annotations were rendered.
postprocessRenderedBlock
Allows editing the AST of the entire code block after all annotations were rendered and all lines were postprocessed.
postprocessRenderedBlockGroup
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.
Referenced types
ExpressiveCodeHook
context
) => void
| Promise
<void
> Type parameters
Parameter | Value |
---|---|
ContextType | ExpressiveCodeHookContext |
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 ExpressiveCodeHookContext, but can vary by hook, so see the list of available hooks for the correct type.
Arguments
Parameter | Type |
---|---|
context | ContextType |
ExpressiveCodeHookContext
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.
Properties
addGutterElement
element
) => void
Registers a gutter element for the current code block.
The engine calls the 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.
Arguments
Parameter | Type |
---|---|
element | GutterElement |
addStyles
css
) => void
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.
Arguments
Parameter | Type |
---|---|
css | string |
codeBlock
ExpressiveCodeBlock
config
ResolvedExpressiveCodeEngineConfig
The Expressive Code engine configuration, with all optional properties resolved to their default values.
cssVar
styleSetting
, fallbackValue
?) => string
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.
Arguments
Parameter | Type |
---|---|
styleSetting | StyleSettingPath |
fallbackValue ? | string |
Example
cssVarName
styleSetting
) => string
Returns the CSS variable name for the given style setting. The CSS variable name is automatically generated based on the setting path.
Arguments
Parameter | Type |
---|---|
styleSetting | StyleSettingPath |
Example
groupContents
codeBlock
: ExpressiveCodeBlock
}[] locale
string
styleVariants
StyleVariant
[] PostprocessRenderedLineContext
A context object that the engine passes to the postprocessRenderedLine
hook function.
In addition to the properties made available by ExpressiveCodeHookContext, it provides access to information about the line currently being rendered, and allows modifying the rendered output.
Additional properties
line
ExpressiveCodeLine
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.
lineIndex
number
The 0-based index of the line inside the code block.
renderData
Object
Allows modifying the line’s rendered output. The lineAst
property of this object contains the Hypertext Abstract 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 in the HAST documentation.
Object properties
- lineAst
- Type:
Element
renderEmptyLine
RenderEmptyLineFn
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.
PostprocessRenderedBlockContext
A context object that the engine passes to the postprocessRenderedBlock
hook function.
In addition to the properties made available by ExpressiveCodeHookContext, it provides access to render data of the code block currently being rendered, and allows modifying the rendered output.
Additional properties
renderData
Object
Allows modifying the block’s rendered output. The blockAst
property of this object contains the Hypertext Abstract 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 in the HAST documentation.
Object properties
- blockAst
- Type:
Element
renderEmptyLine
RenderEmptyLineFn
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.
PostprocessRenderedBlockGroupContext
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.
Properties
addStyles
css
) => void
See ExpressiveCodeHookContext.addStyles.
Arguments
Parameter | Type |
---|---|
css | string |
pluginStyles
pluginName
: string
; styles
: string
}[] 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.
renderData
Object
Allows modifying the rendered output of a group of code blocks. The groupAst
property of this object contains the Hypertext Abstract 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 group’s root element, or you could wrap the entire group in a custom element.
Object properties
- groupAst
- Type:
Element
renderedGroupContents
codeBlock
: ExpressiveCodeBlock
; renderedBlockAst
: Element
}[] 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.