how to custom attr in node? #1884
-
Initial checklist
Affected packages and versionshow to custom attr in node? Link to runnable exampleNo response Steps to reproducehow to custom attr in node? import { visit } from 'unist-util-visit';
import { $remark } from '@milkdown/kit/utils';
// 自定义md 解析器
const headingAnchorCollectorTemp = () => {
return (tree: any) => {
visit(tree, 'heading', (node: any) => {
if (!node.data) node.data = {};
if (!node.data.hProperties) node.data.hProperties = {};
node.data.hProperties.class = 'abc';
return node;
});
};
};
export const headingAnchorCollector = $remark('headingAnchorCollector', () => headingAnchorCollectorTemp); cant work! import './App.css';
import { mdData } from './Mock';
import { nord } from '@milkdown/theme-nord';
import { headingAnchorCollector } from './plugins/tip-schema';
import { Milkdown, MilkdownProvider, useEditor } from '@milkdown/react';
import { commonmark, headingAttr } from '@milkdown/kit/preset/commonmark';
import { Editor, rootCtx, defaultValueCtx } from '@milkdown/kit/core';
const MilkdownEditor: React.FC = () => {
const { get } = useEditor((root) => {
const myEditor = Editor.make()
.config(nord)
.config((ctx) => {
ctx.set(rootCtx, root);
ctx.set(defaultValueCtx, mdData);
ctx.set(headingAttr.key, (node) => {
// id cant override too
return { ...node.attrs, id: 'my-custom-id', class: 'my-custom-class' };
});
})
.use(commonmark)
.use(headingAnchorCollector); // this
return myEditor;
});
return (
<div className="editor-container">
<Milkdown />
</div>
);
};
export const MilkdownEditorWrapper: React.FC = () => {
return (
<MilkdownProvider>
<MilkdownEditor />
</MilkdownProvider>
);
};
export default MilkdownEditorWrapper; Expected behaviorno Actual behaviorno RuntimeNo response OSNo response Build and bundle toolsNo response |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
You'll also need to extend the heading schema and modify the const yourSchema = headingSchema.extendSchema((prev) => {
return ctx => {
const baseSchema = prev(ctx)
return {
...baseSchema,
attrs: {
...baseSchema.attrs,
hProperties: {
default: null,
},
parseMarkdown: {
...baseSchema.parseMarkdown,
runner: (state, node, type) => {
const depth = node.depth as number
const hProperties = node.data.hProperties,
state.openNode(type, { level: depth, hProperties })
state.next(node.children)
state.closeNode()
}
}
}
}
}
}); You may also want to modify other properties. |
Beta Was this translation helpful? Give feedback.
-
omg thanks,i ask help for gpt:"how to extends milkdown node like tiptap editor", it tell me like this 🥲🥲🥲 // 你自己的 id 生成逻辑
const customHeadingIdGenerator = (node: any) => {
// 例如使用 textContent + 前缀生成
return 'custom-' + node.textContent.trim().toLowerCase().replace(/\s+/g, '-');
};
export const customHeadingSchema = $node('heading', (ctx) => {
return {
content: 'inline*',
group: 'block',
defining: true,
attrs: {
id: { default: '', validate: 'string' },
level: { default: 1, validate: 'number' },
},
parseDOM: Array.from({ length: 6 }, (_, i) => ({
tag: `h${i + 1}`,
getAttrs: (dom) => {
if (!(dom instanceof HTMLElement)) return false;
return {
level: i + 1,
id: dom.id || customHeadingIdGenerator(dom),
};
},
})),
toDOM: (node) => {
const level = node.attrs.level;
// const id = node.attrs.id || customHeadingIdGenerator(node);
const id = 'abc';
return [
`h${level}`,
{
id,
class: `heading-${level}`, // 可添加更多自定义属性
},
0,
];
},
parseMarkdown: {
match: ({ type }) => type === 'heading',
runner: (state, node, type) => {
const depth = node.depth as number;
state.openNode(type, { level: depth });
state.next(node.children);
state.closeNode();
},
},
toMarkdown: {
match: (node) => node.type.name === 'heading',
runner: (state, node) => {
state.openNode('heading', undefined, { depth: node.attrs.level });
node.forEach((child) => state.next(child));
state.closeNode();
},
},
};
}); so, i want to submit some smail suggestions: Make the document more complete 😭😭 |
Beta Was this translation helpful? Give feedback.
You'll also need to extend the heading schema and modify the
parseMarkdown
andtoMarkdown
method.