gray-matter
Advanced tools
Comparing version 2.1.1 to 3.0.0
@@ -1,20 +0,15 @@ | ||
declare module "gray-matter" { | ||
export interface GrayMatterOption{ | ||
parser?:Function; | ||
eval?:boolean; | ||
lang?:string; | ||
delims:string; | ||
} | ||
export interface GrayMatter { | ||
(str:string,options?:GrayMatterOption,delims?:Array<string>, | ||
parser?:Function):any; | ||
read(fp:string,options?:GrayMatterOption):any; | ||
stringify(str:string,data:Object,options?:GrayMatterOption):string; | ||
} | ||
declare function matter(str: string, options?: matter.GrayMatterOption): any | ||
var matter:GrayMatter; | ||
export default matter; | ||
declare namespace matter { | ||
interface GrayMatterOption { | ||
parser?: () => void; | ||
eval?: boolean; | ||
lang?: string; | ||
delims?: string | string[]; | ||
} | ||
export function read(fp: string, options?: GrayMatterOption): any; | ||
export function stringify(str: string, data: object, options?: GrayMatterOption): string; | ||
export function test(str: string, options?: GrayMatterOption): string; | ||
} | ||
export = matter |
265
index.js
'use strict'; | ||
var fs = require('fs'); | ||
var extend = require('extend-shallow'); | ||
var parsers = require('./lib/parsers'); | ||
const fs = require('fs'); | ||
const parse = require('./lib/parse'); | ||
const defaults = require('./lib/defaults'); | ||
const stringify = require('./lib/stringify'); | ||
const excerpt = require('./lib/excerpt'); | ||
const engines = require('./lib/engines'); | ||
const toFile = require('./lib/to-file'); | ||
const utils = require('./lib/utils'); | ||
const cache = {}; | ||
/** | ||
* Expose `matter()` | ||
*/ | ||
module.exports = matter; | ||
/** | ||
* Parses a `string` of front-matter with the given `options`, | ||
* and returns an object. | ||
* 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). | ||
* | ||
* ```js | ||
* matter('---\ntitle: foo\n---\nbar'); | ||
* //=> {data: {title: 'foo'}, content: 'bar', orig: '---\ntitle: foo\n---\nbar'} | ||
* var matter = require('gray-matter'); | ||
* console.log(matter('---\ntitle: Home\n---\nOther stuff')); | ||
* //=> { data: { title: 'Home'}, content: 'Other stuff' } | ||
* ``` | ||
* | ||
* @param {String} `string` The string to parse. | ||
* @param {Object|String} `input` String, or object with `content` string | ||
* @param {Object} `options` | ||
* @option {Array} [options] `delims` Custom delimiters formatted as an array. The default is `['---', '---']`. | ||
* @option {Function} [options] `parser` Parser function to use. [js-yaml] is the default. | ||
* @return {Object} Valid JSON | ||
* @return {Object} | ||
* @api public | ||
*/ | ||
function matter(str, options) { | ||
if (typeof str !== 'string') { | ||
throw new Error('gray-matter expects a string'); | ||
} | ||
function matter(input, options) { | ||
const file = toFile(input); | ||
let str = file.content; | ||
// default results to build up | ||
var res = {orig: str, data: {}, content: str}; | ||
if (str === '') { | ||
return res; | ||
if (str === '') return file; | ||
if (typeof options === 'undefined') { | ||
if (cache[str]) { | ||
return cache[str]; | ||
} | ||
cache[str] = file; | ||
} | ||
// delimiters | ||
var delims = arrayify((options && options.delims) || '---'); | ||
var a = delims[0]; | ||
// support "options.delims" for backward compatibility | ||
const opts = defaults(options); | ||
const open = opts.delimiters[0]; | ||
const close = '\n' + opts.delimiters[1]; | ||
// strip byte order marks | ||
str = stripBom(str); | ||
if (opts.language) { | ||
file.language = opts.language; | ||
} | ||
// if the first delim isn't the first thing, return | ||
if (!isFirst(str, a)) { | ||
return res; | ||
const openLen = open.length; | ||
if (!utils.startsWith(str, open, openLen)) { | ||
excerpt(file, opts); | ||
return file; | ||
} | ||
var b = '\n' + (delims[1] || delims[0]); | ||
var alen = a.length; | ||
// if the next character after the first delim | ||
// is a character in the first delim, then just | ||
// return the default object. it's either a bad | ||
// delim or not a delimiter at all. | ||
if (a.indexOf(str.charAt(alen + 1)) !== -1) { | ||
return res; | ||
const nextChar = str.charAt(openLen); | ||
if (nextChar === open.slice(-1)) { | ||
return file; | ||
} | ||
str = str.slice(openLen); | ||
var len = str.length; | ||
// find the index of the next delimiter before | ||
// going any further. If not found, return. | ||
var end = str.indexOf(b, alen + 1); | ||
if (end === -1) { | ||
end = len; | ||
// use the language defined after first delimiter, if it exists | ||
var language = matter.language(str, opts); | ||
if (language.name) { | ||
file.language = language.name; | ||
str = str.slice(language.raw.length); | ||
} | ||
// detect a language, if defined | ||
var lang = str.slice(alen, str.indexOf('\n')); | ||
// measure the lang before trimming whitespace | ||
var start = alen + lang.length; | ||
// get the index of the closing delimiter | ||
let closeIndex = str.indexOf(close); | ||
if (closeIndex === -1) { | ||
closeIndex = len; | ||
} | ||
var opts = options || {}; | ||
opts.lang = opts.lang || 'yaml'; | ||
lang = (lang && lang.trim()) || opts.lang; | ||
// get the raw front-matter block | ||
file.matter = str.slice(0, closeIndex); | ||
// get the front matter (data) string | ||
var data = str.slice(start, end).trim(); | ||
if (data) { | ||
// if data exists, see if we have a matching parser | ||
var fn = opts.parser || parsers[lang]; | ||
if (typeof fn === 'function') { | ||
// run the parser on the data string | ||
res.data = fn(data, opts); | ||
} else { | ||
throw new Error('gray-matter cannot find a parser for: ' + str); | ||
// create file.data by parsing the raw file.matter block | ||
file.data = parse(file.language, file.matter, opts); | ||
// update file.content | ||
if (closeIndex !== len) { | ||
file.content = str.slice(closeIndex + close.length); | ||
if (file.content.charAt(0) === '\r') { | ||
file.content = file.content.slice(1); | ||
} | ||
if (file.content.charAt(0) === '\n') { | ||
file.content = file.content.slice(1); | ||
} | ||
} else { | ||
file.content = ''; | ||
} | ||
// grab the content from the string, stripping | ||
// an optional new line after the second delim | ||
var con = str.substr(end + b.length); | ||
if (con.charAt(0) === '\n') { | ||
con = con.substr(1); | ||
} else if (con.charAt(0) === '\r' && con.charAt(1) === '\n') { | ||
con = con.substr(2); | ||
} | ||
res.content = con; | ||
return res; | ||
excerpt(file, opts); | ||
return file; | ||
} | ||
/** | ||
* Expose `parsers` | ||
* | ||
* @type {Object} | ||
* Expose engines | ||
*/ | ||
matter.parsers = parsers; | ||
matter.engines = engines; | ||
/** | ||
* Requires cache | ||
*/ | ||
var YAML = matter.parsers.requires.yaml || (matter.parsers.requires.yaml = require('js-yaml')); | ||
/** | ||
* Read a file and parse front matter. Returns the same object | ||
* as `matter()`. | ||
* 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. | ||
* | ||
* ```js | ||
* matter.read('home.md'); | ||
* console.log(matter.stringify('foo bar baz', {title: 'Home'})); | ||
* // results in: | ||
* // --- | ||
* // title: Home | ||
* // --- | ||
* // foo bar baz | ||
* ``` | ||
* | ||
* @param {String} `fp` file path of the file to read. | ||
* @param {Object} `options` Options to pass to gray-matter. | ||
* @return {Object} | ||
* @param {String|Object} `file` The content string to append to stringified front-matter, or a file object with `file.content` string. | ||
* @param {Object} `data` Front matter to stringify. | ||
* @param {Object} `options` [Options](#options) to pass to gray-matter and [js-yaml]. | ||
* @return {String} Returns a string created by wrapping stringified yaml with delimiters, and appending that to the given string. | ||
* @api public | ||
*/ | ||
matter.read = function(fp, options) { | ||
var str = fs.readFileSync(fp, 'utf8'); | ||
var obj = matter(str, options); | ||
return extend(obj, { | ||
path: fp | ||
}); | ||
matter.stringify = function(file, data, options) { | ||
if (typeof file === 'string') { | ||
file = matter(file, options); | ||
} | ||
return stringify(file, data, options); | ||
}; | ||
/** | ||
* Stringify an object to front-matter-formatted YAML, and | ||
* concatenate it to the given string. | ||
* Synchronously read a file from the file system and parse | ||
* front matter. Returns the same object as the [main function](#matter). | ||
* | ||
* ```js | ||
* matter.stringify('foo bar baz', {title: 'Home'}); | ||
* var file = matter.read('./content/blog-post.md'); | ||
* ``` | ||
* Results in: | ||
* | ||
* ```yaml | ||
* --- | ||
* title: Home | ||
* --- | ||
* foo bar baz | ||
* ``` | ||
* | ||
* @param {String} `str` The content string to append to stringified front-matter. | ||
* @param {Object} `data` Front matter to stringify. | ||
* @param {Object} `options` Options to pass to js-yaml | ||
* @return {String} | ||
* @param {String} `filepath` file path of the file to read. | ||
* @param {Object} `options` [Options](#options) to pass to gray-matter. | ||
* @return {Object} Returns [an object](#returned-object) with `data` and `content` | ||
* @api public | ||
*/ | ||
matter.stringify = function(str, data, options) { | ||
var delims = arrayify(options && options.delims || '---'); | ||
var res = ''; | ||
res += delims[0] + '\n'; | ||
res += YAML.safeDump(data, options); | ||
res += (delims[1] || delims[0]) + '\n'; | ||
res += str + '\n'; | ||
return res; | ||
matter.read = function(filepath, options) { | ||
const str = fs.readFileSync(filepath, 'utf8'); | ||
const file = matter(str, options); | ||
file.path = filepath; | ||
return file; | ||
}; | ||
/** | ||
* Return true if the given `string` has front matter. | ||
* | ||
* Returns true if the given `string` has front matter. | ||
* @param {String} `string` | ||
* @param {Object} `options` | ||
* @return {Boolean} True if front matter exists. | ||
* @api public | ||
*/ | ||
matter.test = function(str, options) { | ||
var delims = arrayify(options && options.delims || '---'); | ||
return isFirst(str, delims[0]); | ||
const opts = defaults(options); | ||
return utils.startsWith(str, opts.delimiters[0]); | ||
}; | ||
/** | ||
* Return true if the given `ch` the first | ||
* thing in the string. | ||
* Detect the language to use, if one is defined after the | ||
* first front-matter delimiter. | ||
* @param {String} `string` | ||
* @param {Object} `options` | ||
* @return {Object} Object with `raw` (actual language string), and `name`, the language with whitespace trimmed | ||
*/ | ||
function isFirst(str, ch) { | ||
return str.substr(0, ch.length) === ch; | ||
} | ||
matter.language = function(str, options) { | ||
const opts = defaults(options); | ||
const open = opts.delimiters[0]; | ||
/** | ||
* Utility to strip byte order marks | ||
*/ | ||
if (matter.test(str)) { | ||
str = str.slice(open.length); | ||
} | ||
function stripBom(str) { | ||
return str.charAt(0) === '\uFEFF' ? str.slice(1) : str; | ||
} | ||
const language = str.slice(0, str.search(/\r?\n/)); | ||
return { | ||
raw: language, | ||
name: language ? language.trim() : '' | ||
}; | ||
}; | ||
/** | ||
* Typecast `val` to an array. | ||
* Expose `matter` | ||
*/ | ||
function arrayify(val) { | ||
return !Array.isArray(val) ? [val] : val; | ||
} | ||
module.exports = matter; |
{ | ||
"name": "gray-matter", | ||
"description": "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.", | ||
"version": "2.1.1", | ||
"version": "3.0.0", | ||
"homepage": "https://github.com/jonschlinkert/gray-matter", | ||
@@ -9,7 +9,9 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"Andrew Meyer (https://github.com/Ajedi32)", | ||
"Brian Woodward <brian.woodward@gmail.com> (https://github.com/doowb)", | ||
"Brian Woodward (https://twitter.com/doowb)", | ||
"Ian Storm Taylor (http://ianstormtaylor.com)", | ||
"Jon Schlinkert <jon.schlinkert@sellside.com> (http://twitter.com/jonschlinkert)", | ||
"Jon Schlinkert (http://twitter.com/jonschlinkert)", | ||
"Osman Nuri Okumuş (http://onokumus.com)", | ||
"Pawel Kadluczka (http://blog.3d-logic.com)", | ||
"Rob Loach <robloach@gmail.com> (http://robloach.net)" | ||
"Rob Loach (http://robloach.net)", | ||
"(https://github.com/heymind)" | ||
], | ||
@@ -34,7 +36,5 @@ "repository": "jonschlinkert/gray-matter", | ||
"dependencies": { | ||
"ansi-red": "^0.1.1", | ||
"coffee-script": "^1.12.4", | ||
"extend-shallow": "^2.0.1", | ||
"js-yaml": "^3.8.1", | ||
"toml": "^2.3.2" | ||
"kind-of": "^5.0.0", | ||
"strip-bom-string": "^1.0.0" | ||
}, | ||
@@ -44,16 +44,16 @@ "devDependencies": { | ||
"ansi-gray": "^0.1.1", | ||
"ansi-magenta": "^0.1.1", | ||
"benchmarked": "^0.2.5", | ||
"coffee-script": "^1.12.6", | ||
"delimiter-regex": "^2.0.0", | ||
"extend-shallow": "^2.0.1", | ||
"for-own": "^0.1.4", | ||
"front-matter": "^2.1.2", | ||
"glob": "^7.1.1", | ||
"gulp": "^3.9.1", | ||
"gulp-eslint": "^3.0.1", | ||
"gulp-format-md": "^0.1.11", | ||
"gulp-istanbul": "^1.1.1", | ||
"gulp-mocha": "^4.0.1", | ||
"lodash": "^4.17.4", | ||
"gulp-format-md": "^0.1.12", | ||
"matched": "^1.0.2", | ||
"minimist": "^1.2.0", | ||
"should": "^11.2.0", | ||
"sort-object": "^3.0.2" | ||
"mocha": "^3.2.0", | ||
"sort-object": "^3.0.2", | ||
"toml": "^2.3.2", | ||
"vinyl": "^2.0.2" | ||
}, | ||
@@ -94,9 +94,2 @@ "keywords": [ | ||
"verb": { | ||
"related": { | ||
"list": [ | ||
"assemble", | ||
"metalsmith", | ||
"verb" | ||
] | ||
}, | ||
"toc": false, | ||
@@ -110,12 +103,23 @@ "layout": "default", | ||
], | ||
"helpers": { | ||
"examples": "./examples/helper.js" | ||
}, | ||
"lint": { | ||
"reflinks": true | ||
}, | ||
"related": { | ||
"list": [ | ||
"assemble", | ||
"metalsmith", | ||
"verb" | ||
] | ||
}, | ||
"reflinks": [ | ||
"assemble", | ||
"front-matter", | ||
"verb", | ||
"verb-generate-readme" | ||
"coffe-script", | ||
"generate", | ||
"js-yaml", | ||
"toml", | ||
"update" | ||
] | ||
} | ||
} |
516
README.md
@@ -1,2 +0,2 @@ | ||
# 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) | ||
# 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) | ||
@@ -13,112 +13,220 @@ > 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. | ||
See the [benchmarks](#benchmarks). gray-matter is 20-30x faster than [front-matter](https://github.com/jxson/front-matter). | ||
## Heads up! | ||
## Highlights | ||
Please see the [release history](#release-history) to learn about breaking changes that were made in v3.0. | ||
* Reliable and battle-tested by [metalsmith](https://github.com/segmentio/metalsmith), [assemble](https://github.com/assemble/assemble), [verb](https://github.com/assemble/verb), and many other projects! | ||
* Extracts and parses: | ||
- [YAML](http://github.com/nodeca/js-yaml) | ||
- [JSON](http://en.wikipedia.org/wiki/Json) | ||
- [TOML](http://github.com/mojombo/toml) | ||
- [CoffeeScript](http://coffeescript.org) when `options.eval` is set to `true` | ||
- [CSON](https://github.com/bevry/cson) when `options.eval` is set to `true` | ||
- JavaScript: when `options.eval` is set to `true` | ||
* Easy to add additional parsers! pull requests welcome! | ||
## What does this do? | ||
<details> | ||
<summary><strong>Run this example</strong></summary> | ||
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 | ||
var fs = require('fs'); | ||
var matter = require('gray-matter'); | ||
var str = fs.readFileSync('example.html', 'utf8'); | ||
console.log(matter(str)); | ||
``` | ||
</details> | ||
Converts a string with front-matter, like this: | ||
```handlebars | ||
--- | ||
title: Hello | ||
slug: home | ||
--- | ||
<h1>Hello world!</h1> | ||
``` | ||
Into an object like this: | ||
```js | ||
{ | ||
content: '<h1>Hello world!</h1>', | ||
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](https://github.com/nodeca/js-yaml), [JSON](http://en.wikipedia.org/wiki/Json) and JavaScript front-matter. But other [engines](#engines) may be added. | ||
* **extensible**: Use [custom delimiters](#optionsdelimiters), or add support for [any language](#engines), like [TOML](http://github.com/mojombo/toml), [CoffeeScript](http://coffeescript.org), or [CSON](https://github.com/bevry/cson) | ||
* **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. | ||
<details> | ||
<summary><strong>Rationale</strong></summary> | ||
**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 (for debugging): | ||
- `data`: the parsed YAML front matter, as a JSON object | ||
- `content`: the contents as a string, without the front matter | ||
- `orig`: the "original" content | ||
</details> | ||
## Usage | ||
Using Node's `require()` system: | ||
```js | ||
var matter = require('gray-matter'); | ||
matter('---\ntitle: Front Matter\n---\nThis is content.'); | ||
``` | ||
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 | ||
{ | ||
orig: '---\ntitle: Front Matter\n---\nThis is content.', | ||
data: { title: 'Front Matter' }, | ||
content: '\nThis is content.' | ||
{ | ||
content: '\nThis is content.', | ||
data: { | ||
title: 'Front Matter' | ||
} | ||
} | ||
``` | ||
That's it! Just pass a string and gray-matter returns an object. | ||
More about the returned object in the following section. | ||
*** | ||
## API | ||
## Returned object | ||
### [matter](index.js#L30) | ||
gray-matter returns a `file` object with the following properties. | ||
Parses a `string` of front-matter with the given `options`, and returns an object. | ||
**Enumerable** | ||
**Example** | ||
* `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) | ||
```js | ||
matter('---\ntitle: foo\n---\nbar'); | ||
//=> {data: {title: 'foo'}, content: 'bar', orig: '---\ntitle: foo\n---\nbar'} | ||
``` | ||
**Non-enumerable** | ||
**Params** | ||
In addition, the following non-enumberable properties are added to the object to help with debugging. | ||
* `string` **{String}**: The string to parse. | ||
* `options` **{Object}** | ||
* `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 appending it to `file.content`. | ||
- `delims` **{Array}**: Custom delimiters formatted as an array. The default is `['---', '---']`. | ||
- `parser` **{Function}**: Parser function to use. [js-yaml] is the default. | ||
* `returns` **{Object}**: Valid JSON | ||
## Run the examples | ||
### [.read](index.js#L136) | ||
If you'd like to test-drive the examples, first clone gray-matter into `my-project` (or wherever you want): | ||
Read a file and parse front matter. Returns the same object as `matter()`. | ||
```sh | ||
$ git clone https://github.com/jonschlinkert/gray-matter my-project | ||
``` | ||
**Example** | ||
CD into `my-project` and install dependencies: | ||
```js | ||
matter.read('home.md'); | ||
```sh | ||
$ cd my-project && npm install | ||
``` | ||
**Params** | ||
Then run any of the [examples](./examples) to see how gray-matter works: | ||
* `fp` **{String}**: file path of the file to read. | ||
* `options` **{Object}**: Options to pass to gray-matter. | ||
* `returns` **{Object}** | ||
```sh | ||
$ node examples/<example_name> | ||
``` | ||
### [.stringify](index.js#L167) | ||
* [coffee](examples/coffee.js) | ||
* [excerpt-separator](examples/excerpt-separator.js) | ||
* [excerpt-stringify](examples/excerpt-stringify.js) | ||
* [excerpt](examples/excerpt.js) | ||
* [javascript](examples/javascript.js) | ||
* [json-stringify](examples/json-stringify.js) | ||
* [json](examples/json.js) | ||
* [toml](examples/toml.js) | ||
* [yaml-stringify](examples/yaml-stringify.js) | ||
* [yaml](examples/yaml.js) | ||
Stringify an object to front-matter-formatted YAML, and concatenate it to the given string. | ||
## API | ||
Results in: | ||
### [matter](index.js#L29) | ||
**Examples** | ||
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). | ||
**Params** | ||
* `input` **{Object|String}**: String, or object with `content` string | ||
* `options` **{Object}** | ||
* `returns` **{Object}** | ||
**Example** | ||
```js | ||
matter.stringify('foo bar baz', {title: 'Home'}); | ||
var matter = require('gray-matter'); | ||
console.log(matter('---\ntitle: Home\n---\nOther stuff')); | ||
//=> { data: { title: 'Home'}, content: 'Other stuff' } | ||
``` | ||
```yaml | ||
--- | ||
title: Home | ||
--- | ||
foo bar baz | ||
``` | ||
### [.stringify](index.js#L127) | ||
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. | ||
**Params** | ||
* `str` **{String}**: The content string to append to stringified front-matter. | ||
* `file` **{String|Object}**: The content string to append to stringified front-matter, or a file object with `file.content` string. | ||
* `data` **{Object}**: Front matter to stringify. | ||
* `options` **{Object}**: Options to pass to js-yaml | ||
* `returns` **{String}** | ||
* `options` **{Object}**: [Options](#options) to pass to gray-matter and [js-yaml](https://github.com/nodeca/js-yaml). | ||
* `returns` **{String}**: Returns a string created by wrapping stringified yaml with delimiters, and appending that to the given string. | ||
## Options | ||
**Example** | ||
> All methods exposed on the API accept an options object passed as the last argument | ||
```js | ||
console.log(matter.stringify('foo bar baz', {title: 'Home'})); | ||
// results in: | ||
// --- | ||
// title: Home | ||
// --- | ||
// foo bar baz | ||
``` | ||
## options.parser | ||
### [.read](index.js#L147) | ||
Type: `Function` | ||
Synchronously read a file from the file system and parse front matter. Returns the same object as the [main function](#matter). | ||
Default: `undefined` | ||
**Params** | ||
Pass a custom parser on the options. This is useful if you need to, for example, define custom schemas for [js-yaml]. | ||
* `filepath` **{String}**: file path of the file to read. | ||
* `options` **{Object}**: [Options](#options) to pass to gray-matter. | ||
* `returns` **{Object}**: Returns [an object](#returned-object) with `data` and `content` | ||
@@ -128,167 +236,227 @@ **Example** | ||
```js | ||
matter(str, { | ||
parser: require('js-yaml').safeLoad | ||
}); | ||
var file = matter.read('./content/blog-post.md'); | ||
``` | ||
## options.eval | ||
### [.test](index.js#L162) | ||
Type: `Boolean` | ||
Returns true if the given `string` has front matter. | ||
Default: `false` | ||
**Params** | ||
Evaluate coffee-script, CSON or JavaScript in front-matter. If you aren't aware of the dangers, google is your friend. | ||
* `string` **{String}** | ||
* `options` **{Object}** | ||
* `returns` **{Boolean}**: True if front matter exists. | ||
However, if you are aware and you only use front-matter on, say, blog posts for a static site... this feature can be pretty useful. | ||
## Options | ||
## options.lang | ||
### options.excerpt | ||
Type: `String` | ||
**Type**: `Object` | ||
Default: `yaml` | ||
**Default**: `undefined` | ||
The parser to use on the extracted front matter. | ||
Extract an excerpt that directly follows front-matter, or is the first thing in the string if no front-matter exists. | ||
YAML is parsed by default, and the languages listed below are parsed automatically if the language is specified after the first delimiter (e.g. `---`). | ||
**Example** | ||
Valid languages are: | ||
```js | ||
var str = '--\ntitle: Home\n---\nAn excerpt\n---\nOther stuff'; | ||
console.log(matter(str, {excerpt: true})); | ||
``` | ||
* `yaml` | ||
* `json` | ||
* `coffee` | ||
* `cson` | ||
* `toml` | ||
* `js`|`javascript` | ||
Results in: | ||
```js | ||
{ | ||
data: { title: 'Home'}, | ||
excerpt: '\nAn excerpt', | ||
content: '\nAn excerpt\n---\nOther stuff' | ||
} | ||
``` | ||
### options.excerpt_separator | ||
**Type**: `String` | ||
**Default**: `undefined` | ||
Define a custom separator to use for excerpts. | ||
```js | ||
console.log(matter(string, {excerpt_separator: '<!-- end -->'})); | ||
``` | ||
**Example** | ||
To parse coffee front matter, you would define it as follows: | ||
The following HTML string: | ||
```js | ||
---coffee | ||
title: 'coffee functions' | ||
user: 'jonschlinkert' | ||
fn: | ||
reverse = (src) -> | ||
src.split('').reverse().join('') | ||
```html | ||
--- | ||
title: Blog | ||
--- | ||
My awesome blog. | ||
<!-- end --> | ||
<h1>Hello world</h1> | ||
``` | ||
<%= description %> | ||
<%= reverse(user) %> | ||
Results in: | ||
```js | ||
{ | ||
data: { title: 'Blog'}, | ||
excerpt: 'My awesome blog.', | ||
content: 'My awesome blog.\n<!-- end -->\n<h1>Hello world</h1>' | ||
} | ||
``` | ||
## options.delims | ||
### options.engines | ||
Type: `String` | ||
Define custom engines for parsing and/or stringifying front-matter. | ||
Default: `---` | ||
**Type**: `Object` Object of engines | ||
Open and close delimiters can be passed in as an array of strings. | ||
**Default**: `JSON`, `YAML` and `JavaScript` are already handled by default. | ||
**Example:** | ||
**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 | ||
// format delims as a string | ||
matter.read('file.md', {delims: '~~~'}); | ||
// or an array (open/close) | ||
matter.read('file.md', {delims: ['~~~', '~~~']}); | ||
var toml = require('toml'); | ||
/** | ||
* defined as a function | ||
*/ | ||
var file = matter(str, { | ||
engines: { | ||
toml: toml.parse.bind(toml), | ||
} | ||
}); | ||
/** | ||
* Or as an object | ||
*/ | ||
var 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); | ||
``` | ||
would parse: | ||
### options.language | ||
<pre> | ||
**Type**: `String` | ||
**Default**: `yaml` | ||
Define the engine to use for parsing front-matter. | ||
```js | ||
console.log(matter(string, {language: 'toml'})); | ||
``` | ||
title: Home | ||
``` | ||
This is the page. | ||
</pre> | ||
**Example** | ||
## Example usage | ||
The following HTML string: | ||
Given we have a page, `abc.html`, containing: | ||
```html | ||
--- | ||
title: YAML Front matter | ||
description: This is a page | ||
title = "TOML" | ||
description = "Front matter" | ||
categories = "front matter toml" | ||
--- | ||
<h1></h1> | ||
This is content | ||
``` | ||
then running the following in the command line: | ||
Results in: | ||
```js | ||
matter('abc.html'); | ||
{ content: 'This is content', | ||
excerpt: '', | ||
data: | ||
{ title: 'TOML', | ||
description: 'Front matter', | ||
categories: 'front matter toml' } } | ||
``` | ||
returns | ||
**Dynamic language detection** | ||
```json | ||
{ | ||
"data": { | ||
"title": "YAML Front matter", | ||
"description": "This is a page" | ||
}, | ||
"content": "<h1></h1>", | ||
"original": "---\ntitle: YAML Front matter\n---\n<h1></h1>" | ||
} | ||
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 | ||
``` | ||
## Benchmarks | ||
### options.delimiters | ||
**Benchmarks for building the [bootstrap-blog](https://github.com/twbs/bootstrap-blog/tree/gh-pages/_posts)** | ||
**Type**: `String` | ||
gray-matter would process all markdown posts in the [bootstrap-blog](https://github.com/twbs/bootstrap-blog/tree/gh-pages/_posts) **20 times** before the [front-matter](https://github.com/jxson/front-matter) library finished processing it once. | ||
**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: ['~~~', '~~~']}); | ||
``` | ||
front-matter.js x 271 ops/sec ±2.68% (80 runs sampled) | ||
gray-matter.js x 4,294 ops/sec ±0.86% (91 runs sampled) | ||
would parse: | ||
```html | ||
~~~ | ||
title: Home | ||
~~~ | ||
This is the {{title}} page. | ||
``` | ||
**Misc** | ||
## Deprecated options | ||
gray-matter is 12-20x faster than [front-matter](https://github.com/jxson/front-matter) when content or front matter actually exist. | ||
### options.lang | ||
```bash | ||
#1: complex | ||
front-matter x 338 ops/sec ±1.60% (85 runs sampled) | ||
gray-matter x 10,608 ops/sec ±1.97% (86 runs sampled) | ||
Decrecated, please use [options.language](#optionslanguage) instead. | ||
#2: empty | ||
front-matter x 5,755,004 ops/sec ±0.88% (94 runs sampled) | ||
gray-matter x 15,157,998 ops/sec ±0.81% (95 runs sampled) | ||
### options.delims | ||
#3: matter | ||
front-matter x 10,256 ops/sec ±2.18% (92 runs sampled) | ||
gray-matter x 202,026 ops/sec ±0.71% (93 runs sampled) | ||
Decrecated, please use [options.delimiters](#optionsdelimiters) instead. | ||
#4: no-content | ||
front-matter x 10,136 ops/sec ±2.00% (91 runs sampled) | ||
gray-matter x 206,548 ops/sec ±1.16% (94 runs sampled) | ||
### options.parsers | ||
#5: no-matter | ||
front-matter x 3,540,817 ops/sec ±0.68% (95 runs sampled) | ||
gray-matter x 7,959,809 ops/sec ±0.73% (91 runs sampled) | ||
``` | ||
Decrecated, please use [options.engines](#optionsengines) instead. | ||
## Why? | ||
## Release history | ||
> Why another YAML Front Matter library? | ||
### v3.0.0 - June 30, 2007 | ||
Because other libraries we tried failed to meet our requirements with [Assemble](https://github.com/assemble/assemble). Some most of the libraries met most of the requirements, but _none had all of them_. Here are the most important: | ||
* adds support for [excerpts](#optionsexcerpt) | ||
* refactored engines (parsers), so that it's easier to add parsers and stringifiers | ||
* `options.parsers` was renamed to [options.engines](#optionsengines) | ||
* the returned object now has non-enumerable `matter` and `stringify` properties | ||
* Be usable, if not simple | ||
* Allow custom delimiters | ||
* Use a dependable and well-supported library for parsing YAML and other languages | ||
* Don't fail when no content exists | ||
* Don't fail when no front matter exists | ||
* 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. | ||
* Should return an object with 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 | ||
**Breaking changes** | ||
* `toml`, `coffee` and `cson` are no longer supported by default. Please see [options.engines](#optionsengine) and the [examples](./examples) to learn how to add engines. | ||
## About | ||
@@ -308,7 +476,9 @@ | ||
| **Commits** | **Contributor**<br/> | | ||
| **Commits** | **Contributor** | | ||
| --- | --- | | ||
| 121 | [jonschlinkert](https://github.com/jonschlinkert) | | ||
| 128 | [jonschlinkert](https://github.com/jonschlinkert) | | ||
| 7 | [RobLoach](https://github.com/RobLoach) | | ||
| 5 | [heymind](https://github.com/heymind) | | ||
| 2 | [doowb](https://github.com/doowb) | | ||
| 2 | [onokumus](https://github.com/onokumus) | | ||
| 2 | [moozzyk](https://github.com/moozzyk) | | ||
@@ -320,8 +490,8 @@ | 1 | [Ajedi32](https://github.com/Ajedi32) | | ||
_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ | ||
_(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.)_ | ||
To generate the readme and API documentation with [verb](https://github.com/verbose/verb): | ||
To generate the readme, run the following command: | ||
```sh | ||
$ npm install -g verb verb-generate-readme && verb | ||
$ npm install -g verbose/verb#dev verb-generate-readme && verb | ||
``` | ||
@@ -331,6 +501,6 @@ | ||
Install dev dependencies: | ||
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: | ||
```sh | ||
$ npm install -d && npm test | ||
$ npm install && npm test | ||
``` | ||
@@ -343,11 +513,11 @@ | ||
* [github/jonschlinkert](https://github.com/jonschlinkert) | ||
* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) | ||
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert) | ||
### License | ||
Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
Released under the [MIT license](https://github.com/jonschlinkert/gray-matter/blob/master/LICENSE). | ||
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
Released under the [MIT License](LICENSE). | ||
*** | ||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.2.0, on October 25, 2016._ | ||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on June 30, 2017._ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
31724
3
13
447
517
2
+ Addedkind-of@^5.0.0
+ Addedstrip-bom-string@^1.0.0
+ Addedkind-of@5.1.0(transitive)
+ Addedstrip-bom-string@1.0.0(transitive)
- Removedansi-red@^0.1.1
- Removedcoffee-script@^1.12.4
- Removedextend-shallow@^2.0.1
- Removedtoml@^2.3.2
- Removedansi-red@0.1.1(transitive)
- Removedansi-wrap@0.1.0(transitive)
- Removedcoffee-script@1.12.7(transitive)
- Removedextend-shallow@2.0.1(transitive)
- Removedis-extendable@0.1.1(transitive)
- Removedtoml@2.3.6(transitive)