import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers';
import { expressiveCodeHeaderIcons } from '@prosefly/astro-components/expressive-code';
import {
mergeEcConfigOptions,
type AstroExpressiveCodeOptions,
} from 'astro-expressive-code';
import type { LotusMarkdownOptions } from './options';
function createInlineSvgUrl(svgContents: string[]): string {
return `url("data:image/svg+xml,${encodeURIComponent(svgContents.join(''))}")`;
}
const lucideCopyIcon = createInlineSvgUrl([
``,
]);
const proseIsolationPlugin = {
name: 'Lotus prose isolation',
hooks: {
postprocessRenderedBlockGroup: ({ renderData }) => {
const classNames = renderData.groupAst.properties.className as string[] | undefined;
renderData.groupAst.properties.className = [...(classNames ?? []), 'not-prose'];
},
},
} satisfies NonNullable[number];
const defaultExpressiveCodeOptions: AstroExpressiveCodeOptions = {
themes: ['github-light', 'github-dark'],
plugins: [pluginLineNumbers(), expressiveCodeHeaderIcons(), proseIsolationPlugin],
defaultProps: {
showLineNumbers: false,
},
useDarkModeMediaQuery: true,
customizeTheme: (theme) => {
theme.name = theme.type === 'dark' ? 'dark' : 'light';
},
useThemedScrollbars: false,
styleOverrides: {
borderRadius: 'var(--lotus-radius-lg)',
borderWidth: '1px',
borderColor: 'var(--lotus-code-border)',
codeBackground: 'var(--lotus-code-background)',
codeForeground: 'var(--lotus-text)',
codeFontFamily: 'var(--lotus-font-mono)',
codeFontSize: '0.875rem',
codeLineHeight: '1.7142857',
uiFontFamily: 'var(--lotus-font-sans)',
uiFontSize: '0.8125rem',
focusBorder: 'var(--lotus-accent)',
scrollbarThumbColor: 'color-mix(in oklab, var(--lotus-text-muted) 70%, transparent)',
scrollbarThumbHoverColor: 'var(--lotus-text-muted)',
frames: {
copyIcon: lucideCopyIcon,
},
},
};
export function resolveExpressiveCodeOptions(
options: LotusMarkdownOptions['expressiveCode'],
): AstroExpressiveCodeOptions | false {
if (options === false) {
return false;
}
return mergeEcConfigOptions(defaultExpressiveCodeOptions, options ?? {});
}