You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将序列化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:54:53