ToC レンダリング効果を最適化するために editormd コンポーネントを変更しました

序文

StarBlog ブログは現在、 editor.md フロントエンドでマークダウン記事をレンダリングするコンポーネントを使用していますが、このコンポーネントによって自動的に生成される ToC (コンテンツの目次) はあまり美しくありません。以前にツリー コンポーネントの BootStrap- TreeView を修正したので、これを使用したいと考えています目次を表示するツリーコンポーネント。

本来のエフェクトはこんな感じ

私の魔法改造の効果

先分析一波

まず、公式の例に従って、editor.md コンポーネントがどのようにマークダウンをレンダリングするかを見てください。

まずテキストエリアを作成し、そこにマークダウンを置きます

<div id="post-markdown-content" class="post-content">
    <textarea style="display:none;">@Model.Content</textarea>
</div>

ディレクトリを置くdivも​​あります

<div id="post-toc-container"></div>

次に、js を使用してレンダリング メソッドを呼び出します。

let editorMdView = editormd.markdownToHTML("post-markdown-content", {
    htmlDecode: true,
    tocm: true,    // Using [TOCM]
    tocContainer: "#toc-container", // 自定义 ToC 容器层
    emoji: true,
    taskList: true,
    tex: true,  // 默认不解析
    flowChart: true,  // 默认不解析
    sequenceDiagram: true,  // 默认不解析
});

このようにして記事の内容と目次が出てきます。

最初に思ったのは、ディレクトリをレンダリングできるので、使用できるディレクトリツリー構造が必要だということでした。

その結果、このツリー構造をコンソールで 長い間console.log 見ることができませんでした

editormd.markdownToHTML メソッドによって返されるデータは、単なる div 要素のオブジェクトです。

投げ始める

言葉が出ない、ソースコードを見るしかない

コンポーネント全体のソースコードはjsファイルになっていますが、幸い可読性は悪くありません~

メソッドの定義を直接検索し markdownToHTML 、3885 行目から開始して、その中の変数を見つけます markdownToC 。これが目的のものであるはずです。それを印刷して確認します。一般的な構造は次のとおりです。

[
    {"text": "Node1", "slug": "node1", "level": 2},
    {"text": "Django-Dev", "slug": "django-dev", "level": 3},
    {"text": "Java-Dev", "slug": "java-dev", "level": 3},
    {"text": "Spring-Dev", "slug": "spring-dev", "level": 3}
]

ツリー構造ではなく配列です

これは単にマークダウン ドキュメント全体を走査し、level フィールドはタイトル タイプ、つまり # 番号に従って決定されます。

また、以前に変更したコンポーネントは Bootstrap-Treeview レンダリングのためにツリー構造のオブジェクトを渡す必要があるため、さらに処理が必要です。

ハンドルツリー構造

最初はびっくりして、 editor.md 生成されたものを再帰に放り込んだだけでした

うまくいかなかった

その後、気が変わり、最初に配列を変更し、各項目に id と pid を追加しました。これにより、再帰的にツリーを生成するのがはるかに簡単になります~

最初にノード オブジェクトを定義します。これは Bootstrap-Treeview 使用する必要があるデータ構造です。

class TocNode {
    constructor(text, href, tags, nodes) {
        this.text = text
        this.href = href
        this.tags = tags
        this.nodes = nodes
    }
}

次に、 markdownToC その作業をもう一度実行して、最上位ノードの pid を -1 に設定し、各ノードに 0 から順に ID を割り当てます。次に、各ノードの前でレベルが 1 未満のノードを探します。親ノード、pid を設定、完了しました~

let toc = markdownToC
for (let i = 0; i < toc.length; i++) {
    let item = toc[i]
    item.id = i
    item.pid = -1
    for (let j = i; j >= 0; j--) {
        let preItem = toc[j]
        if (item.level === preItem.level + 1) {
            item.pid = j
            break
        }
    }
}

ツリー構造を生成します。非常に単純で、多くを言う必要はありません。

function getNodes(pid = -1) {
    let nodes = toc.filter(item => item.pid === pid)
    if (nodes.length === 0) return null
    return nodes.map(item => new TocNode(item.text, `#${item.text}`, null, getNodes(item.id)))
}

終わった〜

魔法の変化

次に、このアイデアに基づいて、コードのコピーをフォークして魔法の変更を加えます。

元のバージョンでは markdownToHTML メソッドの実行直後に div 要素が返されますが、返された div 要素に 2 つの属性を追加してから div を返しました。

div.markdownToc = markdownToC
div.markdownTocTree = editormd.tocListToTree(markdownToC)
return div

このようにして、使用中に Bootstrap-Treeview コンポーネントを簡単に統合できます。

使用法

まずはリリースしたNPMパッケージをインストールします

// 魔改的 editor.md 组件
npm i editor.md-ext
// 魔改的树形列表组件
npm i bootstrap5-treeview

ページにCSSを導入する

<link rel="stylesheet" href="~/lib/editormd/css/editormd.preview.css">

JSをインポートする

<!-- jQuery -->
<script src="~/lib/jquery/dist/jquery.min.js"></script>

<!-- 树形列表组件 -->
<script src="~/js/bootstrap-treeview.js"></script>

<!-- editor.md 需要的依赖 -->
<script src="~/lib/editormd/lib/marked.min.js"></script>
<script src="~/lib/editormd/lib/prettify.min.js"></script>
<script src="~/lib/editormd/lib/raphael.min.js"></script>
<script src="~/lib/editormd/lib/underscore.min.js"></script>
<script src="~/lib/editormd/lib/sequence-diagram.min.js"></script>
<script src="~/lib/editormd/lib/flowchart.min.js"></script>
<script src="~/lib/editormd/lib/jquery.flowchart.min.js"></script>
<script src="~/lib/editormd/editormd.js"></script>

ディレクトリコンテナとしてdivを用意する

<div id="post-toc-container"></div>

記事のコンテンツを保存する div を用意し、Markdown コンテンツをこのテキストエリアに配置します。

<div id="post-markdown-content" class="post-content">
    <textarea style="display:none;">@Model.Content</textarea>
</div>

レンダリングを有効にするための JS コードを作成します。

$(function () {
    // 渲染文章
    let editorMdView = editormd.markdownToHTML("post-markdown-content", {
        htmlDecode: true,
        tocm: true,    // Using [TOCM]
        emoji: true,
        taskList: true,
        tex: true,  // 默认不解析
        flowChart: true,  // 默认不解析
        sequenceDiagram: true,  // 默认不解析
    });

    // 渲染目录
    $('#post-toc-container').treeview({
        data: editorMdView.markdownTocTree,
        levels: 2,
        enableLinks: true,
        highlightSelected: false,
        showTags: true,
    })
})

ツリー リスト コンポーネントの使用法については、私の GitHub を参照してください。GitHub - Deali-Axy/bootstrap5-treeview: Tree View for Twitter Bootstrap5 - 魔法の修正の元のバージョンは、新しい Bootstrap5 バージョンに適応されています。

関連アドレス

GitHub: https://github.com/Deali-Axy/editor.md-ext

NPM:editor.md-ext - npm

Je suppose que tu aimes

Origine blog.csdn.net/weixin_47367099/article/details/127471043
conseillé
Classement