UNPKG

16.8 kBMarkdownView Raw
1# gray-matter [![NPM version](https://img.shields.io/npm/v/gray-matter.svg?style=flat)](https://www.npmjs.com/package/gray-matter) [![NPM monthly downloads](https://img.shields.io/npm/dm/gray-matter.svg?style=flat)](https://npmjs.org/package/gray-matter) [![NPM total downloads](https://img.shields.io/npm/dt/gray-matter.svg?style=flat)](https://npmjs.org/package/gray-matter) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/gray-matter.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/gray-matter)
2
3> Parse front-matter from a string or file. Fast, reliable and easy to use. Parses YAML front matter by default, but also has support for YAML, JSON, TOML or Coffee Front-Matter, with options to set custom delimiters. Used by metalsmith, assemble, verb and many other projects.
4
5Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
6
7## Install
8
9Install with [npm](https://www.npmjs.com/):
10
11```sh
12$ npm install --save gray-matter
13```
14
15## Heads up!
16
17Please see the [changelog](CHANGELOG.md) to learn about breaking changes that were made in v3.0.
18
19## What does this do?
20
21<details>
22<summary><strong>Run this example</strong></summary>
23
24Add the HTML in the following example to `example.html`, then add the following code to `example.js` and run `$ node example` (without the `$`):
25
26```js
27const fs = require('fs');
28const matter = require('gray-matter');
29const str = fs.readFileSync('example.html', 'utf8');
30console.log(matter(str));
31```
32
33</details>
34
35Converts a string with front-matter, like this:
36
37```handlebars
38---
39title: Hello
40slug: home
41---
42<h1>Hello world!</h1>
43```
44
45Into an object like this:
46
47```js
48{
49 content: '<h1>Hello world!</h1>',
50 data: {
51 title: 'Hello',
52 slug: 'home'
53 }
54}
55```
56
57## Why use gray-matter?
58
59* **simple**: main function takes a string and returns an object
60* **accurate**: better at catching and handling edge cases than front-matter parsers that rely on regex for parsing
61* **fast**: faster than other front-matter parsers that use regex for parsing
62* **flexible**: By default, gray-matter is capable of parsing [YAML](https://github.com/nodeca/js-yaml), [JSON](http://en.wikipedia.org/wiki/Json) and JavaScript front-matter. But other [engines](#optionsengines) may be added.
63* **extensible**: Use [custom delimiters](#optionsdelimiters), or add support for [any language](#optionsengines), like [TOML](http://github.com/mojombo/toml), [CoffeeScript](http://coffeescript.org), or [CSON](https://github.com/bevry/cson)
64* **battle-tested**: used by [assemble](https://github.com/assemble/assemble), [metalsmith](https://github.com/segmentio/metalsmith), [phenomic](https://github.com/phenomic/phenomic), [verb](https://github.com/assemble/verb), [generate](https://github.com/generate/generate), [update](https://github.com/update/update) and many others.
65
66<details>
67<summary><strong>Rationale</strong></summary>
68
69**Why did we create gray-matter in the first place?**
70
71We created gray-matter after trying out other libraries that failed to meet our standards and requirements.
72
73Some libraries met most of the requirements, but _none met all of them_.
74
75**Here are the most important**:
76
77* Be usable, if not simple
78* Use a dependable and well-supported library for parsing YAML
79* Support other languages besides YAML
80* Support stringifying back to YAML or another language
81* Don't fail when no content exists
82* Don't fail when no front matter exists
83* 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.
84* Have no problem reading YAML files directly
85* 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.
86* Support stringifying back to front-matter. This is useful for linting, updating properties, etc.
87* Allow custom delimiters, when it's necessary for avoiding delimiter collision.
88* Should return an object with at least these three properties:
89 - `data`: the parsed YAML front matter, as a JSON object
90 - `content`: the contents as a string, without the front matter
91 - `orig`: the "original" content (for debugging)
92
93</details>
94
95## Usage
96
97Using Node's `require()` system:
98
99```js
100const matter = require('gray-matter');
101```
102
103Or with [typescript](https://www.typescriptlang.org)
104
105```js
106import matter = require('gray-matter');
107// OR
108import * as matter from 'gray-matter';
109```
110
111Pass a string and [options](#options) to gray-matter:
112
113```js
114console.log(matter('---\ntitle: Front Matter\n---\nThis is content.'));
115```
116
117Returns:
118
119```js
120{
121 content: '\nThis is content.',
122 data: {
123 title: 'Front Matter'
124 }
125}
126```
127
128More about the returned object in the following section.
129
130***
131
132## Returned object
133
134gray-matter returns a `file` object with the following properties.
135
136**Enumerable**
137
138* `file.data` **{Object}**: the object created by parsing front-matter
139* `file.content` **{String}**: the input string, with `matter` stripped
140* `file.excerpt` **{String}**: an excerpt, if [defined on the options](#optionsexcerpt)
141* `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.
142* `file.isEmpty` **{Boolean}**: true if front-matter is empty.
143
144**Non-enumerable**
145
146In addition, the following non-enumberable properties are added to the object to help with debugging.
147
148* `file.orig` **{Buffer}**: the original input string (or buffer)
149* `file.language` **{String}**: the front-matter language that was parsed. `yaml` is the default
150* `file.matter` **{String}**: the _raw_, un-parsed front-matter string
151* `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`.
152
153## Run the examples
154
155If you'd like to test-drive the examples, first clone gray-matter into `my-project` (or wherever you want):
156
157```sh
158$ git clone https://github.com/jonschlinkert/gray-matter my-project
159```
160
161CD into `my-project` and install dependencies:
162
163```sh
164$ cd my-project && npm install
165```
166
167Then run any of the [examples](./examples) to see how gray-matter works:
168
169```sh
170$ node examples/<example_name>
171```
172
173**Links to examples**
174
175* [coffee](examples/coffee.js)
176* [excerpt-separator](examples/excerpt-separator.js)
177* [excerpt-stringify](examples/excerpt-stringify.js)
178* [excerpt](examples/excerpt.js)
179* [javascript](examples/javascript.js)
180* [json-stringify](examples/json-stringify.js)
181* [json](examples/json.js)
182* [restore-empty](examples/restore-empty.js)
183* [sections-excerpt](examples/sections-excerpt.js)
184* [sections](examples/sections.js)
185* [toml](examples/toml.js)
186* [yaml-stringify](examples/yaml-stringify.js)
187* [yaml](examples/yaml.js)
188
189## API
190
191### [matter](index.js#L29)
192
193Takes a string or object with `content` property, extracts and parses front-matter from the string, then returns an object with `data`, `content` and other [useful properties](#returned-object).
194
195**Params**
196
197* `input` **{Object|String}**: String, or object with `content` string
198* `options` **{Object}**
199* `returns` **{Object}**
200
201**Example**
202
203```js
204const matter = require('gray-matter');
205console.log(matter('---\ntitle: Home\n---\nOther stuff'));
206//=> { data: { title: 'Home'}, content: 'Other stuff' }
207```
208
209### [.stringify](index.js#L160)
210
211Stringify an object to YAML or the specified language, and append it to the given string. By default, only YAML and JSON can be stringified. See the [engines](#engines) section to learn how to stringify other languages.
212
213**Params**
214
215* `file` **{String|Object}**: The content string to append to stringified front-matter, or a file object with `file.content` string.
216* `data` **{Object}**: Front matter to stringify.
217* `options` **{Object}**: [Options](#options) to pass to gray-matter and [js-yaml](https://github.com/nodeca/js-yaml).
218* `returns` **{String}**: Returns a string created by wrapping stringified yaml with delimiters, and appending that to the given string.
219
220**Example**
221
222```js
223console.log(matter.stringify('foo bar baz', {title: 'Home'}));
224// results in:
225// ---
226// title: Home
227// ---
228// foo bar baz
229```
230
231### [.read](index.js#L178)
232
233Synchronously read a file from the file system and parse front matter. Returns the same object as the [main function](#matter).
234
235**Params**
236
237* `filepath` **{String}**: file path of the file to read.
238* `options` **{Object}**: [Options](#options) to pass to gray-matter.
239* `returns` **{Object}**: Returns [an object](#returned-object) with `data` and `content`
240
241**Example**
242
243```js
244const file = matter.read('./content/blog-post.md');
245```
246
247### [.test](index.js#L193)
248
249Returns true if the given `string` has front matter.
250
251**Params**
252
253* `string` **{String}**
254* `options` **{Object}**
255* `returns` **{Boolean}**: True if front matter exists.
256
257## Options
258
259### options.excerpt
260
261**Type**: `Boolean|Function`
262
263**Default**: `undefined`
264
265Extract an excerpt that directly follows front-matter, or is the first thing in the string if no front-matter exists.
266
267If set to `excerpt: true`, it will look for the frontmatter delimiter, `---` by default and grab everything leading up to it.
268
269**Example**
270
271```js
272const str = '---\nfoo: bar\n---\nThis is an excerpt.\n---\nThis is content';
273const file = matter(str, { excerpt: true });
274```
275
276Results in:
277
278```js
279{
280 content: 'This is an excerpt.\n---\nThis is content',
281 data: { foo: 'bar' },
282 excerpt: 'This is an excerpt.\n'
283}
284```
285
286You 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.
287
288**Example**
289
290```js
291// returns the first 4 lines of the contents
292function firstFourLines(file, options) {
293 file.excerpt = file.content.split('\n').slice(0, 4).join(' ');
294}
295
296const file = matter([
297 '---',
298 'foo: bar',
299 '---',
300 'Only this',
301 'will be',
302 'in the',
303 'excerpt',
304 'but not this...'
305].join('\n'), {excerpt: firstFourLines});
306```
307
308Results in:
309
310```js
311{
312 content: 'Only this\nwill be\nin the\nexcerpt\nbut not this...',
313 data: { foo: 'bar' },
314 excerpt: 'Only this will be in the excerpt'
315}
316```
317
318### options.excerpt_separator
319
320**Type**: `String`
321
322**Default**: `undefined`
323
324Define a custom separator to use for excerpts.
325
326```js
327console.log(matter(string, {excerpt_separator: '<!-- end -->'}));
328```
329
330**Example**
331
332The following HTML string:
333
334```html
335---
336title: Blog
337---
338My awesome blog.
339<!-- end -->
340<h1>Hello world</h1>
341```
342
343Results in:
344
345```js
346{
347 data: { title: 'Blog'},
348 excerpt: 'My awesome blog.',
349 content: 'My awesome blog.\n<!-- end -->\n<h1>Hello world</h1>'
350}
351```
352
353### options.engines
354
355Define custom engines for parsing and/or stringifying front-matter.
356
357**Type**: `Object` Object of engines
358
359**Default**: `JSON`, `YAML` and `JavaScript` are already handled by default.
360
361**Engine format**
362
363Engines may either be an object with `parse` and (optionally) `stringify` methods, or a function that will be used for parsing only.
364
365**Examples**
366
367```js
368const toml = require('toml');
369
370/**
371 * defined as a function
372 */
373
374const file = matter(str, {
375 engines: {
376 toml: toml.parse.bind(toml),
377 }
378});
379
380/**
381 * Or as an object
382 */
383
384const file = matter(str, {
385 engines: {
386 toml: {
387 parse: toml.parse.bind(toml),
388
389 // example of throwing an error to let users know stringifying is
390 // not supported (a TOML stringifier might exist, this is just an example)
391 stringify: function() {
392 throw new Error('cannot stringify to TOML');
393 }
394 }
395 }
396});
397
398console.log(file);
399```
400
401### options.language
402
403**Type**: `String`
404
405**Default**: `yaml`
406
407Define the engine to use for parsing front-matter.
408
409```js
410console.log(matter(string, {language: 'toml'}));
411```
412
413**Example**
414
415The following HTML string:
416
417```html
418---
419title = "TOML"
420description = "Front matter"
421categories = "front matter toml"
422---
423This is content
424```
425
426Results in:
427
428```js
429{ content: 'This is content',
430 excerpt: '',
431 data:
432 { title: 'TOML',
433 description: 'Front matter',
434 categories: 'front matter toml' } }
435```
436
437**Dynamic language detection**
438
439Instead 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.
440
441```html
442---toml
443title = "TOML"
444description = "Front matter"
445categories = "front matter toml"
446---
447This is content
448```
449
450### options.delimiters
451
452**Type**: `String`
453
454**Default**: `---`
455
456Open and close delimiters can be passed in as an array of strings.
457
458**Example:**
459
460```js
461// format delims as a string
462matter.read('file.md', {delims: '~~~'});
463// or an array (open/close)
464matter.read('file.md', {delims: ['~~~', '~~~']});
465```
466
467would parse:
468
469```html
470~~~
471title: Home
472~~~
473This is the {{title}} page.
474```
475
476## Deprecated options
477
478### options.lang
479
480Decrecated, please use [options.language](#optionslanguage) instead.
481
482### options.delims
483
484Decrecated, please use [options.delimiters](#optionsdelimiters) instead.
485
486### options.parsers
487
488Decrecated, please use [options.engines](#optionsengines) instead.
489
490## About
491
492<details>
493<summary><strong>Contributing</strong></summary>
494
495Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
496
497</details>
498
499<details>
500<summary><strong>Running Tests</strong></summary>
501
502Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
503
504```sh
505$ npm install && npm test
506```
507
508</details>
509
510<details>
511<summary><strong>Building docs</strong></summary>
512
513_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
514
515To generate the readme, run the following command:
516
517```sh
518$ npm install -g verbose/verb#dev verb-generate-readme && verb
519```
520
521</details>
522
523### Related projects
524
525You might also be interested in these projects:
526
527* [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit")
528* [metalsmith](https://www.npmjs.com/package/metalsmith): An extremely simple, pluggable static site generator. | [homepage](https://github.com/segmentio/metalsmith#readme "An extremely simple, pluggable static site generator.")
529* [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://github.com/verbose/verb) | [homepage](https://github.com/verbose/verb "Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used on hundreds of projects of all sizes to generate everything from API docs to readmes.")
530* [gray-matter-loader](https://github.com/atlassian/gray-matter-loader): A webpack loader for gray-matter. [homepage](https://github.com/atlassian/gray-matter-loader#gray-matter-loader)
531
532### Contributors
533
534| **Commits** | **Contributor** |
535| --- | --- |
536| 174 | [jonschlinkert](https://github.com/jonschlinkert) |
537| 7 | [RobLoach](https://github.com/RobLoach) |
538| 5 | [heymind](https://github.com/heymind) |
539| 4 | [doowb](https://github.com/doowb) |
540| 3 | [aljopro](https://github.com/aljopro) |
541| 2 | [reccanti](https://github.com/reccanti) |
542| 2 | [onokumus](https://github.com/onokumus) |
543| 2 | [moozzyk](https://github.com/moozzyk) |
544| 1 | [Ajedi32](https://github.com/Ajedi32) |
545| 1 | [caesar](https://github.com/caesar) |
546| 1 | [ianstormtaylor](https://github.com/ianstormtaylor) |
547| 1 | [qm3ster](https://github.com/qm3ster) |
548| 1 | [zachwhaley](https://github.com/zachwhaley) |
549
550### Author
551
552**Jon Schlinkert**
553
554* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
555* [GitHub Profile](https://github.com/jonschlinkert)
556* [Twitter Profile](https://twitter.com/jonschlinkert)
557
558### License
559
560Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert).
561Released under the [MIT License](LICENSE).
562
563***
564
565_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on April 01, 2018._
\No newline at end of file