如何将序列化Lexical编辑器状态转为Markdown/HTML?输出异常求助
问题描述
我想把Lexical编辑器的内容以文件形式下载,所以尝试将序列化后的编辑器状态JSON转换成对应的Markdown。我写了下面的转换函数:
import { createHeadlessEditor } from '@lexical/headless'; import { $convertToMarkdownString, TRANSFORMERS } from '@lexical/markdown'; // 提取markdown的函数 export const getTextEditorMarkdown = async (stringifiedEditorState: string) => { try { const editor = createHeadlessEditor({ nodes: [], onError: () => {} }); editor.setEditorState(editor.parseEditorState(JSON.parse(stringifiedEditorState))); await editor.update(() => { const markdown = $convertToMarkdownString(TRANSFORMERS); console.info('markdown', markdown); }); } catch (e: any) { // 错误处理 } };
测试用的序列化编辑器状态如下:
const stringifiedEditorState = "{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"ju\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}" // 提取markdown getTextEditorMarkdown(stringifiedEditorState);
执行后输出异常,我可以接受Markdown或等价的HTML格式,求解决方法。
解决方法
1. 修复序列化字符串语法错误
你提供的原始stringifiedEditorState内部双引号未转义,会导致JSON解析失败,修正后的字符串需用反斜杠转义内部双引号(如上面测试代码所示)。
2. 调整转换函数逻辑
当前代码存在两个核心问题:editor.update是同步方法无需await,且未返回转换结果。同时必须注册编辑器用到的节点类型,否则Lexical无法解析状态。调整后的函数如下:
import { createHeadlessEditor } from '@lexical/headless'; import { $convertToMarkdownString, TRANSFORMERS } from '@lexical/markdown'; import { ParagraphNode, TextNode } from '@lexical/text'; // 引入必要节点 export const getTextEditorMarkdown = (stringifiedEditorState: string) => { try { const editor = createHeadlessEditor({ nodes: [ParagraphNode, TextNode], // 必须注册用到的节点 onError: (error) => console.error('Lexical错误:', error) }); const parsedState = editor.parseEditorState(JSON.parse(stringifiedEditorState)); editor.setEditorState(parsedState); let markdown = ''; editor.update(() => { markdown = $convertToMarkdownString(TRANSFORMERS); }); console.info('转换后的markdown:', markdown); return markdown; // 返回结果供下载使用 } catch (e: any) { console.error('转换失败:', e); return ''; } };
3. 生成HTML格式(可选)
如果需要HTML而非Markdown,可使用Lexical的$generateHtmlFromNodes工具:
import { $generateHtmlFromNodes } from '@lexical/html'; import { createHeadlessEditor } from '@lexical/headless'; import { ParagraphNode, TextNode } from '@lexical/text'; export const getTextEditorHtml = (stringifiedEditorState: string) => { try { const editor = createHeadlessEditor({ nodes: [ParagraphNode, TextNode], onError: (error) => console.error('Lexical错误:', error) }); const parsedState = editor.parseEditorState(JSON.parse(stringifiedEditorState)); editor.setEditorState(parsedState); let html = ''; editor.update(() => { html = $generateHtmlFromNodes(editor, null); }); console.info('转换后的HTML:', html); return html; } catch (e: any) { console.error('转换失败:', e); return ''; } };
4. 实现文件下载
拿到转换后的内容后,用以下代码实现下载:
// 下载Markdown文件 const downloadMarkdown = (content: string, filename: string = 'editor-content.md') => { const blob = new Blob([content], { type: 'text/markdown' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); }; // 使用示例 const markdown = getTextEditorMarkdown(stringifiedEditorState); downloadMarkdown(markdown);
内容的提问来源于stack exchange,提问作者Ankeeta Sahoo
相关产品推荐
相关产品推荐

