Markdown 与 HTML
可以导出或导入块到 Markdown 和 HTML。
导入/导出 Markdown/HTML 的功能被视为「有损」;导出块到这些格式时,部分信息可能会丢失。
要序列化块为无损格式(例如,存储编辑器内容到后端),只需使用 JSON.stringify(editor.document)
导出内置块格式。
Markdown
BlockNote 可以导入 / 导出块到 Markdown。请注意这也是「有损」的,因为并非所有结构都能完全用 Markdown 表示。
将块转换为 Markdown
blocksToMarkdownLossy
将 Block
对象转换为 Markdown 字符串:
async blocksToMarkdownLossy(blocks?: Block[]): Promise<string>;
// 用法
const markdownFromBlocks = await editor.blocksToMarkdownLossy(blocks);
blocks:
要转换的块。如果未提供,则使用整个文档(所有顶级块)。
返回:
以 Markdown 字符串序列化的块。
输出经过简化,因为 Markdown 不支持 BlockNote 的所有功能(例如:非列表项块的子项会被取消嵌套,且某些样式会被移除)。
演示
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { useCreateBlockNote } from "@blocknote/react";
import { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
// Stores the editor's contents as Markdown.
const [markdown, setMarkdown] = useState<string>("");
// Creates a new editor instance with some initial content.
const editor = useCreateBlockNote({
initialContent: [
{
type: "paragraph",
content: [
"Hello, ",
{
type: "text",
text: "world!",
styles: {
bold: true,
},
},
],
},
],
});
const onChange = async () => {
// Converts the editor's contents from Block objects to Markdown and store to state.
const markdown = await editor.blocksToMarkdownLossy(editor.document);
setMarkdown(markdown);
};
useEffect(() => {
// on mount, trigger initial conversion of the initial content to md
onChange();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Renders the editor instance, and its contents as Markdown below.
return (
<div className={"wrapper"}>
<div>Input (BlockNote Editor):</div>
<div className={"item"}>
<BlockNoteView editor={editor} onChange={onChange} />
</div>
<div>Output (Markdown):</div>
<div className={"item bordered"}>
<pre>
<code>{markdown}</code>
</pre>
</div>
</div>
);
}
解析 Markdown 为块
使用 tryParseMarkdownToBlocks
尝试将 Markdown 字符串解析为 Block
对象:
async tryParseMarkdownToBlocks(markdown: string): Promise<Blocks[]>;
// 用法
const blocksFromMarkdown = await editor.tryParseMarkdownToBlocks(markdown);
返回:
从 Markdown 字符串解析得到的块。
尝试基于 Markdown 语法创建 Block
和 InlineContent
对象,但并非所有符号都被识别。如果 BlockNote 不认识某个符号,则将其作为文本解析。
演示
import "@blocknote/core/fonts/inter.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { ChangeEvent, useCallback, useEffect } from "react";
const initialMarkdown = "Hello, **world!**";
export default function App() {
// Creates a new editor instance.
const editor = useCreateBlockNote();
const markdownInputChanged = useCallback(
async (e: ChangeEvent<HTMLTextAreaElement>) => {
// Whenever the current Markdown content changes, converts it to an array of
// Block objects and replaces the editor's content with them.
const blocks = await editor.tryParseMarkdownToBlocks(e.target.value);
editor.replaceBlocks(editor.document, blocks);
},
[editor],
);
// For initialization; on mount, convert the initial Markdown to blocks and replace the default editor's content
useEffect(() => {
async function loadInitialHTML() {
const blocks = await editor.tryParseMarkdownToBlocks(initialMarkdown);
editor.replaceBlocks(editor.document, blocks);
}
loadInitialHTML();
}, [editor]);
// Renders a text area for you to write/paste Markdown in, and the editor instance
// below, which displays the current Markdown as blocks.
return (
<div className={"wrapper"}>
<div>Input (Markdown):</div>
<div className={"item bordered"}>
<code>
<textarea
defaultValue={initialMarkdown}
onChange={markdownInputChanged}
/>
</code>
</div>
<div>Output (BlockNote Editor):</div>
<div className={"item"}>
<BlockNoteView editor={editor} editable={false} />
</div>
</div>
);
}
导出 HTML(用于静态渲染)
使用 blocksToFullHTML
导出整个文档,包括所有结构、样式和格式。
导出的 HTML 与 BlockNote 用于渲染编辑器的 HTML 相同,包含所有嵌套块的结构。
例如,可以用此方法静态渲染用编辑器创建的文档。 渲染输出 HTML 时,确保引入相同的样式表(参见示例)。
async blocksToFullHTML(blocks?: Block[]): Promise<string>;
// 用法
const HTMLFromBlocks = await editor.blocksToFullHTML(blocks);
blocks:
要转换的块。如果未提供,则使用整个文档(所有顶级块)。
返回:
导出的 HTML 字符串。
HTML(用于互操作)
编辑器提供函数将块与 HTML 相互转换,实现与其他应用的互操作。
此方式将块转换为 HTML 会丢失部分信息,例如节点嵌套,以导出更简洁的 HTML 结构。
将块转换为 HTML
使用 blocksToHTMLLossy
导出 Block
对象为 HTML 字符串:
async blocksToHTMLLossy(blocks?: Block[]): Promise<string>;
// 用法
const HTMLFromBlocks = await editor.blocksToHTMLLossy(blocks);
blocks:
要转换的块。如果未提供,则使用整个文档(所有顶级块)。
返回:
导出的 HTML 字符串。
为了更符合法 HTML 标准,非列表项块的子项在输出 HTML 中会取消嵌套。
演示
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { useCreateBlockNote } from "@blocknote/react";
import { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
// Stores the editor's contents as HTML.
const [html, setHTML] = useState<string>("");
// Creates a new editor instance with some initial content.
const editor = useCreateBlockNote({
initialContent: [
{
type: "paragraph",
content: [
"Hello, ",
{
type: "text",
text: "world!",
styles: {
bold: true,
},
},
],
},
],
});
const onChange = async () => {
// Converts the editor's contents from Block objects to HTML and store to state.
const html = await editor.blocksToHTMLLossy(editor.document);
setHTML(html);
};
useEffect(() => {
// on mount, trigger initial conversion of the initial content to html
onChange();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Renders the editor instance, and its contents as HTML below.
return (
<div className="wrapper">
<div>Input (BlockNote Editor):</div>
<div className="item">
<BlockNoteView editor={editor} onChange={onChange} />
</div>
<div>Output (HTML):</div>
<div className="item bordered">
<pre>
<code>{html}</code>
</pre>
</div>
</div>
);
}
解析 HTML 为块
使用 tryParseHTMLToBlocks
将 HTML 字符串解析为 Block
对象:
async tryParseHTMLToBlocks(html: string): Promise<Blocks[]>;
// 用法
const blocksFromHTML = await editor.tryParseHTMLToBlocks(html);
返回:
从 HTML 字符串解析得到的块。
尝试从任何 HTML 块级元素创建 Block
对象,从任何 HTML 行内元素创建 InlineContent
对象,但并非所有 HTML 标签都被识别。如果 BlockNote 不认识元素标签,则作为段落或纯文本解析。
演示
import "@blocknote/core/fonts/inter.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { ChangeEvent, useCallback, useEffect } from "react";
import "./styles.css";
const initialHTML = "<p>Hello, <strong>world!</strong></p>";
export default function App() {
// Creates a new editor instance.
const editor = useCreateBlockNote();
const htmlInputChanged = useCallback(
async (e: ChangeEvent<HTMLTextAreaElement>) => {
// Whenever the current HTML content changes, converts it to an array of
// Block objects and replaces the editor's content with them.
const blocks = await editor.tryParseHTMLToBlocks(e.target.value);
editor.replaceBlocks(editor.document, blocks);
},
[editor],
);
// For initialization; on mount, convert the initial HTML to blocks and replace the default editor's content
useEffect(() => {
async function loadInitialHTML() {
const blocks = await editor.tryParseHTMLToBlocks(initialHTML);
editor.replaceBlocks(editor.document, blocks);
}
loadInitialHTML();
}, [editor]);
// Renders a text area for you to write/paste HTML in, and the editor instance
// below, which displays the current HTML as blocks.
return (
<div className={"wrapper"}>
<div>Input (HTML):</div>
<div className={"item bordered"}>
<code>
<textarea defaultValue={initialHTML} onChange={htmlInputChanged} />
</code>
</div>
<div>Output (BlockNote Editor):</div>
<div className={"item"}>
<BlockNoteView editor={editor} editable={false} />
</div>
</div>
);
}