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 };
