76 lines
1.7 KiB
JavaScript
76 lines
1.7 KiB
JavaScript
import jsYaml from 'js-yaml';
|
|
|
|
const NEW_LINE = '\n';
|
|
|
|
const hasMatter = (firstThreeChars, fourthChar) => {
|
|
const isYamlDelimiter = firstThreeChars === '---';
|
|
const isFourthCharNewline = fourthChar === NEW_LINE;
|
|
return isYamlDelimiter && isFourthCharNewline;
|
|
};
|
|
|
|
export const frontMatterify = (source) => {
|
|
let index = 3;
|
|
let offset;
|
|
const delimiter = source.slice(0, index);
|
|
const type = 'yaml';
|
|
const NO_FRONTMATTER = {
|
|
source,
|
|
matter: null,
|
|
hasMatter: false,
|
|
spacing: null,
|
|
content: source,
|
|
delimiter: null,
|
|
type: null,
|
|
};
|
|
|
|
if (!hasMatter(delimiter, source.charAt(index))) {
|
|
return NO_FRONTMATTER;
|
|
}
|
|
|
|
offset = source.indexOf(delimiter, index);
|
|
|
|
// Finds the end delimiter that starts at a new line
|
|
while (offset !== -1 && source.charAt(offset - 1) !== NEW_LINE) {
|
|
index = offset + delimiter.length;
|
|
offset = source.indexOf(delimiter, index);
|
|
}
|
|
|
|
if (offset === -1) {
|
|
return NO_FRONTMATTER;
|
|
}
|
|
|
|
const matterStr = source.slice(index, offset);
|
|
const matter = jsYaml.safeLoad(matterStr);
|
|
|
|
let content = source.slice(offset + delimiter.length);
|
|
let spacing = '';
|
|
let idx = 0;
|
|
while (content.charAt(idx).match(/(\s|\n)/)) {
|
|
spacing += content.charAt(idx);
|
|
idx += 1;
|
|
}
|
|
content = content.replace(spacing, '');
|
|
|
|
return {
|
|
source,
|
|
matter,
|
|
hasMatter: true,
|
|
spacing,
|
|
content,
|
|
delimiter,
|
|
type,
|
|
};
|
|
};
|
|
|
|
export const stringify = ({ matter, spacing, content, delimiter }, newMatter) => {
|
|
const matterObj = newMatter || matter;
|
|
|
|
if (!matterObj) {
|
|
return content;
|
|
}
|
|
|
|
const header = `${delimiter}${NEW_LINE}${jsYaml.safeDump(matterObj)}${delimiter}`;
|
|
const body = `${spacing}${content}`;
|
|
return `${header}${body}`;
|
|
};
|