UNPKG

15.1 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
27var fs = require('fs');
28var matter = require('gray-matter');
29var 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 (for debugging):
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
92
93</details>
94
95## Usage
96
97Using Node's `require()` system:
98
99```js
100var 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
142**Non-enumerable**
143
144In addition, the following non-enumberable properties are added to the object to help with debugging.
145
146* `file.orig` **{Buffer}**: the original input string (or buffer)
147* `file.language` **{String}**: the front-matter language that was parsed. `yaml` is the default
148* `file.matter` **{String}**: the _raw_, un-parsed front-matter string
149* `file.stringify` **{Function}**: [stringify](#stringify) the file by converting `file.data` to a string in the given language, wrapping it in delimiters and appending it to `file.content`.
150
151## Run the examples
152
153If you'd like to test-drive the examples, first clone gray-matter into `my-project` (or wherever you want):
154
155```sh
156$ git clone https://github.com/jonschlinkert/gray-matter my-project
157```
158
159CD into `my-project` and install dependencies:
160
161```sh
162$ cd my-project && npm install
163```
164
165Then run any of the [examples](./examples) to see how gray-matter works:
166
167```sh
168$ node examples/<example_name>
169```
170
171* [coffee](examples/coffee.js)
172* [excerpt-separator](examples/excerpt-separator.js)
173* [excerpt-stringify](examples/excerpt-stringify.js)
174* [excerpt](examples/excerpt.js)
175* [javascript](examples/javascript.js)
176* [json-stringify](examples/json-stringify.js)
177* [json](examples/json.js)
178* [toml](examples/toml.js)
179* [yaml-stringify](examples/yaml-stringify.js)
180* [yaml](examples/yaml.js)
181
182## API
183
184### [matter](index.js#L30)
185
186Takes 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).
187
188**Params**
189
190* `input` **{Object|String}**: String, or object with `content` string
191* `options` **{Object}**
192* `returns` **{Object}**
193
194**Example**
195
196```js
197var matter = require('gray-matter');
198console.log(matter('---\ntitle: Home\n---\nOther stuff'));
199//=> { data: { title: 'Home'}, content: 'Other stuff' }
200```
201
202### [.stringify](index.js#L140)
203
204Stringify 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.
205
206**Params**
207
208* `file` **{String|Object}**: The content string to append to stringified front-matter, or a file object with `file.content` string.
209* `data` **{Object}**: Front matter to stringify.
210* `options` **{Object}**: [Options](#options) to pass to gray-matter and [js-yaml](https://github.com/nodeca/js-yaml).
211* `returns` **{String}**: Returns a string created by wrapping stringified yaml with delimiters, and appending that to the given string.
212
213**Example**
214
215```js
216console.log(matter.stringify('foo bar baz', {title: 'Home'}));
217// results in:
218// ---
219// title: Home
220// ---
221// foo bar baz
222```
223
224### [.read](index.js#L160)
225
226Synchronously read a file from the file system and parse front matter. Returns the same object as the [main function](#matter).
227
228**Params**
229
230* `filepath` **{String}**: file path of the file to read.
231* `options` **{Object}**: [Options](#options) to pass to gray-matter.
232* `returns` **{Object}**: Returns [an object](#returned-object) with `data` and `content`
233
234**Example**
235
236```js
237var file = matter.read('./content/blog-post.md');
238```
239
240### [.test](index.js#L175)
241
242Returns true if the given `string` has front matter.
243
244**Params**
245
246* `string` **{String}**
247* `options` **{Object}**
248* `returns` **{Boolean}**: True if front matter exists.
249
250## Options
251
252### options.excerpt
253
254**Type**: `Object`
255
256**Default**: `undefined`
257
258Extract an excerpt that directly follows front-matter, or is the first thing in the string if no front-matter exists.
259
260**Example**
261
262```js
263var str = '--\ntitle: Home\n---\nAn excerpt\n---\nOther stuff';
264console.log(matter(str, {excerpt: true}));
265```
266
267Results in:
268
269```js
270{
271 data: { title: 'Home'},
272 excerpt: '\nAn excerpt',
273 content: '\nAn excerpt\n---\nOther stuff'
274}
275```
276
277### options.excerpt_separator
278
279**Type**: `String`
280
281**Default**: `undefined`
282
283Define a custom separator to use for excerpts.
284
285```js
286console.log(matter(string, {excerpt_separator: '<!-- end -->'}));
287```
288
289**Example**
290
291The following HTML string:
292
293```html
294---
295title: Blog
296---
297My awesome blog.
298<!-- end -->
299<h1>Hello world</h1>
300```
301
302Results in:
303
304```js
305{
306 data: { title: 'Blog'},
307 excerpt: 'My awesome blog.',
308 content: 'My awesome blog.\n<!-- end -->\n<h1>Hello world</h1>'
309}
310```
311
312### options.engines
313
314Define custom engines for parsing and/or stringifying front-matter.
315
316**Type**: `Object` Object of engines
317
318**Default**: `JSON`, `YAML` and `JavaScript` are already handled by default.
319
320**Engine format**
321
322Engines may either be an object with `parse` and (optionally) `stringify` methods, or a function that will be used for parsing only.
323
324**Examples**
325
326```js
327var toml = require('toml');
328
329/**
330 * defined as a function
331 */
332
333var file = matter(str, {
334 engines: {
335 toml: toml.parse.bind(toml),
336 }
337});
338
339/**
340 * Or as an object
341 */
342
343var file = matter(str, {
344 engines: {
345 toml: {
346 parse: toml.parse.bind(toml),
347
348 // example of throwing an error to let users know stringifying is
349 // not supported (a TOML stringifier might exist, this is just an example)
350 stringify: function() {
351 throw new Error('cannot stringify to TOML');
352 }
353 }
354 }
355});
356
357console.log(file);
358```
359
360### options.language
361
362**Type**: `String`
363
364**Default**: `yaml`
365
366Define the engine to use for parsing front-matter.
367
368```js
369console.log(matter(string, {language: 'toml'}));
370```
371
372**Example**
373
374The following HTML string:
375
376```html
377---
378title = "TOML"
379description = "Front matter"
380categories = "front matter toml"
381---
382This is content
383```
384
385Results in:
386
387```js
388{ content: 'This is content',
389 excerpt: '',
390 data:
391 { title: 'TOML',
392 description: 'Front matter',
393 categories: 'front matter toml' } }
394```
395
396**Dynamic language detection**
397
398Instead 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.
399
400```html
401---toml
402title = "TOML"
403description = "Front matter"
404categories = "front matter toml"
405---
406This is content
407```
408
409### options.delimiters
410
411**Type**: `String`
412
413**Default**: `---`
414
415Open and close delimiters can be passed in as an array of strings.
416
417**Example:**
418
419```js
420// format delims as a string
421matter.read('file.md', {delims: '~~~'});
422// or an array (open/close)
423matter.read('file.md', {delims: ['~~~', '~~~']});
424```
425
426would parse:
427
428```html
429~~~
430title: Home
431~~~
432This is the {{title}} page.
433```
434
435## Deprecated options
436
437### options.lang
438
439Decrecated, please use [options.language](#optionslanguage) instead.
440
441### options.delims
442
443Decrecated, please use [options.delimiters](#optionsdelimiters) instead.
444
445### options.parsers
446
447Decrecated, please use [options.engines](#optionsengines) instead.
448
449## About
450
451<details>
452<summary><strong>Contributing</strong></summary>
453
454Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
455
456</details>
457
458<details>
459<summary><strong>Running Tests</strong></summary>
460
461Running 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:
462
463```sh
464$ npm install && npm test
465```
466
467</details>
468
469<details>
470<summary><strong>Building docs</strong></summary>
471
472_(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.)_
473
474To generate the readme, run the following command:
475
476```sh
477$ npm install -g verbose/verb#dev verb-generate-readme && verb
478```
479
480</details>
481
482### Related projects
483
484You might also be interested in these projects:
485
486* [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")
487* [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.")
488* [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.")
489
490### Contributors
491
492| **Commits** | **Contributor** |
493| --- | --- |
494| 163 | [jonschlinkert](https://github.com/jonschlinkert) |
495| 7 | [RobLoach](https://github.com/RobLoach) |
496| 5 | [heymind](https://github.com/heymind) |
497| 2 | [doowb](https://github.com/doowb) |
498| 2 | [onokumus](https://github.com/onokumus) |
499| 2 | [moozzyk](https://github.com/moozzyk) |
500| 1 | [Ajedi32](https://github.com/Ajedi32) |
501| 1 | [caesar](https://github.com/caesar) |
502| 1 | [ianstormtaylor](https://github.com/ianstormtaylor) |
503| 1 | [zachwhaley](https://github.com/zachwhaley) |
504
505### Author
506
507**Jon Schlinkert**
508
509* [github/jonschlinkert](https://github.com/jonschlinkert)
510* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)
511
512### License
513
514Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
515Released under the [MIT License](LICENSE).
516
517***
518
519_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on October 19, 2017._
\No newline at end of file