Vanessa219 / vditor

♏ 一款浏览器端的 Markdown 编辑器,支持所见即所得(富文本)、即时渲染(类似 Typora)和分屏预览模式。An In-browser Markdown editor, support WYSIWYG (Rich Text), Instant Rendering (Typora-like) and Split View modes.
https://b3log.org/vditor
MIT License
8.25k stars 852 forks source link

目录导出 #1568

Closed prclin closed 6 months ago

prclin commented 6 months ago

你在什么场景下需要该功能?

使用vditor渲染markdown到页面后,想自定义目录(大纲)样式

描述最优的解决方案

为Vditor.preview函数增加回调,返回解析出的大纲;可以是json或者对象

描述候选解决方案

自行在renderHeading函数中自己收集标题

其他信息

prclin commented 6 months ago

renders中收集大纲实现:

//类型声明
export interface ReferenceEntry {
    level: number,
    label: string,
    children: ReferenceEntry[]
}
//查找父级
const searchParent = (entries: ReferenceEntry[], level: number): ReferenceEntry[] => {
    if (entries.length == 0) return entries;
    const cLevel = entries[entries.length - 1].level;
    if (cLevel >= level) {
        return entries;
    } else {
        return searchParent(entries[entries.length - 1].children, level);
    }
};

//创建state
const [references, setReferences] = useState<ReferenceEntry[]>([]);

//renderHeading抽取目录
renderHeading: (node, entering) => {
                        const id = Lute.GetHeadingID(node);
                        const level = node.__internal_object__.HeadingLevel;
                        if (entering) {
                            return [
                                `<h${level} id='${id}' class='heading'>`,
                                Lute.WalkContinue];
                        } else {

                            setReferences(prevState => {
                                //lodash 浅拷贝
                                const nextState = clone(prevState);
                                searchParent(nextState, Number(level)).push({
                                    level: Number(level),
                                    label: id,
                                    children: [],
                                });
                                return nextState;
                            });
                            return [
                                `</h${level}>`,
                                Lute.WalkContinue];
                        }
                    }

收集结果:

//收集结果
[
    {
        "level": 2,
        "label": "教程",
        "children": []
    },
    {
        "level": 2,
        "label": "语法指导",
        "children": [
            {
                "level": 3,
                "label": "普通内容",
                "children": []
            },
            {
                "level": 3,
                "label": "提及用户",
                "children": []
            },
            {
                "level": 3,
                "label": "表情符号-Emoji",
                "children": [
                    {
                        "level": 4,
                        "label": "一些表情例子",
                        "children": []
                    }
                ]
            },
            {
                "level": 3,
                "label": "大标题---Heading-3",
                "children": [
                    {
                        "level": 4,
                        "label": "Heading-4",
                        "children": [
                            {
                                "level": 5,
                                "label": "Heading-5",
                                "children": [
                                    {
                                        "level": 6,
                                        "label": "Heading-6",
                                        "children": []
                                    }
                                ]
                            }
                        ]
                    }
                ]
            },
            {
                "level": 3,
                "label": "图片",
                "children": []
            },
            {
                "level": 3,
                "label": "代码块",
                "children": [
                    {
                        "level": 4,
                        "label": "普通",
                        "children": []
                    },
                    {
                        "level": 4,
                        "label": "语法高亮支持",
                        "children": [
                            {
                                "level": 5,
                                "label": "演示-Go-代码高亮",
                                "children": []
                            },
                            {
                                "level": 5,
                                "label": "演示-Java-高亮",
                                "children": []
                            }
                        ]
                    }
                ]
            },
            {
                "level": 3,
                "label": "有序-无序-任务列表",
                "children": [
                    {
                        "level": 4,
                        "label": "无序列表",
                        "children": []
                    },
                    {
                        "level": 4,
                        "label": "有序列表",
                        "children": []
                    },
                    {
                        "level": 4,
                        "label": "任务列表",
                        "children": []
                    }
                ]
            },
            {
                "level": 3,
                "label": "表格",
                "children": []
            },
            {
                "level": 3,
                "label": "隐藏细节",
                "children": []
            },
            {
                "level": 3,
                "label": "段落",
                "children": []
            },
            {
                "level": 3,
                "label": "链接引用",
                "children": []
            },
            {
                "level": 3,
                "label": "数学公式",
                "children": []
            },
            {
                "level": 3,
                "label": "脑图",
                "children": []
            },
            {
                "level": 3,
                "label": "流程图",
                "children": []
            },
            {
                "level": 3,
                "label": "时序图",
                "children": []
            },
            {
                "level": 3,
                "label": "甘特图",
                "children": []
            },
            {
                "level": 3,
                "label": "图表",
                "children": []
            },
            {
                "level": 3,
                "label": "五线谱",
                "children": []
            },
            {
                "level": 3,
                "label": "Graphviz",
                "children": []
            },
            {
                "level": 3,
                "label": "Flowchart",
                "children": []
            },
            {
                "level": 3,
                "label": "多媒体",
                "children": []
            },
            {
                "level": 3,
                "label": "脚注",
                "children": []
            }
        ]
    },
    {
        "level": 2,
        "label": "快捷键",
        "children": []
    }
]

渲染结果

image

Vanessa219 commented 6 months ago

目录导出具体可参见 outlineRender