Markdown Extensions

Header Anchors

Headers automatically get anchor links applied. Rendering of anchors can be configured using the markdown.anchor option.

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
   └─ four.md

And providing you are in foo/one.md:

[Home](/) <!-- Sends the user to the root README.md -->
[foo](/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) -->
[bar - four](../bar/four.html) <!-- Or you can append .html -->

Redirection for URLs

KduPress supports redirecting to clean links. If a link /foo is not found, KduPress will look for a existing /foo/ or /foo.html. Conversely, when one of /foo/ or /foo.html is not found, KduPress will try the other.

TIP

Regardless of whether the permalink and clean-urls plugins are used, your relative path should be defined by the current file structure. In the above example, even though you set the path of /foo/one.md to /foo/one/, you should still access /foo/two.md via ./two.md.

Page Suffix

Pages and internal links get generated with the .html suffix by default.

You can customize this by setting config.markdown.pageSuffix.

Outbound links automatically get target="_blank" rel="noopener noreferrer":

You can customize the attributes added to external links by setting config.markdown.externalLinks.

Frontmatter

YAML frontmatter (opens new window) 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.

GitHub-Style Tables

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

Emoji 🎉

Input

:tada: :100:

Output

🎉 💯

A list of all emojis (opens new window) is available.

Table of Contents

Input

[[toc]]

Output

Rendering of the TOC can be configured using the markdown.toc option.

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
:::

Output

TIP

This is a tip

WARNING

This is a warning

WARNING

This is a dangerous warning

This is a details block, which does not work in Internet Explorer or Edge.

Custom Title

Input

::: danger STOP
Danger zone, do not proceed
:::

::: details Click me to view the code
```js
console.log('Hello, KduPress!')
```
:::

Output

STOP

Danger zone, do not proceed

Click me to view the code
console.log('Hello, KduPress!')

Syntax Highlighting in Code Blocks

KduPress 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:

Input

``` js
export default {
  name: 'MyComponent',
  // ...
}
```

Output

export default {
  name: 'MyComponent',
  // ...
}

Input

``` html
<ul>
  <li
    k-for="todo in todos"
    :key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>
```

Output

<ul>
  <li
    k-for="todo in todos"
    :key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>

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

Line Highlighting in Code Blocks

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-7}
export default { // Highlighted
  data () {
    return {
      msg: `Highlighted!
      This line isn't highlighted,
      but this and the next 2 are.`,
      motd: 'KduPress 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: 'KduPress is awesome',
      lorem: 'ipsum',
    }
  }
}

Line Numbers

You can enable line numbers for each code blocks via config:

module.exports = {
  markdown: {
    lineNumbers: true
  }
}
  • Demo:
Image Image

Import Code Snippets beta

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

<<< @/filepath

It also supports line highlighting:

<<< @/filepath{highlightLines}

Input

<<< @/../@kdupress/markdown/__tests__/fragments/snippet.js{2}

Output


 


export default function () {
  // ..
}

TIP

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

<<< @/../@kdupress/markdown/__tests__/fragments/snippet-with-region.js#snippet{1}

Code file

// #region snippet
function foo () {
  return ({
    dest: '../../kdupress',
    locales: {
      '/': {
        lang: 'en-US',
        title: 'KduPress',
        description: 'Kdu-powered Static Site Generator'
      },
      '/vi/': {
        lang: 'vi-VN',
        title: 'KduPress',
        description: 'Trình tạo trang tĩnh do Kdu cung cấp'
      }
    },
    head: [
      ['link', { rel: 'icon', href: `/logo.png` }],
      ['link', { rel: 'manifest', href: '/manifest.json' }],
      ['meta', { name: 'theme-color', content: '#3eaf7c' }],
      ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
      ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
      ['link', { rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png` }],
      ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
      ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
      ['meta', { name: 'msapplication-TileColor', content: '#000000' }]
    ]
  })
}
// #endregion snippet

export default foo

Output

 



























function foo () {
  return ({
    dest: '../../kdupress',
    locales: {
      '/': {
        lang: 'en-US',
        title: 'KduPress',
        description: 'Kdu-powered Static Site Generator'
      },
      '/vi/': {
        lang: 'vi-VN',
        title: 'KduPress',
        description: 'Trình tạo trang tĩnh do Kdu cung cấp'
      }
    },
    head: [
      ['link', { rel: 'icon', href: `/logo.png` }],
      ['link', { rel: 'manifest', href: '/manifest.json' }],
      ['meta', { name: 'theme-color', content: '#3eaf7c' }],
      ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
      ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
      ['link', { rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png` }],
      ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
      ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
      ['meta', { name: 'msapplication-TileColor', content: '#000000' }]
    ]
  })
}

Advanced Configuration

KduPress uses markdown-it (opens new window) 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 .kdupress/config.js:

module.exports = {
  markdown: {
    // options for markdown-it-anchor
    anchor: { permalink: false },
    // options for markdown-it-toc
    toc: { includeLevel: [1, 2] },
    extendMarkdown: md => {
      // use more markdown-it plugins!
      md.use(require('markdown-it-xxx'))
    }
  }
}