ProseMirror Markdown 模块
prosemirror-markdown 模块用于实现 markdown 与 prosemirror 之间的转换
- 该模块提供了一个
schema数据结构的约束对象,基于 CommonMark 所支持的 Markdown 语法创建对应的 ProseMirror 节点 nodes 和样式标记 marks 类型 - 该模块导出了两个类
- class
MarkdownParser用于构建 parser 解析器,(使用 markdown-it)解析 markdown 文档,转换为 prosemirror 文档(根节点)
该模块已提供了该类的一个实例defaultMarkdownParser它基于 CommonMark 语法对 markdown 文档进行解析,转换为 ProseMirror 文档(采用该模块所提供的schema作为数据结构约束对象)ParseSpec
该模块导出了一种 TypeScript interface
ParseSpec表示 markdown-it 所生成的各种 tokens 应该如何解析(转换为 ProseMirror 对应的节点或样式标记)它是实例化
new MarkdownParser(schema: Schema, tokenizer: any, tokens: Object<ParseSpec>)时,第三个参数tokens所需需要满足的类型 - class
MarkdownSerializer用于构建 serializer 序列化器,将 ProseMirror 文档序列化为 markdown 文档(字符串)
该模块已提供了该类的一个实例defaultMarkdownSerializer它将(采用该模块所提供的schema作为数据结构约束对象)ProseMirror 文档序列化为 markdown 文档进行解析
- class
官方有一个样例 Friendly Markdown 介绍了如何使用该模块,完整的源码可以查看相关的 Github 仓库。
简化版本
根据官方示例编写了一个简化版本
其中关键是使用 defaultMarkdownParser 和 defaultMarkdownSerializer 方法实现 markdown 与 prosemirror 之间的转换,相关代码如下
ts
// setup markdown editor
const markdownEditor = document.querySelector("#markdownEditor") as HTMLTextAreaElement;
const initContent = markdownEditor.value;
markdownEditor.addEventListener('input', () => {
// sync the change from markdown editor to prosemirror rich text editor
const activeEditor = document.activeElement; // get the active/focus editor
if(activeEditor && activeEditor.id === 'markdownEditor') {
// 💡 parse the markdown text to prosemirror doc
const content = defaultMarkdownParser.parse(markdownEditor.value);
const newState = EditorState.create({
doc: content,
plugins: view.state.plugins
})
view.updateState(newState);
}
})
// setup prosemirror editor
const state = EditorState.create({
// parse preset content from (hidden) DOM in page
doc: defaultMarkdownParser.parse(initContent),
// add other augment features for editor
plugins: exampleSetup({schema})
});
const editorContainer = document.querySelector("#prosemirrorEditorContainer");
const view = new EditorView(editorContainer, {
state: state,
dispatchTransaction(tr) {
const newState = view.state.apply(tr);
// sync the change from prosemirror rich text editor to markdown editor
const activeEditor = document.activeElement; // get the active/focus editor
if(activeEditor && activeEditor.id !== 'markdownEditor') {
console.log('update markdown');
// 💡 serializer the prosemirror doc to markdown text
const content = defaultMarkdownSerializer.serialize(newState.doc);
console.log(content);
markdownEditor.value = content;
}
view.updateState(newState);
}
});