## Heads up!
Please see the [changelog](CHANGELOG.md) to learn about breaking changes that were made in v3.0.
# Sponsors
Thanks to the following companies, organizations, and individuals for supporting the ongoing maintenance and development of {%= name %}! [Become a Sponsor](https://github.com/sponsors/jonschlinkert) to add your logo to this README, or any of [my other projects](https://github.com/jonschlinkert?tab=repositories&q=&type=&language=&sort=stargazers)
## Gold Sponsors
| [
](https://jaake.tech/) |
|:---:|
| [https://jaake.tech/](https://jaake.tech/) |
## What does this do?
Run this example
Add the HTML in the following example to `example.html`, then add the following code to `example.js` and run `$ node example` (without the `$`):
```js
const fs = require('fs');
const matter = require('gray-matter');
const str = fs.readFileSync('example.html', 'utf8');
console.log(matter(str));
```
Converts a string with front-matter, like this:
```handlebars
---
title: Hello
slug: home
---
Hello world!
```
Into an object like this:
```js
{
content: 'Hello world!
',
data: {
title: 'Hello',
slug: 'home'
}
}
```
## Why use gray-matter?
- **simple**: main function takes a string and returns an object
- **accurate**: better at catching and handling edge cases than front-matter parsers that rely on regex for parsing
- **fast**: faster than other front-matter parsers that use regex for parsing
- **flexible**: By default, gray-matter is capable of parsing [YAML][js-yaml], [JSON](http://en.wikipedia.org/wiki/Json) and JavaScript front-matter. But other [engines](#optionsengines) may be added.
- **extensible**: Use [custom delimiters](#optionsdelimiters), or add support for [any language](#optionsengines), like [TOML][], [CoffeeScript][], or [CSON][]
- **battle-tested**: used by [assemble][], [metalsmith][], [phenomic][], [verb][], [generate][], [update][] and many others.
Rationale
**Why did we create gray-matter in the first place?**
We created gray-matter after trying out other libraries that failed to meet our standards and requirements.
Some libraries met most of the requirements, but _none met all of them_.
**Here are the most important**:
* Be usable, if not simple
* Use a dependable and well-supported library for parsing YAML
* Support other languages besides YAML
* Support stringifying back to YAML or another language
* Don't fail when no content exists
* Don't fail when no front matter exists
* Don't use regex for parsing. This is a relatively simple parsing operation, and regex is the slowest and most error-prone way to do it.
* Have no problem reading YAML files directly
* Have no problem with complex content, including **non-front-matter** fenced code blocks that contain examples of YAML front matter. Other parsers fail on this.
* Support stringifying back to front-matter. This is useful for linting, updating properties, etc.
* Allow custom delimiters, when it's necessary for avoiding delimiter collision.
* Should return an object with at least these three properties:
- `data`: the parsed YAML front matter, as a JSON object
- `content`: the contents as a string, without the front matter
- `orig`: the "original" content (for debugging)
## Usage
Using Node's `require()` system:
```js
const matter = require('gray-matter');
```
Or with [typescript](https://www.typescriptlang.org)
```js
import matter = require('gray-matter');
// OR
import * as matter from 'gray-matter';
```
Pass a string and [options](#options) to gray-matter:
```js
console.log(matter('---\ntitle: Front Matter\n---\nThis is content.'));
```
Returns:
```js
{
content: '\nThis is content.',
data: {
title: 'Front Matter'
}
}
```
More about the returned object in the following section.
***
## Returned object
gray-matter returns a `file` object with the following properties.
**Enumerable**
- `file.data` **{Object}**: the object created by parsing front-matter
- `file.content` **{String}**: the input string, with `matter` stripped
- `file.excerpt` **{String}**: an excerpt, if [defined on the options](#optionsexcerpt)
- `file.empty` **{String}**: when the front-matter is "empty" (either all whitespace, nothing at all, or just comments and no data), the original string is set on this property. See [#65](https://github.com/jonschlinkert/gray-matter/issues/65) for details regarding use case.
- `file.isEmpty` **{Boolean}**: true if front-matter is empty.
**Non-enumerable**
In addition, the following non-enumberable properties are added to the object to help with debugging.
- `file.orig` **{Buffer}**: the original input string (or buffer)
- `file.language` **{String}**: the front-matter language that was parsed. `yaml` is the default
- `file.matter` **{String}**: the _raw_, un-parsed front-matter string
- `file.stringify` **{Function}**: [stringify](#stringify) the file by converting `file.data` to a string in the given language, wrapping it in delimiters and prepending it to `file.content`.
## Run the examples
If you'd like to test-drive the examples, first clone gray-matter into `my-project` (or wherever you want):
```sh
$ git clone https://github.com/jonschlinkert/gray-matter my-project
```
CD into `my-project` and install dependencies:
```sh
$ cd my-project && npm install
```
Then run any of the [examples](./examples) to see how gray-matter works:
```sh
$ node examples/
```
**Links to examples**
{%= examples() %}
## API
{%= apidocs("index.js") %}
## Options
### options.excerpt
**Type**: `Boolean|Function`
**Default**: `undefined`
Extract an excerpt that directly follows front-matter, or is the first thing in the string if no front-matter exists.
If set to `excerpt: true`, it will look for the frontmatter delimiter, `---` by default and grab everything leading up to it.
**Example**
```js
const str = '---\nfoo: bar\n---\nThis is an excerpt.\n---\nThis is content';
const file = matter(str, { excerpt: true });
```
Results in:
```js
{
content: 'This is an excerpt.\n---\nThis is content',
data: { foo: 'bar' },
excerpt: 'This is an excerpt.\n'
}
```
You can also set `excerpt` to a function. This function uses the 'file' and 'options' that were initially passed to gray-matter as parameters, so you can control how the excerpt is extracted from the content.
**Example**
```js
// returns the first 4 lines of the contents
function firstFourLines(file, options) {
file.excerpt = file.content.split('\n').slice(0, 4).join(' ');
}
const file = matter([
'---',
'foo: bar',
'---',
'Only this',
'will be',
'in the',
'excerpt',
'but not this...'
].join('\n'), {excerpt: firstFourLines});
```
Results in:
```js
{
content: 'Only this\nwill be\nin the\nexcerpt\nbut not this...',
data: { foo: 'bar' },
excerpt: 'Only this will be in the excerpt'
}
```
### options.excerpt_separator
**Type**: `String`
**Default**: `undefined`
Define a custom separator to use for excerpts.
```js
console.log(matter(string, {excerpt_separator: ''}));
```
**Example**
The following HTML string:
```html
---
title: Blog
---
My awesome blog.
Hello world
```
Results in:
```js
{
data: { title: 'Blog'},
excerpt: 'My awesome blog.',
content: 'My awesome blog.\n\nHello world
'
}
```
### options.engines
Define custom engines for parsing and/or stringifying front-matter.
**Type**: `Object` Object of engines
**Default**: `JSON`, `YAML` and `JavaScript` are already handled by default.
**Engine format**
Engines may either be an object with `parse` and (optionally) `stringify` methods, or a function that will be used for parsing only.
**Examples**
```js
const toml = require('toml');
/**
* defined as a function
*/
const file = matter(str, {
engines: {
toml: toml.parse.bind(toml),
}
});
/**
* Or as an object
*/
const file = matter(str, {
engines: {
toml: {
parse: toml.parse.bind(toml),
// example of throwing an error to let users know stringifying is
// not supported (a TOML stringifier might exist, this is just an example)
stringify: function() {
throw new Error('cannot stringify to TOML');
}
}
}
});
console.log(file);
```
### options.language
**Type**: `String`
**Default**: `yaml`
Define the engine to use for parsing front-matter.
```js
console.log(matter(string, {language: 'toml'}));
```
**Example**
The following HTML string:
```html
---
title = "TOML"
description = "Front matter"
categories = "front matter toml"
---
This is content
```
Results in:
```js
{ content: 'This is content',
excerpt: '',
data:
{ title: 'TOML',
description: 'Front matter',
categories: 'front matter toml' } }
```
**Dynamic language detection**
Instead of defining the language on the options, gray-matter will automatically detect the language defined after the first delimiter and select the correct engine to use for parsing.
```html
---toml
title = "TOML"
description = "Front matter"
categories = "front matter toml"
---
This is content
```
### options.delimiters
**Type**: `String`
**Default**: `---`
Open and close delimiters can be passed in as an array of strings.
**Example:**
```js
// format delims as a string
matter.read('file.md', {delims: '~~~'});
// or an array (open/close)
matter.read('file.md', {delims: ['~~~', '~~~']});
```
would parse:
```html
~~~
title: Home
~~~
This is the {{title}} page.
```
## Deprecated options
### options.lang
Decrecated, please use [options.language](#optionslanguage) instead.
### options.delims
Decrecated, please use [options.delimiters](#optionsdelimiters) instead.
### options.parsers
Decrecated, please use [options.engines](#optionsengines) instead.
[bootstrap-blog]: https://github.com/twbs/bootstrap-blog/tree/gh-pages/_posts
[assemble]: https://github.com/assemble/assemble
[metalsmith]: https://github.com/segmentio/metalsmith
[phenomic]: https://github.com/phenomic/phenomic
[verb]: https://github.com/assemble/verb
[TOML]: http://github.com/mojombo/toml
[CoffeeScript]: http://coffeescript.org
[CSON]: https://github.com/bevry/cson