README.md (16646B)
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 5 Please 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 9 Install with [npm](https://www.npmjs.com/): 10 11 ```sh 12 $ npm install --save gray-matter 13 ``` 14 15 ## Heads up! 16 17 Please 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 24 Add 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 27 const fs = require('fs'); 28 const matter = require('gray-matter'); 29 const str = fs.readFileSync('example.html', 'utf8'); 30 console.log(matter(str)); 31 ``` 32 33 </details> 34 35 Converts a string with front-matter, like this: 36 37 ```handlebars 38 --- 39 title: Hello 40 slug: home 41 --- 42 <h1>Hello world!</h1> 43 ``` 44 45 Into 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 71 We created gray-matter after trying out other libraries that failed to meet our standards and requirements. 72 73 Some 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 97 Using Node's `require()` system: 98 99 ```js 100 const matter = require('gray-matter'); 101 ``` 102 103 Or with [typescript](https://www.typescriptlang.org) 104 105 ```js 106 import matter = require('gray-matter'); 107 // OR 108 import * as matter from 'gray-matter'; 109 ``` 110 111 Pass a string and [options](#options) to gray-matter: 112 113 ```js 114 console.log(matter('---\ntitle: Front Matter\n---\nThis is content.')); 115 ``` 116 117 Returns: 118 119 ```js 120 { 121 content: '\nThis is content.', 122 data: { 123 title: 'Front Matter' 124 } 125 } 126 ``` 127 128 More about the returned object in the following section. 129 130 *** 131 132 ## Returned object 133 134 gray-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 146 In 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 155 If 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 161 CD into `my-project` and install dependencies: 162 163 ```sh 164 $ cd my-project && npm install 165 ``` 166 167 Then 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 193 Takes 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 204 const matter = require('gray-matter'); 205 console.log(matter('---\ntitle: Home\n---\nOther stuff')); 206 //=> { data: { title: 'Home'}, content: 'Other stuff' } 207 ``` 208 209 ### [.stringify](index.js#L160) 210 211 Stringify 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 223 console.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 233 Synchronously 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 244 const file = matter.read('./content/blog-post.md'); 245 ``` 246 247 ### [.test](index.js#L193) 248 249 Returns 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 265 Extract an excerpt that directly follows front-matter, or is the first thing in the string if no front-matter exists. 266 267 If 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 272 const str = '---\nfoo: bar\n---\nThis is an excerpt.\n---\nThis is content'; 273 const file = matter(str, { excerpt: true }); 274 ``` 275 276 Results 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 286 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. 287 288 **Example** 289 290 ```js 291 // returns the first 4 lines of the contents 292 function firstFourLines(file, options) { 293 file.excerpt = file.content.split('\n').slice(0, 4).join(' '); 294 } 295 296 const 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 308 Results 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 324 Define a custom separator to use for excerpts. 325 326 ```js 327 console.log(matter(string, {excerpt_separator: '<!-- end -->'})); 328 ``` 329 330 **Example** 331 332 The following HTML string: 333 334 ```html 335 --- 336 title: Blog 337 --- 338 My awesome blog. 339 <!-- end --> 340 <h1>Hello world</h1> 341 ``` 342 343 Results 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 355 Define 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 363 Engines 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 368 const toml = require('toml'); 369 370 /** 371 * defined as a function 372 */ 373 374 const file = matter(str, { 375 engines: { 376 toml: toml.parse.bind(toml), 377 } 378 }); 379 380 /** 381 * Or as an object 382 */ 383 384 const 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 398 console.log(file); 399 ``` 400 401 ### options.language 402 403 **Type**: `String` 404 405 **Default**: `yaml` 406 407 Define the engine to use for parsing front-matter. 408 409 ```js 410 console.log(matter(string, {language: 'toml'})); 411 ``` 412 413 **Example** 414 415 The following HTML string: 416 417 ```html 418 --- 419 title = "TOML" 420 description = "Front matter" 421 categories = "front matter toml" 422 --- 423 This is content 424 ``` 425 426 Results 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 439 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. 440 441 ```html 442 ---toml 443 title = "TOML" 444 description = "Front matter" 445 categories = "front matter toml" 446 --- 447 This is content 448 ``` 449 450 ### options.delimiters 451 452 **Type**: `String` 453 454 **Default**: `---` 455 456 Open and close delimiters can be passed in as an array of strings. 457 458 **Example:** 459 460 ```js 461 // format delims as a string 462 matter.read('file.md', {delims: '~~~'}); 463 // or an array (open/close) 464 matter.read('file.md', {delims: ['~~~', '~~~']}); 465 ``` 466 467 would parse: 468 469 ```html 470 ~~~ 471 title: Home 472 ~~~ 473 This is the {{title}} page. 474 ``` 475 476 ## Deprecated options 477 478 ### options.lang 479 480 Decrecated, please use [options.language](#optionslanguage) instead. 481 482 ### options.delims 483 484 Decrecated, please use [options.delimiters](#optionsdelimiters) instead. 485 486 ### options.parsers 487 488 Decrecated, please use [options.engines](#optionsengines) instead. 489 490 ## About 491 492 <details> 493 <summary><strong>Contributing</strong></summary> 494 495 Pull 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 502 Running 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 515 To 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 525 You 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 531 ### Contributors 532 533 | **Commits** | **Contributor** | 534 | --- | --- | 535 | 174 | [jonschlinkert](https://github.com/jonschlinkert) | 536 | 7 | [RobLoach](https://github.com/RobLoach) | 537 | 5 | [heymind](https://github.com/heymind) | 538 | 4 | [doowb](https://github.com/doowb) | 539 | 3 | [aljopro](https://github.com/aljopro) | 540 | 2 | [reccanti](https://github.com/reccanti) | 541 | 2 | [onokumus](https://github.com/onokumus) | 542 | 2 | [moozzyk](https://github.com/moozzyk) | 543 | 1 | [Ajedi32](https://github.com/Ajedi32) | 544 | 1 | [caesar](https://github.com/caesar) | 545 | 1 | [ianstormtaylor](https://github.com/ianstormtaylor) | 546 | 1 | [qm3ster](https://github.com/qm3ster) | 547 | 1 | [zachwhaley](https://github.com/zachwhaley) | 548 549 ### Author 550 551 **Jon Schlinkert** 552 553 * [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) 554 * [GitHub Profile](https://github.com/jonschlinkert) 555 * [Twitter Profile](https://twitter.com/jonschlinkert) 556 557 ### License 558 559 Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert). 560 Released under the [MIT License](LICENSE). 561 562 *** 563 564 _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on April 01, 2018._