Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/metalsmith/markdown

A metalsmith plugin to render markdown files to HTML.
https://github.com/metalsmith/markdown

markdown metalsmith metalsmith-plugin

Last synced: about 1 month ago
JSON representation

A metalsmith plugin to render markdown files to HTML.

Awesome Lists containing this project

README

        

# @metalsmith/markdown

A Metalsmith plugin to render markdown files to HTML, using [Marked](https://github.com/markedjs/marked) (by default).

[![metalsmith: core plugin][metalsmith-badge]][metalsmith-url]
[![npm: version][npm-badge]][npm-url]
[![ci: build][ci-badge]][ci-url]
[![code coverage][codecov-badge]][codecov-url]
[![license: MIT][license-badge]][license-url]

## Features

- Compiles `.md` and `.markdown` files in `metalsmith.source()` to HTML.
- Enables rendering file or metalsmith metadata keys to HTML through the [keys option](#rendering-metadata)
- Define a dictionary of markdown globalRefs (for links, images) available to all render targets
- Supports using the markdown library of your choice through the [render option](#using-another-markdown-library)

## Installation

NPM:

```bash
npm install @metalsmith/markdown
```

Yarn:

```bash
yarn add @metalsmith/markdown
```

## Usage

`@metalsmith/markdown` is powered by [Marked](https://github.com/markedjs/marked) (by default), and you can pass any of the [Marked options](https://marked.js.org/using_advanced#options) to it, including the ['pro' options](https://marked.js.org/using_pro#extensions): `renderer`, `tokenizer`, `walkTokens` and `extensions`.

```js
import markdown from '@metalsmith/markdown'
import hljs from 'highlight.js'

// use defaults
metalsmith.use(markdown())

// use explicit defaults
metalsmith.use({
wildcard: false,
keys: [],
engineOptions: {}
})

// custom
metalsmith.use(
markdown({
engineOptions: {
highlight: function (code) {
return hljs.highlightAuto(code).value
},
pedantic: false,
gfm: true,
tables: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false
}
})
)
```

`@metalsmith/markdown` provides the following options:

- `keys`: Key names of file metadata to render to HTML in addition to its `contents` - can be nested key paths
- `wildcard` _(default: `false`)_ - Expand `*` wildcards in `keys` option keypaths
- `globalRefs` - An object of `{ refname: 'link' }` pairs that will be available for all markdown files and keys, or a `metalsmith.metadata()` keypath containing such object
- `render` - Specify a custom render function with the signature `(source, engineOptions, context) => string`. `context` is an object with the signature `{ path:string, key:string }` where the `path` key contains the current file path, and `key` contains the target metadata key.
- `engineOptions` Options to pass to the markdown engine (default [marked](https://github.com/markedjs/marked))

### Rendering metadata

You can render markdown to HTML in file or metalsmith metadata keys by specifying the `keys` option.
The `keys` option also supports dot-delimited key-paths. You can also use [globalRefs within them](#defining-a-dictionary-of-markdown-globalrefs)

```js
metalsmith
.metadata({
from_metalsmith_metadata: 'I _shall_ become **markdown** and can even use a [globalref][globalref_link]',
markdownRefs: {
globalref_link: 'https://johndoe.com'
}
})
.use(
markdown({
keys: {
files: ['html_desc', 'nested.data'],
global: ['from_metalsmith_metadata']
},
globalRefs: 'markdownRefs'
})
)
```

You can even render all keys at a certain path by setting the `wildcard` option and using a globstar `*` in the keypaths.
This is especially useful for arrays like the `faq` below:

```js
metalsmith.use(
markdown({
wildcard: true,
keys: ['html_desc', 'nested.data', 'faq.*.*']
})
)
```

A file `page.md` with front-matter:

```md
---
html_desc: A **markdown-enabled** _description_
nested:
data: '#metalsmith'
faq:
- q: '**Question1?**'
a: _answer1_
- q: '**Question2?**'
a: _answer2_
---
```

would be transformed into:

```json
{
"html_desc": "A markdown-enabled description\n",
"nested": {
"data": "

metalsmith

\n"
},
"faq": [
{ "q": "

Question1?

\n", "a": "

answer1

\n" },
{ "q": "

Question2?

\n", "a": "

answer2

\n" }
]
}
```

**Notes about the wildcard**

- It acts like the single bash globstar. If you specify `*` this would only match the properties at the first level of the metadata.
- If a wildcard keypath matches a key whose value is not a string, it will be ignored.
- It is set to `false` by default because it can incur some overhead if it is applied too broadly.

### Defining a dictionary of markdown globalRefs

Markdown allows users to define links in [reference style](https://www.markdownguide.org/basic-syntax/#reference-style-links) (`[]:`).
In a Metalsmith build it may be especially desirable to be able to refer to some links globally. The `globalRefs` options allows this:

```js
metalsmith.use(
markdown({
globalRefs: {
twitter_link: 'https://twitter.com/johndoe',
github_link: 'https://github.com/johndoe',
photo: '/assets/img/me.png'
}
})
)
```

Now _contents of any file or metadata key_ processed by @metalsmith/markdown will be able to refer to these links as `[My Twitter][twitter_link]` or `![Me][photo]`. You can also store the globalRefs object of the previous example in a `metalsmith.metadata()` key and pass its keypath as `globalRefs` option instead.

This enables a flow where you can load the refs into global metadata from a source file with [@metalsmith/metadata](https://github.com/metalsmith/metadata), and use them both in markdown and templating plugins like [@metalsmith/layouts](https://github.com/metalsmith/layouts):

```js
metalsith
.metadata({
global: {
links: {
twitter: 'https://twitter.com/johndoe',
github: 'https://github.com/johndoe'
}
}
})
// eg in a markdown file: [My Twitter profile][twitter]
.use(markdown({ globalRefs: 'global.links' }))
// eg in a handlebars layout: {{ global.links.twitter }}
.use(layouts({ pattern: '**/*.html' }))
```

### Custom markdown rendering

You can use a custom renderer by using `marked.Renderer()`

```js
import markdown from '@metalsmith/markdown'
import { marked } from 'marked'
const markdownRenderer = new marked.Renderer()

markdownRenderer.image = function (href, title, text) {
return `

${title}

${text}



`
}

metalsmith.use(
markdown({
engineOptions: {
renderer: markdownRenderer,
pedantic: false,
gfm: true,
tables: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false
}
})
)
```

### Using another markdown library

If you don't want to use marked, you can use another markdown rendering library through the `render` option. For example, this is how you could use [markdown-it](https://github.com/markdown-it/markdown-it) instead:

```js
import MarkdownIt from 'markdown-it'

let markdownIt
metalsmith.use(markdown({
render(source, opts, context) {
if (!markdownIt) markdownIt = new MarkdownIt(opts)
if (context.key == 'contents') return mdIt.render(source)
return markdownIt.renderInline(source)
},
// specify markdownIt options here
engineOptions: { ... }
}))
```

### Debug

To enable debug logs, set the `DEBUG` environment variable to `@metalsmith/markdown*`:

```
metalsmith.env('DEBUG', '@metalsmith/markdown*')
```

### CLI Usage

Add `@metalsmith/markdown` key to your `metalsmith.json` plugins key

```json
{
"plugins": {
"@metalsmith/markdown": {
"engineOptions": {
"pedantic": false,
"gfm": true,
"tables": true,
"breaks": false,
"sanitize": false,
"smartLists": true,
"smartypants": false,
"xhtml": false
}
}
}
}
```

## License

[MIT](LICENSE)

[npm-badge]: https://img.shields.io/npm/v/@metalsmith/markdown.svg
[npm-url]: https://www.npmjs.com/package/@metalsmith/markdown
[ci-badge]: https://github.com/metalsmith/markdown/actions/workflows/test.yml/badge.svg
[ci-url]: https://github.com/metalsmith/markdown/actions/workflows/test.yml
[metalsmith-badge]: https://img.shields.io/badge/metalsmith-core_plugin-green.svg?longCache=true
[metalsmith-url]: https://metalsmith.io
[codecov-badge]: https://img.shields.io/coveralls/github/metalsmith/markdown
[codecov-url]: https://coveralls.io/github/metalsmith/markdown
[license-badge]: https://img.shields.io/github/license/metalsmith/markdown
[license-url]: LICENSE