diff options
Diffstat (limited to 'packages/integrations/markdoc/src/extensions')
-rw-r--r-- | packages/integrations/markdoc/src/extensions/prism.ts | 21 | ||||
-rw-r--r-- | packages/integrations/markdoc/src/extensions/shiki.ts | 35 |
2 files changed, 56 insertions, 0 deletions
diff --git a/packages/integrations/markdoc/src/extensions/prism.ts b/packages/integrations/markdoc/src/extensions/prism.ts new file mode 100644 index 000000000..721564871 --- /dev/null +++ b/packages/integrations/markdoc/src/extensions/prism.ts @@ -0,0 +1,21 @@ +import { runHighlighterWithAstro } from '@astrojs/prism/dist/highlighter'; +import { unescapeHTML } from 'astro/runtime/server/index.js'; +import { type AstroMarkdocConfig, Markdoc } from '../config.js'; + +export default function prism(): AstroMarkdocConfig { + return { + nodes: { + fence: { + attributes: Markdoc.nodes.fence.attributes!, + transform({ attributes: { language, content } }) { + const { html, classLanguage } = runHighlighterWithAstro(language, content); + + // Use `unescapeHTML` to return `HTMLString` for Astro renderer to inline as HTML + return unescapeHTML( + `<pre class="${classLanguage}"><code class="${classLanguage}">${html}</code></pre>`, + ) as any; + }, + }, + }, + }; +} diff --git a/packages/integrations/markdoc/src/extensions/shiki.ts b/packages/integrations/markdoc/src/extensions/shiki.ts new file mode 100644 index 000000000..1102242fd --- /dev/null +++ b/packages/integrations/markdoc/src/extensions/shiki.ts @@ -0,0 +1,35 @@ +import { createShikiHighlighter } from '@astrojs/markdown-remark'; +import Markdoc from '@markdoc/markdoc'; +import type { ShikiConfig } from 'astro'; +import { unescapeHTML } from 'astro/runtime/server/index.js'; +import type { AstroMarkdocConfig } from '../config.js'; + +export default async function shiki(config?: ShikiConfig): Promise<AstroMarkdocConfig> { + const highlighter = await createShikiHighlighter({ + langs: config?.langs, + theme: config?.theme, + themes: config?.themes, + }); + + return { + nodes: { + fence: { + attributes: Markdoc.nodes.fence.attributes!, + async transform({ attributes }) { + // NOTE: The `meta` from fence code, e.g. ```js {1,3-4}, isn't quite supported by Markdoc. + // Only the `js` part is parsed as `attributes.language` and the rest is ignored. This means + // some Shiki transformers may not work correctly as it relies on the `meta`. + const lang = typeof attributes.language === 'string' ? attributes.language : 'plaintext'; + const html = await highlighter.codeToHtml(attributes.content, lang, { + wrap: config?.wrap, + defaultColor: config?.defaultColor, + transformers: config?.transformers, + }); + + // Use `unescapeHTML` to return `HTMLString` for Astro renderer to inline as HTML + return unescapeHTML(html) as any; + }, + }, + }, + }; +} |