Trouble with children in custom "admonition" plugin in compiler #2355
-
Hi there, I'm having some issues with passing children in a plugin made for directives. I'm using MDX Editor to write the mdx, which, upon hitting a save button, sends the mdx string to the compiler. I've almost got it working but in order for the admonition to appear as it does in the MDX Editor, I need to insert an additional So basically, all I want to do is to insert a new But when I pass the Here is the compiler, the plugin, and the mdx source. import {compile} from '@mdx-js/mdx'
import remarkGfm from "remark-gfm";
import remarkDirective from 'remark-directive';
export const mdxCompiler = async (mdxSource: string) => {
try {
const mdxCompiled = String(await compile(mdxSource, {
outputFormat: 'function-body',
development: false,
remarkPlugins: [remarkGfm, remarkDirective, adminitionPlugin],
}));
console.log("COMPILED: \n", mdxCompiled) // this line does not get hit
return mdxCompiled;
} catch(e) {
throw new Error("An error occured in the mdxCompiler");
}
}
import {h} from 'hastscript'
import {visit} from 'unist-util-visit'
const ADMONITION_TYPES = ["note", "tip", "danger", "info", "caution"]
function adminitionPlugin() {
// @ts-ignore
return (tree) => {
visit(tree, (node) => {
if (
node.type === 'containerDirective' ||
node.type === 'leafDirective' ||
node.type === 'textDirective'
) {
if (ADMONITION_TYPES.includes(node.name)) {
const data = node.data || (node.data = {});
const tagName = node.type === 'textDirective' ? 'span' : 'div';
if (node.name === ADMONITION_TYPES[0]) {
node.attributes = {
...node.attributes,
class: '_admonitionNote_13nbk_63',
};
} else if (node.name === ADMONITION_TYPES[1]) {
node.attributes = {
...node.attributes,
class: '_admonitionTip_13nbk_63',
};
} else if (node.name === ADMONITION_TYPES[2]) {
node.attributes = {
...node.attributes,
class: '_admonitionDanger_13nbk_63',
};
} else if (node.name === ADMONITION_TYPES[3]) {
node.attributes = {
...node.attributes,
class: '_admonitionInfo_13nbk_63',
};
} else if (node.name === ADMONITION_TYPES[4]) {
node.attributes = {
...node.attributes,
class: '_admonitionCaution_13nbk_63',
};
}
data.hName = tagName;
data.hProperties = h(tagName, node.attributes || {}).properties;
console.log("NODE CHILDREN: \n", node.children)
// inserting new child to node.data and passing node.data's children to this new child
data.hChildren = [
h('div', {class: "_nestedEditor_w1wlt_891"}, node.children)
// if i swap node.children here with a string, the compilation runs fine
];
console.log("DATA: \n", data)
console.log("old children under new child of node.data: \n", data.hChildren[0].children)
}
}
})
}
} The mdx source: # Supercool big title
:::danger
danger multi-line admonition
here is the second line
and third
:::
last sentence Logs from the console: // this is prior the h() function being called, and so these are the children of the directive
NODE CHILDREN:
[
{
type: 'paragraph',
children: [ [Object] ],
position: { start: [Object], end: [Object] }
},
{
type: 'paragraph',
children: [ [Object] ],
position: { start: [Object], end: [Object] }
},
{
type: 'paragraph',
children: [ [Object] ],
position: { start: [Object], end: [Object] }
}
]
// this is after the h() function is called, so the directive gets a new class attribute as well as
// a new child div, which itself is supposed to take over its children
DATA:
{
hName: 'div',
hProperties: { className: [ '_admonitionDanger_13nbk_63' ] },
hChildren: [
{
type: 'element',
tagName: 'div',
properties: [Object],
children: [Array]
}
]
}
// inspecting the transfered children, it appears just as it was in the first console log
// which is expected
old children under new child of node.data:
[
{
type: 'paragraph',
children: [ [Object] ],
position: { start: [Object], end: [Object] }
},
{
type: 'paragraph',
children: [ [Object] ],
position: { start: [Object], end: [Object] }
},
{
type: 'paragraph',
children: [ [Object] ],
position: { start: [Object], end: [Object] }
}
] So I'm really not sure what's going here. Thanks for any help! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 21 replies
-
Welcome @Firgrep! 👋 The easier approach to solve this would be to use plain |
Beta Was this translation helpful? Give feedback.
Focus on the distinction between what properties can be applied directly to
node
and which go onnode.data
children
is a property directly of node.hProperties
andhName
are ofnode.data
.ref: https://github.com/syntax-tree/mdast#readme and https://github.com/syntax-tree/mdast-util-to-hast#fields-on-nodes
Those were flipped in a few spots causing bugs.
I'd highly recommend using TypeScript or JSDoc (with TypeScript validation) to help catch mismatch in object structures.
With the data put in the correct spot, it adds the elements as expected:
https://stackblitz.com/edit/github-qo53wd-7vuhzr?file=src%2FApp.js
source from sandbox