Add multi-format frontmatter parser

This commit is contained in:
Joseph Earl
2017-04-07 22:40:30 +01:00
parent d503547883
commit a2e8602fdd
6 changed files with 177 additions and 18 deletions

View File

View File

@ -0,0 +1,105 @@
import YAMLFrontmatter from '../yaml-frontmatter';
const YamlFrontmatterFormatter = new YAMLFrontmatter();
describe('YAMLFrontmatter', () => {
it('should parse YAML with --- delimiters', () => {
expect(
YamlFrontmatterFormatter.fromFile('---\ntitle: YAML\ndescription: Something longer\n---\nContent')
).toEqual(
{
title: 'YAML',
description: 'Something longer',
body: 'Content',
}
);
});
it('should parse YAML with ---yaml delimiters', () => {
expect(
YamlFrontmatterFormatter.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(
YamlFrontmatterFormatter.fromFile('---\ntitle: The Title\nbody: Something longer\n---\nContent')
).toEqual(
{
title: 'The Title',
body: 'Content',
}
);
});
it('should parse TOML with +++ delimiters', () => {
expect(
YamlFrontmatterFormatter.fromFile('+++\ntitle = "TOML"\ndescription = "Front matter"\n+++\nContent')
).toEqual(
{
title: 'TOML',
description: 'Front matter',
body: 'Content',
}
);
});
it('should parse TOML with ---toml delimiters', () => {
expect(
YamlFrontmatterFormatter.fromFile('---toml\ntitle = "TOML"\ndescription = "Something longer"\n---\nContent')
).toEqual(
{
title: 'TOML',
description: 'Something longer',
body: 'Content',
}
);
});
it('should parse JSON with { } delimiters', () => {
expect(
YamlFrontmatterFormatter.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(
YamlFrontmatterFormatter.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(
YamlFrontmatterFormatter.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')
);
});
});

View File

@ -1,31 +1,31 @@
import YAML from './yaml';
import preliminaries from 'preliminaries';
import yamlParser from 'preliminaries-parser-yaml';
import tomlParser from 'preliminaries-parser-toml';
const regexp = /^---\n([^]*?)\n---\n([^]*)$/;
// Automatically register parsers
preliminaries(true);
yamlParser(true);
tomlParser(true);
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;
const result = preliminaries.parse(content);
const data = result.data;
data.body = result.content;
return data;
}
toFile(data, sortedKeys) {
const meta = {};
let body = '';
let content = '';
for (var key in data) {
Object.keys(data).forEach((key) => {
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;
});
// always stringify to YAML
return preliminaries.stringify(body, meta, { lang: 'yaml', delims: '---' });
}
}