## 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/](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\n

Hello 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