Files
website/node_modules/astro/components/Code.astro
2024-05-06 17:15:30 -04:00

97 lines
2.4 KiB
Plaintext

---
import type { ThemePresets } from '@astrojs/markdown-remark';
import type {
BuiltinLanguage,
LanguageRegistration,
SpecialLanguage,
ThemeRegistration,
ThemeRegistrationRaw,
} from 'shiki';
import { bundledLanguages } from 'shiki/langs';
import { getCachedHighlighter } from '../dist/core/shiki.js';
import type { HTMLAttributes } from '../types';
interface Props extends Omit<HTMLAttributes<'pre'>, 'lang'> {
/** The code to highlight. Required. */
code: string;
/**
* The language of your code.
* Supports all languages listed here: https://shiki.style/languages
* Instructions for loading a custom language: https://shiki.style/guide/load-lang
*
* @default "plaintext"
*/
lang?: BuiltinLanguage | SpecialLanguage | LanguageRegistration;
/**
* The styling theme.
* Supports all themes listed here: https://shiki.style/themes
* Instructions for loading a custom theme: https://shiki.style/guide/load-theme
*
* @default "github-dark"
*/
theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
/**
* Multiple themes to style with -- alternative to "theme" option.
* Supports all themes found above; see https://shiki.style/guide/dual-themes for more information.
*/
themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
/**
* Enable word wrapping.
* - true: enabled.
* - false: disabled.
* - null: All overflow styling removed. Code will overflow the element by default.
*
* @default false
*/
wrap?: boolean | null;
/**
* Generate inline code element only, without the pre element wrapper.
*
* @default false
*/
inline?: boolean;
}
const {
code,
lang = 'plaintext',
theme = 'github-dark',
themes = {},
wrap = false,
inline = false,
...rest
} = Astro.props;
// shiki 1.0 compat
if (typeof lang === 'object') {
// `id` renamed to `name` (always override)
if ((lang as any).id) {
lang.name = (lang as any).id;
}
// `grammar` flattened to lang itself
if ((lang as any).grammar) {
Object.assign(lang, (lang as any).grammar);
}
}
const highlighter = await getCachedHighlighter({
langs: [
typeof lang === 'string'
? Object.keys(bundledLanguages).includes(lang)
? lang
: 'plaintext'
: (lang as any),
],
theme,
themes,
wrap,
});
const html = await highlighter.highlight(code, typeof lang === 'string' ? lang : lang.name, {
inline,
attributes: rest as any,
});
---
<Fragment set:html={html} />