diff --git a/packages/rehype-shikiji/package.json b/packages/rehype-shikiji/package.json index dd5d3d60..212d1b04 100644 --- a/packages/rehype-shikiji/package.json +++ b/packages/rehype-shikiji/package.json @@ -58,6 +58,7 @@ "unist-util-visit": "^5.0.0" }, "devDependencies": { + "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.0" diff --git a/packages/rehype-shikiji/src/core.ts b/packages/rehype-shikiji/src/core.ts index 60161c0b..95a6060f 100644 --- a/packages/rehype-shikiji/src/core.ts +++ b/packages/rehype-shikiji/src/core.ts @@ -58,6 +58,15 @@ export type RehypeShikijiCoreOptions = & CodeOptionsMeta & RehypeShikijiExtraOptions +declare module 'hast' { + interface Data { + meta?: string + } + interface Properties { + metastring?: string + } +} + const rehypeShikijiFromHighlighter: Plugin<[HighlighterGeneric, RehypeShikijiCoreOptions], Root> = function ( highlighter, options, @@ -108,8 +117,8 @@ const rehypeShikijiFromHighlighter: Plugin<[HighlighterGeneric, Rehype return } - const attrs = (head.data as any)?.meta - const meta = parseMetaString?.(attrs, node, tree) || {} + const metaString = head.data?.meta ?? head.properties.metastring ?? '' + const meta = parseMetaString?.(metaString, node, tree) || {} const codeOptions: CodeToHastOptions = { ...rest, @@ -117,7 +126,7 @@ const rehypeShikijiFromHighlighter: Plugin<[HighlighterGeneric, Rehype meta: { ...rest.meta, ...meta, - __raw: attrs, + __raw: metaString, }, } @@ -132,7 +141,7 @@ const rehypeShikijiFromHighlighter: Plugin<[HighlighterGeneric, Rehype }) } - if (highlightLines && typeof attrs === 'string') { + if (highlightLines && typeof metaString === 'string') { codeOptions.transformers ||= [] codeOptions.transformers.push( transformerMetaHighlight({ diff --git a/packages/rehype-shikiji/test/core.test.ts b/packages/rehype-shikiji/test/core.test.ts index 304f87a7..d1152f6d 100644 --- a/packages/rehype-shikiji/test/core.test.ts +++ b/packages/rehype-shikiji/test/core.test.ts @@ -2,10 +2,13 @@ import fs from 'node:fs/promises' import { unified } from 'unified' import remarkParse from 'remark-parse' import remarkRehype from 'remark-rehype' +import rehypeRaw from 'rehype-raw' import rehypeStringify from 'rehype-stringify' +import { visit } from 'unist-util-visit' import { expect, it } from 'vitest' import { getHighlighter } from 'shikiji' +import type { Root } from 'hast' import rehypeShikijiFromHighlighter from '../src/core' it('run', async () => { @@ -30,3 +33,37 @@ it('run', async () => { expect(file.toString()).toMatchFileSnapshot('./fixtures/a.core.out.html') }) + +it('run with rehype-raw', async () => { + const highlighter = await getHighlighter({ + themes: [ + 'vitesse-light', + ], + langs: [ + 'javascript', + ], + }) + + const rehypeMetaString = () => (tree: Root) => { + visit(tree, 'element', (node) => { + if (node.tagName === 'code' && node.data?.meta) { + node.properties ??= {} + node.properties.metastring = node.data.meta + } + }) + } + + const file = unified() + .use(remarkParse) + .use(remarkRehype) + .use(rehypeMetaString) + .use(rehypeRaw) + .use(rehypeShikijiFromHighlighter, highlighter, { + theme: 'vitesse-light', + highlightLines: true, + }) + .use(rehypeStringify) + .processSync(await fs.readFile(new URL('./fixtures/a.md', import.meta.url))) + + expect(file.toString()).toMatchFileSnapshot('./fixtures/a.core.out.html') +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8002ff1..80ed27d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -251,6 +251,9 @@ importers: specifier: ^5.0.0 version: 5.0.0 devDependencies: + rehype-raw: + specifier: ^7.0.0 + version: 7.0.0 rehype-stringify: specifier: ^10.0.0 version: 10.0.0 @@ -7534,6 +7537,14 @@ packages: jsesc: 0.5.0 dev: true + /rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + dependencies: + '@types/hast': 3.0.3 + hast-util-raw: 9.0.0 + vfile: 6.0.1 + dev: true + /rehype-stringify@10.0.0: resolution: {integrity: sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==} dependencies: