Skip to content

Instantly share code, notes, and snippets.

@samselikoff
Last active May 6, 2021 14:18
Show Gist options
  • Select an option

  • Save samselikoff/38c59bdff8ca619a87c28e9c8d8b99f9 to your computer and use it in GitHub Desktop.

Select an option

Save samselikoff/38c59bdff8ca619a87c28e9c8d8b99f9 to your computer and use it in GitHub Desktop.
withProse remark plugin that escapes `prose` for MDX components
/*
Usage:
const withMDX = require("@next/mdx")({
options: {
remarkPlugins: [
withProse,
],
},
});
*/
const proseComponents = ["Heading"];
const isJsNode = (node) => {
return (
["jsx", "import", "export"].includes(node.type) &&
!/^<[a-z]+(>|\s)/.test(node.value) &&
!new RegExp(`^<(${proseComponents.join("|")})(>|\\s)`).test(node.value)
);
};
module.exports.withProse = () => {
return (tree) => {
let insideProse = false;
tree.children = tree.children.flatMap((node, i) => {
if (insideProse && isJsNode(node)) {
insideProse = false;
return [{ type: "jsx", value: "</div>" }, node];
}
if (!insideProse && !isJsNode(node)) {
insideProse = true;
return [
{ type: "jsx", value: '<div className="prose">' },
node,
...(i === tree.children.length - 1
? [{ type: "jsx", value: "</div>" }]
: []),
];
}
if (i === tree.children.length - 1 && insideProse) {
return [node, { type: "jsx", value: "</div>" }];
}
return [node];
});
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment