How to parse/convert markdown to hast to render/display needed HTML? #112
-
I am trying to turn a markdown directive defined as:
into this HTML: <div class="notice">
<div class="notice-icon">
<HiOutlineInformationCircle /> // this is coming from https://react-icons.github.io/react-icons
<div>
<div class="notice-content">
This is a note notice
</div>
</div> But I am unsure how to turn such markdown into the properly hast and I will need some help/guidance. This is what I currently have: const processNotice = (node: any) => {
const allowedTypes = ['warning', 'important', 'note', 'tip', 'info'];
const type = Object.keys(node.attributes)[0];
if (allowedTypes.indexOf(type) === -1) {
throw new Error('Invalid notice type: ' + type);
}
node.children.unshift({
type: 'containerDirective',
children: [
{
type: 'svg',
data: {
hName: 'svg',
hProperties: {
class: node.name + '-icon',
variant: type
}
}
},
{
type: 'paragraph',
children: [
{
type: 'text',
value: 'some'
}
]
}
]
});
// node.children.push(img)
}
export default processNotice; but as you can see in the runable example: https://codesandbox.io/s/muddy-hill-gvlrvs?file=/src/app.tsx is not working :| certainly I am missing something but unsure what it is. And this one is not as easy as others where I just built an object and push it back to the node childrens. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 22 replies
-
The examples in the As mentioned before, it is recommended to use actual types if you prefer types, instead of Also, your code is just messy: you are not using the plugin you are making in codesandbox? You are including other code for images, but not explaining what they should do? And why do images use an Here’s an example I made from your code to handle container directives with a name of /// <reference types="remark-directive" />
import type { Image, Paragraph, Root, RootContent } from "mdast";
import { visit } from "unist-util-visit";
/**
* Plugin to support custom directives.
*/
const myRemarkShortcodePlugin: import("unified").Plugin<
[],
Root
> = function () {
return (tree, file) => {
visit(tree, (node, index, parent) => {
if (
node.type === "containerDirective" &&
typeof index === "number" &&
parent
) {
if (node.name === "image") {
const url = node.attributes.id;
// Require an `url`, crash otherwise.
if (typeof url !== "string") {
file.fail("Expected `url` attribute on image directive", node);
}
// Create a markdown image node.
const img: Image = {
type: "image",
url,
alt: node.attributes.alt || undefined,
title: null
};
// Images cannot be directly in things.
// They are phrasing content.
const paragraph: Paragraph = {
type: "paragraph",
children: [img]
};
// You also don’t want to *add* it to the directive,
// you want to *replace* the directive.
// @ts-expect-error: content model is fine.
const siblings: RootContent[] = parent.children;
// Replace directive with paragraph.
siblings.splice(index, 1, paragraph);
}
}
});
};
};
export default myRemarkShortcodePlugin; |
Beta Was this translation helpful? Give feedback.
-
hey @wooorm many thanks for this but I think you diverge from my OP and got distracted with the image code. Can I get some ideas for the |
Beta Was this translation helpful? Give feedback.
@reypm with a minimal reproducible example, aim to remove as many unrelated pieces as possible.
There are a lot of random plugins which are unrelated to your question on directives which make it harder to interpret and debug.
Back on your question of how to handle a
notice
.Focus on how you want the
mdast
directive to translate tohast
, using thedata
attributes inmdast
https://github.com/syntax-tree/mdast-util-to-hast#fields-on-nodes.