Preserve code element node meta for rehype syntax highlighters (#5335)
This commit is contained in:
parent
dc00ca4648
commit
dca762cf73
7 changed files with 71 additions and 1 deletions
5
.changeset/heavy-kangaroos-sin.md
Normal file
5
.changeset/heavy-kangaroos-sin.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/mdx': patch
|
||||
---
|
||||
|
||||
Preserve code element node `data.meta` in `properties.metastring` for rehype syntax highlighters, like `rehype-pretty-code``
|
|
@ -39,6 +39,7 @@
|
|||
"github-slugger": "^1.4.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"kleur": "^4.1.4",
|
||||
"rehype-pretty-code": "^0.4.0",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"remark-frontmatter": "^4.0.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
|
|
|
@ -11,6 +11,7 @@ import remarkSmartypants from 'remark-smartypants';
|
|||
import type { Data, VFile } from 'vfile';
|
||||
import { MdxOptions } from './index.js';
|
||||
import rehypeCollectHeadings from './rehype-collect-headings.js';
|
||||
import rehypeMetaString from './rehype-meta-string.js';
|
||||
import remarkPrism from './remark-prism.js';
|
||||
import remarkShiki from './remark-shiki.js';
|
||||
import { jsToTreeNode } from './utils.js';
|
||||
|
@ -150,6 +151,8 @@ export function getRehypePlugins(
|
|||
let rehypePlugins: PluggableList = [
|
||||
// getHeadings() is guaranteed by TS, so we can't allow user to override
|
||||
rehypeCollectHeadings,
|
||||
// ensure `data.meta` is preserved in `properties.metastring` for rehype syntax highlighters
|
||||
rehypeMetaString,
|
||||
// rehypeRaw allows custom syntax highlighters to work without added config
|
||||
[rehypeRaw, { passThrough: nodeTypes }] as any,
|
||||
];
|
||||
|
|
17
packages/integrations/mdx/src/rehype-meta-string.ts
Normal file
17
packages/integrations/mdx/src/rehype-meta-string.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { visit } from 'unist-util-visit';
|
||||
|
||||
/**
|
||||
* Moves `data.meta` to `properties.metastring` for the `code` element node
|
||||
* as `rehype-raw` strips `data` from all nodes, which may contain useful information.
|
||||
* e.g. ```js {1:3} => metastring: "{1:3}"
|
||||
*/
|
||||
export default function rehypeMetaString() {
|
||||
return function (tree: any) {
|
||||
visit(tree, (node) => {
|
||||
if (node.type === 'element' && node.tagName === 'code' && node.data?.meta) {
|
||||
node.properties ??= {};
|
||||
node.properties.metastring = node.data.meta;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
# Syntax highlighting
|
||||
|
||||
```astro
|
||||
```astro {2}
|
||||
---
|
||||
const handlesAstroSyntax = true
|
||||
---
|
||||
|
|
|
@ -4,6 +4,7 @@ import { expect } from 'chai';
|
|||
import { parseHTML } from 'linkedom';
|
||||
import { loadFixture } from '../../../astro/test/test-utils.js';
|
||||
import shikiTwoslash from 'remark-shiki-twoslash';
|
||||
import rehypePrettyCode from 'rehype-pretty-code';
|
||||
|
||||
const FIXTURE_ROOT = new URL('./fixtures/mdx-syntax-hightlighting/', import.meta.url);
|
||||
|
||||
|
@ -88,4 +89,31 @@ describe('MDX syntax highlighting', () => {
|
|||
const twoslashCodeBlock = document.querySelector('pre.shiki');
|
||||
expect(twoslashCodeBlock).to.not.be.null;
|
||||
});
|
||||
|
||||
it('supports custom highlighter - rehype-pretty-code', async () => {
|
||||
const fixture = await loadFixture({
|
||||
root: FIXTURE_ROOT,
|
||||
markdown: {
|
||||
syntaxHighlight: false,
|
||||
},
|
||||
integrations: [
|
||||
mdx({
|
||||
rehypePlugins: [
|
||||
[
|
||||
rehypePrettyCode,
|
||||
{
|
||||
onVisitHighlightedLine(node) {
|
||||
node.properties.style = 'background-color:#000000';
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
await fixture.build();
|
||||
|
||||
const html = await fixture.readFile('/index.html');
|
||||
expect(html).to.include('style="background-color:#000000"')
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2782,6 +2782,7 @@ importers:
|
|||
mdast-util-to-string: ^3.1.0
|
||||
mocha: ^9.2.2
|
||||
reading-time: ^1.5.0
|
||||
rehype-pretty-code: ^0.4.0
|
||||
rehype-raw: ^6.1.1
|
||||
remark-frontmatter: ^4.0.1
|
||||
remark-gfm: ^3.0.1
|
||||
|
@ -2802,6 +2803,7 @@ importers:
|
|||
github-slugger: 1.5.0
|
||||
gray-matter: 4.0.3
|
||||
kleur: 4.1.5
|
||||
rehype-pretty-code: 0.4.0_shiki@0.11.1
|
||||
rehype-raw: 6.1.1
|
||||
remark-frontmatter: 4.0.1
|
||||
remark-gfm: 3.0.1
|
||||
|
@ -15280,6 +15282,10 @@ packages:
|
|||
unist-util-visit-children: 1.1.4
|
||||
dev: false
|
||||
|
||||
/parse-numeric-range/1.3.0:
|
||||
resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==}
|
||||
dev: false
|
||||
|
||||
/parse-package-name/1.0.0:
|
||||
resolution: {integrity: sha512-kBeTUtcj+SkyfaW4+KBe0HtsloBJ/mKTPoxpVdA57GZiPerREsUWJOhVj9anXweFiJkm5y8FG1sxFZkZ0SN6wg==}
|
||||
dev: true
|
||||
|
@ -16210,6 +16216,16 @@ packages:
|
|||
unified: 10.1.2
|
||||
dev: false
|
||||
|
||||
/rehype-pretty-code/0.4.0_shiki@0.11.1:
|
||||
resolution: {integrity: sha512-Bp91nfo4blpgCXlvGP1hsG+kRFfjqBVU09o1RFcnNA62u+iIzJiJRGzpfBj4FaItq7CEQL5ASGB7vLxN5xCvyA==}
|
||||
engines: {node: ^12.16.0 || >=13.2.0}
|
||||
peerDependencies:
|
||||
shiki: '*'
|
||||
dependencies:
|
||||
parse-numeric-range: 1.3.0
|
||||
shiki: 0.11.1
|
||||
dev: false
|
||||
|
||||
/rehype-raw/6.1.1:
|
||||
resolution: {integrity: sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==}
|
||||
dependencies:
|
||||
|
|
Loading…
Reference in a new issue