Add multi-format frontmatter parser
This commit is contained in:
0
src/formats/__tests__/toml.md
Normal file
0
src/formats/__tests__/toml.md
Normal file
105
src/formats/__tests__/yaml-frontmatter.spec.js
Normal file
105
src/formats/__tests__/yaml-frontmatter.spec.js
Normal 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')
|
||||
);
|
||||
});
|
||||
});
|
@ -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: '---' });
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user