尝试扩展丰富的 Markdown 编辑器
Trying to extend rich markdown editor
我正在尝试扩展具有以下架构的 markdown editor library - which itself extends Prosemirror. I'd like to build my own Node:
attrs: {
id: number
}
和returns以下HTML
<div class=`story-block ${attrs.id}`>
<div contenteditable="false">
<button>Story</button>
</div>
<div>
<p>Text that we can edit</p>
</div>
</div>
这里的技巧是因为编辑器保存为markdown。我们需要一些方法来理解这是一种特殊类型的节点,Story
,但将其包装在一组独特的字符中,我使用的是 %%%
。这类似于我使用 :::
作为其 Notice
节点
的信号扩展库的方式
我可以添加一个新的 Story
节点,它可以正确呈现我的按钮和样式。当我去保存时,一切都正确保存,我得到的降价看起来像
%%%123 // the id
Whatever text I write
%%%
但是,当我想将 markdown 渲染回 DOM 元素时,它失败了,我再次在文档中获得纯文本。具体来说,DOM 看起来像
<p>%%%123
Whatever text I write</p>
<p>%%%</p>
客户节点的代码如下。有没有人成功地扩展了这个库或者可以告诉我我做错了什么?谢谢
import { wrappingInputRule } from "prosemirror-inputrules";
import toggleWrap from "../commands/toggleWrap"; //Rule file from library
import Node from "./Node";
export default class Story extends Node {
get name() {
return "container_story";
}
get schema() {
return {
attrs: {
id: {
default: "story",
},
},
content: "block+",
group: "block",
defining: true,
draggable: true,
parseDOM: [
{
tag: "div.story-block",
preserveWhitespace: "full",
contentElement: "div:last-child",
getAttrs: () => ({
id: "story",
}),
},
],
toDOM: node => {
node.attrs.id =
node.attrs.id === "story"
? Math.round(Math.random() * 10000)
: node.attrs.id;
console.log(node.attrs.id);
const button = document.createElement("button");
button.innerText = "Story";
button.id = node.attrs.id;
button.addEventListener(
"click",
(function () {
return function (e) {
alert(`Story ${e.target.id} clicked!`);
};
})(),
false
);
return [
"div",
{ class: `story-block ${node.attrs.id}` },
["div", { contentEditable: false }, button],
["div", { class: "content story-content" }, 0],
];
},
};
}
commands({ type }) {
return attrs => toggleWrap(type, attrs);
}
inputRules({ type }) {
return [wrappingInputRule(/^%%%$/, type)];
}
toMarkdown(state, node) {
state.write("\n%%%" + "story" + "\n");
state.renderContent(node);
state.ensureNewLine();
state.write("%%%");
state.closeBlock(node);
console.log(state);
}
parseMarkdown() {
return {
block: "container_story",
getAttrs: tok => {
console.log(tok.attrGet("id"));
({ id: tok.attrGet("id") });
},
};
}
}
您似乎缺少降价规则的配置。
您可以在 /src/lib/markdown
中添加一个文件,例如 story.ts
,内容如下(copy/paste 来自 notice.ts)
import customFence from "markdown-it-container";
export default function story(md): void {
return customFence(md, "story", {
marker: "%",
validate: () => true,
});
}
并且在 rules.ts
文件(同一目录)中,您使用新规则
import markdownit from "markdown-it";
...
import storyPlugin from "./story";
export default function rules({ embeds }) {
return markdownit("default", {
breaks: false,
html: false,
})
...
.use(noticesPlugin)
.use(storyPlugin);
}
我正在尝试扩展具有以下架构的 markdown editor library - which itself extends Prosemirror. I'd like to build my own Node:
attrs: {
id: number
}
和returns以下HTML
<div class=`story-block ${attrs.id}`>
<div contenteditable="false">
<button>Story</button>
</div>
<div>
<p>Text that we can edit</p>
</div>
</div>
这里的技巧是因为编辑器保存为markdown。我们需要一些方法来理解这是一种特殊类型的节点,Story
,但将其包装在一组独特的字符中,我使用的是 %%%
。这类似于我使用 :::
作为其 Notice
节点
我可以添加一个新的 Story
节点,它可以正确呈现我的按钮和样式。当我去保存时,一切都正确保存,我得到的降价看起来像
%%%123 // the id
Whatever text I write
%%%
但是,当我想将 markdown 渲染回 DOM 元素时,它失败了,我再次在文档中获得纯文本。具体来说,DOM 看起来像
<p>%%%123
Whatever text I write</p>
<p>%%%</p>
客户节点的代码如下。有没有人成功地扩展了这个库或者可以告诉我我做错了什么?谢谢
import { wrappingInputRule } from "prosemirror-inputrules";
import toggleWrap from "../commands/toggleWrap"; //Rule file from library
import Node from "./Node";
export default class Story extends Node {
get name() {
return "container_story";
}
get schema() {
return {
attrs: {
id: {
default: "story",
},
},
content: "block+",
group: "block",
defining: true,
draggable: true,
parseDOM: [
{
tag: "div.story-block",
preserveWhitespace: "full",
contentElement: "div:last-child",
getAttrs: () => ({
id: "story",
}),
},
],
toDOM: node => {
node.attrs.id =
node.attrs.id === "story"
? Math.round(Math.random() * 10000)
: node.attrs.id;
console.log(node.attrs.id);
const button = document.createElement("button");
button.innerText = "Story";
button.id = node.attrs.id;
button.addEventListener(
"click",
(function () {
return function (e) {
alert(`Story ${e.target.id} clicked!`);
};
})(),
false
);
return [
"div",
{ class: `story-block ${node.attrs.id}` },
["div", { contentEditable: false }, button],
["div", { class: "content story-content" }, 0],
];
},
};
}
commands({ type }) {
return attrs => toggleWrap(type, attrs);
}
inputRules({ type }) {
return [wrappingInputRule(/^%%%$/, type)];
}
toMarkdown(state, node) {
state.write("\n%%%" + "story" + "\n");
state.renderContent(node);
state.ensureNewLine();
state.write("%%%");
state.closeBlock(node);
console.log(state);
}
parseMarkdown() {
return {
block: "container_story",
getAttrs: tok => {
console.log(tok.attrGet("id"));
({ id: tok.attrGet("id") });
},
};
}
}
您似乎缺少降价规则的配置。
您可以在 /src/lib/markdown
中添加一个文件,例如 story.ts
,内容如下(copy/paste 来自 notice.ts)
import customFence from "markdown-it-container";
export default function story(md): void {
return customFence(md, "story", {
marker: "%",
validate: () => true,
});
}
并且在 rules.ts
文件(同一目录)中,您使用新规则
import markdownit from "markdown-it";
...
import storyPlugin from "./story";
export default function rules({ embeds }) {
return markdownit("default", {
breaks: false,
html: false,
})
...
.use(noticesPlugin)
.use(storyPlugin);
}