Skip to content

Commit ba0dac3

Browse files
authored
feat(plugin-icon): support markdown syntax (#338)
1 parent f315804 commit ba0dac3

File tree

6 files changed

+156
-74
lines changed

6 files changed

+156
-74
lines changed

docs/plugins/features/icon.md

+59-27
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,43 @@ export default {
2626
}
2727
```
2828

29-
We support multiple types of icons as well:
29+
We support multiple types of icons:
3030

3131
- `iconify` (default)
3232
- `fontawesome`
3333
- `iconfont`
3434

35-
Also, images links are supported with any icon types (relative links are NOT supported).
35+
Also, you can use images links with any icon types (relative links are NOT supported).
3636

3737
If you want a new type of icon, please open an issue or submit a PR.
3838

39+
In markdown, you can use `::icon decorators... =size /color key=value complex-key="complex value"...::` to insert custom icons.
40+
41+
- A string starting with `=` will be treated as a size definition.
42+
- A string starting with `/` will be treated as a color definition.
43+
- Any string which itself is a valid html attribute will parsed, standardized and added to the icon element.
44+
- The rest part will be treated as the icon name.
45+
46+
```md
47+
::icon =16 /red:: <!-- <VPIcon class="icon" color="red" size="16px" -->
48+
49+
::icon rotate vertical-align=middle:: <!-- <VPIcon icon="icon rotate" vertical-align="middle" -->
50+
```
51+
52+
::: info Demo
53+
54+
::mdi:home /blue::
55+
::mdi:apple =2rem vertical-align=text-bottom::
56+
57+
```md
58+
::mdi:home /blue::
59+
::mdi:apple =2rem vertical-align=text-bottom::
60+
```
61+
62+
:::
63+
64+
## Icon Types
65+
3966
### Iconify
4067

4168
For full icon list, see <https://icon-sets.iconify.design/>. To use a icon, copy it's icon name of `iconify-icon` in the selector.
@@ -50,8 +77,8 @@ Additionally, iconify support the following props:
5077
If you use 1 icon set mostly, you can set the prefix to the icon set name (E.g.: `mdi:`), Then you can use the icon name without the prefix. Manually declaring a full icon name will override the prefix:
5178

5279
```md
53-
<VPIcon icon="home" /> <!-- mdi:home -->
54-
<VPIcon icon="svg-spinners:180-ring" /> <!-- svg-spinners:180-ring -->
80+
::home:: <!-- mdi:home -->
81+
::svg-spinners:180-ring:: <!-- svg-spinners:180-ring -->
5582
```
5683

5784
### Font Awesome
@@ -63,38 +90,38 @@ The `fontawesome` keyword only includes the free solid and regular icons. If you
6390
Solid icons can be used directly. if you want to use regular or brand icons, you need to add the `regular:` or `brands:` prefix to the icon name:
6491

6592
```md
66-
<VPIcon icon="home" /> <!-- fas fa-home (solid is default) -->
67-
<VPIcon icon="solid:home" /> <!-- fas fa-home -->
68-
<VPIcon icon="regular:heart" /> <!-- far fa-heart -->
69-
<VPIcon icon="brands:apple" /> <!-- fab fa-apple -->
93+
::home:: <!-- fas fa-home (solid is default) -->
94+
::solid:home:: <!-- fas fa-home -->
95+
::regular:heart:: <!-- far fa-heart -->
96+
::brands:apple:: <!-- fab fa-apple -->
7097
```
7198

7299
Besides, a three letter prefix, first letter or full class name are also supported:
73100

74101
```md
75-
<VPIcon icon="s:home" /> <!-- fas fa-home -->
76-
<VPIcon icon="fas:home" /> <!-- fas fa-home -->
77-
<VPIcon icon="fa-solid:home" /> <!-- fa-solid fa-home -->
102+
::s:home:: <!-- fas fa-home -->
103+
::fas:home:: <!-- fas fa-home -->
104+
::fa-solid:home:: <!-- fa-solid fa-home -->
78105

79-
<VPIcon icon="b:apple" /> <!-- fab fa-apple -->
80-
<VPIcon icon="fab:apple" /> <!-- fab fa-apple -->
81-
<VPIcon icon="fa-brands:apple" /> <!-- fa-brands fa-apple -->
106+
::b:apple:: <!-- fab fa-apple -->
107+
::fab:apple:: <!-- fab fa-apple -->
108+
::fa-brands:apple:: <!-- fa-brands fa-apple -->
82109

83-
<VPIcon icon="r:heart" /> <!-- far fa-heart -->
84-
<VPIcon icon="far:heart" /> <!-- far fa-heart -->
85-
<VPIcon icon="fa-regular:heart" /> <!-- fa-regular fa-heart -->
110+
::r:heart:: <!-- far fa-heart -->
111+
::far:heart:: <!-- far fa-heart -->
112+
::fa-regular:heart:: <!-- fa-regular fa-heart -->
86113
```
87114

88115
You can add other classes that fontawesome supports after the icon name and split them with a space, where `fa-` prefix is optional:
89116

90117
```md
91118
<!-- a small size icon -->
92119

93-
<VPIcon icon="home fa-sm" /> <!-- fas fa-home fa-sm -->
120+
::home fa-sm:: <!-- fas fa-home fa-sm -->
94121

95122
<!-- rotate 180deg -->
96123

97-
<VPIcon icon="home rotate-180" /> <!-- fas fa-home fa-rotate-180 -->
124+
::home rotate-180:: <!-- fas fa-home fa-rotate-180 -->
98125
```
99126

100127
See <https://docs.fontawesome.com/web/style/styling> for all available classes.
@@ -166,16 +193,13 @@ Images links are supported with any icon types (relative links are NOT supported
166193

167194
```md
168195
<!-- A full link -->
169-
<VPIcon icon="https://example.com/icon.png" />
170196

171-
<!-- icon.png should be placed in .vuepress/public folder -->
172-
<VPIcon icon="/icon.png" />
173-
```
197+
::https://example.com/icon.png::
174198

175-
## Demo
199+
<!-- icon.png should be placed in .vuepress/public folder -->
176200

177-
- <VPIcon icon="mdi:home" color="blue" />: home icon
178-
- <VPIcon icon="mdi:apple" size="2rem" vertical-align="text-bottom" />: apple icon
201+
<VPIcon icon="/icon.png" /> <!-- ::/icon.png:: is NOT supported as it will be parsed as color -->
202+
```
179203

180204
## Options
181205

@@ -248,9 +272,17 @@ Images links are supported with any icon types (relative links are NOT supported
248272
249273
Name of the icon component. If set to `null`, the plugin will not register the icon component globally.
250274
275+
### markdown
276+
277+
- Type: `boolean`
278+
- Default: `true`
279+
- Details:
280+
281+
Whether to enable icon syntax (`::icon::`) in markdown.
282+
251283
## Component Props
252284
253-
### icon
285+
### icon {#icon-prop}
254286
255287
- Type: `string`
256288
- Required: Yes

docs/zh/plugins/features/icon.md

+51-27
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,43 @@ export default {
2626
}
2727
```
2828

29-
我们还支持多种类型的图标
29+
我们支持多种类型的图标
3030

3131
- `iconify`(默认)
3232
- `fontawesome`
3333
- `iconfont`
3434

35-
另外,图标类型支持任何图像链接(不支持相对链接)。
35+
此外,你也可以使用任何图像链接作为图标(不支持相对链接)。
3636

3737
如果你想要一个新的图标类型,请提交一个议题或提交 PR。
3838

39+
在 Markdown 中,你可以使用 `::icon decorators... =size /color key=value complex-key="complex value"...::` 插入自定义图标。
40+
41+
-`=` 开头的字符串将被视为尺寸定义。
42+
-`/` 开头的字符串将被视为颜色定义。
43+
- 任何本身是有效 html 属性的字符串将被解析、标准化并添加到图标元素中。
44+
- 其余部分将被视为图标名称。
45+
46+
```md
47+
::icon =16 /red:: <!-- <VPIcon class="icon" color="red" size="16px" -->
48+
49+
::icon rotate vertical-align=middle:: <!-- ::icon rotate" vertical-align="middle" -->
50+
```
51+
52+
::: info 案例
53+
54+
::mdi:home /blue::
55+
::mdi:apple =2rem vertical-align=text-bottom::
56+
57+
```md
58+
::mdi:home /blue::
59+
::mdi:apple =2rem vertical-align=text-bottom::
60+
```
61+
62+
:::
63+
64+
## 图标类型
65+
3966
### Iconify
4067

4168
有关完整的图标列表,请参见 <https://icon-sets.iconify.design/>。要使用图标,请复制选择器中的 `iconify-icon` 的图标名称。
@@ -50,8 +77,8 @@ export default {
5077
如果你主要使用 1 个图标集,可以将前缀设置为图标集名称(例如:`mdi:`),然后你可以使用图标名称而无需前缀。手动声明完整图标名称将覆盖前缀:
5178

5279
```md
53-
<VPIcon icon="home" /> <!-- mdi:home -->
54-
<VPIcon icon="svg-spinners:180-ring" /> <!-- svg-spinners:180-ring -->
80+
::home:: <!-- mdi:home -->
81+
::svg-spinners:180-ring:: <!-- svg-spinners:180-ring -->
5582
```
5683

5784
### Font Awesome
@@ -63,38 +90,38 @@ export default {
6390
实心图标可以直接使用。如果要使用常规或品牌图标,则需要在图标名称前添加 `regular:``brands:` 前缀:
6491

6592
```md
66-
<VPIcon icon="home" /> <!-- fas fa-home (实心是默认的) -->
67-
<VPIcon icon="solid:home" /> <!-- fas fa-home -->
68-
<VPIcon icon="regular:heart" /> <!-- far fa-heart -->
69-
<VPIcon icon="brands:apple" /> <!-- fab fa-apple -->
93+
::home:: <!-- fas fa-home (实心是默认的) -->
94+
::solid:home:: <!-- fas fa-home -->
95+
::regular:heart:: <!-- far fa-heart -->
96+
::brands:apple:: <!-- fab fa-apple -->
7097
```
7198

7299
此外,还支持三个字母前缀、第一个字母或完整类名:
73100

74101
```md
75-
<VPIcon icon="s:home" /> <!-- fas fa-home -->
76-
<VPIcon icon="fas:home" /> <!-- fas fa-home -->
77-
<VPIcon icon="fa-solid:home" /> <!-- fa-solid fa-home -->
102+
::s:home:: <!-- fas fa-home -->
103+
::fas:home:: <!-- fas fa-home -->
104+
::fa-solid:home:: <!-- fa-solid fa-home -->
78105

79-
<VPIcon icon="b:apple" /> <!-- fab fa-apple -->
80-
<VPIcon icon="fab:apple" /> <!-- fab fa-apple -->
81-
<VPIcon icon="fa-brands:apple" /> <!-- fa-brands fa-apple -->
106+
::b:apple:: <!-- fab fa-apple -->
107+
::fab:apple:: <!-- fab fa-apple -->
108+
::fa-brands:apple:: <!-- fa-brands fa-apple -->
82109

83-
<VPIcon icon="r:heart" /> <!-- far fa-heart -->
84-
<VPIcon icon="far:heart" /> <!-- far fa-heart -->
85-
<VPIcon icon="fa-regular:heart" /> <!-- fa-regular fa-heart -->
110+
::r:heart:: <!-- far fa-heart -->
111+
::far:heart:: <!-- far fa-heart -->
112+
::fa-regular:heart:: <!-- fa-regular fa-heart -->
86113
```
87114

88115
你可以在图标名称后添加其他 fontawesome 支持的类,并用空格分隔,其中 `fa-` 前缀是可选的:
89116

90117
```md
91118
<!-- 一个小尺寸 icon -->
92119

93-
<VPIcon icon="home fa-sm" /> <!-- fas fa-home fa-sm -->
120+
::home fa-sm:: <!-- fas fa-home fa-sm -->
94121

95122
<!-- 旋转 180° -->
96123

97-
<VPIcon icon="home rotate-180" /> <!-- fas fa-home fa-rotate-180 -->
124+
::home rotate-180:: <!-- fas fa-home fa-rotate-180 -->
98125
```
99126

100127
有关所有可用类的详细信息,请参见 <https://docs.fontawesome.com/web/style/styling>
@@ -166,16 +193,13 @@ export default {
166193

167194
```md
168195
<!-- 完整链接 -->
169-
<VPIcon icon="https://example.com/icon.png" />
170196

171-
<!-- icon.png 应该放在 .vuepress/public 文件夹中 -->
172-
<VPIcon icon="/icon.png" />
173-
```
197+
::https://example.com/icon.png::
174198

175-
## 案例
199+
<!-- icon.png 应该放在 .vuepress/public 文件夹中 -->
176200

177-
- <VPIcon icon="mdi:home" color="blue" />: 家图标
178-
- <VPIcon icon="mdi:apple" size="2rem" vertical-align="text-bottom" />: 苹果图标
201+
<VPIcon icon="/icon.png" /> <!-- ::/icon.png:: 是不被支持的,因为它会被解析为颜色 -->
202+
```
179203

180204
## 选项
181205

@@ -249,7 +273,7 @@ export default {
249273
250274
## 组件属性
251275
252-
### icon
276+
### icon {#icon-prop}
253277
254278
- 类型:`string`
255279
- 必填: 是

plugins/features/plugin-icon/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"style": "sass src:lib --embed-sources --style=compressed"
4242
},
4343
"dependencies": {
44+
"@mdit/plugin-icon": "^0.16.5",
4445
"@vuepress/helper": "workspace:*",
4546
"@vueuse/core": "^12.4.0",
4647
"vue": "^3.5.13"

plugins/features/plugin-icon/src/node/iconPlugin.ts

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { extractInfo, icon, stringifyAttrs } from '@mdit/plugin-icon'
12
import { addCustomElement, addViteSsrNoExternal } from '@vuepress/helper'
23
import type { Plugin } from 'vuepress/core'
34

@@ -19,6 +20,23 @@ export const iconPlugin = (options: IconPluginOptions = {}): Plugin => {
1920
addCustomElement(bundlerOptions, app, 'iconify-icon')
2021
},
2122

23+
extendsMarkdown: (md): void => {
24+
if (options.markdown !== false) {
25+
md.use(icon, {
26+
render: (raw) => {
27+
const { attrs, content, color, size } = extractInfo({
28+
content: raw,
29+
})
30+
31+
if (color && !attrs.color) attrs.color = color
32+
if (size && !attrs.size) attrs.size = size
33+
34+
return `<${options.component ?? 'VPIcon'} icon="${content}"${stringifyAttrs(attrs)} />`
35+
},
36+
})
37+
}
38+
},
39+
2240
clientConfigFile: (app) => prepareConfigFile(app, options, iconType),
2341
}
2442
}

plugins/features/plugin-icon/src/node/options.ts

+9
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,13 @@ export interface IconPluginOptions {
4646
* @default "VPIcon"
4747
*/
4848
component?: string
49+
50+
/**
51+
* Enable markdown syntax
52+
*
53+
* 启用 Markdown 语法
54+
*
55+
* @default true
56+
*/
57+
markdown?: boolean
4958
}

0 commit comments

Comments
 (0)