import unifiedTypes, { unified } from "unified"; import remarkParse from "remark-parse"; import remarkRehype, { HastRoot } from "remark-rehype"; import rehypeShiki from "."; import rehypeStringify from "rehype-stringify"; import * as shiki from "shiki"; import { visit as unistUtilVisit } from "unist-util-visit"; test("supported language", async () => { expect( unified() .use(remarkParse) .use(remarkRehype) .use(rehypeShiki, { highlighter: await shiki.getHighlighter({ theme: "light-plus" }), }) .use(rehypeStringify) .processSync( ` \`\`\`javascript return unified() \`\`\` ` ) .toString() ).toMatchInlineSnapshot( `"
return unified()
"` ); }); test("text", async () => { expect( unified() .use(remarkParse) .use(remarkRehype) .use(rehypeShiki, { highlighter: await shiki.getHighlighter({ theme: "light-plus" }), }) .use(rehypeStringify) .processSync( ` \`\`\`text Leandro Facchinetti \`\`\` ` ) .toString() ).toMatchInlineSnapshot( `"
Leandro Facchinetti
"` ); }); test("unsupported language", async () => { expect( unified() .use(remarkParse) .use(remarkRehype) .use(rehypeShiki, { highlighter: await shiki.getHighlighter({ theme: "light-plus" }), }) .use(rehypeStringify) .processSync( ` \`\`\`not-a-language Leandro Facchinetti \`\`\` ` ) .toString() ).toMatchInlineSnapshot(` "
Leandro Facchinetti
    
" `); }); test("throw on unsupported language", async () => { await expect(async () => { unified() .use(remarkParse) .use(remarkRehype) .use(rehypeShiki, { highlighter: await shiki.getHighlighter({ theme: "light-plus" }), throwOnUnsupportedLanguage: true, }) .use(rehypeStringify) .processSync( ` \`\`\`not-a-language Leandro Facchinetti \`\`\` ` ) .toString(); }).rejects.toThrowErrorMatchingInlineSnapshot( `"No language registration for not-a-language"` ); }); test("multiple highlighters", async () => { expect( unified() .use(remarkParse) .use(remarkRehype) .use(rehypeShiki, { highlighter: { light: await shiki.getHighlighter({ theme: "light-plus" }), dark: await shiki.getHighlighter({ theme: "dark-plus" }), }, }) .use(rehypeStringify) .processSync( ` \`\`\`javascript return unified() \`\`\` ` ) .toString() ).toMatchInlineSnapshot(` "
return unified()
return unified()
" `); }); test("preserve position", async () => { const positionSaver: unifiedTypes.Plugin = () => (tree) => { unistUtilVisit(tree, (node) => { if ((node as any).properties !== undefined && node.position !== undefined) (node as any).properties.dataPosition = JSON.stringify(node.position); }); }; expect( unified() .use(remarkParse) .use(remarkRehype) .use(rehypeShiki, { highlighter: await shiki.getHighlighter({ theme: "light-plus" }), }) .use(positionSaver) .use(rehypeStringify) .processSync( ` Some text before \`\`\`javascript return unified() \`\`\` and some after ` ) .toString() ).toMatchInlineSnapshot(` "

Some

text

before

return unified()

and

some

after

" `); expect( unified() .use(remarkParse) .use(remarkRehype) .use(rehypeShiki, { highlighter: { light: await shiki.getHighlighter({ theme: "light-plus" }), dark: await shiki.getHighlighter({ theme: "dark-plus" }), }, }) .use(positionSaver) .use(rehypeStringify) .processSync( ` Some text before \`\`\`javascript return unified() \`\`\` and some after ` ) .toString() ).toMatchInlineSnapshot(` "

Some

text

before

return unified()
return unified()

and

some

after

" `); }); test("only one root for separate transforms", async () => { const ast = unified() .use(remarkParse) .use(remarkRehype) .use(function () { this.Compiler = (html) => html; }).processSync(` \`\`\`js console.log(value == null) \`\`\` `).result as HastRoot; const transformedAst = unified() .use(rehypeShiki, { highlighter: await shiki.getHighlighter({ theme: "light-plus" }), }) .runSync(ast); let rootCount = 0; unistUtilVisit(transformedAst, "root", () => rootCount++); expect(rootCount).toBe(1); });