Skip to content

Commit

Permalink
refactor/perf: regexp & split shorthand (#34)
Browse files Browse the repository at this point in the history
* refactor: regexp & split shorthand
* test: add more cases
  • Loading branch information
SukkaW committed Jul 25, 2020
1 parent dc1f24d commit 720131d
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 36 deletions.
66 changes: 30 additions & 36 deletions lib/front_matter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,36 @@

const yaml = require('js-yaml');
const rPrefixSep = /^(-{3,}|;{3,})/;
const rFrontMatter = /^(-{3,}|;{3,})\n([\s\S]+?)\n\1(?:$|\n([\s\S]*)$)/;
const rFrontMatterNew = /^([\s\S]+?)\n(-{3,}|;{3,})(?:$|\n([\s\S]*)$)/;
const rFrontMatter = /^(-{3,}|;{3,})\n([\s\S]+?)\n\1\n?([\s\S]*)/;
const rFrontMatterNew = /^([\s\S]+?)\n(-{3,}|;{3,})\n?([\s\S]*)/;

function split(str) {
if (typeof str !== 'string') throw new TypeError('str is required!');

if (rFrontMatter.test(str)) return splitOld(str);
if (rFrontMatterNew.test(str)) return splitNew(str);

return {content: str};
}
const matchOld = str.match(rFrontMatter);
if (matchOld) {
return {
data: matchOld[2],
content: matchOld[3] || '',
separator: matchOld[1],
prefixSeparator: true
};
}

function splitOld(str) {
const match = str.match(rFrontMatter);
if (rPrefixSep.test(str)) return { content: str };

return {
data: match[2],
content: match[3] || '',
separator: match[1],
prefixSeparator: true
};
}
const matchNew = str.match(rFrontMatterNew);

function splitNew(str) {
if (rPrefixSep.test(str)) return {content: str};

const match = str.match(rFrontMatterNew);
if (matchNew) {
return {
data: matchNew[1],
content: matchNew[3] || '',
separator: matchNew[2],
prefixSeparator: false
};
}

return {
data: match[1],
content: match[3] || '',
separator: match[2],
prefixSeparator: false
};
return { content: str };
}

function parse(str, options) {
Expand All @@ -44,17 +40,17 @@ function parse(str, options) {
const splitData = split(str);
const raw = splitData.data;

if (!raw) return {_content: str};
if (!raw) return { _content: str };

let data;

if (splitData.separator[0] === ';') {
if (splitData.separator.startsWith(';')) {
data = parseJSON(raw);
} else {
data = parseYAML(raw, options);
}

if (!data) return {_content: str};
if (!data) return { _content: str };

// Convert timezone
Object.keys(data).forEach(key => {
Expand Down Expand Up @@ -98,21 +94,19 @@ function escapeYAML(str) {
});
}

function stringify(obj, options) {
function stringify(obj, options = {}) {
if (!obj) throw new TypeError('obj is required!');

options = options || {};

const content = obj._content || '';
const { _content: content = '' } = obj;
delete obj._content;

if (!Object.keys(obj).length) return content;

const mode = options.mode;
const { mode, prefixSeparator } = options;
const separator = options.separator || (mode === 'json' ? ';;;' : '---');
let result = '';

if (options.prefixSeparator) result += `${separator}\n`;
if (prefixSeparator) result += `${separator}\n`;

if (mode === 'json') {
result += stringifyJSON(obj);
Expand Down Expand Up @@ -172,7 +166,7 @@ function stringifyJSON(obj) {
}

function doubleDigit(num) {
return num < 10 ? `0${num}` : num;
return num.toString().padStart(2, '0');
}

function formatDate(date) {
Expand Down
93 changes: 93 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,39 @@ describe('Front-matter', () => {
});
});

it('yaml mode - no content', () => {
const str = [
'---',
'foo',
'---'
].join('\n');

yfm.split(str).should.eql({
data: 'foo',
content: '',
separator: '---',
prefixSeparator: true
});
});

it('yaml mode - content conflict', () => {
const str = [
'---',
'foo',
'---',
'bar',
'---',
'baz'
].join('\n');

yfm.split(str).should.eql({
data: 'foo',
content: 'bar\n---\nbaz',
separator: '---',
prefixSeparator: true
});
});

it('json mode', () => {
const str = [
';;;',
Expand All @@ -39,6 +72,21 @@ describe('Front-matter', () => {
});
});

it('json mode - no content', () => {
const str = [
';;;',
'foo',
';;;'
].join('\n');

yfm.split(str).should.eql({
data: 'foo',
content: '',
separator: ';;;',
prefixSeparator: true
});
});

it('yaml mode: new', () => {
const str = [
'foo',
Expand All @@ -54,6 +102,37 @@ describe('Front-matter', () => {
});
});

it('yaml mode: new - no content', () => {
const str = [
'foo',
'---'
].join('\n');

yfm.split(str).should.eql({
data: 'foo',
content: '',
separator: '---',
prefixSeparator: false
});
});

it('yaml mode: new - content conflict', () => {
const str = [
'foo',
'---',
'bar',
'---',
'baz'
].join('\n');

yfm.split(str).should.eql({
data: 'foo',
content: 'bar\n---\nbaz',
separator: '---',
prefixSeparator: false
});
});

it('json mode: new', () => {
const str = [
'foo',
Expand All @@ -69,6 +148,20 @@ describe('Front-matter', () => {
});
});

it('json mode: new - no content', () => {
const str = [
'foo',
';;;'
].join('\n');

yfm.split(str).should.eql({
data: 'foo',
content: '',
separator: ';;;',
prefixSeparator: false
});
});

it('without data', () => {
const str = [
'foo',
Expand Down

0 comments on commit 720131d

Please sign in to comment.