个人博客搭建(一):多级目录展示与渐构标签


个人博客搭建(一):Hexo多级目录展示与渐构标签

说明

搭建目的

想到自己的博客网站已经搭建好几年了,但是内容写的不是特别多,很多的内容都是写在个人的Obsidian本地仓库中,以及「渐构」网站上。很多本地仓库中的文章写得七零八碎,很多没有写完整,所以也没有再博客上发布。所以想重构一下自己的博客网站,使得自己的编写的好的内容能过发布,同时也促使自己认真写文章,记录自己的「学习过程」。

整理了一下自己的网站需要:

  • 需要实现Obsidian的多端同步:Windows,Linux,iPad,手机之间的同步
  • 需要能够再网站中展现「渐构」标签,因为自己自从加入渐构过后,就一直沿用渐构的标签的写作方法,所有写的文章大部分只能再渐构网站上看见样式。
  • 解决图床问题,自己的文章需要多端发布,有的需要再公众号中发布,有的则需要再一些其他网站中发布,所以需要一个图床来解决图片的显示问题。

Matery多级目录

需求1

多级目录展示

在用Hexo搭建个人博客网站时,用的是Matery主题,但是Matery菜单配置文件,只能展示展示二级目录,我希望在PC端能够展示多级目录,在手机端只需要展示到二级目录。

修改导航菜单

找到matery主题文件下的/layout/_partial/navigation.ejs并修改代码,这里使用的是「递归函数」来访问配置菜单中的多级目录,并进行多级目录的渲染。

<%
    var configRoot = config.root
    configRoot = (configRoot === null || configRoot === undefined || configRoot === '/') ? '' : configRoot;
%>

<% function renderMenu(menu, level = 1) { %>
  <% menu.forEach(function(item) { %>
    <li class="menu-level-<%- level %>">
      <a href="<%- url_for(item.url) %>" class="waves-effect waves-light">
        <% if (item.icon && item.icon.length > 0) { %>
        <i class="<%- item.icon %> moz-zoom" style="zoom: 0.6;"></i>
        <% } %>
        <span><%- item.name || __(item.key) %></span>
        <% if (item.children && item.children.length > 0) { %>
        <i class="fas fa-chevron-right moz-zoom" aria-hidden="true" style="zoom: 0.6;"></i>
        <% } %>
      </a>
      <% if (item.children && item.children.length > 0) { %>
      <ul class="sub-nav menu-level-<%- level + 1 %> <%- level === 1 ? 'menus_item_child' : 'menus_item_child_level' %>">
        <% renderMenu(item.children, level + 1); %>
      </ul>
      <% } %>
    </li>
  <% }); %>
<% } %>

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  <% renderMenu(Object.keys(theme.menu).map(key => ({
    key,
    ...theme.menu[key]
  }))); %>
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search " title="<%= __('search') %>" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>

<%- partial('_partial/mobile-nav') %>

添加样式

修改目录的渲染方式过后,需要对样式进行修改,这里我是修改source/css/matery.css文件的内容,当然也可以在source/css/my.css中修改,避免混淆。但感觉在matery.css的基础上修改方便些。

.menus_item_child_level {
        position: absolute;
    top: 0px !important;
    list-style: none;
    margin-left: 100px !important;
    display: block;
     background-color: rgba(255, 255, 255, .8);
    width: fit-content;
    border-radius: 10px;
    -webkit-box-shadow: 0 5px 20px -4px rgba(0, 0, 0, .5);
    box-shadow: 0 5px 20px -4px rgba(0, 0, 0, .5);
    opacity: 0.98;
    -ms-filter: none;
    filter: none;
    -webkit-animation: sub_menus .3s .1s ease both;
    -moz-animation: sub_menus .3s .1s ease both;
    -o-animation: sub_menus .3s .1s ease both;
    animation: sub_menus .3s .1s ease both;
}
.nav-show>a>i[aria-hidden=true] {
    -webkit-transform: rotate(180deg) !important;
    -moz-transform: rotate(180deg) scale(0.7, 0.7) !important;
    -moz-transform-origin: 60% 50% !important;
    -o-transform: rotate(180deg) !important;
    -ms-transform: rotate(180deg) !important;
    -webkit-transition: all .3s;
    -moz-transition: all .3s;
    -o-transition: all .3s;
    transition: all .3s;
}
.nav-menu>li>a>span {
    font-size: 1.4rem;
}
/*小屏幕下(手机类)的样式*/
@media only screen and (max-width: 601px) {
    .container {
        width: 95%;
    }
    .my-movies {
        height: 22rem;
        width: 80%;
        display: block;
        margin: 0 auto;
    }
    .right.nav-menu {
        display: none;
    }
}

渐构标签展示

需求2

渐构标签展示

由于自己写文章,大部分都是使用「渐构」标签来展示的,在Obsidian中有对应的插件进行展示,但在PC网站上,只能在「渐构」的官网上才能显示,微信公众号,可以从渐构网站中导出并粘贴上。在自己的网站中就只能自己编写逻辑代码。

Hexo处理流程

Hexo 在执行 hexo g(即 hexo generate)命令时,将 Markdown (.md) 文件转换为 HTML 的整个流程涉及多个核心组件。下面是详细拆解流程,帮助理解 Hexo 是如何一步步地把 .md 文件渲染成最终的 HTML 页面。

Markdown (.md)
   ↓
Hexo 内部解析(hexo-source + hexo-renderer)
   ↓
主题渲染(layouts + ejs/pug等模板)
   ↓
最终 HTML 文件写入 public/ 目录
  1. 读取 Markdown 文件

Hexo 会扫描 source/_posts 和其他配置中的 source 目录,识别所有 .md 文件。这些文件的头部通常包含 YAML front-matter,例如:

---
title: My Post
date: 2025-04-23
tags:
  - test
---

这部分会被解析为一个对象,Markdown 正文部分则保留为内容。

  1. 渲染器处理 Markdown → HTML
    Hexo 使用插件系统来处理内容渲染,默认是:
    hexo-renderer-marked:把 Markdown 转成 HTML(基于 marked)
    也可以使用 hexo-renderer-markdown-it 等其他插件
    这一步把 Markdown 转换为 HTML 字符串。

  2. Hexo 插件处理阶段
    这时候,Hexo 会运行你注册的各种 filter:

  • before_post_render
  • after_post_render
  • before_generate
  • after_generate

👉可以在这些阶段插入自定义逻辑。

  1. 布局文件应用(主题层)
    Hexo 会根据 Front-matter 中的 layout 字段,找到对应主题中的布局模板,比如:
layout: post

通常模板写在 themes/<your-theme>/layout/post.ejs 之类。

然后将你转换好的 HTML 内容插入这个模板中去。例如:

<%- page.content %>

这里的 page.content 就是渲染出来的 HTML。

  1. 输出到 public/ 目录
    最终 Hexo 会把所有页面渲染成静态 HTML 文件并输出到 public/ 目录中:
source/_posts/hello.md → public/hello/index.html

这些 HTML 文件是纯静态网页,可以直接部署到 GitHub Pages、Netlify、Vercel 等平台。

插件扩展点(Filter)

Hexo 提供了多个 hook(过滤器),常用于处理内容:
|过滤器名|说明|

before_post_render 在渲染 Markdown 前
after_post_render Markdown 已转为 HTML,但没写入布局
before_generate 所有页面准备生成前
after_generate 所有页面生成后
而需要实现的「渐构标签」替换,推荐放在after_post_render这个阶段,因为:
✅ Markdown 已经渲染成 HTML
✅ 内容还没嵌入到布局模板里
✅ 可以安全地操作 HTML 字符串

编写插件脚本

cheerio 可以避免直接操作 Markdown 的文本,HTML 更安全可靠。

npm install cheerio

在Matery主题下:/scripts/replace_line_tags.js创建渐构标签替换逻辑。把#d/e/t/c/v/a替换成对应的svg图标。代码如下:

const cheerio = require('cheerio');

hexo.extend.filter.register('after_post_render', function (data) {
    const svgMap = {
      '#d': '<svg type="d" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m21.15 6.85c0-2.2056-1.7944-4-4-4-4.1765-0.01989-5.4993 5.7322-1.8147 7.5629-0.263 0.63631-0.4627 1.4421-0.6559 2.2215-0.1397 0.56337-0.2841 1.1459-0.4405 1.6084-0.0728 0.2155-0.1286 0.4813-0.1891 0.4813-0.5072-0.7362-0.8126-2.2507-1.0979-3.3161-0.47879-1.5358-0.72936-4.4237-2.8018-4.558-0.77422 7e-5 -1.3844 0.52253-1.8138 1.553-0.55019 1.254-0.75064 3.2421-1.3784 4.4472-0.39648 3e-4 -0.79576 0.0045-1.1877 0.0703-0.67978 0.1073-1.3339 0.4195-1.798 0.9347-0.39707 0.4315-0.6427 0.9874-0.74275 1.5623-0.063545 0.351-0.07691 0.7094-0.07883 1.0654 0.001935 0.4718-0.01324 0.9457 0.027745 1.4163 0.09435 1.151 0.65732 2.1308 1.7281 2.6237 0.43467 0.1975 0.91053 0.2877 1.3854 0.3129 0.40096 0.0215 0.80345 0.0129 1.2048 0.0139 0.6491 2e-4 1.2891-0.0515 1.888-0.3229 0.90042-0.4067 1.4845-1.2039 1.6712-2.1666 0.0761-0.3779 0.09179-0.7654 0.09344-1.15 7.7e-4 -0.2699 0.00148-0.5413-7.8e-4 -0.8111-0.00379-0.4854-0.04143-0.9771-0.19121-1.4414-0.28748-0.9172-0.98053-1.616-1.8964-1.909 0.43984-1.1576 0.66815-2.7594 1.1268-3.8895 0.3537 0.72804 0.57113 1.7669 0.82283 2.7298 0.26567 1.0724 0.5404 2.1814 0.90896 3.0557 0.87204 2.2985 3.1124 2.7586 4.0452 0.392 0.5508-1.2642 0.7508-3.279 1.3828-4.4916 2.1142-0.10339 3.8024-1.8557 3.8024-3.995zm-12.073 8.8023c0.05605 0.2275 0.06623 0.465 0.07092 0.6983 0.00363 0.2444 0.00195 0.4906 0.00214 0.735-0.0063 0.408 0.01486 0.882-0.18359 1.2496-0.24573 0.4539-0.8026 0.501-1.2651 0.5114-0.33714 0.0058-0.67525 0.0041-1.0124 0.0018-0.46455-0.0092-1.0361-0.0245-1.3192-0.4545-0.16612-0.2552-0.19733-0.5702-0.21202-0.8673-0.01004-0.2443-0.00683-0.4906-0.0075-0.735 5.9e-4 -0.2322-0.00201-0.4664 0.01171-0.6983 0.01886-0.2936 0.06332-0.6069 0.24969-0.8453 0.34185-0.4331 1.0226-0.3889 1.5228-0.3979 0.38828 0.0035 0.77905-0.0131 1.1658 0.0285 0.49865 0.0566 0.85211 0.2621 0.97684 0.7737zm8.0732-6.8023c-2.6379-0.06696-2.6373-3.9334 0-4 2.6378 0.06697 2.6373 3.9334 0 4z" fill="currentColor"></path></svg>',
      '#c': '<svg type="c" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m6.825 4.8749c1.8175-0.03033 2.3249 0.02869 2.25 2.0152 0.01496 1.139 0.01338 1.984-1.3875 1.9798-1.6108-0.01491-2.7285 0.30288-2.6124-1.796-0.019-1.5193-0.04171-2.2697 1.7499-2.1989zm0-2c-2.5847-0.10689-3.8882 1.4181-3.7496 3.8782-0.058825 1.6262 0.20934 2.9456 1.5713 3.7018 0.98591 0.49526 1.6843 0.40204 2.4713 0.42016 0.661-0.00557 1.2079 0.02014 1.9275-0.21866 1.051-0.35295 1.7794-1.2693 1.9533-2.3675 0.08948-0.54803 0.07327-0.95095 0.0762-1.3975-0.00196-0.42752 0.01114-0.8053-0.05632-1.306-0.24162-1.9408-1.9089-2.8188-3.6634-2.7097-0.17686-7.9441e-4 -0.35349-2.3937e-4 -0.53038-7.7934e-4z" fill="currentColor"></path><path d="m17.075 8.6749c1.8175-0.03034 2.3249 0.02868 2.25 2.0152 0.01495 1.139 0.01338 1.984-1.3875 1.9797-1.6108-0.01491-2.7285 0.30288-2.6124-1.796-0.01899-1.5193-0.04171-2.2697 1.7499-2.1989zm0-2c-2.5847-0.10689-3.8882 1.4181-3.7496 3.8782-0.05882 1.6262 0.20933 2.9457 1.5713 3.7017 0.98593 0.49528 1.6843 0.40205 2.4713 0.42017 0.66099-0.00556 1.2079 0.02015 1.9275-0.21865 1.051-0.35295 1.7794-1.2693 1.9533-2.3675 0.08949-0.54803 0.07328-0.95095 0.07621-1.3975-0.00197-0.42839 0.0112-0.80698-0.05673-1.3089-0.24288-1.9391-1.9097-2.8158-3.663-2.7068-0.17688-7.9346e-4 -0.35351-2.388e-4 -0.5304-7.7896e-4z" fill="currentColor"></path><path d="m8.4749 15.525c1.8175-0.03033 2.3249 0.02868 2.25 2.0152 0.01496 1.139 0.01338 1.984-1.3875 1.9797-1.6108-0.01491-2.7285 0.30288-2.6124-1.796-0.01899-1.5193-0.04172-2.2697 1.7499-2.1989zm0-2c-2.5847-0.10689-3.8882 1.4181-3.7496 3.8782-0.058825 1.6262 0.20934 2.9456 1.5713 3.7018 0.98591 0.49526 1.6843 0.40203 2.4713 0.42016 0.66099-0.00557 1.2079 0.02014 1.9276-0.21866 1.051-0.35294 1.7794-1.2693 1.9533-2.3675 0.08949-0.54803 0.07328-0.95095 0.07621-1.3975-0.00197-0.42753 0.01113-0.80529-0.05633-1.306-0.24162-1.9408-1.9089-2.8188-3.6634-2.7097-0.17688-7.9346e-4 -0.35351-2.4262e-4 -0.5304-7.8736e-4z" fill="currentColor"></path></svg>',
      '#e': '<svg type="e" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path fill="currentColor" d="m21.9 15.621c0.1248-1.8535-0.6087-3.4099-2.6058-3.8292-0.7712-0.15744-1.3921-0.13977-2.1113-0.14543-0.6323 0.0048-1.1718-0.01567-1.8401 0.03203 1.5356-0.8078 1.6998-2.205 1.6567-3.546 0.1272-2.3708-1.4685-3.666-3.7727-3.673-2.2427-0.04024-5.0463-0.27229-5.9443 1.9172-0.28083 0.6692-0.27606 1.2179-0.28202 1.6587-0.08527 1.4303 0.20687 2.9224 1.662 3.6429-2.3051-0.05275-5.3273-0.39212-6.28 1.8983-0.28073 0.66862-0.27595 1.2174-0.282 1.6572-0.10329 1.6061 0.3059 3.171 2.0252 3.8067 1.2061 0.4187 2.2175 0.2869 3.3945 0.3134 2.0524 0.0901 4.0448-0.4637 4.4796-2.4982 0.609 2.5638 3.2086 2.5463 5.3204 2.4982 2.7823 0.1278 4.7024-0.9368 4.5798-3.7329zm-12.899-7.6287c-0.14889-1.8665 1.8839-1.4921 3.1358-1.546 0.8939 0.05358 2.4743-0.21158 2.8003 0.88445 0.2729 2.4494-0.0297 2.8555-2.5242 2.8232-0.94713-0.07259-2.869 0.28949-3.3134-0.77077-0.14881-0.44557-0.08538-0.92893-0.09846-1.3909zm0.2606 9.2128c-0.56638 0.162-1.1652 0.1412-1.7487 0.1488-0.59786-0.0036-1.1977 0.0131-1.7948-0.0233-0.93407-0.0365-1.6776-0.3579-1.6157-1.4217 0.01574-0.5119-0.06845-1.0551 0.11822-1.5436 0.4432-0.84155 1.5978-0.6728 2.4032-0.7191 0.81712 0.01614 1.6464-0.05154 2.4536 0.10154 0.99382 0.17537 1.0564 0.91742 1.0227 1.7752-6.1e-4 0.7729 0.04085 1.416-0.83867 1.6821zm2.9212-3.6286c-0.0836 0.19457-0.14194 0.3848-0.18279 0.56614-0.18535-0.87758-0.76293-1.6189-1.5605-2.02 1.0871 0.04933 2.0387 0.04959 3.1216-8e-5 -0.7672 0.39034-1.1687 0.96486-1.3783 1.4539zm6.8788 3.6286c-0.5664 0.162-1.1652 0.1412-1.7488 0.1488-0.5978-0.0036-1.1977 0.0131-1.7947-0.0233-0.9341-0.0365-1.6776-0.3579-1.6157-1.4217 0.0157-0.5119-0.0685-1.0551 0.1182-1.5436 0.4432-0.84155 1.5978-0.6728 2.4033-0.7191 0.8171 0.01614 1.6464-0.05154 2.4536 0.10154 0.9938 0.17537 1.0563 0.91742 1.0227 1.7752-6e-4 0.7729 0.0409 1.416-0.8386 1.6821z"></path></svg>',
      '#t': '<svg type="t" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m15.385 10.538c-0.52922 1.222-0.74082 3.1121-1.2852 4.3107-0.06906-2e-5 -0.24102-0.40954-0.40553-0.85764-0.54849-1.4968-0.91293-3.7816-1.4977-5.2179-0.49825-1.7178-2.7313-2.8836-3.8104-0.24557-0.55221 1.2498-0.75261 3.2793-1.3921 4.4683-0.45354 0.09492-0.79418 0.49706-0.79418 0.9788 0 0.5523 0.4477 1 1 1 0.77414 0 1.3844-0.52246 1.8137-1.5529 0.50969-1.1819 0.73444-2.9587 1.2241-4.138 0.07175 2e-5 0.14687 0.33291 0.23664 0.59492 0.20698 0.60425 0.39119 1.3477 0.58618 2.1349 0.2657 1.0724 0.54043 2.1814 0.90899 3.0557 0.87212 2.2985 3.1123 2.7586 4.0452 0.39202 0.55283-1.2608 0.75203-3.309 1.3936-4.5083 0.4522-0.0959 0.7915-0.49744 0.7915-0.97823 0-0.55229-0.4477-1-1-1-0.7755 0-1.3861 0.526-1.8148 1.5634z" fill="currentColor"></path><path d="m15.802 6.9697c-0.1557 0.1946-0.1882 0.58884 0.1331 0.60533 1.2616 0.02168 2.5193 0.48654 3.5913 1.2655 0.2705 0.19453 0.6808 0.05368 0.7176-0.30435 0.0793-0.76097 0.0572-1.5713-0.086-2.401-0.1456-0.82752-0.4109-1.6736-0.8018-2.5036-0.1536-0.34251-0.6624-0.55548-0.9204-0.23779l-0.7238 0.98277c-3.8989-2.9446-9.692-2.2836-12.827 1.4659-6.4518 7.8165 1.8281 18.818 11.123 14.783 1.8924-0.8564 3.4853-2.3528 4.4507-4.1927 0.0679-0.1218 0.1291-0.2481 0.1823-0.377 0.1017-0.2304 0.1549-0.518-0.0557-0.7052-0.1162-0.1043-0.2646-0.1628-0.4074-0.221-0.1475-0.0577-0.2953-0.116-0.4439-0.1706-0.2042-0.0713-0.4475-0.1531-0.6498-0.0358-0.0846 0.0496-0.1444 0.131-0.1982 0.2109-0.0747 0.1157-0.1266 0.2445-0.1952 0.3636-0.4837 0.9276-1.1717 1.74-1.9925 2.3831-0.8208 0.6431-1.7745 1.1169-2.7897 1.3673-7.0612 1.7198-12.182-6.5444-7.5021-12.107 2.4634-2.9539 7.0543-3.4782 10.119-1.154" fill="currentColor"></path></svg>',
      '#v': '<svg type="v" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m12.006 2.4861c8.295-0.034635 12.587 10.042 6.9396 15.995 0.302-0.0792 0.5884 0.106 0.8099 0.2931 0.1763 0.1517 0.337 0.3223 0.4938 0.4938 0.1806 0.1987 0.3602 0.3999 0.5393 0.6 0.158 0.1775 0.3162 0.3571 0.4573 0.5485 0.0932 0.127 0.1803 0.2635 0.2402 0.4098 0.0591 0.1432 0.0867 0.3066 0.0463 0.4586l-0.0182 0.058c-0.0546 0.1443-0.1606 0.2646-0.2695 0.3712-0.0972 0.0941-0.2013 0.1853-0.3018 0.2759-0.1104 0.0982-0.2212 0.201-0.3417 0.287-0.1188 0.0852-0.2583 0.1531-0.4066 0.159-0.2688 9e-3 -0.5043-0.1558-0.7006-0.3227-0.1407-0.1218-0.2719-0.2564-0.3983-0.3929-0.2101-0.2279-0.4164-0.4606-0.6233-0.6914-0.1578-0.1777-0.3167-0.3566-0.4572-0.5485-0.0869-0.1186-0.1682-0.2449-0.2272-0.3799-0.06-0.136-0.0946-0.2901-0.0688-0.4385l0.0117-0.0521 0.0161-0.0498c-1.7182 1.3134-3.966 2.0444-6.2474 1.9119-12.23-1.0527-11.717-18.608 0.50643-18.986zm-6.8e-4 2c-3.9794 3.5e-4 -7.2654 3.1166-7.4809 7.0946-0.30103 4.0208 3.0533 7.76 7.0834 7.8947 4.1153 0.2383 7.6845-2.9602 7.8946-7.0833 0.319-4.1746-3.3113-8.0014-7.4964-7.9059" fill="currentColor"></path><path d="m8.2769 7.8469c0.29326 0.69532 0.64074 1.1934 1.5 1.3397 0.4567-0.53241 1.0671-0.92645 1.7212-0.97652 0.65414-0.05007 1.1756 0.26304 1.2305 0.98096 0.10016 1.3082-2.47 2.532-1.899 4.9596 0.64656 0.38624 1.7475 0.36741 2.2073 0.03029-0.36861-2.09 2.575-3.1725 2.4052-5.3901-0.16975-2.2175-1.7734-3.0416-3.7676-2.8889-1.4358 0.10991-2.597 0.87279-3.3975 1.945z" fill="currentColor"></path><path d="m12.01 14.568c-0.99198 0-1.696 0.76802-1.696 1.7601 0 0.992 0.70406 1.776 1.696 1.776 0.97603 0 1.696-0.78404 1.696-1.776 0-0.99204-0.72002-1.7601-1.696-1.7601z" fill="currentColor"></path></svg>',
      '#a': '<svg type="a" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m15.45 7.35c-0.0022-1.4574-0.7043-2.0002-2.0001-2.0002-0.5281 0-1.0428 0.12066-1.6692 0.8986-1.2172 1.2052-3.5662 1.5773-6.4138 1.5566-0.92067 0.00495-1.8844 0.27586-2.521 0.97407-0.89662 0.97053-0.8534 2.1136-0.84541 3.3436-0.088935 2.0639 1.0163 3.5806 3.1554 3.6639 0.18073 0.9556 0.68251 3.671 0.86079 4.5885 0.11273 0.6047 0.44099 0.6361 0.97316 0.525 0.52124-0.1078 1.1127-0.1057 0.99809-0.819-0.14025-0.8342-0.63023-3.3751-0.78778-4.2434 2.2128 0.1862 3.6134 0.5907 4.5806 1.5138 0.63361 0.6782 1.2967 0.8987 1.6692 0.8987 1.2958-1e-4 2.0107-0.6194 2.0001-2.0002v-3.2681c0.2954-0.13425 0.725-0.23189 1.35-0.23189v-2c-0.625 0-1.0546-0.09763-1.35-0.23189v-3.1681zm-2 8.9q-1.45-2.45-7.4205-2.45c-1.4917 0.02186-2.072-0.06445-2.0295-1.7275 0.00524-1.5258-0.13158-2.3285 1.723-2.2725 5.5801 0.23384 7.964-2.492 7.727-2.45v8.9z" fill="currentColor"></path><path d="m22.024 11.62c0.00399-0.58801-0.05448-1.0153-0.74975-1.0361-0.41509-0.00662-0.82816 0.057395-1.2409 0.094325-0.33033 0.040455-0.73566 0.076976-1.0072 0.28268-0.28398 0.21724-0.23153 0.59429-0.23733 0.9112-0.0015854 0.30307-0.0045853 0.60983 0.27663 0.79666 0.23484 0.15349 0.52158 0.19534 0.7942 0.23343 0.23915 0.02956 0.48002 0.05101 0.71976 0.07523 0.48243 0.03148 1.2248 0.19557 1.394-0.41829 0.0757-0.30577 0.04467-0.627 0.05067-0.93912z" fill="currentColor"></path><path d="m17.348 5.7962c0.042171 0.25853 0.19707 0.48146 0.30883 0.71387 0.28865 0.62708 0.76754 0.52952 1.3216 0.33695 0.29707-0.1074 0.5898-0.22819 0.88354-0.34427 1.2431-0.47478 0.99431-0.8753 0.46485-1.8723-0.42612-0.90268-0.91649-0.67014-1.6207-0.2097-0.32028 0.21007-0.65168 0.40646-0.95187 0.64525-0.21815 0.17815-0.44959 0.42625-0.40623 0.73022z" fill="currentColor"></path><path d="m20.756 17.801c-0.08779-0.41834-0.59472-0.57-0.94009-0.72238-0.31748-0.12454-0.63252-0.2579-0.95618-0.36584-0.27393-0.083771-0.59373-0.17244-0.86319-0.031395-0.21247 0.11853-0.30992 0.35702-0.4191 0.56205-0.12688 0.25243-0.31107 0.53775-0.19892 0.82794 0.1101 0.27652 0.36419 0.46004 0.59732 0.62904 0.18414 0.12824 0.3747 0.24849 0.56281 0.37079 0.15333 0.0986 0.3065 0.19968 0.46418 0.29127 0.21755 0.12307 0.46707 0.25848 0.72501 0.21843 0.34543-0.06224 0.50617-0.44433 0.6571-0.72156 0.07714-0.15037 0.15704-0.30255 0.23064-0.4547 0.08692-0.18674 0.17446-0.39353 0.14043-0.60364z" fill="currentColor"></path></svg>'
  };
  
    const linkSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="0.9411764705882353em" height="0.9411764705882353em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class="untouchable"><path d="m9.5652 14.45 0.72891-2.0026c-0.651 0.00713-1.3027 0.00104-1.9532 0.00179-1.0991-0.02908-3.0336 0.08306-3.605-1.0524-0.28828-0.61588-0.2054-1.3226-0.22136-1.9833 0.00663-0.74044-0.05553-1.6362 0.5758-2.1558 0.70637-0.5555 1.7411-0.56129 2.6027-0.59834 0.743-0.015 1.4884-0.00764 2.2315-0.00868 0.68471 0.01536 1.6274-0.01783 2.4184 0.16762l0.68711-1.8879c-0.0146-0.003965-0.0287-0.00841-0.0435-0.01227-0.94653-0.24905-1.9355-0.25901-2.9083-0.26688-0.78352-1.3008e-4 -1.5692-0.0063751-2.3527 0.006805-1.2709 0.027555-2.6299 0.13739-3.6978 0.89566-1.6654 1.2031-1.53 2.9573-1.5068 4.79-0.0012251 1.7732 0.89765 3.2159 2.626 3.7562 0.80589 0.26191 1.6615 0.32018 2.5036 0.34101 0.6376 0.01106 1.2763 0.01096 1.9146 0.00915z" fill="currentColor"></path><path d="m14.589 9.125h1.3099c0.02865-0.88714-0.11774-1.6826-0.45594-2.3461l-0.85392 2.3461z" fill="currentColor"></path><path d="m15.587 12.025h-2.0527l-0.80604 2.2146c1.2326-0.27362 2.3169-0.88582 2.8588-2.2146z" fill="currentColor"></path><path d="m8.394 12.025h2.0538l0.82406-2.2641c-1.2457 0.2734-2.3327 0.8901-2.8779 2.2641z" fill="currentColor"></path><path d="m8.5566 17.221 0.83571-2.2961h-1.2914c-0.025394 0.86685 0.12295 1.645 0.45565 2.2961z" fill="currentColor"></path><path d="m21.485 14.399c7e-4 -0.67593 0.0063-1.3662-0.1779-2.0223-0.58881-2.115-2.5706-2.7532-4.5608-2.8041-0.76964-0.031175-1.5416-0.02264-2.3121-0.022365l-0.72832 2.0011c0.38557-0.00297 0.77131 7.6e-4 1.1559-0.00173 1.1244 0.02284 2.8396-0.10221 3.8152 0.44616 0.82512 0.45526 0.81194 1.4036 0.80798 2.2308-0.01538 0.64171 0.05949 1.3145-0.1601 1.93-0.39418 1.0145-1.651 1.1102-2.5915 1.1694-0.7426 0.03331-1.4884 0.0209-2.2315 0.02365-0.81334-0.01641-1.9395 0.04306-2.8448-0.16914l-0.68792 1.89c0.014845 0.00401 0.02915 0.0085 0.044115 0.0124 0.94522 0.24688 1.9316 0.25913 2.9027 0.2657 0.83456-2.2e-4 1.6713 0.00786 2.5057-0.00999 2.0286-0.02122 4.1491-0.51576 4.8438-2.6752 0.2358-0.7292 0.22-1.5067 0.2196-2.2644z" fill="currentColor"></path><path d="m14.979 6.7378c0.17824-0.52033 0.90905-2.4486 1.0626-2.9514 0.05601-0.19527 0.10768-0.39984 0.08232-0.60408-0.03096-0.33264-0.36035-0.4603-0.63671-0.55464-0.20794-0.070665-0.41593-0.17228-0.63943-0.174-0.33751 0.005805-0.52152 0.33878-0.64452 0.61072-1.4256 3.8005-4.7612 13.07-6.1617 16.891-0.10636 0.34-0.29285 0.7891-0.06874 1.1109 0.1296 0.1673 0.34386 0.232 0.53431 0.3042 0.30778 0.1107 0.70325 0.3075 0.98251 0.0365 0.14514-0.1339 0.23561-0.315 0.31595-0.4926 0.10005-0.2274 0.1811-0.4632 0.26694-0.6962 0.4854-1.3337 4.3257-11.885 4.9065-13.481z" fill="currentColor"></path></svg>';
  

  const $ = cheerio.load(data.content);
  const labelMap = {};  // 内容 -> 标签类型,例如 A: '#d'

  // 收集定义段落
  $('p').each((_, el) => {
    const text = $(el).text().trim();
    let match;

    // #c 标签 内容c
    if ((match = text.match(/^#c\s+(\S+)\s+(.*)$/))) {
      const [, label, content] = match;
      labelMap[content] = '#c';

      $(el).replaceWith(`
        <div class="evoldown" id="${content}" type="c">
          <span class="icon">
            ${svgMap['#c']}
            <p name="label">${label}</p>
            <p name="id">${content}</p>
          </span>
        </div>
      `);
    }
    // #x 内容x
    else if ((match = text.match(/^(#\w)\s+(\S+)\s*$/))) {
      const [_, tag, content] = match;
      labelMap[content] = tag;

      $(el).replaceWith(`
        <div class="evoldown" id="${content}" type="${tag.slice(1)}">
          <span class="icon">
            ${svgMap[tag]}
            <p name="id">${content}</p>
          </span>
        </div>
      `);
    }
  });

  // 处理引用段落
  $('p').each((_, el) => {
    const text = $(el).text().trim();
    const match = text.match(/^(#\w)\s+(\S+)\s+(\S+)$/);
    if (match) {
      const [_, tag, first, second] = match;

      const secondTag = labelMap[second];
      const secondSvg = secondTag ? svgMap[secondTag] : '';

      $(el).replaceWith(`
        <div class="evoldown" id="${first}" type="${tag.slice(1)}">
          <span class="icon">
            ${svgMap[tag]}
            <p name="id">${first}</p>
          </span>
          <span class="link-icon ml-[0.5em] mr-[0.25em]">
            ${linkSvg}
          </span>
          ${secondSvg ? `
          <span class="icon">
            ${secondSvg}
            <p name="id">${second}</p>
          </span>` : ''}
        </div>
      `);
    }
  });

  data.content = $.html();
  return data;
});

渐构样式

在把「渐构标签」渲染成与之对应的svg图标过后,需要调整图标的样式,我的样式是写在source/css/my.css中的。

/*渐构模式展示的css样式*/
:root{
  --heroui-content2: 240 26.32% 88.82%;
  --sxd: 1.2em;
  --heroui-block-d: 203.66999999999996 69.01% 41.76%;
  --heroui-block-e: 358.36 46.22% 53.33%;
  --heroui-block-t: 37.889999999999986 59.38% 37.65%;
  --heroui-block-c: 240 .43% 45.69%;
  --heroui-block-v: 246.47000000000003 51.52% 61.18%;
  --heroui-block-a: 282 47.01% 54.12%;
  --block-color: var(--heroui-block-c);
  --heroui-primary-900: 240 16.98% 10.39%;
}

.evoldown {
  display: block;
  width: 100%;
  border-radius: .5em .5em 0 0 / .5em .5em 0px 0px;
  background-color: hsl(var(--heroui-content2) / .2);
  padding-left: var(--sxd);
  padding-right: var(--sxd);
  padding-top: min(1em, var(--sxd));
  --sb: .25em;
  position: relative;
  margin-bottom: var(--sb);
}

.evoldown{
  display: inline-flex;
  align-items: center;
}

.evoldown p {
  padding: 0;
  margin: 2px 2px 10px !important;
  font-size: var(--sxd) !important;
}

.evoldown svg {
  width: 1.7em;
  height: 1.7em;
  vertical-align: middle;
  margin-bottom:0.5em ;
  border-radius: 5px; /* 设置圆角半径 */
}

.evoldown svg[type="c"] {
  color: hsl(var(--heroui-block-c));
  background-color:hsl(var(--heroui-block-c) / .2); ;
}

.evoldown svg[type="d"] {
  color: hsl(var(--heroui-block-d));
  background-color:hsl(var(--heroui-block-d) / .2); ;
}

.evoldown svg[type="e"] {
  color: hsl(var(--heroui-block-e));
  background-color:hsl(var(--heroui-block-e) / .2); ;
}

.evoldown svg[type="t"] {
  color: hsl(var(--heroui-block-t));
  background-color:hsl(var(--heroui-block-t) / .2); ;
}

.evoldown svg[type="v"] {
  color: hsl(var(--heroui-block-v));
  background-color:hsl(var(--heroui-block-v) / .2); ;
}

.evoldown svg[type="a"] {
  color: hsl(var(--heroui-block-a));
  background-color:hsl(var(--heroui-block-a) / .2); ;
}


.evoldown span {
  display: inline-flex;
  align-items: center;
}

.evoldown .icon.c {
  margin-right: .25em;
}

.evoldown  p[name=label] {
  margin-right: .15em;
  height: 1.667em;
  border-radius: .333em;
  padding: .1em .5em .15em;
  font-size: 1em !important;
  line-height: 1.4em !important;
  --tw-text-opacity: 1;
  color: hsl(var(--heroui-block-c) / var(--heroui-block-c-opacity, var(--tw-text-opacity)));
  background-color: hsl(var(--block-color) / .2);
}

.evoldown p[name=id]{
  font-weight: 600;
  --tw-text-opacity: 1;
  color: hsl(var(--heroui-primary-900) / var(--heroui-primary-900-opacity, var(--tw-text-opacity)));
  font-family: Source Han Sans;
  font-variation-settings: "opsz" auto;
  letter-spacing: .07em;
}

.evoldown .link-icon {
  display: inline-flex;
  width: 1.4em !important;
  height: 1.4em !important;
  align-content: center;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
}

TOC导航跳转

在完成了「渐构标签」对应的svg图标的渲染过后,需要简历对应的TOC导航,这里重写了tocbot的逻辑,但是使用它的样式。这里暂时有一个bug没有修复,那就是文章必须要有一级标题才能宣传出所有的TOC,如果没有的话是渲染不出来的。

找到主题下的themes\hexo-theme-matery\layout\_partial\post-detail-toc.ejs文件,修改TOC的逻辑代码:

$(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('<%- theme.toc.collapseDepth %>'),
            // headingSelector: '<%- theme.toc.heading %>'
            headingSelector: 'none',
        });
        var tocList = $('<ol>', { class: 'toc-list' }); // 创建顶层 <ol> 容器
        var currentLevel = 1; // 当前层级
        var parentStack = [tocList]; // 用于存储父级 <ol> 的栈

        $('#articleContent').find('h1, h2, h3, h4, h5, h6').each(function () {
            var $heading = $(this);
            var headingText = $heading.text();
            var level = parseInt($heading[0].tagName[1], 10); // 获取当前标题的层级,例如 h1 -> 1, h2 -> 2
            // var tocList = $('<ol>', { class: 'toc-list ' }); // 创建 <ol> 容器
            var tocListItem = $('<li>', { class: 'toc-list-item' }); // 创建 <li> 容器

            var tocItem = $('<a>', { 
                href: '#' + $heading.attr('id'), 
                class: 'toc-link' // 添加 class="toc-link"
            }).text(headingText); // 创建 <a> 标签

            // 创建箭头 SVG
            var arrowSvg = `<svg class="arrow-icon" xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1" viewBox="0 0 24 24" class="h-[0.96em] w-[0.96em] text-foreground" style="transition: transform 233ms cubic-bezier(0.42, 0, 0.24, 1); transform: rotate(0deg);"><path d="m18.707 9.7075 4e-4 -3.75e-4q0.1407-0.14065 0.2168-0.32442 0.0761-0.18377 0.0761-0.38268t-0.0761-0.38268q-0.0761-0.18377-0.2168-0.32442-0.1406-0.14065-0.3244-0.21677-0.1838-0.07612-0.3827-0.07612t-0.3827 0.076121q-0.1838 0.07612-0.3244 0.21677l-4e-4 3.75e-4 -5.2925 5.2925-5.2929-5.2929q-0.14065-0.14065-0.32442-0.21677-0.18377-0.07612-0.38268-0.07612t-0.38268 0.07612q-0.18377 0.076121-0.32442 0.21677t-0.21677 0.32442q-0.07612 0.18377-0.07612 0.38268t0.07612 0.38268q0.076121 0.18377 0.21677 0.32442l6 6q0.14066 0.14065 0.32443 0.21677 0.18377 0.07612 0.38268 0.07612t0.38268-0.07612q0.18377-0.07612 0.32443-0.21677l5.9996-5.9996z" fill="currentColor" fill-rule="evenodd"></path></svg>`;

            // 包裹 <a> 标签的 <div>
            var tocItemWrapper = $('<div>', { 
                class: 'toc-item-wrapper' // 添加 class="toc-item-wrapper"
            }).append(tocItem).append(arrowSvg); // 将 <a> 添加到 <div>
            // 将 <a> 添加到 <li>
            tocListItem.append(tocItemWrapper);
             // 如果当前标题层级比上一个标题层级高,创建新的嵌套 <ol>
                if (level > currentLevel) {
                var nestedList = $('<ol>', { class: 'toc-list' }); // 创建嵌套的 <ol>
                parentStack[parentStack.length - 1].children('li:last').append(nestedList); // 将嵌套 <ol> 添加到父级 <li>
                parentStack.push(nestedList); // 将嵌套 <ol> 压入栈
            } 
            // 如果当前标题层级比上一个标题层级低,回退到正确的父级
            else if (level < currentLevel) {
                while (level < currentLevel) {
                    parentStack.pop(); // 弹出栈顶,回退到上一级
                    currentLevel--;
                }
            }
            // 将当前 <li> 添加到当前层级的 <ol>
            parentStack[parentStack.length - 1].append(tocListItem);
            currentLevel = level; // 更新当前层级            
            // 查找该标题下的 evoldown 内容(#d, #e, #t, #c, #v, #a)
            $heading.nextUntil('h1, h2, h3, h4, h5, h6').each(function () {
                var $div = $(this);
                if ($div.hasClass('evoldown')) {
                    var type = $div.attr('type');
                    var id = $div.attr('id');
                    var label = $div.text(); // 假设需要从内容中提取 label
                    var icon = '';

                    // 根据类型插入相应的图标
                    switch (type) {
                        case 'd':
                            icon = '<svg type="d" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m21.15 6.85c0-2.2056-1.7944-4-4-4-4.1765-0.01989-5.4993 5.7322-1.8147 7.5629-0.263 0.63631-0.4627 1.4421-0.6559 2.2215-0.1397 0.56337-0.2841 1.1459-0.4405 1.6084-0.0728 0.2155-0.1286 0.4813-0.1891 0.4813-0.5072-0.7362-0.8126-2.2507-1.0979-3.3161-0.47879-1.5358-0.72936-4.4237-2.8018-4.558-0.77422 7e-5 -1.3844 0.52253-1.8138 1.553-0.55019 1.254-0.75064 3.2421-1.3784 4.4472-0.39648 3e-4 -0.79576 0.0045-1.1877 0.0703-0.67978 0.1073-1.3339 0.4195-1.798 0.9347-0.39707 0.4315-0.6427 0.9874-0.74275 1.5623-0.063545 0.351-0.07691 0.7094-0.07883 1.0654 0.001935 0.4718-0.01324 0.9457 0.027745 1.4163 0.09435 1.151 0.65732 2.1308 1.7281 2.6237 0.43467 0.1975 0.91053 0.2877 1.3854 0.3129 0.40096 0.0215 0.80345 0.0129 1.2048 0.0139 0.6491 2e-4 1.2891-0.0515 1.888-0.3229 0.90042-0.4067 1.4845-1.2039 1.6712-2.1666 0.0761-0.3779 0.09179-0.7654 0.09344-1.15 7.7e-4 -0.2699 0.00148-0.5413-7.8e-4 -0.8111-0.00379-0.4854-0.04143-0.9771-0.19121-1.4414-0.28748-0.9172-0.98053-1.616-1.8964-1.909 0.43984-1.1576 0.66815-2.7594 1.1268-3.8895 0.3537 0.72804 0.57113 1.7669 0.82283 2.7298 0.26567 1.0724 0.5404 2.1814 0.90896 3.0557 0.87204 2.2985 3.1124 2.7586 4.0452 0.392 0.5508-1.2642 0.7508-3.279 1.3828-4.4916 2.1142-0.10339 3.8024-1.8557 3.8024-3.995zm-12.073 8.8023c0.05605 0.2275 0.06623 0.465 0.07092 0.6983 0.00363 0.2444 0.00195 0.4906 0.00214 0.735-0.0063 0.408 0.01486 0.882-0.18359 1.2496-0.24573 0.4539-0.8026 0.501-1.2651 0.5114-0.33714 0.0058-0.67525 0.0041-1.0124 0.0018-0.46455-0.0092-1.0361-0.0245-1.3192-0.4545-0.16612-0.2552-0.19733-0.5702-0.21202-0.8673-0.01004-0.2443-0.00683-0.4906-0.0075-0.735 5.9e-4 -0.2322-0.00201-0.4664 0.01171-0.6983 0.01886-0.2936 0.06332-0.6069 0.24969-0.8453 0.34185-0.4331 1.0226-0.3889 1.5228-0.3979 0.38828 0.0035 0.77905-0.0131 1.1658 0.0285 0.49865 0.0566 0.85211 0.2621 0.97684 0.7737zm8.0732-6.8023c-2.6379-0.06696-2.6373-3.9334 0-4 2.6378 0.06697 2.6373 3.9334 0 4z" fill="currentColor"></path></svg>'; // 填入 #d 对应的 SVG 图标
                            break;
                        case 'e':
                            icon = '<svg type="e" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path fill="currentColor" d="m21.9 15.621c0.1248-1.8535-0.6087-3.4099-2.6058-3.8292-0.7712-0.15744-1.3921-0.13977-2.1113-0.14543-0.6323 0.0048-1.1718-0.01567-1.8401 0.03203 1.5356-0.8078 1.6998-2.205 1.6567-3.546 0.1272-2.3708-1.4685-3.666-3.7727-3.673-2.2427-0.04024-5.0463-0.27229-5.9443 1.9172-0.28083 0.6692-0.27606 1.2179-0.28202 1.6587-0.08527 1.4303 0.20687 2.9224 1.662 3.6429-2.3051-0.05275-5.3273-0.39212-6.28 1.8983-0.28073 0.66862-0.27595 1.2174-0.282 1.6572-0.10329 1.6061 0.3059 3.171 2.0252 3.8067 1.2061 0.4187 2.2175 0.2869 3.3945 0.3134 2.0524 0.0901 4.0448-0.4637 4.4796-2.4982 0.609 2.5638 3.2086 2.5463 5.3204 2.4982 2.7823 0.1278 4.7024-0.9368 4.5798-3.7329zm-12.899-7.6287c-0.14889-1.8665 1.8839-1.4921 3.1358-1.546 0.8939 0.05358 2.4743-0.21158 2.8003 0.88445 0.2729 2.4494-0.0297 2.8555-2.5242 2.8232-0.94713-0.07259-2.869 0.28949-3.3134-0.77077-0.14881-0.44557-0.08538-0.92893-0.09846-1.3909zm0.2606 9.2128c-0.56638 0.162-1.1652 0.1412-1.7487 0.1488-0.59786-0.0036-1.1977 0.0131-1.7948-0.0233-0.93407-0.0365-1.6776-0.3579-1.6157-1.4217 0.01574-0.5119-0.06845-1.0551 0.11822-1.5436 0.4432-0.84155 1.5978-0.6728 2.4032-0.7191 0.81712 0.01614 1.6464-0.05154 2.4536 0.10154 0.99382 0.17537 1.0564 0.91742 1.0227 1.7752-6.1e-4 0.7729 0.04085 1.416-0.83867 1.6821zm2.9212-3.6286c-0.0836 0.19457-0.14194 0.3848-0.18279 0.56614-0.18535-0.87758-0.76293-1.6189-1.5605-2.02 1.0871 0.04933 2.0387 0.04959 3.1216-8e-5 -0.7672 0.39034-1.1687 0.96486-1.3783 1.4539zm6.8788 3.6286c-0.5664 0.162-1.1652 0.1412-1.7488 0.1488-0.5978-0.0036-1.1977 0.0131-1.7947-0.0233-0.9341-0.0365-1.6776-0.3579-1.6157-1.4217 0.0157-0.5119-0.0685-1.0551 0.1182-1.5436 0.4432-0.84155 1.5978-0.6728 2.4033-0.7191 0.8171 0.01614 1.6464-0.05154 2.4536 0.10154 0.9938 0.17537 1.0563 0.91742 1.0227 1.7752-6e-4 0.7729 0.0409 1.416-0.8386 1.6821z"></path></svg>'; // 填入 #e 对应的 SVG 图标
                            break;
                        case 't':
                            icon = '<svg type="t" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m15.385 10.538c-0.52922 1.222-0.74082 3.1121-1.2852 4.3107-0.06906-2e-5 -0.24102-0.40954-0.40553-0.85764-0.54849-1.4968-0.91293-3.7816-1.4977-5.2179-0.49825-1.7178-2.7313-2.8836-3.8104-0.24557-0.55221 1.2498-0.75261 3.2793-1.3921 4.4683-0.45354 0.09492-0.79418 0.49706-0.79418 0.9788 0 0.5523 0.4477 1 1 1 0.77414 0 1.3844-0.52246 1.8137-1.5529 0.50969-1.1819 0.73444-2.9587 1.2241-4.138 0.07175 2e-5 0.14687 0.33291 0.23664 0.59492 0.20698 0.60425 0.39119 1.3477 0.58618 2.1349 0.2657 1.0724 0.54043 2.1814 0.90899 3.0557 0.87212 2.2985 3.1123 2.7586 4.0452 0.39202 0.55283-1.2608 0.75203-3.309 1.3936-4.5083 0.4522-0.0959 0.7915-0.49744 0.7915-0.97823 0-0.55229-0.4477-1-1-1-0.7755 0-1.3861 0.526-1.8148 1.5634z" fill="currentColor"></path><path d="m15.802 6.9697c-0.1557 0.1946-0.1882 0.58884 0.1331 0.60533 1.2616 0.02168 2.5193 0.48654 3.5913 1.2655 0.2705 0.19453 0.6808 0.05368 0.7176-0.30435 0.0793-0.76097 0.0572-1.5713-0.086-2.401-0.1456-0.82752-0.4109-1.6736-0.8018-2.5036-0.1536-0.34251-0.6624-0.55548-0.9204-0.23779l-0.7238 0.98277c-3.8989-2.9446-9.692-2.2836-12.827 1.4659-6.4518 7.8165 1.8281 18.818 11.123 14.783 1.8924-0.8564 3.4853-2.3528 4.4507-4.1927 0.0679-0.1218 0.1291-0.2481 0.1823-0.377 0.1017-0.2304 0.1549-0.518-0.0557-0.7052-0.1162-0.1043-0.2646-0.1628-0.4074-0.221-0.1475-0.0577-0.2953-0.116-0.4439-0.1706-0.2042-0.0713-0.4475-0.1531-0.6498-0.0358-0.0846 0.0496-0.1444 0.131-0.1982 0.2109-0.0747 0.1157-0.1266 0.2445-0.1952 0.3636-0.4837 0.9276-1.1717 1.74-1.9925 2.3831-0.8208 0.6431-1.7745 1.1169-2.7897 1.3673-7.0612 1.7198-12.182-6.5444-7.5021-12.107 2.4634-2.9539 7.0543-3.4782 10.119-1.154" fill="currentColor"></path></svg>'; // 填入 #t 对应的 SVG 图标
                            break;
                        case 'v':
                            icon = '<svg type="v" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m12.006 2.4861c8.295-0.034635 12.587 10.042 6.9396 15.995 0.302-0.0792 0.5884 0.106 0.8099 0.2931 0.1763 0.1517 0.337 0.3223 0.4938 0.4938 0.1806 0.1987 0.3602 0.3999 0.5393 0.6 0.158 0.1775 0.3162 0.3571 0.4573 0.5485 0.0932 0.127 0.1803 0.2635 0.2402 0.4098 0.0591 0.1432 0.0867 0.3066 0.0463 0.4586l-0.0182 0.058c-0.0546 0.1443-0.1606 0.2646-0.2695 0.3712-0.0972 0.0941-0.2013 0.1853-0.3018 0.2759-0.1104 0.0982-0.2212 0.201-0.3417 0.287-0.1188 0.0852-0.2583 0.1531-0.4066 0.159-0.2688 9e-3 -0.5043-0.1558-0.7006-0.3227-0.1407-0.1218-0.2719-0.2564-0.3983-0.3929-0.2101-0.2279-0.4164-0.4606-0.6233-0.6914-0.1578-0.1777-0.3167-0.3566-0.4572-0.5485-0.0869-0.1186-0.1682-0.2449-0.2272-0.3799-0.06-0.136-0.0946-0.2901-0.0688-0.4385l0.0117-0.0521 0.0161-0.0498c-1.7182 1.3134-3.966 2.0444-6.2474 1.9119-12.23-1.0527-11.717-18.608 0.50643-18.986zm-6.8e-4 2c-3.9794 3.5e-4 -7.2654 3.1166-7.4809 7.0946-0.30103 4.0208 3.0533 7.76 7.0834 7.8947 4.1153 0.2383 7.6845-2.9602 7.8946-7.0833 0.319-4.1746-3.3113-8.0014-7.4964-7.9059" fill="currentColor"></path><path d="m8.2769 7.8469c0.29326 0.69532 0.64074 1.1934 1.5 1.3397 0.4567-0.53241 1.0671-0.92645 1.7212-0.97652 0.65414-0.05007 1.1756 0.26304 1.2305 0.98096 0.10016 1.3082-2.47 2.532-1.899 4.9596 0.64656 0.38624 1.7475 0.36741 2.2073 0.03029-0.36861-2.09 2.575-3.1725 2.4052-5.3901-0.16975-2.2175-1.7734-3.0416-3.7676-2.8889-1.4358 0.10991-2.597 0.87279-3.3975 1.945z" fill="currentColor"></path><path d="m12.01 14.568c-0.99198 0-1.696 0.76802-1.696 1.7601 0 0.992 0.70406 1.776 1.696 1.776 0.97603 0 1.696-0.78404 1.696-1.776 0-0.99204-0.72002-1.7601-1.696-1.7601z" fill="currentColor"></path></svg>'; // 填入 #v 对应的 SVG 图标
                            break;
                        case 'a':
                            icon = '<svg type="a" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m15.45 7.35c-0.0022-1.4574-0.7043-2.0002-2.0001-2.0002-0.5281 0-1.0428 0.12066-1.6692 0.8986-1.2172 1.2052-3.5662 1.5773-6.4138 1.5566-0.92067 0.00495-1.8844 0.27586-2.521 0.97407-0.89662 0.97053-0.8534 2.1136-0.84541 3.3436-0.088935 2.0639 1.0163 3.5806 3.1554 3.6639 0.18073 0.9556 0.68251 3.671 0.86079 4.5885 0.11273 0.6047 0.44099 0.6361 0.97316 0.525 0.52124-0.1078 1.1127-0.1057 0.99809-0.819-0.14025-0.8342-0.63023-3.3751-0.78778-4.2434 2.2128 0.1862 3.6134 0.5907 4.5806 1.5138 0.63361 0.6782 1.2967 0.8987 1.6692 0.8987 1.2958-1e-4 2.0107-0.6194 2.0001-2.0002v-3.2681c0.2954-0.13425 0.725-0.23189 1.35-0.23189v-2c-0.625 0-1.0546-0.09763-1.35-0.23189v-3.1681zm-2 8.9q-1.45-2.45-7.4205-2.45c-1.4917 0.02186-2.072-0.06445-2.0295-1.7275 0.00524-1.5258-0.13158-2.3285 1.723-2.2725 5.5801 0.23384 7.964-2.492 7.727-2.45v8.9z" fill="currentColor"></path><path d="m22.024 11.62c0.00399-0.58801-0.05448-1.0153-0.74975-1.0361-0.41509-0.00662-0.82816 0.057395-1.2409 0.094325-0.33033 0.040455-0.73566 0.076976-1.0072 0.28268-0.28398 0.21724-0.23153 0.59429-0.23733 0.9112-0.0015854 0.30307-0.0045853 0.60983 0.27663 0.79666 0.23484 0.15349 0.52158 0.19534 0.7942 0.23343 0.23915 0.02956 0.48002 0.05101 0.71976 0.07523 0.48243 0.03148 1.2248 0.19557 1.394-0.41829 0.0757-0.30577 0.04467-0.627 0.05067-0.93912z" fill="currentColor"></path><path d="m17.348 5.7962c0.042171 0.25853 0.19707 0.48146 0.30883 0.71387 0.28865 0.62708 0.76754 0.52952 1.3216 0.33695 0.29707-0.1074 0.5898-0.22819 0.88354-0.34427 1.2431-0.47478 0.99431-0.8753 0.46485-1.8723-0.42612-0.90268-0.91649-0.67014-1.6207-0.2097-0.32028 0.21007-0.65168 0.40646-0.95187 0.64525-0.21815 0.17815-0.44959 0.42625-0.40623 0.73022z" fill="currentColor"></path><path d="m20.756 17.801c-0.08779-0.41834-0.59472-0.57-0.94009-0.72238-0.31748-0.12454-0.63252-0.2579-0.95618-0.36584-0.27393-0.083771-0.59373-0.17244-0.86319-0.031395-0.21247 0.11853-0.30992 0.35702-0.4191 0.56205-0.12688 0.25243-0.31107 0.53775-0.19892 0.82794 0.1101 0.27652 0.36419 0.46004 0.59732 0.62904 0.18414 0.12824 0.3747 0.24849 0.56281 0.37079 0.15333 0.0986 0.3065 0.19968 0.46418 0.29127 0.21755 0.12307 0.46707 0.25848 0.72501 0.21843 0.34543-0.06224 0.50617-0.44433 0.6571-0.72156 0.07714-0.15037 0.15704-0.30255 0.23064-0.4547 0.08692-0.18674 0.17446-0.39353 0.14043-0.60364z" fill="currentColor"></path></svg>'; // 填入 #a 对应的 SVG 图标
                            break;
                        case 'c':
                            icon = '<svg type="c" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="0" stroke-linecap="round" stroke-linejoin="round" version="1.1" aria-hidden="true" class=""><path d="m6.825 4.8749c1.8175-0.03033 2.3249 0.02869 2.25 2.0152 0.01496 1.139 0.01338 1.984-1.3875 1.9798-1.6108-0.01491-2.7285 0.30288-2.6124-1.796-0.019-1.5193-0.04171-2.2697 1.7499-2.1989zm0-2c-2.5847-0.10689-3.8882 1.4181-3.7496 3.8782-0.058825 1.6262 0.20934 2.9456 1.5713 3.7018 0.98591 0.49526 1.6843 0.40204 2.4713 0.42016 0.661-0.00557 1.2079 0.02014 1.9275-0.21866 1.051-0.35295 1.7794-1.2693 1.9533-2.3675 0.08948-0.54803 0.07327-0.95095 0.0762-1.3975-0.00196-0.42752 0.01114-0.8053-0.05632-1.306-0.24162-1.9408-1.9089-2.8188-3.6634-2.7097-0.17686-7.9441e-4 -0.35349-2.3937e-4 -0.53038-7.7934e-4z" fill="currentColor"></path><path d="m17.075 8.6749c1.8175-0.03034 2.3249 0.02868 2.25 2.0152 0.01495 1.139 0.01338 1.984-1.3875 1.9797-1.6108-0.01491-2.7285 0.30288-2.6124-1.796-0.01899-1.5193-0.04171-2.2697 1.7499-2.1989zm0-2c-2.5847-0.10689-3.8882 1.4181-3.7496 3.8782-0.05882 1.6262 0.20933 2.9457 1.5713 3.7017 0.98593 0.49528 1.6843 0.40205 2.4713 0.42017 0.66099-0.00556 1.2079 0.02015 1.9275-0.21865 1.051-0.35295 1.7794-1.2693 1.9533-2.3675 0.08949-0.54803 0.07328-0.95095 0.07621-1.3975-0.00197-0.42839 0.0112-0.80698-0.05673-1.3089-0.24288-1.9391-1.9097-2.8158-3.663-2.7068-0.17688-7.9346e-4 -0.35351-2.388e-4 -0.5304-7.7896e-4z" fill="currentColor"></path><path d="m8.4749 15.525c1.8175-0.03033 2.3249 0.02868 2.25 2.0152 0.01496 1.139 0.01338 1.984-1.3875 1.9797-1.6108-0.01491-2.7285 0.30288-2.6124-1.796-0.01899-1.5193-0.04172-2.2697 1.7499-2.1989zm0-2c-2.5847-0.10689-3.8882 1.4181-3.7496 3.8782-0.058825 1.6262 0.20934 2.9456 1.5713 3.7018 0.98591 0.49526 1.6843 0.40203 2.4713 0.42016 0.66099-0.00557 1.2079 0.02014 1.9276-0.21866 1.051-0.35294 1.7794-1.2693 1.9533-2.3675 0.08949-0.54803 0.07328-0.95095 0.07621-1.3975-0.00197-0.42753 0.01113-0.80529-0.05633-1.306-0.24162-1.9408-1.9089-2.8188-3.6634-2.7097-0.17688-7.9346e-4 -0.35351-2.4262e-4 -0.5304-7.8736e-4z" fill="currentColor"></path></svg>'; // 填入 #c 对应的 SVG 图标
                            break;
                    }
                    // 创建 <span> 包裹图标和附加信息
                    var iconSpan = $('<span>', { class: 'icon' }).html(`
                        <a href="#${id}" class: 'toc-link evoldown_toc_link'>
                            ${icon}
                            <p name="label">${id}</p>
                        </a>
                    `);

                    // 创建 <ol> 容器,设置与标题相同的缩进
                    var tocIconList = $('<ol>', { 
                        class: 'toc-list evoldown ', 
                        type: type,
                    });
                    tocIconList.append(iconSpan);
                    // 将 <ol> 添加到当前 TOC 项
                    tocListItem.append(tocIconList);
                }
            });
            // 点击箭头切换展开/隐藏
            tocItemWrapper.find('.arrow-icon').click(function (e) {
                e.stopPropagation(); // 阻止事件冒泡
                var $arrow = $(this);
                var $parentDiv = $arrow.closest('.toc-item-wrapper'); // 获取箭头所在的父级 <div>
                var $nextLists =  $parentDiv.siblings('ol.toc-list'); // 获取与父级 <div> 同级的 <ol>
                // 判断箭头当前的旋转状态
                if ($arrow.css('transform') === 'matrix(1, 0, 0, 1, 0, 0)') { // rotate(0deg) 表示箭头指向下
                    // 隐藏逻辑
                    $arrow.css('transform', 'rotate(90deg)'); // 将箭头旋转为向左
                    $nextLists.css('display', 'none'); // 隐藏内容
                } else {
                    // 展开逻辑
                    $arrow.css('transform', 'rotate(0deg)'); // 将箭头旋转为向下
                    $nextLists.css('display', 'block'); // 显示内容
                }
            });
            // 将 TOC 项添加到 TOC 容器
            $('#toc-content').append(tocList);
        });

结果展示

渐构样式


文章作者: Hkini
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hkini !
评论
  目录