mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
feat: add support optional icon for file-tree and code-tabs (#216)
* feat(theme)!: migrate `plugin-markdown-hint` * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * fix(theme): improve `home-blog` styles in mobile, close #210 * chore: tweak * chore: tweak * chore: tweak * feat: add support optional icon for `file-tree` and `code-tabs` * chore: tweak * chore: tweak * chore: tweak * chore: tweak
This commit is contained in:
parent
49672724eb
commit
ca21d1b8cb
@ -38,6 +38,8 @@ export const themeConfig = defineNoteConfig({
|
||||
'阅读统计',
|
||||
'markdown增强',
|
||||
'markdownPower',
|
||||
'markdownImage',
|
||||
'markdownMath',
|
||||
'水印',
|
||||
],
|
||||
},
|
||||
|
||||
@ -20,10 +20,8 @@ export const theme: Theme = plumeTheme({
|
||||
imageSize: 'all',
|
||||
pdf: true,
|
||||
caniuse: true,
|
||||
plot: true,
|
||||
bilibili: true,
|
||||
youtube: true,
|
||||
icons: true,
|
||||
codepen: true,
|
||||
replit: true,
|
||||
codeSandbox: true,
|
||||
|
||||
@ -6,7 +6,6 @@ permalink: /article/enx7c9s/
|
||||
tags:
|
||||
- 预览
|
||||
- 标签
|
||||
sticky: true
|
||||
---
|
||||
|
||||
这是一篇 示例文章。
|
||||
|
||||
72
docs/3.更新说明/102-103.md
Normal file
72
docs/3.更新说明/102-103.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
title: 1.0.0-rc.102 至 rc.103 更新说明
|
||||
createTime: 2024/09/24 23:45:49
|
||||
permalink: /article/6pa64b1n/
|
||||
sticky: 3
|
||||
---
|
||||
|
||||
这两个版本做了一些 破坏性的更新,主要围绕以下两个方面:
|
||||
|
||||
- 适配 [Vuepress Guidelines](https://ecosystem.vuejs.press/zh/themes/guidelines.html)
|
||||
- 更新 vuepress-plugin-md-enhance 插件,并迁移其中的部分功能,改用 VuePress 官方插件
|
||||
|
||||
## 适配 VuePress Guidelines
|
||||
|
||||
VuePress 推出了 [主题开发指南](https://ecosystem.vuejs.press/zh/themes/guidelines.html)。
|
||||
|
||||
这一举措旨在规范化主题开发流程,并提出了主题开发过程中需要遵守的几个约定,这包括:
|
||||
|
||||
- 约定 CSS 变量命名规范,并约束 主要 CSS 变量的命名,如 `--vp-c-accent`,`--vp-c-text` 等。
|
||||
- 约定 主要的 HTML 元素容器应添加指定的 属性名,如 `vp-content`, `vp-navbar` 等。
|
||||
- 约定 双主题模式应使用 `[data-theme="light"]` 和 `[data-theme="dark"]` 来区分。
|
||||
|
||||
围绕这几个约定,可以使得 VuePress 的 开发者们,可以很方便的 开发出 更具通用性的 主题和插件。
|
||||
|
||||
`plume` 主题也同样适配了这些约定:
|
||||
|
||||
- **CSS 变量命名的变更** 和 **HTML 元素添加属性**,对于用户是无感知的,您无需关注这方面是否会有影响。
|
||||
|
||||
- **双主题模式**,对于有自定义主题需求的用户而言,如果您有重新定义深色模式下的样式,则需要做出一些调整:
|
||||
|
||||
在 CSS 中的 `.dark` 类应替换为 `[data-theme="dark"]`,请不用担心替换会带来额外的副作用,它们在 CSS 中的
|
||||
优先级是相同的,您可以安全的执行替换操作。
|
||||
|
||||
## vuepress-plugin-md-enhance 插件迁移
|
||||
|
||||
[vuepress-plugin-md-enhance](https://plugin-md-enhance.vuejs.press/zh/) 提供了非常多的功能支持,但与之带来的困难是,
|
||||
它变得越来越臃肿,变得难以维护了。
|
||||
|
||||
我在 [#4130](https://github.com/vuepress-theme-hope/vuepress-theme-hope/issues/4130) 中提出了拆分迁移的计划。
|
||||
因此从 `@2.0.0-rc.53` 版本开始,逐步开始拆分迁移的计划。
|
||||
|
||||
截止到 `@2.0.0-rc.54` 版本,已经拆分出了以下插件:
|
||||
|
||||
- [@vuepress/plugin-markdown-hint](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-hint.html)
|
||||
- [@vuepress/plugin-markdown-image](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-image.html)
|
||||
- [@vuepress/plugin-markdown-math](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-math.html)
|
||||
- [@vuepress/plugin-markdown-tab](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-tab.html)
|
||||
|
||||
当前主题也将 vuepress-plugin-md-enhance 更新到 `@2.0.0-rc.54` 版本,因此,也重新接入了上述的插件。
|
||||
|
||||
- `@vuepress/plugin-markdown-hint` 提供了 提示容器 和 `github alerts` 支持,主题已内置了该插件,对于该插件的迁移,
|
||||
用户是无需做任何修改的,您可以继续使用这些功能。
|
||||
|
||||
- `@vuepress/plugin-markdown-image` 提供了图片支持,主题已内置了该插件,但不启用该插件的默认功能,
|
||||
因此,如果您使用了如 `plugins.mdEnhance.imgSize` 配置项,您需要通过`plugins.markdownImage` 重新进行配置。
|
||||
|
||||
- `@vuepress/plugin-markdown-math` 提供了数学公式支持,主题已内置了该插件,并默认启用了 `katex` 支持。
|
||||
|
||||
- `@vuepress/plugin-markdown-tab` 提供了 Tab 容器 和 代码分组支持,主题重写了插件部分内容,对 `code-tabs` 容器
|
||||
做了一些调整,支持在 代码分组标题中显示 相关联的图标。
|
||||
|
||||
## 其它更新
|
||||
|
||||
- **文件树** 现在支持 不同的图标方案,可在 `:::file-tree` 后跟随 `:simple-icon` / `:colored-icon` 切换。
|
||||
|
||||
默认为 colored-icon,如果切换为 simple-icon,则不再根据 文件夹名和文件扩展名匹配不同的图标,仅显示默认的
|
||||
文件夹图标和文件图标。
|
||||
|
||||
- **代码块分组** 的标题现在支持显示 图标。当作为 文件名时,与 **文件树** 采用相同的图标解析规则,还额外支持
|
||||
不同的技术、框架、语言的名称图标。
|
||||
|
||||
- 优化了 容器、任务列表、脚注、等的样式。
|
||||
@ -1,9 +1,7 @@
|
||||
---
|
||||
title: 1.0.0-rc.73 至 rc.77 更新说明
|
||||
author: pengzhanbo
|
||||
createTime: 2024/07/11 09:18:48
|
||||
permalink: /article/5vjshyi9/
|
||||
sticky: 3
|
||||
---
|
||||
|
||||
近期的这几个版本主要围绕 **实现单独的主题配置文件** ,监听并支持热更新。
|
||||
|
||||
40
docs/notes/theme/config/plugins/markdownImage.md
Normal file
40
docs/notes/theme/config/plugins/markdownImage.md
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
title: Markdown Image
|
||||
createTime: 2024/09/24 12:06:28
|
||||
permalink: /config/plugins/markdown-image/
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
为 Markdown 图像添加附加功能。
|
||||
|
||||
关联插件:[@vuepress/plugin-markdown-image](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-image.html)
|
||||
|
||||
## 配置
|
||||
|
||||
插件默认不启用任何功能,你需要手动开启它们。
|
||||
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownImage: {
|
||||
// 启用 figure
|
||||
// figure: true,
|
||||
|
||||
// 启用图片懒加载
|
||||
// lazyload: true,
|
||||
|
||||
// 启用图片标记
|
||||
// mark: true,
|
||||
|
||||
// 启用图片大小
|
||||
// size: true,
|
||||
}
|
||||
}
|
||||
}),
|
||||
})
|
||||
```
|
||||
32
docs/notes/theme/config/plugins/markdownMath.md
Normal file
32
docs/notes/theme/config/plugins/markdownMath.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Markdown Math
|
||||
createTime: 2024/09/24 13:20:41
|
||||
permalink: /config/plugins/markdown-math/
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
为 Markdown 添加数学支持。
|
||||
|
||||
关联插件:[@vuepress/plugin-markdown-math](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-math.html)
|
||||
|
||||
此插件允许你使用 mathjax 或 katex 在 Markdown 中渲染 $\TeX$ 内容。
|
||||
|
||||
## 配置
|
||||
|
||||
插件默认启用 `katex`。
|
||||
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownMath: {
|
||||
type: 'katex',
|
||||
}
|
||||
}
|
||||
}),
|
||||
})
|
||||
```
|
||||
@ -1,13 +1,12 @@
|
||||
---
|
||||
title: Markdown Power
|
||||
author: pengzhanbo
|
||||
createTime: 2024/04/04 06:56:33
|
||||
permalink: /config/plugin/markdown-power/
|
||||
permalink: /config/plugins/markdown-power/
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
提供 Markdown 增强功能。
|
||||
为 主题 提供 Markdown 增强功能。
|
||||
|
||||
关联插件: [@vuepress-plume/plugin-md-power](https://github.com/pengzhanbo/vuepress-theme-plume/tree/main/plugins/plugin-md-power)
|
||||
|
||||
@ -23,9 +22,12 @@ export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownPower: {
|
||||
// 默认不启用任何功能,你需要手动开启它们
|
||||
fileTree: true, // :::file-tree 文件树容器
|
||||
plot: true, // !!plot!! 隐秘文本
|
||||
icons: true, // :[collect:name]: 内联 iconify 图标
|
||||
|
||||
// 默认不启用以下功能,你需要手动开启它们
|
||||
// pdf: true, // @[pdf](url) 嵌入 PDF 文件
|
||||
// icons: true, // :[collect:name]: 内联 iconify 图标
|
||||
// bilibili: true, // @[bilibili](bvid) 嵌入 bilibili 视频
|
||||
// youtube: true, // @[youtube](id) 嵌入 youtube 视频
|
||||
// codepen: true, // @[codepen](user/slash) 嵌入 codepen
|
||||
@ -34,8 +36,6 @@ export default defineUserConfig({
|
||||
// jsfiddle: true, // @[jsfiddle](id) 嵌入 jsfiddle
|
||||
// caniuse: true, // @[caniuse](feature) 嵌入 caniuse
|
||||
// repl: true, // :::go-repl :::kotlin-repl :::rust-repl
|
||||
// plot: true, // !!plot!! 隐秘文本
|
||||
// fileTree: true, // :::file-tree 文件树容器
|
||||
|
||||
// imageSize: true, // 在构建阶段为 图片添加 width/height 属性
|
||||
}
|
||||
|
||||
@ -21,28 +21,17 @@ export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownEnhance: {
|
||||
hint: true, // 提示容器
|
||||
codetabs: true, // 代码组
|
||||
tabs: true, // 选项卡
|
||||
align: true, // 对齐容器
|
||||
mark: true, // 标记语法
|
||||
tasklist: true, // 任务列表语法
|
||||
attrs: true, // 属性语法
|
||||
sup: true, // 上标语法
|
||||
sub: true, // 下标语法
|
||||
alert: true, // GFM 通知语法
|
||||
footnote: true, // 注脚语法
|
||||
katex: true, // 数学公式
|
||||
|
||||
// 以下可选项在 主题中默认不启用,
|
||||
// 请在主题中自行配置
|
||||
// include: true, // Markdown 导入支持
|
||||
// figure: true, // 启用图片 Figure 支持
|
||||
// imgLazyload: true, // 使用原生方式懒加载页面图片
|
||||
// imgMark: true, // 浅色/深色 图片标记
|
||||
// imgSize: true, // 图片尺寸支持
|
||||
// obsidianImgSize: true, // obsidian 图片尺寸支持
|
||||
// mathjax: true, // Math Jax 数学公式 语法支持
|
||||
// chart: true, // 图表支持
|
||||
// echarts: true, // ECharts 图表支持
|
||||
// flowchart: true, // 流程图支持
|
||||
@ -53,7 +42,6 @@ export default defineUserConfig({
|
||||
// vuePlayground: true, // Vue 交互演示
|
||||
// sandpack: true, // sandpack 交互演示
|
||||
// demo: true, // 代码案例
|
||||
// revealJs: true, // 幻灯片支持
|
||||
}
|
||||
}
|
||||
}),
|
||||
@ -68,3 +56,12 @@ export default defineUserConfig({
|
||||
主题还未完全对 该插件提供的 所有 增强功能 进行 样式上的适配。
|
||||
如果你在使用过程中遇到样式上的问题,可以在 [issue](https://github.com/pengzhanbo/vuepress-theme-plume/issues) 里提出。
|
||||
:::
|
||||
|
||||
::: warning
|
||||
该插件从 `2.0.0-rc.53` 开始,移除了部分功能。主题从 `1.0.0-rc.103` 版本开始,适配至最新版。
|
||||
由此带来的影响是,`plugins.mdEnhance` 中 `imgSize`/`imgLazyload`/`imgMark`/`figure`/`obsidianImgSize`/`katex`/`mathjax`/`tabs`/`code-tabs`/`hint`/`alerts`弃用。
|
||||
|
||||
- `imgSize`/`imgLazyload`/`imgMark`/`figure`/`obsidianImgSize` 所实现的功能,您可以使用 `plugins.markdownImage` 重新进行配置。
|
||||
- `katex` / `mathjax` 所实现的功能,您可以使用 `plugins.markdownMath` 进行配置。
|
||||
- `tabs` / `code-tabs` / `hint` / `alerts` 已变更为 主题的内置功能,您无需额外的配置。
|
||||
:::
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
---
|
||||
title: 阅读统计
|
||||
author: pengzhanbo
|
||||
createTime: 2024/03/06 15:23:39
|
||||
permalink: /config/plugins/reading-time/
|
||||
---
|
||||
|
||||
@ -88,11 +88,13 @@ export default defineUserConfig({
|
||||
你可以直接在 [VuePress 配置文件](#vuepress-配置文件) 相同的路径下创建一个 `plume.config.js` 文件,这样就可以在该文件中进行主题配置。
|
||||
你也可以使用 TypeScript 来创建一个 `plume.config.ts` 文件,以获得更好的类型提示。
|
||||
|
||||
```txt :no-line-numbers
|
||||
{sourceDir}/.vuepress/
|
||||
├── config.ts
|
||||
└── plume.config.ts // [!code ++]
|
||||
```
|
||||
::: file-tree
|
||||
|
||||
- docs
|
||||
- .vuepress
|
||||
- config.ts
|
||||
- **plume.config.ts**
|
||||
:::
|
||||
|
||||
::: code-tabs
|
||||
@tab plume.config.ts
|
||||
|
||||
@ -178,6 +178,7 @@ tags:
|
||||
- 通过加粗文件名或目录名来突出显示,例如 `**README.md**`
|
||||
- 通过在名称后添加更多文本来为文件或目录添加注释
|
||||
- 使用 `...` 或 `…` 作为名称来添加占位符文件和目录。
|
||||
- 在 `:::file-tree` 后添加 `:simple-icon` 或 添加 `:colored-icon` 可以切换为简单图标或彩色图标,默认为彩色图标。
|
||||
|
||||
**输入:**
|
||||
|
||||
@ -233,6 +234,60 @@ tags:
|
||||
- …
|
||||
:::
|
||||
|
||||
### 使用简单图标
|
||||
|
||||
**输入:**
|
||||
|
||||
```md
|
||||
::: file-tree:simple-icon
|
||||
- docs
|
||||
- .vuepress
|
||||
- config.ts
|
||||
- page1.md
|
||||
- README.md
|
||||
- package.json
|
||||
:::
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
::: file-tree:simple-icon
|
||||
|
||||
- docs
|
||||
- .vuepress
|
||||
- config.ts
|
||||
- page1.md
|
||||
- README.md
|
||||
- package.json
|
||||
:::
|
||||
|
||||
### 配置
|
||||
|
||||
你可以在 `plugins.mdPower.fileTree` 选项中配置 文件树的图标默认类型:
|
||||
|
||||
```ts
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownPower: {
|
||||
fileTree: {
|
||||
icon: 'simple', // 'simple' | 'colored'
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
::: tip 担心彩色图标会影响构建包体积?
|
||||
您无需担心,文件树的彩色图标 也是从 `iconify` 解析获取,推荐您在本地安装 `@iconify/json` 项目,
|
||||
主题会自动将 `@iconify/json` 中的图标数据解析为本地图标资源,即使您在不同的页面
|
||||
多次使用,这包括了 导航栏、侧边栏、图标组件等,相同图标仅会存在一份资源!
|
||||
|
||||
每个彩色图标的大小约在 `1kb ~ 2kb` 之间,即使您的文件树非常夸张的使用了 100+ 不同的图标,对最终的构建包体积影响
|
||||
也不会很大。
|
||||
:::
|
||||
|
||||
## 选项组
|
||||
|
||||
在 Markdown 中支持选项卡。
|
||||
@ -513,34 +568,13 @@ interface PlotOptions {
|
||||
|
||||
## iconify 图标
|
||||
|
||||
在 Markdown 文件中使用 [iconify](https://iconify.design/) 的图标。 主题一方面提供了
|
||||
[`<Icon />`](../功能/组件.md#图标) 组件来支持在 markdown 中使用图标,
|
||||
在 Markdown 文件中使用 [iconify](https://iconify.design/) 的图标。
|
||||
|
||||
一方面,主题还提供了另一种可选的方式,以更简单的方式,在 Markdown 中使用图标,并且将 图标资源编译到
|
||||
本地静态资源中。
|
||||
主题一方面提供了[`<Icon />`](../功能/组件.md#图标) 组件来支持在 markdown 中使用图标;
|
||||
另一方面,主题还提供了图标的 markdown 语法,以更简单的方式,在 Markdown 中使用图标。
|
||||
|
||||
### 配置
|
||||
|
||||
该功能默认不启用,你需要在 `theme` 配置中启用。
|
||||
|
||||
::: code-tabs
|
||||
@tab .vuepress/config.ts
|
||||
|
||||
```ts
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownPower: {
|
||||
icons: true,
|
||||
},
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
同时,该功能还需要你额外安装 `@iconify/json` 依赖。
|
||||
为了更好的使用该功能,主题推荐你安装 `@iconify/json` 依赖。主题会自动解析 `@iconify/json` 中的图标数据,
|
||||
将有使用的图标打包为本地资源,以获得更好的访问体验。
|
||||
|
||||
::: code-tabs
|
||||
@tab pnpm
|
||||
|
||||
@ -70,3 +70,193 @@ export default config
|
||||
:::
|
||||
|
||||
你还可以通过 `@tab:active` 选择其中一个代码块作为默认显示的代码块。
|
||||
|
||||
**输入:**
|
||||
|
||||
````md
|
||||
::: code-tabs
|
||||
@tab config.js
|
||||
```js
|
||||
/**
|
||||
* @type {import('vuepress').UserConfig}
|
||||
*/
|
||||
const config = {
|
||||
// ..
|
||||
}
|
||||
|
||||
export default config
|
||||
```
|
||||
|
||||
@tab:active config.ts <!-- [!code hl] -->
|
||||
```ts
|
||||
import type { UserConfig } from 'vuepress'
|
||||
|
||||
const config: UserConfig = {
|
||||
// ..
|
||||
}
|
||||
|
||||
export default config
|
||||
```
|
||||
:::
|
||||
````
|
||||
|
||||
**输出:**
|
||||
|
||||
::: code-tabs
|
||||
@tab config.js
|
||||
|
||||
```js
|
||||
/**
|
||||
* @type {import('vuepress').UserConfig}
|
||||
*/
|
||||
const config = {
|
||||
// ..
|
||||
}
|
||||
|
||||
export default config
|
||||
```
|
||||
|
||||
@tab:active config.ts
|
||||
|
||||
```ts
|
||||
import type { UserConfig } from 'vuepress'
|
||||
|
||||
const config: UserConfig = {
|
||||
// ..
|
||||
}
|
||||
|
||||
export default config
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## 分组标题图标 <Badge type="tip" text="v1.0.0-rc.103 +" />
|
||||
|
||||
主题支持在 代码块分组的组标题上显示图标。 图标根据 标题,即 `@tab 标题` 进行解析适配不同的图标
|
||||
|
||||
默认解析规则与 [文件树](../markdown/进阶.md#文件树) 一致。
|
||||
|
||||
如, `pnpm / yarn / npm` 分组图标:
|
||||
|
||||
**输入:**
|
||||
|
||||
````md
|
||||
::: code-tabs
|
||||
@tab pnpm
|
||||
|
||||
```sh
|
||||
pnpm i
|
||||
```
|
||||
|
||||
@tab yarn
|
||||
|
||||
```sh
|
||||
yarn
|
||||
```
|
||||
|
||||
@tab npm
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
:::
|
||||
````
|
||||
|
||||
**输出:**
|
||||
|
||||
::: code-tabs
|
||||
@tab pnpm
|
||||
|
||||
```sh
|
||||
pnpm i
|
||||
```
|
||||
|
||||
@tab yarn
|
||||
|
||||
```sh
|
||||
yarn
|
||||
```
|
||||
|
||||
@tab npm
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
主题默认适配了 前端主流的一些技术:
|
||||
|
||||
- 运行环境,如: `NodeJs / Deno / Bun`
|
||||
- 包管理器,如: `pnpm / yarn / npm`
|
||||
- 库、框架,如: `vue / react / angular / svelte / solid / Next / Nuxt` 等
|
||||
|
||||
还包括一些主流的语言,如: `TypeScript / JavaScript / C / C++ / Java / Python / Rust / Kotlin / Swift / Go` 等
|
||||
|
||||
::: info
|
||||
如果您发现您所使用的 库、框架、语言等未能正确显示图标,可以提出 [issue](https://github.com/pengzhanbo/vuepress-theme-plume/issues/new) 告诉我,我会尽量添加相关图标。
|
||||
:::
|
||||
|
||||
### 配置
|
||||
|
||||
您可以通过 `plugins.mdPower.codeTabs` 控制分组图标的行为:
|
||||
|
||||
```ts
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownPower: {
|
||||
codeTabs: {
|
||||
icon: true, // CodeTabsOptions
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```ts
|
||||
export interface CodeTabsOptions {
|
||||
icon?: boolean | { named?: false | string[], extensions?: false | string[] }
|
||||
}
|
||||
```
|
||||
|
||||
- `true`: 使用默认解析规则显示图标
|
||||
- `false`: 不显示图标
|
||||
- `{ named?: false | string[], extensions?: false | string[] }`:
|
||||
- `named`: 表示 库/框架/语言 名称,严格匹配 `@tab 标题` 中的 `标题` 字段,如 `pnpm`、`yarn`、`npm` 等,如果设置为 `false` 则不显示图标,如果为 空数组,则使用默认匹配规则
|
||||
- `extensions`: 表示 文件扩展名,匹配 `@tab 标题` 中的 `标题` 字段是否包含扩展名,如 `.ts`、`.js` 等,如果设置为 `false` 则不显示图标,如果为 空数组,则使用默认匹配规则
|
||||
|
||||
请注意, `named` 和 `extensions` 数组中的元素必须是 `string` 类型,且严格区分大小写。
|
||||
|
||||
举一个例子,如果您是一个前端开发,且仅想在 `pnpm/yarn/npm` 分组时显示图标,其它分组时不显示图标,
|
||||
那么可以进行如下配置:
|
||||
|
||||
```ts
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
plugins: {
|
||||
markdownPower: {
|
||||
codeTabs: {
|
||||
icon: {
|
||||
named: ['pnpm', 'yarn', 'npm'], // [!code ++:2]
|
||||
extensions: false,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
你可以灵活地配置图标显示规则。
|
||||
|
||||
::: tip 担心图标会影响构建包体积?
|
||||
您无需担心,代码块分组的图标 也是从 `iconify` 解析获取,推荐您在本地安装 `@iconify/json` 项目,
|
||||
主题会自动将 `@iconify/json` 中的图标数据解析为本地图标资源,即使您在不同的页面
|
||||
多次使用,这包括了 导航栏、侧边栏、图标组件等,相同图标仅会存在一份资源!
|
||||
|
||||
每个彩色图标的大小约在 `1kb ~ 2kb` 之间,即使您的文件树非常夸张的使用了 100+ 不同的图标,对最终的构建包体积影响
|
||||
也不会很大。
|
||||
:::
|
||||
|
||||
@ -8,9 +8,24 @@ permalink: /guide/features/icon/
|
||||
|
||||
## 概述
|
||||
|
||||
主题支持 [iconify](https://icon-sets.iconify.design/) 的所有图标,并提供了不同的方式来使用它们。
|
||||
主题支持 [iconify](https://icon-sets.iconify.design/) 的所有图标,并提供了不同的方式来使用它们:
|
||||
|
||||
## 组件
|
||||
- [导航栏图标](../../config/导航栏配置.md#配置)
|
||||
- [侧边栏图标](../../guide/知识笔记.md#侧边栏图标)
|
||||
- [图标组件](#图标组件)
|
||||
- [图标语法糖](../../guide/markdown/进阶.md#iconify-图标)
|
||||
- [文件树图标](../../guide/markdown/进阶.md#文件树)
|
||||
- [代码分组标题图标](../代码/代码组.md#分组标题图标)
|
||||
|
||||
::: tip 主题对图标的优化
|
||||
上述的不同的使用图标的方式,主题在内部都采取了相同的解析策略,即使您在不同的位置使用了相同的图标,
|
||||
也不会重复加载相同的图标资源。
|
||||
|
||||
图标默认是通过远程请求加载,主题也非常建议您在本地项目中安装 `@iconify/json` 包,以便主题能够将图标全部解析为本地资源,
|
||||
这可以有效的提高页面的访问体验。
|
||||
:::
|
||||
|
||||
## 图标组件
|
||||
|
||||
通过 `<Icon />` 组件来使用图标。
|
||||
|
||||
|
||||
@ -281,3 +281,28 @@ cd open-source # 进入 D: 分区下的 open-source 目录
|
||||
- ### 完成
|
||||
|
||||
::::
|
||||
|
||||
## 更新主题
|
||||
|
||||
您可以直接在项目中运行以下命令检查是否有可用的更新:
|
||||
|
||||
::: code-tabs
|
||||
@tab pnpm
|
||||
|
||||
```sh
|
||||
pnpm dlx vp-update
|
||||
```
|
||||
|
||||
@tab yarn
|
||||
|
||||
``` sh
|
||||
yarn dlx vp-update
|
||||
```
|
||||
|
||||
@tab npm
|
||||
|
||||
``` sh
|
||||
npx vp-update
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
@ -12,7 +12,7 @@ const el = ref<HTMLElement>()
|
||||
|
||||
function toggle(e: HTMLElementEventMap['click']) {
|
||||
const target = e.target as HTMLElement
|
||||
if (target.matches('.comment'))
|
||||
if (target.matches('.comment') || e.currentTarget === target)
|
||||
return
|
||||
active.value = !active.value
|
||||
}
|
||||
|
||||
@ -24,6 +24,6 @@ export async function containerPlugin(
|
||||
|
||||
if (options.fileTree) {
|
||||
// ::: file-tree
|
||||
fileTreePlugin(md)
|
||||
fileTreePlugin(md, isPlainObject(options.fileTree) ? options.fileTree : {})
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,13 +6,14 @@
|
||||
*/
|
||||
import type { PluginWithOptions } from 'markdown-it'
|
||||
import type { RuleInline } from 'markdown-it/lib/parser_inline.mjs'
|
||||
import type { IconsOptions } from '../../shared/index.js'
|
||||
|
||||
const [openTag, endTag] = [':[', ']:']
|
||||
|
||||
export const iconsPlugin: PluginWithOptions<never> = md =>
|
||||
md.inline.ruler.before('emphasis', 'iconify', createTokenizer())
|
||||
export const iconsPlugin: PluginWithOptions<IconsOptions> = (md, options = {}) =>
|
||||
md.inline.ruler.before('emphasis', 'iconify', createTokenizer(options))
|
||||
|
||||
function createTokenizer(): RuleInline {
|
||||
function createTokenizer(options: IconsOptions): RuleInline {
|
||||
return (state, silent) => {
|
||||
let found = false
|
||||
const max = state.posMax
|
||||
@ -56,8 +57,8 @@ function createTokenizer(): RuleInline {
|
||||
state.posMax = state.pos
|
||||
state.pos = start + 2
|
||||
|
||||
const [name, options = ''] = content.split(/\s+/)
|
||||
const [size, color] = options.split('/')
|
||||
const [name, opt = ''] = content.split(/\s+/)
|
||||
const [size = options.size, color = options.color] = opt.split('/')
|
||||
|
||||
const icon = state.push('vp_iconify_open', 'VPIcon', 1)
|
||||
icon.markup = openTag
|
||||
@ -65,7 +66,7 @@ function createTokenizer(): RuleInline {
|
||||
if (name)
|
||||
icon.attrSet('name', name)
|
||||
if (size)
|
||||
icon.attrSet('size', size)
|
||||
icon.attrSet('size', String(size))
|
||||
if (color)
|
||||
icon.attrSet('color', color)
|
||||
|
||||
|
||||
@ -22,12 +22,12 @@ export function inlineSyntaxPlugin(
|
||||
|
||||
if (options.icons) {
|
||||
// :[collect:name]:
|
||||
md.use(iconsPlugin)
|
||||
md.use(iconsPlugin, isPlainObject(options.icons) ? options.icons : {})
|
||||
}
|
||||
|
||||
if (
|
||||
options.plot === true
|
||||
|| (typeof options.plot === 'object' && options.plot.tag !== false)
|
||||
|| (isPlainObject(options.plot) && options.plot.tag !== false)
|
||||
) {
|
||||
// !!plot!!
|
||||
md.use(plotPlugin)
|
||||
|
||||
@ -7,7 +7,9 @@ import { imageSizePlugin } from './enhance/imageSize.js'
|
||||
import { inlineSyntaxPlugin } from './inline/index.js'
|
||||
import { prepareConfigFile } from './prepareConfigFile.js'
|
||||
|
||||
export function markdownPowerPlugin(options: MarkdownPowerPluginOptions = {}): Plugin {
|
||||
export function markdownPowerPlugin(
|
||||
options: MarkdownPowerPluginOptions = {},
|
||||
): Plugin {
|
||||
return {
|
||||
name: 'vuepress-plugin-md-power',
|
||||
|
||||
@ -19,11 +21,7 @@ export function markdownPowerPlugin(options: MarkdownPowerPluginOptions = {}): P
|
||||
|
||||
extendsBundlerOptions(bundlerOptions, app) {
|
||||
if (options.repl) {
|
||||
addViteOptimizeDepsInclude(
|
||||
bundlerOptions,
|
||||
app,
|
||||
['shiki/core', 'shiki/wasm'],
|
||||
)
|
||||
addViteOptimizeDepsInclude(bundlerOptions, app, ['shiki/core', 'shiki/wasm'])
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
3
plugins/plugin-md-power/src/shared/codeTabs.ts
Normal file
3
plugins/plugin-md-power/src/shared/codeTabs.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export interface CodeTabsOptions {
|
||||
icon?: boolean | { named?: false | string[], extensions?: false | string[] }
|
||||
}
|
||||
5
plugins/plugin-md-power/src/shared/fileTree.ts
Normal file
5
plugins/plugin-md-power/src/shared/fileTree.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export type FileTreeIconMode = 'simple' | 'colored'
|
||||
|
||||
export interface FileTreeOptions {
|
||||
icon?: FileTreeIconMode
|
||||
}
|
||||
@ -1,10 +1,4 @@
|
||||
export interface IconsOptions {
|
||||
/**
|
||||
* The prefix of the icon className
|
||||
* @default 'vp-mdi'
|
||||
*/
|
||||
prefix?: string
|
||||
|
||||
/**
|
||||
* The size of the icon
|
||||
* @default '1em'
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
export * from './caniuse.js'
|
||||
export * from './codepen.js'
|
||||
export * from './codeSandbox.js'
|
||||
export * from './codeTabs.js'
|
||||
export * from './fileTree.js'
|
||||
export * from './icons.js'
|
||||
export * from './jsfiddle.js'
|
||||
export * from './pdf.js'
|
||||
@ -8,7 +10,5 @@ export * from './plot.js'
|
||||
export * from './plugin.js'
|
||||
export * from './repl.js'
|
||||
export * from './replit.js'
|
||||
|
||||
export * from './size.js'
|
||||
|
||||
export * from './video.js'
|
||||
|
||||
@ -1,10 +1,16 @@
|
||||
import type { CanIUseOptions } from './caniuse.js'
|
||||
import type { CodeTabsOptions } from './codeTabs.js'
|
||||
import type { FileTreeOptions } from './fileTree.js'
|
||||
import type { IconsOptions } from './icons.js'
|
||||
import type { PDFOptions } from './pdf.js'
|
||||
import type { PlotOptions } from './plot.js'
|
||||
import type { ReplOptions } from './repl.js'
|
||||
|
||||
export interface MarkdownPowerPluginOptions {
|
||||
/**
|
||||
* 配置代码块分组
|
||||
*/
|
||||
codeTabs?: CodeTabsOptions
|
||||
/**
|
||||
* 是否启用 PDF 嵌入语法
|
||||
*
|
||||
@ -92,7 +98,7 @@ export interface MarkdownPowerPluginOptions {
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
fileTree?: boolean
|
||||
fileTree?: boolean | FileTreeOptions
|
||||
|
||||
/**
|
||||
* 是否启用 caniuse 嵌入语法
|
||||
|
||||
@ -5,7 +5,7 @@ import VPDocFooter from '@theme/VPDocFooter.vue'
|
||||
import VPDocMeta from '@theme/VPDocMeta.vue'
|
||||
import VPEncryptPage from '@theme/VPEncryptPage.vue'
|
||||
import VPTransitionFadeSlideY from '@theme/VPTransitionFadeSlideY.vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { computed, nextTick, ref, resolveComponent, watch } from 'vue'
|
||||
import { useRoute } from 'vuepress/client'
|
||||
import {
|
||||
useBlogPageData,
|
||||
@ -24,7 +24,7 @@ const headers = useHeaders()
|
||||
const { isPageDecrypted } = useEncrypt()
|
||||
|
||||
const hasComments = computed(() => {
|
||||
return page.value.frontmatter.comments !== false && isPageDecrypted.value
|
||||
return !!resolveComponent('CommentService') && page.value.frontmatter.comments !== false && isPageDecrypted.value
|
||||
})
|
||||
|
||||
const enableAside = computed(() => {
|
||||
@ -136,6 +136,7 @@ watch(
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<slot name="doc-bottom" />
|
||||
</div>
|
||||
</VPTransitionFadeSlideY>
|
||||
</template>
|
||||
|
||||
@ -4,7 +4,7 @@ import VPLink from '@theme/VPLink.vue'
|
||||
|
||||
defineProps<{
|
||||
href: string
|
||||
title: string
|
||||
title?: string
|
||||
icon?: string | { svg: string }
|
||||
description?: string
|
||||
}>()
|
||||
@ -13,7 +13,7 @@ defineProps<{
|
||||
<template>
|
||||
<div class="vp-link-card">
|
||||
<span class="body">
|
||||
<VPLink :href="href" no-icon class="link">
|
||||
<VPLink :href="href" no-icon class="link no-icon">
|
||||
<slot name="title">
|
||||
<VPIcon v-if="icon" :name="icon" />
|
||||
<span v-if="title" v-html="title" />
|
||||
|
||||
@ -159,7 +159,7 @@ export function resolveHeaders(headers: MenuItem[], range?: ThemeOutline): MenuI
|
||||
return ret
|
||||
}
|
||||
|
||||
export function useActiveAnchor(container: Ref<HTMLElement>, marker: Ref<HTMLElement>): void {
|
||||
export function useActiveAnchor(container: Ref<HTMLElement | null>, marker: Ref<HTMLElement | null>): void {
|
||||
const { isAsideEnabled } = useAside()
|
||||
|
||||
let prevActiveLink: HTMLAnchorElement | null = null
|
||||
@ -219,21 +219,25 @@ export function useActiveAnchor(container: Ref<HTMLElement>, marker: Ref<HTMLEle
|
||||
prevActiveLink = null
|
||||
}
|
||||
else {
|
||||
prevActiveLink = container.value.querySelector(
|
||||
prevActiveLink = container.value?.querySelector(
|
||||
`a[href="${decodeURIComponent(hash)}"]`,
|
||||
)
|
||||
) ?? null
|
||||
}
|
||||
|
||||
const activeLink = prevActiveLink
|
||||
|
||||
if (activeLink) {
|
||||
activeLink.classList.add('active')
|
||||
marker.value.style.top = `${activeLink.offsetTop + 39}px`
|
||||
marker.value.style.opacity = '1'
|
||||
if (marker.value) {
|
||||
marker.value.style.top = `${activeLink.offsetTop + 39}px`
|
||||
marker.value.style.opacity = '1'
|
||||
}
|
||||
}
|
||||
else {
|
||||
marker.value.style.top = '33px'
|
||||
marker.value.style.opacity = '0'
|
||||
if (marker.value) {
|
||||
marker.value.style.top = '33px'
|
||||
marker.value.style.opacity = '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user