Text & Line Markers
Expressive Code allows you to add annotations to lines & line ranges, as well as individual text inside your lines. You can use them to highlight important parts of your code, or to indicate changes between different versions of your code.
Good to know: No matter how much color you add to your code snippets, Expressive Code automatically ensures accessible color contrast, tweaking the text colors if necessary while keeping syntax highlighting intact.
Usage in markdown / MDX
Marking full lines & line ranges
Lines can be marked by adding their line numbers inside curly brackets to a code block’s meta information. Line numbers start at 1, just like in VS Code and other popular editors.
You can either mark a single line, or a range of lines, and you can combine multiple line markers by separating them with commas:
- Single line:
{4}
- Three separate lines:
{4, 8, 12}
- Range of lines defined by a start and end:
{4-8}
- Multiple selectors combined:
{1, 4, 7-8}
Here’s an example combining multiple line number & line range selectors:
This will render as follows:
Selecting line marker types (mark
, ins
, del
)
By default, all targeted lines will use the marker type mark
, which is rendered in a neutral color that just highlights the line without adding any semantic meaning to it.
There are two other marker types available that add semantic meaning to your lines: ins
(inserted) and del
(deleted). These are rendered in green and red, respectively, and are commonly used to indicate changes to your code.
To specify the marker type for targeted lines, add it in front of their opening curly brace, followed by an equals sign. For example, ins={4}
would mark line 4 as inserted, and del={7-12}
would mark lines 7 to 12 as deleted.
Here’s an example combining all three marker types:
This will render as follows:
Adding labels to line markers
You can add a text label to any line marker, which will be rendered as a colorful box in the first line of the marked line range. This allows you to reference specific parts of your code in the surrounding text.
To add any text as a label, enclose it in single or double quotes and add it directly after the opening curly brace, followed by a colon (:
). For example, ins={"A":6-10}
would mark lines 6 to 10 as inserted and add the label A
to them.
Here’s an example:
This will render as follows:
Adding long labels on their own lines
If you want to use labels that are too long to fit on the side, you can add them above the marked line range instead. To do so, add an empty line inside your code block where you want the label to appear, and target this empty line as the beginning of your line range. Example:
This will render as follows:
Using diff
-like syntax
Instead of adding line numbers to the opening code fence as shown above, you can also use the diff
language, which is supported on many platforms (e.g. GitHub). Set the language in the opening code fence to diff
and add a +
or -
marker to the first column of any line:
To make the raw contents in your markdown / MDX document more readable, you can add whitespace after the +
or -
marker (not before), and align unchanged lines with the changed ones. This additional whitespace will be automatically detected and removed from the rendered code block:
Both variants above will render as follows:
To avoid unexpected modifications of actual diff files (which would make them unusable), this plugin will automatically detect diff content based on its common metadata lines. It will detect unified and context mode diff syntax like ***
, +++
, ---
, @@
, as well as the default mode location syntax (e.g. 0a1
, 1,2c1,2
, 1,2d1
):
Combining syntax highlighting with diff
-like syntax
Usually, a downside of using the diff
language is that you lose syntax highlighting of the actual code’s language. To work around this, this plugin allows you to specify a second language identifier by adding a lang="..."
attribute to the opening code fence. The value of this attribute will then be used for syntax highlighting, while the diff
-like syntax can be used for marking lines:
This will render as follows:
Marking individual text inside lines
Plaintext search strings
To match a string of text inside your code block’s lines, simply wrap it in quotes. You can use either double or single quotes:
"this will be marked"
'this will be marked'
If the text you want to match contains quotes itself, you can use the other quote type to wrap it without having to escape the nested quotes:
"these 'single' quotes need no escaping"
'these "double" quotes need no escaping'
If you cannot avoid nested quotes of the same type, you can escape them using a backslash:
"this contains both \"double\" and 'single' quotes"
'this contains both "double" and \'single\' quotes'
Example:
This will render as follows:
Regular expressions
To match a regular expression inside your code block’s lines, wrap it in forward slashes:
This will render as follows:
Escaping forward slashes
To match a forward slash inside your regular expression, you can escape it using a backslash:
This will render as follows:
Marking capture group contents
If you only want to mark certain parts matched by your regular expression, you can use capture groups. For example, the expression /ye(s|p)/
will match yes
and yep
, but only mark the character s
or p
:
To prevent this special treatment of capture groups, you can convert them to non-capturing groups by adding ?:
after the opening parenthesis. For example:
Selecting inline marker types (mark
, ins
, del
)
Just like with line markers, you can select the marker type for plaintext and regular expression markers by adding it in front of the opening quote or forward slash, followed by an equals sign. Here’s an example:
This will render as follows:
Usage in the <Code>
component
The text markers plugin adds multiple props to the <Code>
component that allow direct access to its features. The following props are available:
Props
del
MarkerDefinition
| MarkerDefinition
[] Defines the code block’s text & line markers of the “deleted” type.
You can either pass a single marker definition or an array of them.
ins
MarkerDefinition
| MarkerDefinition
[] Defines the code block’s text & line markers of the “inserted” type.
You can either pass a single marker definition or an array of them.
mark
MarkerDefinition
| MarkerDefinition
[] Defines the code block’s text & line markers of the default neutral type.
You can either pass a single marker definition or an array of them.
useDiffSyntax
boolean
Allows you to enable processing of diff syntax for non-diff languages.
If set to true
, you can prefix lines with +
or -
, no matter what the language of the code block is. The prefixes will be removed and the lines will be highlighted as inserted or deleted lines.
Referenced types
MarkerDefinition
string
| RegExp
| number
| { range: string; label?: string | undefined }
A single text marker definition that can be used in the mark
, ins
, and del
props to define text and line markers.
Configuration
You can override this plugin’s default styles by adding a textMarkers
object to the styleOverrides
engine config option. You can find a list of all overridable styles below.
Here are configuration examples for common scenarios:
Available plugin options
This plugin does not provide any configuration options that can be passed to its initialization function.
Available style overrides
This plugin adds a textMarkers
object to the styleOverrides
engine config option, allowing you to customize the visual appearance of the markers. The object contains the following properties:
backgroundOpacity
The opacity of the background color of all text marker types.
borderLuminance
The LCH luminance to be used for the border color of all text marker types.
borderOpacity
The opacity of the border color of all text marker types.
defaultChroma
The LCH chroma to be used for all text marker types.
The chroma value defines the saturation of the color. Higher values lead to more saturated colors, lower values lead to less saturated colors.
defaultLuminance
The LCH luminance to be used for all text marker types.
delBackground
lch(<defaultLuminance> <defaultChroma> <delHue> / <backgroundOpacity>)
The background color of deleted text (text marker type del
).
delBorderColor
lch(<borderLuminance> <defaultChroma> <delHue> / <borderOpacity>)
The border color of deleted text (text marker type del
).
delDiffIndicatorColor
lch(<indicatorLuminance> <defaultChroma> <delHue> / <indicatorOpacity>)
The color of the diff indicator (e.g. +
or -
) of deleted lines.
delDiffIndicatorContent
The content to be displayed inside the diff indicator of deleted lines.
Note that this is used as the content
value in a CSS pseudo-element, so you need to wrap any text in additional quotes.
delHue
The LCH hue to be used for deleted text (text marker type del
).
indicatorLuminance
The LCH luminance to be used for the diff indicator (e.g. +
or -
).
indicatorOpacity
The opacity of the diff indicator (e.g. +
or -
).
inlineMarkerBorderRadius
The border radius of inline text markers.
inlineMarkerBorderWidth
The width of the border around inline text markers, rendered in a way that does not cause marked code to shift.
inlineMarkerPadding
The inline padding of inline text markers. Keep this low to prevent marked code from shifting too much compared to the original text.
insBackground
lch(<defaultLuminance> <defaultChroma> <insHue> / <backgroundOpacity>)
The background color of inserted text (text marker type ins
).
insBorderColor
lch(<borderLuminance> <defaultChroma> <insHue> / <borderOpacity>)
The border color of inserted text (text marker type ins
).
insDiffIndicatorColor
lch(<indicatorLuminance> <defaultChroma> <insHue> / <indicatorOpacity>)
The color of the diff indicator (e.g. +
or -
) of inserted lines.
insDiffIndicatorContent
The content to be displayed inside the diff indicator of inserted lines.
Note that this is used as the content
value in a CSS pseudo-element, so you need to wrap any text in additional quotes.
insHue
The LCH hue to be used for inserted text (text marker type ins
).
lineDiffIndicatorMarginLeft
The margin between the code block border and the diff indicator (e.g. +
or -
) displayed on the left side of a full-line text marker.
lineMarkerAccentMargin
The margin between the code block border and the line marker accent bar displayed on the left side of a full-line text marker.
lineMarkerAccentWidth
The width of the line marker accent bar. This is the vertical border-like bar displayed on the left side of a full-line text marker.
lineMarkerLabelColor
The text color of the optional labels that can be displayed on the left side of a full-line text marker.
lineMarkerLabelPaddingInline
The inline padding (= left & right padding in horizontal writing mode) around line marker labels.
markBackground
lch(<defaultLuminance> <defaultChroma> <markHue> / <backgroundOpacity>)
The background color of marked text (text marker type mark
).
markBorderColor
lch(<borderLuminance> <defaultChroma> <markHue> / <borderOpacity>)
The border color of marked text (text marker type mark
).
markHue
The LCH hue to be used for marked text (text marker type mark
).