Mutating Unist AST
Great example https://css-tricks.com/how-to-modify-nodes-in-an-abstract-syntax-tree/
The code below will change a list of images into a grid of images.
import { selectAll } from "unist-util-select";
import { visit } from "unist-util-visit";
export default () => {
return (ast) => {
visit(
ast,
(x) => x.tagName === "ul",
(node) => {
const images = selectAll("element", node).filter(
(y) => y.tagName === "img"
);
if (images.length) {
node.tagName = "div";
node.properties["class"] =
"grid grid-col-1 md:grid-col-3 lg:grid-cols-4";
node.children = images;
}
}
);
};
};
Wrapping an element
For the code examples on this site I needed to wrap the pre > code
tags in a div
with the class not-prose
so that they could be highlighted correctly using highlightjs via remark-highlight. This is because I am using the typography plugin from tailwindcss.
import { visit } from "unist-util-visit";
import { h } from "hastscript";
export default () => {
return (ast, file) => {
visit(
ast,
(x) =>
x.tagName === "pre" && x.children.some((n) => n.tagName === "code"),
(node, idx, parent) => {
file.data.meta = file.data.meta || {};
file.data.meta.hasCode = true;
parent.children[idx] = h("div", { class: "not-prose" }, [node]);
}
);
};
};
The code above turns:
<pre>
<code>Some code</code>
</pre>
into:
<div class="not-prose">
<pre>
<code>Some code</code>
</pre>
</div>