Giter Site home page Giter Site logo

jonschlinkert / gray-matter Goto Github PK

View Code? Open in Web Editor NEW
3.8K 27.0 133.0 338 KB

Smarter YAML front matter parser, used by metalsmith, Gatsby, Netlify, Assemble, mapbox-gl, phenomic, vuejs vitepress, TinaCMS, Shopify Polaris, Ant Design, Astro, hashicorp, garden, slidev, saber, sourcegraph, and many others. Simple to use, and battle tested. Parses YAML by default but can also parse JSON Front Matter, Coffee Front Matter, TOML Front Matter, and has support for custom parsers. Please follow gray-matter's author: https://github.com/jonschlinkert

Home Page: https://github.com/jonschlinkert

License: MIT License

JavaScript 100.00%
yaml front-matter matter javascript parse markdown data gatsby assemble phenomic

gray-matter's Introduction

gray-matter NPM version NPM monthly downloads NPM total downloads

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.

Please consider following this project's author, Jon Schlinkert, and consider starring the project to show your ❤️ and support.

Install

Install with npm:

$ npm install --save gray-matter

Heads up!

Please see the changelog to learn about breaking changes that were made in v3.0.


Sponsors

Thanks to the following companies, organizations, and individuals for supporting the ongoing maintenance and development of gray-matter! Become a Sponsor to add your logo to this README, or any of my other projects

Gold Sponsors

https://jaake.tech/
https://jaake.tech/

What does this do?

Run this example

Add the HTML in the following example to example.html, then add the following code to example.js and run $ node example (without the $):

const fs = require('fs');
const matter = require('gray-matter');
const str = fs.readFileSync('example.html', 'utf8');
console.log(matter(str));

Converts a string with front-matter, like this:

---
title: Hello
slug: home
---
<h1>Hello world!</h1>

Into an object like this:

{
  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, JSON and JavaScript front-matter. But other engines may be added.
  • extensible: Use custom delimiters, or add support for any language, like TOML, CoffeeScript, or CSON
  • battle-tested: used by assemble, metalsmith, phenomic, verb, generate, update and many others.
Rationale

Why did we create gray-matter in the first place?

We created gray-matter after trying out other libraries that failed to meet our standards and requirements.

Some libraries met most of the requirements, but none met all of them.

Here are the most important:

  • Be usable, if not simple
  • Use a dependable and well-supported library for parsing YAML
  • Support other languages besides YAML
  • Support stringifying back to YAML or another language
  • Don't fail when no content exists
  • Don't fail when no front matter exists
  • Don't use regex for parsing. This is a relatively simple parsing operation, and regex is the slowest and most error-prone way to do it.
  • Have no problem reading YAML files directly
  • Have no problem with complex content, including non-front-matter fenced code blocks that contain examples of YAML front matter. Other parsers fail on this.
  • Support stringifying back to front-matter. This is useful for linting, updating properties, etc.
  • Allow custom delimiters, when it's necessary for avoiding delimiter collision.
  • Should return an object with at least these three properties:
    • data: the parsed YAML front matter, as a JSON object
    • content: the contents as a string, without the front matter
    • orig: the "original" content (for debugging)

Usage

Using Node's require() system:

const matter = require('gray-matter');

Or with typescript

import matter = require('gray-matter');
// OR
import * as matter from 'gray-matter';

Pass a string and options to gray-matter:

console.log(matter('---\ntitle: Front Matter\n---\nThis is content.'));

Returns:

{
  content: '\nThis is content.',
  data: {
    title: 'Front Matter'
  }
}

More about the returned object in the following section.


Returned object

gray-matter returns a file object with the following properties.

Enumerable

  • file.data {Object}: the object created by parsing front-matter
  • file.content {String}: the input string, with matter stripped
  • file.excerpt {String}: an excerpt, if defined on the options
  • 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 for details regarding use case.
  • file.isEmpty {Boolean}: true if front-matter is empty.

Non-enumerable

In addition, the following non-enumberable properties are added to the object to help with debugging.

  • file.orig {Buffer}: the original input string (or buffer)
  • file.language {String}: the front-matter language that was parsed. yaml is the default
  • file.matter {String}: the raw, un-parsed front-matter string
  • file.stringify {Function}: stringify the file by converting file.data to a string in the given language, wrapping it in delimiters and prepending it to file.content.

Run the examples

If you'd like to test-drive the examples, first clone gray-matter into my-project (or wherever you want):

$ git clone https://github.com/jonschlinkert/gray-matter my-project

CD into my-project and install dependencies:

$ cd my-project && npm install

Then run any of the examples to see how gray-matter works:

$ node examples/<example_name>

Links to examples

API

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.

Params

  • input {Object|String}: String, or object with content string
  • options {Object}
  • returns {Object}

Example

const matter = require('gray-matter');
console.log(matter('---\ntitle: Home\n---\nOther stuff'));
//=> { data: { title: 'Home'}, content: 'Other stuff' }

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 section to learn how to stringify other languages.

Params

  • 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 gray-matter and js-yaml.
  • returns {String}: Returns a string created by wrapping stringified yaml with delimiters, and appending that to the given string.

Example

console.log(matter.stringify('foo bar baz', {title: 'Home'}));
// results in:
// ---
// title: Home
// ---
// foo bar baz

Synchronously read a file from the file system and parse front matter. Returns the same object as the main function.

Params

  • filepath {String}: file path of the file to read.
  • options {Object}: Options to pass to gray-matter.
  • returns {Object}: Returns an object with data and content

Example

const file = matter.read('./content/blog-post.md');

Returns true if the given string has front matter.

Params

  • string {String}
  • options {Object}
  • returns {Boolean}: True if front matter exists.

Options

options.excerpt

Type: Boolean|Function

Default: undefined

Extract an excerpt that directly follows front-matter, or is the first thing in the string if no front-matter exists.

If set to excerpt: true, it will look for the frontmatter delimiter, --- by default and grab everything leading up to it.

Example

const str = '---\nfoo: bar\n---\nThis is an excerpt.\n---\nThis is content';
const file = matter(str, { excerpt: true });

Results in:

{
  content: 'This is an excerpt.\n---\nThis is content',
  data: { foo: 'bar' },
  excerpt: 'This is an excerpt.\n'
}

You can also set excerpt to a function. This function uses the 'file' and 'options' that were initially passed to gray-matter as parameters, so you can control how the excerpt is extracted from the content.

Example

// returns the first 4 lines of the contents
function firstFourLines(file, options) {
  file.excerpt = file.content.split('\n').slice(0, 4).join(' ');
}

const file =  matter([
  '---',
  'foo: bar',
  '---',
  'Only this',
  'will be',
  'in the',
  'excerpt',
  'but not this...'
].join('\n'), {excerpt: firstFourLines});

Results in:

{
  content: 'Only this\nwill be\nin the\nexcerpt\nbut not this...',
  data: { foo: 'bar' },
  excerpt: 'Only this will be in the excerpt'
}

options.excerpt_separator

Type: String

Default: undefined

Define a custom separator to use for excerpts.

console.log(matter(string, {excerpt_separator: '<!-- end -->'}));

Example

The following HTML string:

---
title: Blog
---
My awesome blog.
<!-- end -->
<h1>Hello world</h1>

Results in:

{
  data: { title: 'Blog'},
  excerpt: 'My awesome blog.',
  content: 'My awesome blog.\n<!-- end -->\n<h1>Hello world</h1>'
}

options.engines

Define custom engines for parsing and/or stringifying front-matter.

Type: Object Object of engines

Default: JSON, YAML and JavaScript are already handled by default.

Engine format

Engines may either be an object with parse and (optionally) stringify methods, or a function that will be used for parsing only.

Examples

const toml = require('toml');

/**
 * defined as a function
 */

const file = matter(str, {
  engines: {
    toml: toml.parse.bind(toml),
  }
});

/**
 * Or as an object
 */

const file = matter(str, {
  engines: {
    toml: {
      parse: toml.parse.bind(toml),

      // example of throwing an error to let users know stringifying is
      // not supported (a TOML stringifier might exist, this is just an example)
      stringify: function() {
        throw new Error('cannot stringify to TOML');
      }
    }
  }
});

console.log(file);

options.language

Type: String

Default: yaml

Define the engine to use for parsing front-matter.

console.log(matter(string, {language: 'toml'}));

Example

The following HTML string:

---
title = "TOML"
description = "Front matter"
categories = "front matter toml"
---
This is content

Results in:

{ content: 'This is content',
  excerpt: '',
  data:
   { title: 'TOML',
     description: 'Front matter',
     categories: 'front matter toml' } }

Dynamic language detection

Instead of defining the language on the options, gray-matter will automatically detect the language defined after the first delimiter and select the correct engine to use for parsing.

---toml
title = "TOML"
description = "Front matter"
categories = "front matter toml"
---
This is content

options.delimiters

Type: String

Default: ---

Open and close delimiters can be passed in as an array of strings.

Example:

// format delims as a string
matter.read('file.md', {delims: '~~~'});
// or an array (open/close)
matter.read('file.md', {delims: ['~~~', '~~~']});

would parse:

~~~
title: Home
~~~
This is the {{title}} page.

Deprecated options

options.lang

Decrecated, please use options.language instead.

options.delims

Decrecated, please use options.delimiters instead.

options.parsers

Decrecated, please use options.engines instead.

About

Contributing

Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.

Running Tests

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:

$ npm install && npm test
Building docs

(This project's readme.md is generated by verb, please don't edit the readme directly. Any changes to the readme must be made in the .verb.md readme template.)

To generate the readme, run the following command:

$ npm install -g verbose/verb#dev verb-generate-readme && verb

Related projects

You might also be interested in these projects:

  • assemble: Get the rocks out of your socks! Assemble makes you fast at creating web projects… more | homepage
  • metalsmith: An extremely simple, pluggable static site generator. | homepage
  • verb: Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… more | homepage

Contributors

Commits Contributor
179 jonschlinkert
13 robertmassaioli
7 RobLoach
5 doowb
5 heymind
3 aljopro
3 shawnbot
2 reccanti
2 onokumus
2 moozzyk
2 ajaymathur
1 Ajedi32
1 arlair
1 caesar
1 ianstormtaylor
1 qm3ster
1 zachwhaley

Author

Jon Schlinkert

License

Copyright © 2023, Jon Schlinkert. Released under the MIT License.


This file was generated by verb-generate-readme, v0.8.0, on July 12, 2023.

gray-matter's People

Contributors

ajaymathur avatar ajedi32 avatar arlair avatar caesar avatar doowb avatar heymind avatar ianstormtaylor avatar jonschlinkert avatar moozzyk avatar onokumus avatar qm3ster avatar reccanti avatar robertmassaioli avatar robloach avatar shawnbot avatar zachwhaley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gray-matter's Issues

Bad signature in `d.ts`

this

  export function test(str: string, options?: GrayMatterOption): string;

should be

  export function test(str: string, options?: GrayMatterOption): boolean;

Should js-yaml be loaded via NPM?

I noticed that a minified version of js-yaml seems to be included in this project's lib/ directory. Shouldn't that dependency be pulled in via npm instead?

leading newline in body

Hey, looking to port Metalsmith to gray-matter!

Ran into a question: it was previously using front-matter which stripped a trailing newline after the closing ---, which seemed to mesh more with how a user "perceives" the frontmatter, if not with the way a computer reads it.

Such that...


---
property: true

---
body

...would end up being stripped so that it is exactly equal to...

body

What do you think about supporting that, by swallowing a single newline if one (or more) are present after the closing ---? Technically not "pure", but matches with users editing the frontmatter more I think?

TOML situation is unclear

The readme and description imply that, though YAML is parsed by default, other languages (in this case only TOML is relevant) are supported by adding the language name after the ---, e.g. ---toml\n.

However, I've found that toml is only included in devDependencies not in dependencies, and since the require("toml") call in lib/parsers.js#186 fails silently if the opts.strict mode is off (undocumented), the user only gets an empty object as a return value. They wouldn't know that all they needed to do was to install toml locally to get it working.

I'm not sure whether toml support is supposed to be built in to the library, or if it is mean as an "optional extra" to be installed it manually if the user wants TOML support, so I was just wondering what the "official" position was on this?

parsers

@ianstormtaylor, I wanted to get your feedback on this in light of you potentially using this in metalsmith. one of gray-matter's features is that you can pass a parser function on the options, like if you don't want to use js-yaml for instance.

There are a few parsers currently, for yaml, coffee, javascript, json and toml. I recently had a discussion with @doowb about externalizing/ripping out the parsers and just allowing implementors to just pass in what they want to use - but the vast majority of users will use js-yaml anyway...

Any opinion on this? I could probably go either way - leaning towards ripping them out. if we decide to rip out the parses I can just do it at the same time as the whitespace change, since both would be breaking changes.

{ excerpt: true } option returns empty string

Given a sample file:

---
title: Hello
slug: home
---
<html>
    <h1>Hello world!</h1>
    <!-- end -->
    <p>How are you?</p>
</html>

And the following code

var fs = require('fs');
var matter = require('gray-matter');
var str = fs.readFileSync('example.html', 'utf8');
console.log(matter(str, {excerpt: true}));

gray-matter produces the following output:

{ content: '<html>\n    <h1>Hello world!</h1>\n    <!-- end -->\n    <p>How are you?</p>\n</html>',
  data: { title: 'Hello', slug: 'home' },
  excerpt: '' }

It does work if I use an excerpt separator, though

var fs = require('fs');
var matter = require('gray-matter');
var str = fs.readFileSync('example.html', 'utf8');
console.log(matter(str, {excerpt_separator: '<!-- end -->'}));
{ content: '<html>\n    <h1>Hello world!</h1>\n    <!-- end -->\n    <p>How are you?</p>\n</html>',
  data: { title: 'Hello', slug: 'home' },
  excerpt: '<html>\n    <h1>Hello world!</h1>\n    ' }

Relaxing front matter requirements (allowing "back matter")

Would you consider a PR that allowed for an option that:

  • removed the need for the first delimiter to be the first thing in the file
  • removed the need for the last delimiter if the EOF is reached

I find "back matter" (end matter?) is much more human friendly than front matter:

#Day 1

Today I...

- slept in

---
author: BigAB
template: journal

I was looking for a module to extract back matter from markdown. I like the options gray-matter offers. If I made a PR with such an option would you consider it?

Merge changes upstream?

I have a fork of gray-matter that splits out the core from the parsers, similar to the currently open PR. Parsers can define custom delimiters to enable auto-detection of that format.

Stringifying is supported for all languages. I've also removed the strict option in favor of just throwing errors.

I'd be happy to contribute the changes back in some form if you're interested. There are some changes to the interface in my fork - I opted for a .parse and .stringify to match JSON - but that should be simple enough to undo to make it feasible.

Use generics to type data property in GrayMatterFile interface

I originally posted this in #67, but I realize that this is actually a bug when using Typescript.

I would like to type the data property in GrayMatterFile interface. With a generic type, of curse. Could be done with this:

  interface GrayMatterFile<T = any, I extends Input = Input> {
    data: T;
    content: string;
    excrept?: string;
    orig: Buffer | I;
    language: string;
    matter: string;
    stringify(lang: string): string;
  }

Using default generics again, allow this to keep backward compatibility, if the T is declared after the I.

  interface GrayMatterFile<I extends Input = Input, T = any> {
    data: T;
    content: string;
    excrept?: string;
    orig: Buffer | I;
    language: string;
    matter: string;
    stringify(lang: string): string;
  }

This is because object does not allow accessing any custom properties, so effectively there are only a couple of properties that you can access when using this with Typescript. By using generics, developers are allowed to shape that property as they probably now the actual model of data property. By using defaults, if the developer does not provide a type, then data will be any, allowing to access any custom property.

Cannot find module 'coffee-script' 'toml'

Hey, thanks for the awesome package! I love that I can parse/stringify both ways with it.

I have an encountered a problem when using gray-matter with Browserify for the browser:

Error: Cannot find module 'toml' from '/.../node_modules/gray-matter/lib'
Error: Cannot find module 'coffee-script' from '/.../node_modules/gray-matter/lib'

The issue is obviously resolved when coffee-script and toml are installed. If I understand correctly, Node supports dynamic requires here, while Browserify bundles everything right away. What could be the optimal solution? Maybe moving parsers out of the module and allowing the user to require/set his own? I guess PR #15 solves this.

Thanks!

Option to disable cache?

I ran into an issue where I was mutating the output in a loop expecting the object to be brand new on each invocation.

const frontMatter = require('gray-matter');

const docs = [
  {
    id: 1,
    content: ''
  },
  {
    id: 2,
    content: ''
  }
];

const parsedDocs = docs.map(doc => {
  const output = frontMatter(doc.content);
  Object.assign(output, { id: doc.id });
  return output;
}).map(({ id }) => id);

console.log(parsedDocs); // [2, 2] <-- expecting this to be [1, 2]

Changelog

It's hard to find the 'releases' section buried near the end of the huge Readme. (No complaint about the huge readme; that's great!)

Best practice is to keep a dedicated CHANGELOG.md file. This makes it easy to find out what breaking changes are in a new major release (for example).

See http://keepachangelog.com/ for more info.

Inconsistent yaml file reading behaviour

Problem

Given two variants of a file, which are each read with matter.read(), where the only difference is the YAML document header (---), the data is automatically loaded for the first file, and the second file is treated as text only.

Case A

---
# config-A.yml
author: "an author"
contact: "https://twitter.com/"
description: "Personal blog"
domain: "https://domain.com"
name: "Blog"
rootPath:
> matter.read('config-A.yml')
{ orig: '---\r\nauthor: "an author"\r\ncontact: "https://twitter.com/"\r\ndescription: "Personal blog"\r\ndomain: "https://domain.com"\r\nname: "Blog"\r\nrootPath:',
  data:
   { author: 'an author',
     contact: 'https://twitter.com/',
     description: 'Personal blog',
     domain: 'https://domain.com',
     name: 'Blog',
     rootPath: null },
  content: '',
  path: 'config-A.yml' }

Case B

# config-B.yml
author: "an author"
contact: "https://twitter.com/"
description: "Personal blog"
domain: "https://domain.com"
name: "Blog"
rootPath:
> matter.read('config-B.yml')
{ orig: 'author: "an author"\r\ncontact: "https://twitter.com/"\r\ndescription: "Personal blog"\r\ndomain: "https://domain.com"\r\nname: "Blog"\r\nrootPath:',
  data: {},
  content: 'author: "an author"\r\ncontact: "https://twitter.com/"\r\ndescription: "Personal blog"\r\ndomain: "https://domain.com"\r\nname: "Blog"\r\nrootPath:',
  path: 'config-B.yml' }

Expected behaviour:

Honestly, I was surprised to find out gray-matter loaded data only files at all. However, since that is a stated goal, I'd expect both config files to be loaded, since they are both valid YAML documents (the document header is optional (If I'm reading the spec right)).

Lastly, js-yaml has no problems parsing either file and returns identical objects.


Package version tested against: [email protected]

optional descriptive field

Just one suggestion. Can you allow for optional descriptive field after the 'language specifier'? This is most useful, for repeated metadata within the documents. E.g. Slideshow apps might need to set different stylesheet for each slides, so need to be able to distinguish between different metadata boxes.

---yaml: slide01 ---
CSS: style.css

---

Originally from: Metadata in documents

Related discussion: Jekyll style “do not show or parse”

Frontmatter not parsed into data if blank lines at top

If I run the gray-matter example, but have a couple of blank lines at the top of example.html, the title and slug are not included in the data node.

example.html with two blank lines at the top:



---
title: Hello
slug: home
---
<h1>Hello world!</h1>

Result from running node example. Note the empty data node.
image

I expected gray-matter to skip the blank lines until it found content, and the first content happens to be the front-matter.

Emit on parse error

So far if Gray Matter encounters Matter block, but unable to parse it (let's say, due to wrong escaping), it silently ignores it and outputs empty file.

It would be much better if Gray Matter instead emitted some event, so we can hook on it and log warning about invalid syntax, etc.

Depth

Is there a depth limit at all?

images:
  a:
    image:
      title: 'title'

Returns:

 images: { a: { image: [Object] } },

Disable date parsing?

We're using gray-matter very successfully in Gatsby (thanks!). @tremby ran into an issue recently where he needs to access the original form of a date field in the frontmatter but since it's converted into a date object, he doesn't have access to it anymore. Since Gatsby handles date conversion automatically, would it be possible to turn off date parsing in gray-matter?

consider removing fs

The goal is to make gray-matter easier to use in browsers/non-node.js environments.

Related: #49

My first thought is that we could achieve this by publishing gray-matter-fs or something. Any other ideas?

cc @tech4him1

Do it support multiple documents in one file?

like this:

---
Time: 2001-11-23 15:01:42 -5
User: ed
Warning:
  This is an error message
  for the log file

---
Time: 2001-11-23 15:02:31 -5
User: ed
Warning:
  A slightly different error
  message.

---
Date: 2001-11-23 15:03:17 -5
User: ed
Fatal:
  Unknown variable "bar"
Stack:
  - file: TopClass.py
    line: 23
    code: |
      x = MoreObject("345\n")
  - file: MoreClass.py
    line: 58
    code: |-
      foo = bar

I tried, but failed...

> var matter = require('gray-matter');
> matter('---\ntitle: Front Matter\n---\nThis is content.\n---\ndddsss');
{ orig: '---\ntitle: Front Matter\n---\nThis is content.\n---\ndddsss',
  data: { title: 'Front Matter' },
  content: 'This is content.\n---\ndddsss' }

I want to save multiple part html,

title: aaa
description: bbb

---
<div>
    <div id="ad-535" class="ad-535"></div>
    <div id="ad-267" class="ad-267 ad-middle"></div>
    <div id="ad-458" class="ad-458"></div>
</div>

---
<div>
    <div id="ad-535" class="ad-535"></div>
    <div id="ad-267" class="ad-267 ad-middle"></div>
    <div id="ad-458" class="ad-458"></div>
</div>

and I don't want to write something like this:

part1: <div><div id="ad-535" class="ad-535"></div><div id="ad-267" class="ad-267 ad-middle"></div><div id="ad-458" class="ad-458"></div></div>
part2: <div><div id="ad-535" class="ad-535"></div><div id="ad-267" class="ad-267 ad-middle"></div><div id="ad-458" class="ad-458"></div></div>

syncronising with "Jekyll style "do not show or parse"" concept in commonmark talks

I would like to at least synchronize the concept in http://talk.commonmark.org/t/jekyll-style-do-not-show-or-parse-sections/918 with grey-matter. E.g. change bits of gray-matter or "jekyll style non parse block" to better match each other.

The objective of "jekyll style do not parse", is to inform commonmark of what section to ignore, since it was determined though discussion that metadata handling is better performed by an external program (like grey-matter ).

Some of the things that differs between them is:

More than just front matter metadata.

The non parse block can occur in more places than just the top via these two forms:


---
CONTENT WITHOUT ANY NEW LINE INBETWEEN
E.G. YAML OR JSON CONTENT

---

:---

Multiline Non parsed content

:---

optional stylized boxes

--------- yaml --------
YAML: INSERT YAML HERE
-----------------------

optional descriptive field

--- yaml: slide01 ---
CSS: style.css

---

Discussion

Is there any issue with adding this form, for both grey-matter and "non parse block"? (A space is added).

--- yaml
CSS: style.css

---

README documentation for matter function doesn't indent options correctly

At https://github.com/jonschlinkert/gray-matter#matter, the way the parameters are indented implies that delims and parser are seperate arguments, not part of the options object:

Params

  • string {String}: The string to parse.
  • options {Object}
  • delims {Array}: Custom delimiters formatted as an array. The default is ['---', '---'].
  • parser {Function}: Parser function to use. js-yamlis the default.
  • returns {Object}: Valid JSON

This confused me for a bit until I looked at the source code.

date parse bug

const matter = require('gray-matter');

console.log(matter(`---
date:  2018-09-19 15:19:29
---
`))

output:

{ content: '',
  data: { date: '2018-09-19T15:19:29.000Z' },
  isEmpty: false,
  excerpt: '' }

however, the date is a locale string...

when i use :

 dayjs(this.$page.frontmatter.date).format('YYYY-MM-DD HH:mm:ss')

it becomes:

2018-09-19 23:19:29

Support multiple delimiters.

Would you consider supporting multiple types of delimiters at one time, or is there already a way do do it? For example, I would like to be able to parse front matter beginning with ---, +++, or ~~~.

Support for jekyll's `excerpt` property

Hey @jonschlinkert thanks for writing gray-matter. I'm migrating Electron's website away from ruby and Jekyll to a node server, and gray-matter has become an instrumental piece of that transition, by way of tree-hugger.

Jekyll has this concept of excerpts which we are making use of in our site. The gist is that they extract initial content of a document. By default it's the first paragraph, but can be overridden with an excerpt_separator property.

In Electron's specific case the separator is ---, also known as <hr>.

Would you be interested in supporting excerpt extraction in gray-matter? If so, I'd be happy to work on a PR.

Use default generics

Hi there. I'm using this, and I notice that you are using a lot of generics in the Typescript typing. I wonder if you could consider using them with defaults.

  interface GrayMatterOption<
    I extends Input = Input,
    O extends GrayMatterOption<I, O> = GrayMatterOption<I, O>
  > {
    parser?: () => void;
    eval?: boolean;
    excerpt?: boolean | ((input: I, options: O) => string);
    excerpt_separator?: string;
    engines?: {
      [index: string]:
        | ((string) => object)
        | { parse: (string) => object; stringify?: (object) => string };
    };
    language?: string;
    delimiters?: string | [string, string];
  }

I don't actually understand where is the generic being used, and using this would allow to keep the type checking as it is suppose to be without declaring the generics any.


Also, I would like to type the data property in GrayMatterFile interface. With a generic type, of curse. Could be done with this:

  interface GrayMatterFile<T = object, I extends Input = Input> {
    data: T;
    content: string;
    excrept?: string;
    orig: Buffer | I;
    language: string;
    matter: string;
    stringify(lang: string): string;
  }

Using default generics again, allow this to keep backward compatibility, if the T is declared after the I.

  interface GrayMatterFile<I extends Input = Input, T = object> {
    data: T;
    content: string;
    excrept?: string;
    orig: Buffer | I;
    language: string;
    matter: string;
    stringify(lang: string): string;
  }

Let me know what you think about this, I happily would do the PR with the changes.

fails to read front matter with duplicate keys

Given a file like this (test.html):


---
id: 1
foo: bar
foo: baz

---
> require('gray-matter').read('test.html')
{ orig: '---\nid: 1\nfoo: bar\nfoo: baz\n---',
  data: {},
  content: '',
  path: 'test.html' }

The data is completely empty because one key repeats. I would expect gray-matter to use the latest value in the front matter, or perhaps to throw an error.

matter.stringify() to accept output format

Although gray-matter can parse many different types of format, matter.stringify() can only generate yaml front matters.
That'd be nice to be able to output all the formats supported (json is an obvious example of easy one to add support for).

Read folder with JSON-Files

Hey hey,

I'm currently setting up a project with metalsmith and gray-matter.
I try to store all my contents inside of one folder - saved as JSON-File.
Is there a way to read all Files from one folder and access it inside my YAML definition?

To be more clear I have this example:

// Folder structure:
- dataContent
  - navigationEntries.json
  - stageContent.json

In one of my Template-Files I would like to use it like this (more or less)

// Maybe like this as I know it from assemble

---
title: A neat title
navEntries: <%= navigationEntries %>

---

<h1>
    {{ title }}
</h1>
{{#each navEntries}}
    {{> navPartial}}
{{/each}}
// Or maybe we can access the files directly without file extension?

---
title: A neat title

---
<h1>
    {{ title }}
</h1>
{{#each navigationEntries}}
    {{> navPartial}}
{{/each}}

Would be awesome if someone could help me :)
Thank you :)

Add support for JSON5

It will be great to have support for JSON5. It is more readable than json for staying in the front mater.

importing `fs` breaks webpack builds

When using gray-matter with WebPack, it breaks the build because it imports the fs module. As far as I can tell, the fs module is only used in matter.read. Would you consider changing this to allow gray-matter to work with WebPack builds as well?

Question: Where should I add add link to the webpack loader created for this project

Hi, Love the library by the way ❤️

We needed to achieve this but wanted to do extract the gray matter from the docs at the build time. Therefore, we have created a webpack loader for gray-matter( https://github.com/atlassian/gray-matter-loader ).

I am looking forward to add the link to the project in readme of this project so that someone with a use case can find it easily.

I see Related projects as the most relevant section. What are the thoughts on this?

Not all emojis are parsed

When stringifying I see emoji codepoints and not the characters, but weirdly some emojis work.

I made this runkit where the behaviour can be tested https://runkit.com/embed/d0vr3nxedg9u.

const grayMatter = require("gray-matter")
const emojis = [ '😂', '😒', '😔', '✌️', '😭', '👌', '😑', '😞', '😏', '😢' ]
grayMatter.stringify('Foo', { emojis })

Results in:

---
emojis:
  - "\uD83D\uDE02"
  - "\uD83D\uDE12"
  - "\uD83D\uDE14"
  - ✌️
  - "\uD83D\uDE2D"
  - "\uD83D\uDC4C"
  - "\uD83D\uDE11"
  - "\uD83D\uDE1E"
  - "\uD83D\uDE0F"
  - "\uD83D\uDE22"
---
Foo

Allow engines to specify default delimiters for auto-detection

Currently, language detection is supported by specifying a parameter after the opening frontmatter delimiter (---lang). It would be great if engines could also specify a default delimiter alongside the parse and stringify functions. Then if no language or delimiter was specified via options, the engine could be chosen based on the type of delimiter.

In particular, I'd like to see support for using +++ to delimit TOML frontmatter which is fairly common.

Not installing with bower

When I try to run
bower install gray-matter --save
I get the following error:
bower extend-shallow#^1.1.2 ENORESTARGET No tag found that was able to satisfy ^1.1.2

request: make `gray-matter` natively, backwards-compatible with older browsers

gray-matter uses features of Node that are not supported in all browsers (e.g. let, const, fs module). This is a big downside, as the entire gray-matter module must be run through something like Babel to work. Even then, it would fail while importing the fs module. Would you consider supporting this, maybe with a pre-built version of gray-matter that can be used on the web?

Parser for org mode tags [FEATURE REQUEST]

Similar to YAML, org files often have a particular markup:

#+TITLE:       Something
#+AUTHOR:      Someone
#+EMAIL:       [email protected]
#+DATE:        2015-06-12 Sun
#+URI:         /blog/%y/%m/%d/title/
#+KEYWORDS:    some,stuff,this,says
#+TAGS:     blah
#+LANGUAGE:    en
#+OPTIONS:     H:3 num:nil toc:nil \n:nil ::t |:t ^:nil -:nil f:t *:t <:t
#+DESCRIPTION: I speak of tests

Which should be equivalent to:

title:       Something
author:      Someone
email:       [email protected]
date:        2015-06-12 Sun
uri:         /blog/%y/%m/%d/title/
keywods:    some,stuff,this,says
tags:     blah
language:    en
options:     H:3 num:nil toc:nil \n:nil ::t |:t ^:nil -:nil f:t *:t <:t
description: I speak of tests

Would this be a viable feature?

Invalid TypeScript type definition for `engines` option

The TypeScript type definition is invalid due to missing types on the parameters for the engines callbacks.

When running TypeScript with the noImplicitAny option, the following error is emitted three times:
Parameter has a name but no type. Did you mean 'arg0: string'?

The incorrect definition is in the following lines (the two strings and the object are being interpreted as parameter names rather than types because no names are given).

engines?: {
[index: string]:
| ((string) => object)
| { parse: (string) => object; stringify?: (object) => string }
}

If I can work out what the syntax is for the engines callbacks I'll submit a PR.

Handling of "---" within values

Hi,

Values containing '---' do not seem to be handled correctly. For example the following is valid yaml (the value of name is quoted and so the -- should not be treated as the start of the markdown block).

- name: "troublesome --- value"

---
here is some content

We ran across this because we want to have more than one block of markdown.

Thanks,

David

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.