pengzhanbo
3295字约11分钟
2024-03-05
在 Markdown 文件中使用 iconify 的图标。 主题虽然提供了 <Iconify />
组件来支持在 markdown 中使用图标, 但是它需要从远程加载图标,可能速度比较慢。
为此,主题提供了另一种可选的方式,以更简单的方式,在 Markdown 中使用图标,并且将 图标资源编译到 本地静态资源中。
该功能默认不启用,你需要在 theme
配置中启用。
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
icons: true,
},
}
})
})
同时,该功能还需要你额外安装 @iconify/json
依赖。
pnpm add @iconify/json
yarn add @iconify/json
npm install @iconify/json
:[collect:name]:
设置图标大小和颜色
:[collect:name size]:
:[collect:name /color]:
:[collect:name size/color]:
iconify
拥有非常多的图标,这些图标被分组为不同的 collect
,每个 collect
都有自己的 图标。
你可以从 https://icon-sets.iconify.design/ 中获取 collect 和 name。
输入:
:[ion:logo-markdown]:
输出:
该语法为行内语法,因此,你可以在同一行中跟其他 markdown 语法 一起使用。
输入:
github: :[tdesign:logo-github-filled]:
修改颜色::[tdesign:logo-github-filled /#f00]:
修改大小::[tdesign:logo-github-filled 36px]:
修改大小颜色::[tdesign:logo-github-filled 36px/#f00]:
输出:
github: 修改颜色: 修改大小: 修改大小颜色:
让你的 Markdown 文件支持选项卡。
你需要将选项卡包装在 tabs
容器中。
你可以在 tabs
容器中添加一个 id 后缀,该后缀将用作选项卡 id。 所有具有相同 id 的选项卡将共享相同的切换事件。
::: tabs#fruit
<!-- 这里,fruit 将用作 id,它是可选的 -->
<!-- 选项卡内容 -->
:::
在这个容器内,你应该使用 @tab
标记来标记和分隔选项卡内容。
在 @tab
标记后,你可以添加文本 :active
默认激活选项卡,之后的文本将被解析为选项卡标题。
::: tabs
@tab 标题 1
<!-- tab 1 内容 -->
@tab 标题 2
<!-- tab 2 内容 -->
@tab:active 标题 3
<!-- tab 3 将会被默认激活 -->
<!-- tab 3 内容 -->
:::
默认情况下,标题将用作选项卡的值,但你可以使用 id 后缀覆盖它。
::: tabs
@tab 标题 1
<!-- 此处,选项卡 1 的标题“标题 1”将用作值。 -->
<!-- tab 1 内容 -->
@tab 标题 2#值 2
<!-- 这里,tab 2 的标题将是 “标题 2”,但它会使用 “值 2” 作为选项卡的值-->
<!-- tab 2 内容 -->
:::
你可以在每个选项卡中使用 Vue 语法和组件,并且你可以访问 value 和 isActive, 表示选项卡的绑定值和选项卡是否处于激活状态。
输入:
::: tabs
@tab npm
npm 应该与 Node.js 被一同安装。
@tab pnpm
```sh
corepack enable
corepack use pnpm@8
```
:::
输出:
npm 应该与 Node.js 被一同安装。
corepack enable
corepack use pnpm@8
有时候,你可能需要在 内容中补充一些 示例,但期望能与 其它内容 分隔开来呈现。 主题支持在 Markdown 文件中添加示例容器。
::: demo-wrapper
添加你的示例
:::
title="xxx"
:标题no-padding
:不添加内边距img
: 仅包含图片时使用height="xxx"
: 高度仅包含图片:
::: demo-wrapper img no-padding
![hero](/images/custom-hero.png)
:::
输出:
包含 markdown 语法:
::: demo-wrapper title="标题"
### 三级标题
这是示例容器中的内容。
:::
输出:
标题
这是示例容器中的内容。
包含 html /vue 代码:
::: demo-wrapper
<h1 class="your-demo-title">这是标题</h1>
<p class="your-demo-paragraph">这是段落</p>
<style>
.your-demo-title {
color: red;
}
.your-demo-paragraph {
color: blue;
}
</style>
:::
输出:
这是段落
此功能默认不启用,你可以在配置文件中启用它。
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
caniuse: true,
},
}
})
})
在编写文章时, 提供嵌入 can-i-use WEB feature 各平台支持说明 的功能。
方便在描述某个 WEB feature 时,能更直观的表述 该特性的支持程度。
在你的 文章 markdown文件中,使用以下格式:
@[caniuse](feature)
@[caniuse](feature)
@[caniuse{browser_versions}](feature)
@[caniuse embed_type](feature)
@[caniuse embed_type{browser_versions}](feature)
feature
必填。 正确取值请参考 https://caniuse.bitsofco.de/
{browser_versions}
可选。当前特性在多个版本中的支持情况。
默认值为: {-2,-1,1}
格式: {number,number,...}
取值范围为 -5 ~ 3
0
表示低于当前浏览器版本的支持情况0
表示当前浏览器版本的支持情况0
表示高于当前浏览器版本的支持情况embed_type
可选。 资源嵌入的类型。
类型: 'embed' | 'image'
默认值为:'embed'
获取 css 伪类选择器 :dir()
在各个浏览器的支持情况:
@[caniuse](css-matches-pseudo)
效果:
以图片的形式,获取 css 伪类选择器 :dir()
在各个浏览器的支持情况:
@[caniuse image](css-matches-pseudo)
效果:
获取 css 伪类选择器 :dir()
特定范围浏览器的支持情况:
@[caniuse{-2,-1,1,2,3}](css-matches-pseudo)
效果:
主题支持在 Markdown 文件中嵌入 CodePen。
此功能默认不启用,你可以在配置文件中启用它。
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
codepen: true,
},
}
})
})
简单语法:
@[codepen](user/slash)
更多选项支持:
@[codepen preview editable tab="css,result" theme="dark" height="500px" width="100%"](user/slash)
preview
: 是否渲染为预览模式editable
: 是否可编辑tab
: 默认显示的标签, 默认为 result
,多个使用 ,
分隔theme
: 主题, 可选值 dark
和 light
height
: 容器高度, 默认为 400px
width
: 容器宽度, 默认为 100%
user
: CodePen 用户名slash
: CodePen 代码文件名输入:
@[codepen](leimapapa/RwOZQOW)
输出:
预览模式:
输入:
@[codepen preview](leimapapa/RwOZQOW)
输出:
编辑模式:
输入:
@[codepen editable tab="html,result"](leimapapa/RwOZQOW)
输出:
主题支持在 Markdown 文件中嵌入 Replit。
此功能默认不启用,你可以在配置文件中启用它。
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
replit: true,
},
}
})
})
简单的语法
@[replit](user/repl-name)
更多选项
@[replit title="" width="100%" height="450px" theme="dark"](user/repl-name#filepath)
title
: 标题width
: 容器宽度height
: 容器高度theme
: 主题, 可选值 dark
和 light
user
: Replit 用户名repl-name
: Replit repl 名称filepath
: Replit 默认打开的文件路径输入:
@[replit](@TechPandaPro/Cursor-Hangout#package.json)
输出:
主题支持在 Markdown 文件中导入文件切片。
导入文件 默认不启用,你可以通过配置来启用它。
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownEnhance: {
include: true,
},
}
})
})
使用 <!-- @include: filename -->
导入文件。
如果要部分导入文件,你可以指定导入的行数:
<!-- @include: filename{start-end} -->
<!-- @include: filename{start-} -->
<!-- @include: filename{-end} -->
同时你也可以导入文件区域:
<!-- @include: filename#region -->
文件区域
文件区域是 vscode 中的一个概念,区域内容被 #region
和 #endregion
注释包围。
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- region snippet -->
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eligendi,
repellendus. Voluptatibus alias cupiditate at, fuga tenetur error officiis
provident quisquam autem, porro facere! Neque quibusdam animi quaerat
eligendi recusandae eaque.
</p>
<!-- endregion snippet -->
<p>
Veniam harum illum natus omnis necessitatibus numquam architecto eum
dignissimos, quos a adipisci et non quam maxime repellendus alias ipsum,
vero praesentium laborum commodi perferendis velit repellat? Vero,
cupiditate sequi.
</p>
</body>
</html>
## Hello world
<!-- #region snippet -->
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptates
inventore iure quo aut doloremque, ipsum ab voluptatem ipsa, velit laborum
illo quae omnis reiciendis hic, ut dolorem non debitis in!
<!-- #endregion snippet -->
Veniam harum illum natus omnis necessitatibus numquam architecto eum
dignissimos, quos a adipisci et non quam maxime repellendus alias ipsum,
vero praesentium laborum commodi perferendis velit repellat? Vero,
cupiditate sequi.
import MarkdownIt from 'markdown-it'
import { include } from '@mdit/plugin-include'
// #region snippet
const mdIt = MarkdownIt().use(include, {
// your options, currentPath is required
currentPath: env => env.filePath,
})
// #endregion snippet
mdIt.render('<!-- @include: ./path/to/include/file.md -->', {
filePath: 'path/to/current/file.md',
})
const MarkdownIt = require('markdown-it')
const { include } = require('@mdit/plugin-include')
// #region snippet
const mdIt = MarkdownIt().use(include, {
// your options, currentPath is required
currentPath: env => env.filePath,
})
// #endregion snippet
mdIt.render('<!-- @include: ./path/to/include/file.md -->', {
filePath: 'path/to/current/file.md',
})
html,
body {
margin: 0;
padding: 0;
}
/* #region snippet */
h1 {
font-size: 1.5rem;
}
/* #endregion snippet */
h2 {
font-size: 1.2rem;
}
html,
body {
margin: 0;
padding: 0;
}
/* #region snippet */
h1 {
font-size: 1.5rem;
}
/* #endregion snippet */
h2 {
font-size: 1.2rem;
}
html,
body {
margin: 0;
padding: 0;
}
/* #region snippet */
h1 {
font-size: 1.5rem;
}
/* #endregion snippet */
h2 {
font-size: 1.2rem;
}
public class HelloWorld {
// #region snippet
public static void main(String args[]){
System.out.println("Hello World");
}
// #endregion snippet
}
class MyClass:
msg = "world"
#region snippet
def sayHello(self):
print("Hello " + self.msg + "!")
#region snippet
def sayBye(self):
print("Bye " + self.msg + "!")
Imports System
Module Module1
# Region snippet
Sub Main()
Console.WriteLine("Hello World!")
Console.WriteLine("Press Enter Key to Exit.")
Console.ReadLine()
End Sub
# EndRegion
End Module
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' NEQ '0' (
echo Requesting administrative privileges...
goto UACPrompt
) else ( goto gotAdmin )
::#region snippet
:UACPrompt
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
exit /B
::#endregion snippet
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
pushd "%CD%"
CD /D "%~dp0"
using System;
namespace HelloWorldApp {
class Geeks {
// #region snippet
static void Main(string[] args) {
// statement
// printing Hello World!
Console.WriteLine("Hello World!");
// To prevents the screen from
// running and closing quickly
Console.ReadKey();
}
// #endregion snippet
}
}
#include <iostream>
#include <vector>
std::vector<int> v;
#pragma region snippet
int f() {
for (int item : v) std::cout << item << std::endl;
return v.size();
}
#pragma endregion snippet
int main() {
int n, u;
std::cin >> n;
for (int i = 1; i <= n; ++i) {
std::cin >> u;
v.push_back(u);
}
std::cout << f();
return 0;
}
你还可以设置一个对象来自定义包含文件路径和包含行为。
interface IncludeOptions {
/**
* 处理 include 文件路径
*
* @default (path) => path
*/
resolvePath?: (path: string, cwd: string | null) => string
/**
* 是否深度导入包含的 Markdown 文件
*
* @default false
*/
deep?: boolean
/**
* 是否使用 `<!-- @include: xxx -->` 代替 `@include: xxx` 导入文件
*
* @default true
*/
useComment?: boolean
/**
* 是否解析包含的 Markdown 文件的里的相对图像路径
*
* @default true
*/
resolveImagePath?: boolean
/**
* 是否解析包含的 Markdown 文件的里的文件相对路径
*
* @default true
*/
resolveLinkPath?: boolean
}
例如: 你可以使用 @src 作为源文件夹的别名。
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownEnhance: {
include: {
resolvePath: (file) => {
if (file.startsWith('@src'))
return file.replace('@src', path.resolve(__dirname, '..'))
return file
},
},
},
}
})
})
此外,如果你想将 Markdown 文件直接放在实际文件旁边,但不希望它们呈现为页面, 你可以在 VuePress 配置中设置 pagePatterns
选项。 有关详细信息,请参阅 pagePatterns。
export default defineUserConfig({
// 现在任何带有 `.snippet.md` 扩展名的文件都不会呈现为页面
pagePatterns: ['**/*.md', '!**/*.snippet.md', '!.vuepress', '!node_modules'],
theme: plumeTheme({
plugins: {
markdownEnhance: {
include: true,
},
}
})
})
在项目中有一个 foo.snippet.md
文件:
### 三级标题
这是 foo.snippet.md 文件中的内容。
::: info
提示容器包括的内容
:::
<!-- region snippet -->
这里是被 `<!-- region snippet -->` 包裹的内容。
通过 `<!-- @include: ./foo.snippet.md#snippet -->` 来引入。
<!-- endregion snippet -->
使用 <!-- @include: ./foo.snippet.md -->
导入文件:
Include by file
这是 foo.snippet.md 文件中的内容。
相关信息
提示容器包括的内容
这里是被 <!-- region snippet -->
包裹的内容。
通过 <!-- @include: ./foo.snippet.md#snippet -->
来引入。
使用 <!-- @include: ./foo.snippet.md{5-7} -->
导入文件内的 5 到 7 行:
Include by lines
相关信息
提示容器包括的内容
使用 <!-- @include: ./foo.snippet.md#snippet -->
导入 snippet
区域
Include by file region
这里是被 <!-- region snippet -->
包裹的内容。
通过 <!-- @include: ./foo.snippet.md#snippet -->
来引入。
代码演示 默认不启用,你可以通过配置来启用它。
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownEnhance: {
demo: true,
},
}
})
})
::: [类型]-demo 可选的标题文字
```html
<!-- ↑ 使用可用的语言 -->
<!-- 在代码块中放置你对应语言的代码,一个语言不能出现多个块 -->
<!-- 你可以有多个代码块,并且 html, js, css 都是视情况可选的 -->
```
```json
// json block 作为插件配置存放处
{
// 放置你的配置 (可选的)
}
```
:::
提示
JSON 块是可选的,可用的配置详见配置
插件支持三种类型
你可以在演示块中使用不同语言。
当你设置一些不能在浏览器上直接运行的语言时,由于插件无法解析它们,因此网页演示将被禁用。插件只显示代码。同时提供一个 "在 CodePen 中打开" 按钮允许用户直接在 CodePen 打开并浏览代码。
可用的 HTML 语言:
"html"
(默认)"slim"
"haml"
"markdown"
可用的 JS 语言:
"javascript"
(default)"coffeescript"
"babel"
"livescript"
"typescript"
你也可以在代码块中使用
js
,ts
,coffee
和ls。
可用的 CSS 语言:
"css"
(default)"less"
"scss"
"sass"
"stylus"
# 标题
十分强大
const message: string = 'VuePress Theme Hope'
document.querySelector('h1').innerHTML = message
h1 {
font-style: italic;
+ p {
color: red;
}
}
::: normal-demo 一个使用浏览器不支持解析语言 Demo
```md
# 标题
十分强大
```
```ts
const message: string = 'VuePress Theme Hope'
document.querySelector('h1').innerHTML = message
```
```scss
h1 {
font-style: italic;
+ p {
color: red;
}
}
```
:::
格式:
::: normal-demo 可选的标题文字
```html
<!-- html code -->
```
```js
// js code
```
```css
/* css code */
```
```json
// 配置 (可选)
{
"jsLib": [
// ...
],
"cssLib": [
// ...
]
}
```
:::
注意事项
我们使用 "ShadowDOM"
进行样式隔离,并已经将 document
替换为了 shadowRoot
对象。如果需要访问页面的 document,请访问
window.document
。
<h1>Hello Word!</h1>
<p><span id="very">非常</span>强大!</p>
document.querySelector('#very').addEventListener('click', () => {
alert('非常强大')
})
span {
color: red;
}
::: normal-demo Demo 演示
```html
<h1>Hello Word!</h1>
<p><span id="very">非常</span>强大!</p>
```
```js
document.querySelector('#very').addEventListener('click', () => {
alert('非常强大')
})
```
```css
span {
color: red;
}
```
:::
::: vue-demo 可选的标题文字
```vue
<!-- ↑ 你也可以使用 html -->
<script>
export default {
// vue 组件
}
</script>
<template>
<!-- vue 模板 -->
<div>demo</div>
</template>
<style>
/* css 代码 */
</style>
```
```json
// 配置 (可选)
{}
```
:::
注意事项
Vue3
。export default
默认导出"ShadowDOM"
进行样式隔离,并已经将 document
替换为了 shadowRoot
对象。如果需要访问页面的 document
,请访问 window.document
。<script>
const { ref } = Vue
export default {
setup() {
const message = ref('powerful')
const handler = () => {
message.value = `very ${message.value}`
}
return {
message,
handler,
}
},
}
</script>
<template>
<div class="box">
<code>Hello Word</code> is
<span @click="handler">{{ message }}</span>!
</div>
</template>
<style>
.box span {
color: red;
}
</style>
::: vue-demo 一个 Vue Composition 演示
```vue
<script>
const { ref } = Vue
export default {
setup() {
const message = ref('powerful')
const handler = () => {
message.value = `very ${message.value}`
}
return {
message,
handler,
}
},
}
</script>
<template>
<div class="box">
<code>Hello Word</code> is
<span @click="handler">{{ message }}</span>!
</div>
</template>
<style>
.box span {
color: red;
}
</style>
```
:::
::: react-demo 可选的标题文字
```js
// 放置脚本,并通过 `export default` 导出你的 react 组件
```
```css
/* 你的 css 内容 */
```
```json
// 配置 (可选)
{}
```
:::
注意事项
export default
默认导出"ShadowDOM"
进行样式隔离,并已经将 document
替换为了 shadowRoot
对象。如果需要访问页面的 document
,请访问 window.document
。const { useState } = React
export default () => {
const [message, setMessage] = useState(' 强大')
const handler = () => {
setMessage(`十分${message}`)
}
return (
<div className="box">
<code>Hello Word !</code>
<span id="powerful" onClick={handler}>
{message}
</span>
</div>
)
}
.box #powerful {
color: blue;
}
::: react-demo 一个函数式 React Demo
```js
const { useState } = React
export default () => {
const [message, setMessage] = useState(' 强大')
const handler = () => {
setMessage(`十分${message}`)
}
return (
<div className="box">
<code>Hello Word !</code>
<span id="powerful" onClick={handler}>
{message}
</span>
</div>
)
}
```
```css
.box #powerful {
color: blue;
}
```
:::