title | date | excerpt |
---|---|---|
Markdown Extensions |
2049-10-12 |
true |
这个页面是从VitePress 文档原样复制来的。
用于展示这个博客主题的各种元素的样式。
VitePress comes with built in Markdown Extensions.
Headers automatically get anchor links applied. Rendering of anchors can be configured using the markdown.anchor
option.
To specify a custom anchor tag for a heading instead of using the auto-generated one, add a suffix to the heading:
# Using custom anchors {#my-anchor}
This allows you to link to the heading as #my-anchor
instead of the default #using-custom-anchors
.
Both internal and external links gets special treatments.
Internal links are converted to router link for SPA navigation. Also, every index.md
contained in each sub-directory will automatically be converted to index.html
, with corresponding URL /
.
For example, given the following directory structure:
.
├─ index.md
├─ foo
│ ├─ index.md
│ ├─ one.md
│ └─ two.md
└─ bar
├─ index.md
├─ three.md
└─ four.md
And providing you are in foo/one.md
:
[Home](/) <!-- sends the user to the root index.md -->
[foo](/foo/) <!-- sends the user to index.html of directory foo -->
[foo heading](./#heading) <!-- anchors user to a heading in the foo index file -->
[bar - three](../bar/three) <!-- you can omit extension -->
[bar - three](../bar/three.md) <!-- you can append .md -->
[bar - four](../bar/four.html) <!-- or you can append .html -->
Pages and internal links get generated with the .html
suffix by default.
Outbound links automatically get target="_blank" rel="noreferrer"
:
YAML frontmatter is supported out of the box:
---
title: Blogging Like a Hacker
lang: en-US
---
This data will be available to the rest of the page, along with all custom and theming components.
For more details, see Frontmatter.
Input
| Tables | Are | Cool |
| ------------- | :-----------: | ----: |
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
Output
Tables | Are | Cool |
---|---|---|
col 3 is | right-aligned | $1600 |
col 2 is | centered | $12 |
zebra stripes | are neat | $1 |
Input
:tada: :100:
Output
🎉 💯
A list of all emojis is available.
Input
[[toc]]
Output
[[toc]]
Rendering of the TOC can be configured using the markdown.toc
option.
Custom containers can be defined by their types, titles, and contents.
Input
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
Output
::: info This is an info box. :::
::: tip This is a tip. :::
::: warning This is a warning. :::
::: danger This is a dangerous warning. :::
::: details This is a details block. :::
You may set custom title by appending the text right after the "type" of the container.
Input
::: danger STOP
Danger zone, do not proceed
:::
::: details Click me to view the code
```js
console.log("Hello, VitePress!");
```
:::
Output
::: danger STOP Danger zone, do not proceed :::
::: details Click me to view the code
console.log("Hello, VitePress!");
:::
This is a special container that can be used to prevent style and router conflicts with VitePress. This is especially useful when you're documenting component libraries. You might also wanna check out whyframe for better isolation.
Syntax
::: raw
Wraps in a <div class="vp-raw">
:::
vp-raw
class can be directly used on elements too. Style isolation is currently opt-in:
::: details
-
Install required deps with your preferred package manager:
$ npm install -D postcss postcss-prefix-selector
-
Create a file named
docs/.postcssrc.cjs
and add this to it:module.exports = { plugins: { "postcss-prefix-selector": { prefix: ":not(:where(.vp-raw *))", includeFiles: [/vp-doc\.css/], transform(prefix, _selector) { const [selector, pseudo = ""] = _selector.split(/(:\S*)$/); return selector + prefix + pseudo; }, }, }, };
:::
VitePress uses Shiki to highlight language syntax in Markdown code blocks, using coloured text. Shiki supports a wide variety of programming languages. All you need to do is append a valid language alias to the beginning backticks for the code block:
Input
```js
export default {
name: 'MyComponent',
// ...
}
```
```html
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
```
Output
export default {
name: "MyComponent",
// ...
};
<ul>
<li v-for="todo in todos" :key="todo.id">{{ todo.text }}</li>
</ul>
A list of valid languages is available on Shiki's repository.
You may also customize syntax highlight theme in app config. Please see markdown
options for more details.
Input
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
Output
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
In addition to a single line, you can also specify multiple single lines, ranges, or both:
- Line ranges: for example
{5-8}
,{3-10}
,{10-17}
- Multiple single lines: for example
{4,7,9}
- Line ranges and single lines: for example
{4,7-13,16,23-27,40}
Input
```js{1,4,6-8}
export default { // Highlighted
data () {
return {
msg: `Highlighted!
This line isn't highlighted,
but this and the next 2 are.`,
motd: 'VitePress is awesome',
lorem: 'ipsum'
}
}
}
```
Output
export default { // Highlighted
data () {
return {
msg: `Highlighted!
This line isn't highlighted,
but this and the next 2 are.`,
motd: 'VitePress is awesome',
lorem: 'ipsum',
}
}
}
Alternatively, it's possible to highlight directly in the line by using the // [!code hl]
comment.
Input
```js
export default {
data () {
return {
msg: 'Highlighted!' // [!code hl]
}
}
}
```
Output
export default {
data() {
return {
msg: "Highlighted!", // [!code hl]
};
},
};
Adding the // [!code focus]
comment on a line will focus it and blur the other parts of the code.
Additionally, you can define a number of lines to focus using // [!code focus:<lines>]
.
Input
Note that only one space is required after !code
, here are two to prevent processing.
```js
export default {
data () {
return {
msg: 'Focused!' // [!code focus]
}
}
}
```
Output
export default {
data() {
return {
msg: "Focused!", // [!code focus]
};
},
};
Adding the // [!code --]
or // [!code ++]
comments on a line will create a diff of that line, while keeping the colors of the codeblock.
Input
Note that only one space is required after !code
, here are two to prevent processing.
```js
export default {
data () {
return {
msg: 'Removed' // [!code --]
msg: 'Added' // [!code ++]
}
}
}
```
Output
export default {
data () {
return {
msg: 'Removed' // [!code --]
msg: 'Added' // [!code ++]
}
}
}
Adding the // [!code warning]
or // [!code error]
comments on a line will color it accordingly.
Input
Note that only one space is required after !code
, here are two to prevent processing.
```js
export default {
data () {
return {
msg: 'Error', // [!code error]
msg: 'Warning' // [!code warning]
}
}
}
```
Output
export default {
data() {
return {
msg: "Error", // [!code error]
msg: "Warning", // [!code warning]
};
},
};
You can enable line numbers for each code blocks via config:
export default {
markdown: {
lineNumbers: true,
},
};
Please see markdown
options for more details.
You can add :line-numbers
/ :no-line-numbers
mark in your fenced code blocks to override the value set in config.
Input
```ts {1}
// line-numbers is disabled by default
const line2 = "This is line 2";
const line3 = "This is line 3";
```
```ts:line-numbers {1}
// line-numbers is enabled
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
Output
// line-numbers is disabled by default
const line2 = "This is line 2";
const line3 = "This is line 3";
// line-numbers is enabled
const line2 = 'This is line 2'
const line3 = 'This is line 3'
You can import code snippets from existing files via following syntax:
<<< @/filepath
It also supports line highlighting:
<<< @/filepath{highlightLines}
Input
<<< @/snippets/snippet.js{2}
Code file
<<< @/snippets/snippet.js
Output
<<< @/snippets/snippet.js{2}
::: tip
The value of @
corresponds to the source root. By default it's the VitePress project root, unless srcDir
is configured. Alternatively, you can also import from relative paths:
<<< ../snippets/snippet.js
:::
You can also use a VS Code region to only include the corresponding part of the code file. You can provide a custom region name after a #
following the filepath:
Input
<<< @/snippets/snippet-with-region.js#snippet{1}
Code file
<<< @/snippets/snippet-with-region.js
Output
<<< @/snippets/snippet-with-region.js#snippet{1}
You can also specify the language inside the braces ({}
) like this:
<<< @/snippets/snippet.cs{c#}
<!-- with line highlighting: -->
<<< @/snippets/snippet.cs{1,2,4-6 c#}
<!-- with line numbers: -->
<<< @/snippets/snippet.cs{1,2,4-6 c#:line-numbers}
This is helpful if source language cannot be inferred from your file extension.
You can group multiple code blocks like this:
Input
::: code-group
```js [config.js]
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
};
export default config;
```
```ts [config.ts]
import type { UserConfig } from "vitepress";
const config: UserConfig = {
// ...
};
export default config;
```
:::
Output
::: code-group
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
};
export default config;
import type { UserConfig } from "vitepress";
const config: UserConfig = {
// ...
};
export default config;
:::
You can also import snippets in code groups:
Input
::: code-group
<!-- filename is used as title by default -->
<<< @/snippets/snippet.js
<!-- you can provide a custom one too -->
<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
:::
Output
::: code-group
<<< @/snippets/snippet.js
<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
:::
You can include a markdown file in another markdown file, even nested.
::: tip
You can also prefix the markdown path with @
, it will act as the source root. By default, it's the VitePress project root, unless srcDir
is configured.
:::
For example, you can include a relative markdown file using this:
Input
# Docs
## Basics
<!--@include: ./parts/basics.md-->
Part file (parts/basics.md
)
Some getting started stuff.
### Configuration
Can be created using `.foorc.json`.
Equivalent code
# Docs
## Basics
Some getting started stuff.
### Configuration
Can be created using `.foorc.json`.
It also supports selecting a line range:
Input
# Docs
## Basics
<!--@include: ./parts/basics.md{3,}-->
Part file (parts/basics.md
)
Some getting started stuff.
### Configuration
Can be created using `.foorc.json`.
Equivalent code
# Docs
## Basics
### Configuration
Can be created using `.foorc.json`.
The format of the selected line range can be: {3,}
, {,10}
, {1,10}
::: warning Note that this does not throw errors if your file is not present. Hence, when using this feature make sure that the contents are being rendered as expected. :::
VitePress uses markdown-it as the Markdown renderer. A lot of the extensions above are implemented via custom plugins. You can further customize the markdown-it
instance using the markdown
option in .vitepress/config.js
:
const anchor = require("markdown-it-anchor");
module.exports = {
markdown: {
// options for markdown-it-anchor
// https://github.com/valeriangalliat/markdown-it-anchor#usage
anchor: {
permalink: anchor.permalink.headerLink(),
},
// options for @mdit-vue/plugin-toc
// https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
toc: { level: [1, 2] },
config: (md) => {
// use more markdown-it plugins!
md.use(require("markdown-it-xxx"));
},
},
};
See full list of configurable properties in Config Reference: App Config.