Merge pull request #348 from josephearl/multi-format-frontmatter
Add multi-format frontmatter parser
This commit is contained in:
commit
b5e839468e
@ -11,7 +11,13 @@
|
|||||||
window.repoFiles = {
|
window.repoFiles = {
|
||||||
_posts: {
|
_posts: {
|
||||||
"2015-02-14-this-is-a-post.md": {
|
"2015-02-14-this-is-a-post.md": {
|
||||||
content: "---\ntitle: This is a post\nimage: /nf-logo.png\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n"
|
content: "---\ntitle: This is a YAML front matter post\nimage: /nf-logo.png\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n"
|
||||||
|
},
|
||||||
|
"2015-02-15-this-is-a-json-frontmatter-post.md": {
|
||||||
|
content: "{\n\"title\": \"This is a JSON front matter post\",\n\"image\": \"/nf-logo.png\",\n\"date\": \"2015-02-15T00:00:00.000Z\"\n}\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n"
|
||||||
|
},
|
||||||
|
"2015-02-16-this-is-a-toml-frontmatter-post.md": {
|
||||||
|
content: "+++\ntitle = \"This is a TOML front matter post\"\nimage = \"/nf-logo.png\"\n\"date\" = \"2015-02-16T00:00:00.000Z\"\n+++\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_faqs: {
|
_faqs: {
|
||||||
|
@ -113,6 +113,9 @@
|
|||||||
"netlify-auth-js": "^0.5.5",
|
"netlify-auth-js": "^0.5.5",
|
||||||
"normalize.css": "^4.2.0",
|
"normalize.css": "^4.2.0",
|
||||||
"pluralize": "^3.0.0",
|
"pluralize": "^3.0.0",
|
||||||
|
"preliminaries": "1.1.0",
|
||||||
|
"preliminaries-parser-toml": "1.1.0",
|
||||||
|
"preliminaries-parser-yaml": "1.1.0",
|
||||||
"prismjs": "^1.5.1",
|
"prismjs": "^1.5.1",
|
||||||
"prosemirror-commands": "^0.16.0",
|
"prosemirror-commands": "^0.16.0",
|
||||||
"prosemirror-history": "^0.16.0",
|
"prosemirror-history": "^0.16.0",
|
||||||
|
105
src/formats/__tests__/frontmatter.spec.js
Normal file
105
src/formats/__tests__/frontmatter.spec.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import Frontmatter from '../frontmatter';
|
||||||
|
|
||||||
|
const FrontmatterFormatter = new Frontmatter();
|
||||||
|
|
||||||
|
describe('Frontmatter', () => {
|
||||||
|
it('should parse YAML with --- delimiters', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.fromFile('---\ntitle: YAML\ndescription: Something longer\n---\nContent')
|
||||||
|
).toEqual(
|
||||||
|
{
|
||||||
|
title: 'YAML',
|
||||||
|
description: 'Something longer',
|
||||||
|
body: 'Content',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse YAML with ---yaml delimiters', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.fromFile('---yaml\ntitle: YAML\ndescription: Something longer\n---\nContent')
|
||||||
|
).toEqual(
|
||||||
|
{
|
||||||
|
title: 'YAML',
|
||||||
|
description: 'Something longer',
|
||||||
|
body: 'Content',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should overwrite any body param in the front matter', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.fromFile('---\ntitle: The Title\nbody: Something longer\n---\nContent')
|
||||||
|
).toEqual(
|
||||||
|
{
|
||||||
|
title: 'The Title',
|
||||||
|
body: 'Content',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse TOML with +++ delimiters', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.fromFile('+++\ntitle = "TOML"\ndescription = "Front matter"\n+++\nContent')
|
||||||
|
).toEqual(
|
||||||
|
{
|
||||||
|
title: 'TOML',
|
||||||
|
description: 'Front matter',
|
||||||
|
body: 'Content',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse TOML with ---toml delimiters', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.fromFile('---toml\ntitle = "TOML"\ndescription = "Something longer"\n---\nContent')
|
||||||
|
).toEqual(
|
||||||
|
{
|
||||||
|
title: 'TOML',
|
||||||
|
description: 'Something longer',
|
||||||
|
body: 'Content',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse JSON with { } delimiters', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.fromFile('{\n"title": "The Title",\n"description": "Something longer"\n}\nContent')
|
||||||
|
).toEqual(
|
||||||
|
{
|
||||||
|
title: 'The Title',
|
||||||
|
description: 'Something longer',
|
||||||
|
body: 'Content',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse JSON with ---json delimiters', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.fromFile('---json\n{\n"title": "The Title",\n"description": "Something longer"\n}\n---\nContent')
|
||||||
|
).toEqual(
|
||||||
|
{
|
||||||
|
title: 'The Title',
|
||||||
|
description: 'Something longer',
|
||||||
|
body: 'Content',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should stringify YAML with --- delimiters', () => {
|
||||||
|
expect(
|
||||||
|
FrontmatterFormatter.toFile({ body: 'Some content\nOn another line', tags: ['front matter', 'yaml'], title: 'YAML' })
|
||||||
|
).toEqual(
|
||||||
|
[
|
||||||
|
'---',
|
||||||
|
'tags:',
|
||||||
|
' - front matter',
|
||||||
|
' - yaml',
|
||||||
|
'title: YAML',
|
||||||
|
'---',
|
||||||
|
'Some content',
|
||||||
|
'On another line\n',
|
||||||
|
].join('\n')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
0
src/formats/__tests__/toml.md
Normal file
0
src/formats/__tests__/toml.md
Normal file
@ -1,32 +1,32 @@
|
|||||||
import YAML from './yaml';
|
import YAML from './yaml';
|
||||||
import JSONFormatter from './json';
|
import JSONFormatter from './json';
|
||||||
import YAMLFrontmatter from './yaml-frontmatter';
|
import Frontmatter from './frontmatter';
|
||||||
|
|
||||||
const yamlFormatter = new YAML();
|
const yamlFormatter = new YAML();
|
||||||
const jsonFormatter = new JSONFormatter();
|
const jsonFormatter = new JSONFormatter();
|
||||||
const YamlFrontmatterFormatter = new YAMLFrontmatter();
|
const FrontmatterFormatter = new Frontmatter();
|
||||||
|
|
||||||
function formatByType(type) {
|
function formatByType(type) {
|
||||||
// Right now the only type is "editorialWorkflow" and
|
// Right now the only type is "editorialWorkflow" and
|
||||||
// we always returns the same format
|
// we always returns the same format
|
||||||
return YamlFrontmatterFormatter;
|
return FrontmatterFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatByExtension(extension) {
|
export function formatByExtension(extension) {
|
||||||
return {
|
return {
|
||||||
yml: yamlFormatter,
|
yml: yamlFormatter,
|
||||||
json: jsonFormatter,
|
json: jsonFormatter,
|
||||||
md: YamlFrontmatterFormatter,
|
md: FrontmatterFormatter,
|
||||||
markdown: YamlFrontmatterFormatter,
|
markdown: FrontmatterFormatter,
|
||||||
html: YamlFrontmatterFormatter,
|
html: FrontmatterFormatter,
|
||||||
}[extension] || YamlFrontmatterFormatter;
|
}[extension] || FrontmatterFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatByName(name) {
|
function formatByName(name) {
|
||||||
return {
|
return {
|
||||||
yaml: yamlFormatter,
|
yaml: yamlFormatter,
|
||||||
frontmatter: YamlFrontmatterFormatter,
|
frontmatter: FrontmatterFormatter,
|
||||||
}[name] || YamlFrontmatterFormatter;
|
}[name] || FrontmatterFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveFormat(collectionOrEntity, entry) {
|
export function resolveFormat(collectionOrEntity, entry) {
|
||||||
|
31
src/formats/frontmatter.js
Normal file
31
src/formats/frontmatter.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import preliminaries from 'preliminaries';
|
||||||
|
import yamlParser from 'preliminaries-parser-yaml';
|
||||||
|
import tomlParser from 'preliminaries-parser-toml';
|
||||||
|
|
||||||
|
// Automatically register parsers
|
||||||
|
preliminaries(true);
|
||||||
|
yamlParser(true);
|
||||||
|
tomlParser(true);
|
||||||
|
|
||||||
|
export default class Frontmatter {
|
||||||
|
fromFile(content) {
|
||||||
|
const result = preliminaries.parse(content);
|
||||||
|
const data = result.data;
|
||||||
|
data.body = result.content;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
toFile(data, sortedKeys) {
|
||||||
|
const meta = {};
|
||||||
|
let body = '';
|
||||||
|
Object.keys(data).forEach((key) => {
|
||||||
|
if (key === 'body') {
|
||||||
|
body = data[key];
|
||||||
|
} else {
|
||||||
|
meta[key] = data[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// always stringify to YAML
|
||||||
|
return preliminaries.stringify(body, meta, { lang: 'yaml', delims: '---' });
|
||||||
|
}
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
import YAML from './yaml';
|
|
||||||
|
|
||||||
const regexp = /^---\n([^]*?)\n---\n([^]*)$/;
|
|
||||||
|
|
||||||
export default class YAMLFrontmatter {
|
|
||||||
fromFile(content) {
|
|
||||||
const match = content.match(regexp);
|
|
||||||
const obj = match ? new YAML().fromFile(match[1]) : {};
|
|
||||||
obj.body = match ? (match[2] || '').replace(/^\n+/, '') : content;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
toFile(data, sortedKeys) {
|
|
||||||
const meta = {};
|
|
||||||
let body = '';
|
|
||||||
let content = '';
|
|
||||||
for (var key in data) {
|
|
||||||
if (key === 'body') {
|
|
||||||
body = data[key];
|
|
||||||
} else {
|
|
||||||
meta[key] = data[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
content += '---\n';
|
|
||||||
content += new YAML().toFile(meta, sortedKeys);
|
|
||||||
content += '---\n\n';
|
|
||||||
content += body;
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
38
yarn.lock
38
yarn.lock
@ -2773,6 +2773,10 @@ esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1:
|
|||||||
version "2.7.3"
|
version "2.7.3"
|
||||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
|
||||||
|
|
||||||
|
esprima@^3.1.1:
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
|
||||||
|
|
||||||
esprima@~3.0.0:
|
esprima@~3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9"
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9"
|
||||||
@ -4555,7 +4559,14 @@ js-tokens@^2.0.0:
|
|||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5"
|
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5"
|
||||||
|
|
||||||
js-yaml@3.x, js-yaml@^3.4.2, js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@^3.7.0:
|
js-yaml@3.x, js-yaml@^3.4.2, js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@^3.8.1:
|
||||||
|
version "3.8.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.3.tgz#33a05ec481c850c8875929166fe1beb61c728766"
|
||||||
|
dependencies:
|
||||||
|
argparse "^1.0.7"
|
||||||
|
esprima "^3.1.1"
|
||||||
|
|
||||||
|
js-yaml@^3.7.0:
|
||||||
version "3.7.0"
|
version "3.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
|
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -6779,6 +6790,23 @@ pre-commit@^1.1.3:
|
|||||||
spawn-sync "^1.0.15"
|
spawn-sync "^1.0.15"
|
||||||
which "1.2.x"
|
which "1.2.x"
|
||||||
|
|
||||||
|
preliminaries-parser-toml@1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/preliminaries-parser-toml/-/preliminaries-parser-toml-1.1.0.tgz#00cacf5ab619561380e0f6f2495b2ec449b8e70e"
|
||||||
|
dependencies:
|
||||||
|
toml "^2.3.2"
|
||||||
|
toml-js "0.0.8"
|
||||||
|
|
||||||
|
preliminaries-parser-yaml@1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/preliminaries-parser-yaml/-/preliminaries-parser-yaml-1.1.0.tgz#cd0968d10e0220f55477cc8cbeb428aa27e9f84f"
|
||||||
|
dependencies:
|
||||||
|
js-yaml "^3.8.1"
|
||||||
|
|
||||||
|
preliminaries@1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/preliminaries/-/preliminaries-1.1.0.tgz#28ceb5f988b83594de0a7b155124693b0c4a777f"
|
||||||
|
|
||||||
prelude-ls@~1.1.2:
|
prelude-ls@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||||
@ -8556,6 +8584,14 @@ to-fast-properties@^1.0.1:
|
|||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
|
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
|
||||||
|
|
||||||
|
toml-js@0.0.8:
|
||||||
|
version "0.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/toml-js/-/toml-js-0.0.8.tgz#648ea6f1a4d63b19c0bb30b8ed03e40d09473b0a"
|
||||||
|
|
||||||
|
toml@^2.3.2:
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.2.tgz#5eded5ca42887924949fd06eb0e955656001e834"
|
||||||
|
|
||||||
topbar@^0.1.3:
|
topbar@^0.1.3:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/topbar/-/topbar-0.1.3.tgz#c9ef8776dc4469f7840e6416f4136ddeccf4b7c6"
|
resolved "https://registry.yarnpkg.com/topbar/-/topbar-0.1.3.tgz#c9ef8776dc4469f7840e6416f4136ddeccf4b7c6"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user