Builtin Markdown features

Mr.Hope ... February 25, 2021 20:25 Basic
  • Markdown
About 3 min

Here are some enhance VuePress makes on Markdown syntax.

# Header Anchors

Headers automatically get anchor links applied.

Internal links are converted to <router-link> for SPA navigation. Also, every README.md or index.md contained in each sub-directory will automatically be converted to index.html, with corresponding URL /.

For example, given the following directory structure:

.
├─ README.md
├─ foo
│  ├─ README.md
│  ├─ one.md
│  └─ two.md
└─ bar
   ├─ README.md
   └─ three.md
1
2
3
4
5
6
7
8
9

And providing you are in foo/one.md:

[Home](../) <!-- Sends the user to the root README.md -->
[foo](./) <!-- Sends the user to index.html of directory foo -->
[foo heading](./#heading) <!-- Anchors user to a heading in the foo README file -->
[bar - three](../bar/three.md) <!-- You can append .md (recommended) -->
1
2
3
4

Note

We always recommend that you use relative links in the document to connect to other parts of the document.

Outbound links automatically get target="_blank" rel="noopener noreferrer", and add an external icon:

# Frontmatter

YAML frontmatter (opens new window) is supported out of the box:

The frontmatter must be at the top of the Markdown file, and must take the form of valid YAML set between triple-dashed lines. Example:

---
title: Blogging with VuePress
lang: en-US
---
1
2
3
4

Between the triple-dashed lines, you can set variables. These variables can be used via the $frontmatter variable. This data will be available to the rest of the page, along with all custom and theming components.

# Alternative frontmatter Formats

VuePress also supports JSON and TOML (opens new window) frontmatter syntax.

JSON frontmatter needs to start and end in curly braces:

---
{ "title": "Blogging Like a Hacker", "lang": "en-US" }
---
1
2
3

TOML frontmatter needs to be explicitly marked as TOML:

---toml
title = "Blogging Like a Hacker"
lang = "en-US"
---
1
2
3
4
---
title: Blogging Like a Hacker
lang: en-US
---
1
2
3
4

# Table of Contents

Input:


[[toc]]

1
2
3

Output:

# Custom Containers default theme

Custom containers can be defined by their types, titles, and contents.

# Default Title

Input:

::: tip

This is a tip

:::

::: warning

This is a warning

:::

::: danger

This is a dangerous warning

:::

::: details

This is a details block, which does not work in IE / Edge

:::
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Output:

Tips

This is a tip

Note

This is a warning

Warning

This is a dangerous warning

DETAILS

This is a details block, which does not work in IE / Edge

# Custom Title

Input:

::: danger STOP

Danger zone, do not proceed

:::

::: details Click me to view the code

```js
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello, VuePress!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
```

:::
1
2
3
4
5
6
7
8
9
10
11
12
13

Output:

STOP

Danger zone, do not proceed

Click me to view the code
console.log("Hello, VuePress!");
1

# Syntax Highlighting in Code Blocks

VuePress uses Prism (opens new window) to highlight language syntax in Markdown code blocks, using coloured text. Prism 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:

Demo

Input:

``` js
export default {
  name: 'MyComponent',
  // ...
}
```
1
2
3
4
5
6

Output:

export default {
  name: "MyComponent",
  // ...
};
1
2
3
4

Input:

``` html
<ul>
  <li
    v-for="todo in todos"
    :key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>
```
1
2
3
4
5
6
7
8
9
10

Output:

<ul>
  <li v-for="todo in todos" :key="todo.id">{{ todo.text }}</li>
</ul>
1
2
3

A list of valid languages (opens new window) is available on Prism’s site.

# Line Highlighting in Code Blocks

You can add {line} to highlight specific line.

Demo

Input:

``` js{4}
export default {
  data () {
    return {
      msg: 'Highlighted!'
    }
  }
}
```
1
2
3
4
5
6
7
8
9

Output:




 




export default {
  data () {
    return {
      msg: 'Highlighted!'
    }
  }
}
1
2
3
4
5
6
7

Beides 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}
Demo

Input:

``` js{1,4,6-7}
export default { // Highlighted
  data () {
    return {
      msg: `Highlighted!
      This line isn’t highlighted,
      but this and the next 2 are.`,
      motd: 'VuePress is awesome',
      lorem: 'ipsum',
    }
  }
}
```
1
2
3
4
5
6
7
8
9
10
11
12
13

Output:

 


 

 
 
 




export default { // Highlighted
  data () {
    return {
      msg: `Highlighted!
      This line isn’t highlighted,
      but this and the next 2 are.`,
      motd: 'VuePress is awesome',
      lorem: 'ipsum',
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11

# Line Numbers

By default, line numbers for each code blocks are enabled, you can set markdown.lineNumbers to false to disable it.

# Import Code Snippets beta

You can import code snippets from existing files via following syntax:

<<< @/filepath
1

It also supports line highlighting:

<<< @/filepath{highlightLines}
1
Demo

Input:

<<< @/../../packages/theme/node/eject.ts{6-14}
1

Output:






 
 
 
 
 
 
 
 
 




















import { cyan, red } from "chalk";
import { copy } from "fs-extra";
import { relative, resolve } from "path";

// #region exclude-files
const EXCLUDED_FILES = [
  "__tests__",
  ".npmignore",
  "LICENSE",
  "package.json",
  "node_modules",
  "README.md",
  "readme.md",
];
// #endregion exclude-files

export const eject = async (dir: string): Promise<void> => {
  try {
    const sourceDir = resolve(__dirname, "../");
    const targetDir = resolve(resolve(dir), ".vuepress/theme");

    await copy(sourceDir, targetDir, {
      filter: (src) => {
        return !EXCLUDED_FILES.includes(relative(sourceDir, src));
      },
    });

    console.log(`Copied vuepress-theme-hope into ${cyan(targetDir)}.\n`);
  } catch (err) {
    console.error(red((err as Error).stack || ""));
    process.exitCode = 1;
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Tips

Since the import of the code snippets will be executed before webpack compilation, you can’t use the path alias in webpack. The default value of @ is process.cwd().

You can also use a VS Code region (opens new window) to only include the corresponding part of the code file. You can provide a custom region name after a # following the filepath (snippet by default):

例子

Input:

<<< @/../../packages/theme/node/eject.ts#exclude-files{2-8}
1

Code file:

import { cyan, red } from "chalk";
import { copy } from "fs-extra";
import { relative, resolve } from "path";

// #region exclude-files
const EXCLUDED_FILES = [
  "__tests__",
  ".npmignore",
  "LICENSE",
  "package.json",
  "node_modules",
  "README.md",
  "readme.md",
];
// #endregion exclude-files

export const eject = async (dir: string): Promise<void> => {
  try {
    const sourceDir = resolve(__dirname, "../");
    const targetDir = resolve(resolve(dir), ".vuepress/theme");

    await copy(sourceDir, targetDir, {
      filter: (src) => {
        return !EXCLUDED_FILES.includes(relative(sourceDir, src));
      },
    });

    console.log(`Copied vuepress-theme-hope into ${cyan(targetDir)}.\n`);
  } catch (err) {
    console.error(red((err as Error).stack || ""));
    process.exitCode = 1;
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Output:


 
 
 
 
 
 
 

const EXCLUDED_FILES = [
  "__tests__",
  ".npmignore",
  "LICENSE",
  "package.json",
  "node_modules",
  "README.md",
  "readme.md",
];
1
2
3
4
5
6
7
8