summaryrefslogtreecommitdiff
path: root/packages/markdown
diff options
context:
space:
mode:
authorGravatar Juan Martín Seery <me@juanm04.com> 2022-02-07 13:31:02 -0300
committerGravatar GitHub <noreply@github.com> 2022-02-07 08:31:02 -0800
commit2bc91543ceeb5f3dd45e201bf75d79f186e85141 (patch)
tree0b001adedd69a248746974462640f081f7a351f9 /packages/markdown
parent0caf9169bc0867f41332bd2cc8ab0066b39d286e (diff)
downloadastro-2bc91543ceeb5f3dd45e201bf75d79f186e85141.tar.gz
astro-2bc91543ceeb5f3dd45e201bf75d79f186e85141.tar.zst
astro-2bc91543ceeb5f3dd45e201bf75d79f186e85141.zip
feat: Added the ability to add custom themes/languages to Shiki (#2518)
* Replaced `shikiTheme` with `shikiConfig` * Code.astro now accepts custom themes/langs * Updated docs * Updated tests * Fixed language loading * Added customization examples * Updated documentation * Added more tests * Changelogs * Changed some spaces to tabs * Fixed typo in changesets * Moved tests fixtures * Rolled back changes to with-markdown-shiki * Removed lang example in docs * Optimized Code component * Try to fix windows errors * Try to see if this new tests work
Diffstat (limited to 'packages/markdown')
-rw-r--r--packages/markdown/remark/src/index.ts4
-rw-r--r--packages/markdown/remark/src/remark-shiki.ts41
-rw-r--r--packages/markdown/remark/src/types.ts4
3 files changed, 44 insertions, 5 deletions
diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts
index 78d645227..e8a315ef1 100644
--- a/packages/markdown/remark/src/index.ts
+++ b/packages/markdown/remark/src/index.ts
@@ -39,7 +39,7 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
const scopedClassName = opts?.$?.scopedClassName;
const mode = opts?.mode ?? 'mdx';
const syntaxHighlight = opts?.syntaxHighlight ?? 'prism';
- const shikiTheme = opts?.shikiTheme ?? 'github-dark';
+ const shikiConfig = opts?.shikiConfig ?? {};
const isMDX = mode === 'mdx';
const { headers, rehypeCollectHeaders } = createCollectHeaders();
@@ -70,7 +70,7 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
if (syntaxHighlight === 'prism') {
parser.use([remarkPrism(scopedClassName)]);
} else if (syntaxHighlight === 'shiki') {
- parser.use([await remarkShiki(shikiTheme)]);
+ parser.use([await remarkShiki(shikiConfig)]);
}
parser.use([[markdownToHtml as any, { allowDangerousHtml: true, passThrough: ['raw', 'mdxTextExpression', 'mdxJsxTextElement', 'mdxJsxFlowElement'] }]]);
diff --git a/packages/markdown/remark/src/remark-shiki.ts b/packages/markdown/remark/src/remark-shiki.ts
index 5becad76d..91f1b76e3 100644
--- a/packages/markdown/remark/src/remark-shiki.ts
+++ b/packages/markdown/remark/src/remark-shiki.ts
@@ -1,9 +1,41 @@
import shiki from 'shiki';
import { visit } from 'unist-util-visit';
-const remarkShiki = async (theme: shiki.Theme) => {
+export interface ShikiConfig {
+ /**
+ * The languages loaded to Shiki.
+ * 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 []
+ */
+ langs?: 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: enabled.
+ * - null: All overflow styling removed. Code will overflow the element by default.
+ *
+ * @default false
+ */
+ wrap?: boolean | null;
+}
+
+const remarkShiki = async ({ langs = [], theme = 'github-dark', wrap = false }: ShikiConfig) => {
const highlighter = await shiki.getHighlighter({ theme });
+ for (const lang of langs) {
+ await highlighter.loadLanguage(lang);
+ }
+
return () => (tree: any) => {
visit(tree, 'code', (node) => {
let html = highlighter.codeToHtml(node.value, { lang: node.lang ?? 'plaintext' });
@@ -12,6 +44,13 @@ const remarkShiki = async (theme: shiki.Theme) => {
html = html.replace('<pre class="shiki"', '<pre class="astro-code"');
// Replace "shiki" css variable naming with "astro".
html = html.replace(/style="(background-)?color: var\(--shiki-/g, 'style="$1color: var(--astro-code-');
+ // 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;"');
+ }
node.type = 'html';
node.value = html;
diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts
index 94c3e78a3..040c33b79 100644
--- a/packages/markdown/remark/src/types.ts
+++ b/packages/markdown/remark/src/types.ts
@@ -1,12 +1,12 @@
import type * as unified from 'unified';
-import type * as shiki from 'shiki';
+import type { ShikiConfig } from './remark-shiki';
export type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any];
export interface AstroMarkdownOptions {
mode?: 'md' | 'mdx';
syntaxHighlight?: 'prism' | 'shiki' | false;
- shikiTheme?: shiki.Theme;
+ shikiConfig?: ShikiConfig;
remarkPlugins?: Plugin[];
rehypePlugins?: Plugin[];
}