文章摘要
加载中...|
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结 投诉

写博客一般离不开标签,比如 Hexo 的 标签插件(Tag Plugins),可以在文章中快速插入特定内容的插件。但是,如你所见,本站是基于 VitePress 的,它支持的插件可以说基本上没有,所以需要自定义。

遂去查看文档,在 Markdown 扩展 一节中有这么一段:

VitePress 使用 markdown-it 作为 Markdown 渲染器。上面提到的很多扩展功能都是通过自定义插件实现的。可以使用 .vitepress/config.js 中的 markdown 选项来进一步自定义 markdown-it 实例。

那么就好办了,去找找如何在 markdown-it 中自定义标签就行了。但是问题又出现了,相关的教程几乎没有 😢,没办法,只能在 Github 以及 StackOverflow 的相关问题中慢慢摸索,再结合一下 ChatGPT,也算是实现了一些标签。

基础配置

首先,得先确保在 .vitepress/config.js 中添加了 markdown 配置项:

js
export default {
  markdown: {
    // 一些基础配置...
    // 在这里使用相关插件和自定义标签
    config: (md) => {
      // ...
    },
  },
};

安装插件

在基础配置完成后,得先安装 markdown-it-container 插件,它允许你自定义容器标签。

bash
pnpm add markdown-it-container -D

然后在配置文件中引入它:

js
import container from "markdown-it-container";

export default {
  markdown: {
    // ...
    config: (md) => {
      // 一个简单的示例
      md.use(container, "demo");
    },
  },
};

自定义标签

准备工作完成后,就可以开始自定义标签了。

首先,比如你想实现一个按钮标签,那么你得先在 md 文档中这样写:

md
::: button
这是一个按钮
:::

然后,你得在配置文件中这样写:

js
import container from "markdown-it-container";

export default {
  markdown: {
    config: (md) => {
      md.use(container, "button", {
        render: (tokens, idx, _options, env) => {
          const token = tokens[idx];
          if (token.nesting === 1) {
            return "<button>";
          } else {
            return "</button>";
          }
        },
      });
    },
  },
};

来详细看下这个配置文件都做了些什么:

  1. md.use(container, "button")

    这一行是告诉 markdown-it 实例 "button" 将用作自定义容器的名称,在 Markdown 文档中匹配所有 ::: button 形式的内容。

  2. { render: (tokens, idx, _options, env) => { ... } }

    render 属性是一个渲染函数,它定义了如何将自定义容器转换成 HTML。这个函数接受四个参数:

    • tokens 是一个 token 数组,表示 Markdown 解析器生成的标记( tokens ),表示来源的标记流。
    • idx 是当前 token 在数组中的索引。
    • _options 是可选的,表示传递给 markdown-it-container 插件的选项,这里用下划线前缀表示它是未使用的。
    • env 是关于整个 Markdown 解析环境的信息。
  3. const token = tokens[idx]

    这一步从 tokens 数组中获取当前的 token,即当前正在处理的 Markdown 部分

  4. if (token.nesting === 1)

    这条 if 语句检查 nesting 属性。在 markdown-it-container 插件中,nesting 可以是 1、-1 或 0:

    • 如果 nesting1,表示这是容器的开始标记
    • 如果 nesting-1,表示这是容器的结束标记
    • 如果 nesting0,表示这是一个不可嵌套的自闭合标记
  5. 后面配置就是将自定义元素返回,并且根据 nesting 值添加开始和结束标签。

最终,会在页面中渲染出这样的 HTML:

html
<button>这是一个按钮</button>

接下来就可以进行自定义样式等操作了。

使用参数

有些时候还想在自定义标签中使用一些参数,比如按钮的颜色、大小等。

md
::: button red
这是一个红色按钮
:::

那么配置文件应该这样写:

js
module.exports = {
  // ...
  markdown: {
    config: (md) => {
      md.use(container, "button", {
        render: (tokens, idx) => {
          const token = tokens[idx];
          if (token.nesting === 1) {
            const color = tokens[idx].info.trim().replace("button ", "");
            return `<button class="buttom ${color}">`;
          }
          return "</button>";
        },
      });
    },
  },
};

与上面的配置文件不同的是,多了这一句:

js
const color = tokens[idx].info.trim().replace("button ", "");

这一句将 button 部分从 ::: button red 中去除,这样就能得到 red 参数了,然后将 red 参数作为 class 添加到按钮中,然后就可以设置相应的样式来实现了。

结束

这就是一些最基础的配置方法了,更高级的用法还没学会,以后再更新吧。

赞赏博主
评论 隐私政策