mirror of
https://github.com/withastro/astro.git
synced 2025-02-24 22:46:02 -05:00
65 lines
2.1 KiB
Text
65 lines
2.1 KiB
Text
---
|
|
import type * as shiki from 'shiki';
|
|
import { getHighlighter } from './Shiki.js';
|
|
|
|
export interface Props {
|
|
/** The code to highlight. Required. */
|
|
code: string;
|
|
/**
|
|
* The language of your code.
|
|
* Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
|
|
* Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
|
|
*
|
|
* @default "plaintext"
|
|
*/
|
|
lang?: shiki.Lang | shiki.ILanguageRegistration;
|
|
/**
|
|
* The styling theme.
|
|
* Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
|
|
* Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
|
|
*
|
|
* @default "github-dark"
|
|
*/
|
|
theme?: shiki.IThemeRegistration;
|
|
/**
|
|
* Enable word wrapping.
|
|
* - true: enabled.
|
|
* - false: disabled.
|
|
* - null: All overflow styling removed. Code will overflow the element by default.
|
|
*
|
|
* @default false
|
|
*/
|
|
wrap?: boolean | null;
|
|
}
|
|
|
|
const { code, lang = 'plaintext', theme = 'github-dark', wrap = false } = Astro.props;
|
|
|
|
/** Replace the shiki class name with a custom astro class name. */
|
|
function repairShikiTheme(html: string): string {
|
|
// Replace "shiki" class naming with "astro"
|
|
html = html.replace(/<pre class="(.*?)shiki(.*?)"/, '<pre class="$1astro-code$2"');
|
|
// Handle code wrapping
|
|
// if wrap=null, do nothing.
|
|
if (wrap === false) {
|
|
html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"');
|
|
} else if (wrap === true) {
|
|
html = html.replace(
|
|
/style="(.*?)"/,
|
|
'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"'
|
|
);
|
|
}
|
|
return html;
|
|
}
|
|
|
|
const highlighter = await getHighlighter({
|
|
theme,
|
|
// Load custom lang if passed an object, otherwise load the default
|
|
langs: typeof lang !== 'string' ? [lang] : undefined,
|
|
});
|
|
const _html = highlighter.codeToHtml(code, {
|
|
lang: typeof lang === 'string' ? lang : lang.id,
|
|
});
|
|
const html = repairShikiTheme(_html);
|
|
---
|
|
|
|
<Fragment set:html={html} />
|