Embed mdast AST in Markdown "template"? #54
-
Is there already a way, given an existing mdast AST and a Markdown "template", to parse the template s.t. the existing AST is embedded within it? For example: import { fromMarkdown } from "mdast-util-from-markdown";
const emphasis = fromMarkdown`*emphasis*`;
const list = fromMarkdown`- ${emphasis}`;
console.dir(list, { depth: null }); What I want is the Instead what I get is:{
type: 'root',
children: [
{
type: 'list',
ordered: false,
start: null,
spread: false,
children: [
{
type: 'listItem',
spread: false,
checked: null,
children: [
{
type: 'paragraph',
children: [
{
type: 'text',
value: ',',
position: {
start: { line: 1, column: 3, offset: 2 },
end: { line: 1, column: 4, offset: 3 }
}
}
],
position: {
start: { line: 1, column: 3, offset: 2 },
end: { line: 1, column: 4, offset: 3 }
}
}
],
position: {
start: { line: 1, column: 1, offset: 0 },
end: { line: 1, column: 4, offset: 3 }
}
}
],
position: {
start: { line: 1, column: 1, offset: 0 },
end: { line: 1, column: 4, offset: 3 }
}
}
],
position: {
start: { line: 1, column: 1, offset: 0 },
end: { line: 1, column: 4, offset: 3 }
}
} Which (predictably) is what I'd get from If not (a way doesn't already exist), I guess how I'd approach it is with some kind of micromark extension? Maybe micromark-extension-directive? Interleave the template strings with the extension, parse, then walk the result and swap the extension nodes for the template args? Something like: function md(strings, ...values) {
const tree = fromMarkdown(strings.join(":expression"));
// Walk tree, swap textDirectives for values
return tree;
} Is there a better way? What I'm trying to do is assemble a Markdown document from different sources, and I want to parse the fragments independently: I don't want the embedded Markdown interpreted with respect to the container or vice versa. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
In theory, yes.
Potentially yes. import Mdx from "@mdx-js/runtime";
const mainDocument = `- <Emphasis />`;
const childEmphasisDcoument = `*emphasis*`;
export default function App() {
return (
<Mdx
components={{
Emphasis: () => <Mdx>{childEmphasisDcoument}</Mdx>
}}
>
{mainDocument}
</Mdx>
);
} 📓 note that there are two instances of runtime which can be configured independent of each other Another would be directives as a replacement and create a plugin to handle replacement const sourceMarkdown = `
- :template{emphasis}
`;
const childMarkdown = `*emphasis*`;
const remarkTemplateDirectives = (templateMapping) => (tree) =>
visit(tree, "textDirective", (node, index, parent) => {
if (node.name === "template") {
parent.children[index] = templateMapping[Object.keys(node.attributes)[0]];
}
});
unified()
.use(remarkParse)
.use(remarkDirective)
.use(remarkTemplateDirectives, {
emphasis: unified().use(remarkParse).parse(childMarkdown)
}) 👷 runnable example https://codesandbox.io/s/remark-directive-templates-960dt?file=/src/index.js |
Beta Was this translation helpful? Give feedback.
In theory, yes.
directives could be inserted as placeholders and replaced by a transformer.
Potentially yes.
One approach would be to use MDX, which could look like: