gitlab-org--gitlab-foss/app/assets/javascripts/static_site_editor/services/front_matterify.js

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}`;
};