In Expressive Code, all processing of your code blocks and their metadata is performed by plugins and annotations. To render markup around lines or inline ranges of characters, plugins create annotations and attach them to the target lines.
Adding existing plugins
To add a plugin to Expressive Code that is not installed by default, install its package using your package manager, import its initialization function into your config file, and call it inside the plugins array property.
The following example shows how to add the Collapsible Sections plugin to your Expressive Code configuration. After installing the plugin using your package manager, make the following changes to your Expressive Code configuration:
To write a new plugin, you need to create a plugin initialization function that returns an object matching the interface ExpressiveCodePlugin.
The easiest way to do this is by importing the definePlugin helper function from the @expressive-code/core package, which will provide your editor with the required type information to help define the plugin correctly. This function takes a single argument, an object containing the properties of your plugin:
Then, add the plugin to your Expressive Code configuration just like any other plugin:
🎉 Success! From now on, your plugin will be loaded and executed whenever you run your site generator. If you add any hooks, it will be able to process your code blocks.
Adding options to your plugin
If your plugin needs configuration options, you can add a single options argument to your initialization function. This argument must be an object type containing the desired configuration properties.
When adding the plugin to your Expressive Code configuration, pass the desired options as an object to the plugin’s initialization function:
In Expressive Code, annotations are used by plugins to attach semantic information to lines or inline ranges of code. They are used to represent things like syntax highlighting, text markers, comments, errors, warnings, and other semantic information.
Expressive Code provides a built-in InlineStyleAnnotation that allows applying simple inline styles to code. See its documentation for a usage example.
To provide full styling flexibility, plugins can also create their own annotations. In the following example, you will create a plugin that uses two custom annotations:
a SquigglesAnnotation to render squiggly red underlines under words surrounded by a pair of ~~ characters, and
an ErrorMessageAnnotation to render error messages in red and italic with a semitransparent background.
For both custom annotations, you will create a class that extends the abstract ExpressiveCodeAnnotation class, and provide an implementation for the render function that transforms its contained AST nodes, e.g. by wrapping them in HTML tags. This function is called by the engine when it’s time to render the line the annotation has been attached to.
Now, let’s create the plugin:
After saving your new plugin, you need to add it to your Expressive Code configuration:
You can now use the new syntax in code blocks to add error annotations to lines! For example, you can use the following markup:
This will render the following result:
🎉 Success! You have created a plugin that uses custom annotations to render squiggly underlines and error messages in your code blocks.
Adding CSS styles to your plugin
Plugins can add CSS styles by providing a baseStyles property in the plugin object returned by the plugin’s initialization function.
You can see an example of this in the previous section, where the baseStyles property is used to add styles for the squiggly underline and error message annotations.
Automatic style scoping
All provided styles will be scoped by default to Expressive Code, so they will not affect the rest of the page. This means that you can define styles like font-weight: 800, or del { text-decoration: line-through }, and they will only apply to code blocks. SASS-like nesting is also supported.
If you explicitly want to add global styles, you can use the @at-root rule or target :root, html or body in your selectors. Please be careful with global styles, as users may not expect your plugin to contain a style like body { color: red } that changes the look of the entire page.
Making your styles theme-dependent
If you want your CSS styles to use colors from the configured themes, you can add a styleSettings property to your plugin object, which will be used to generate CSS variables automatically.
To use the generated CSS variables in your baseStyles property, set its value to a function instead of a string. The function will be called by the engine with a context argument of the type ResolverContext that provides access to the names of all generated CSS variables.