rehype-expressive-code
Version:
Rehype plugin for Expressive Code, a modular syntax highlighting & annotation engine for presenting source code on the web. Offers full VS Code theme support, editor & terminal frames, copy to clipboard, text markers, collapsible sections, and more.
123 lines (119 loc) • 5.95 kB
TypeScript
import { VFileWithOutput } from 'unified';
import { VFile } from 'vfile';
import { ExpressiveCodeConfig, ExpressiveCodeBlockOptions, ExpressiveCodeBlock, BundledShikiTheme, ExpressiveCodeTheme, ExpressiveCodeThemeInput, ExpressiveCode } from 'expressive-code';
export * from 'expressive-code';
import { Root } from 'expressive-code/hast';
type AnyVFile = VFile | VFileWithOutput<null>;
type RehypeExpressiveCodeOptions = Omit<ExpressiveCodeConfig, 'themes'> & {
/**
* 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.
*
* The following item types are supported in this array:
* - any theme name bundled with Shiki (e.g. `dracula`)
* - any theme object compatible with VS Code or Shiki (e.g. imported from an NPM theme package)
* - any ExpressiveCodeTheme instance (e.g. using `ExpressiveCodeTheme.fromJSONString(...)`
* to load a custom JSON/JSONC theme file yourself)
*
* Defaults to `['github-dark', 'github-light']`, two themes bundled with Shiki.
*/
themes?: ThemeObjectOrShikiThemeName[] | undefined;
/**
* The number of spaces that should be used to render tabs. Defaults to 2.
*
* Any tabs found in code blocks in your markdown/MDX documents will be replaced
* with the specified number of spaces. This ensures that the code blocks are
* rendered consistently across browsers and platforms.
*
* If you want to preserve tabs in your code blocks, set this option to 0.
*/
tabWidth?: number | undefined;
/**
* This optional function provides support for multi-language sites by allowing you
* to customize the locale used for a given code block.
*
* The function is called with an object containing the following properties:
* - `input`: Block data for the `ExpressiveCodeBlock` constructor.
* - `file`: A `RehypeExpressiveCodeDocument` object with information about the parent document.
*
* If the function returns `undefined`, the default locale provided in the
* Expressive Code configuration is used.
*/
getBlockLocale?: (({ input, file }: {
input: ExpressiveCodeBlockOptions;
file: RehypeExpressiveCodeDocument;
}) => string | undefined | Promise<string | undefined>) | undefined;
/**
* This optional function allows you to customize how `ExpressiveCodeBlock`
* instances are created from code blocks found in the Markdown document.
*
* The function is called with an object containing the following properties:
* - `input`: Block data for the `ExpressiveCodeBlock` constructor.
* - `file`: A `RehypeExpressiveCodeDocument` object with information about the parent document.
*
* The function is expected to return an `ExpressiveCodeBlock` instance
* or a promise resolving to one.
*/
customCreateBlock?: (({ input, file }: {
input: ExpressiveCodeBlockOptions;
file: RehypeExpressiveCodeDocument;
}) => ExpressiveCodeBlock | Promise<ExpressiveCodeBlock>) | undefined;
/**
* This advanced option allows you to influence the rendering process by creating
* your own `ExpressiveCode` instance or processing the base styles and JS modules
* added to every page.
*
* The return value will be cached and used for all code blocks on the site.
*/
customCreateRenderer?: ((options: RehypeExpressiveCodeOptions) => Promise<RehypeExpressiveCodeRenderer> | RehypeExpressiveCodeRenderer) | undefined;
};
type ThemeObjectOrShikiThemeName = BundledShikiTheme | ExpressiveCodeTheme | ExpressiveCodeThemeInput;
type RehypeExpressiveCodeDocument = {
/**
* The full path to the source file containing the code block.
*
* This path might be an empty string if the source file location of the parent document is
* unknown, e.g. when processing a dynamically generated code block, or when the parent
* document is not loaded from a file. It is recommended to check the `url` property first,
* and only use `path` as a fallback if the URL is not available.
*/
path: string;
/**
* Base of `path`.
*
* Defaults to `process.cwd()` or `'/'` in browsers.
*/
cwd: string;
/**
* The URL to the page containing the code block.
*
* This can be `undefined` if the parent document is not loaded from a URL, or if the
* URL is unknown at the current processing stage. It is recommended to implement a fallback
* that uses the `path` and `cwd` properties in case the `url` is undefined.
*/
url?: URL | undefined;
/**
* Optional document data that might be provided by the integration.
*/
data: Record<string, unknown> | undefined;
};
type RehypeExpressiveCodeRenderer = {
ec: ExpressiveCode;
baseStyles: string;
themeStyles: string;
jsModules: string[];
};
/**
* Creates an `ExpressiveCode` instance using the given `options`,
* including support to load themes bundled with Shiki by name.
*
* Returns the created `ExpressiveCode` instance together with the base styles and JS modules
* that should be added to every page.
*/
declare function createRenderer(options?: RehypeExpressiveCodeOptions): Promise<RehypeExpressiveCodeRenderer>;
declare function rehypeExpressiveCode(options?: RehypeExpressiveCodeOptions): (tree: Root, file: AnyVFile) => Promise<void>;
export { RehypeExpressiveCodeDocument, RehypeExpressiveCodeOptions, RehypeExpressiveCodeRenderer, ThemeObjectOrShikiThemeName, createRenderer, rehypeExpressiveCode as default };