#242 - Keep comments at front matter root

This commit is contained in:
Elio Struyf
2022-02-16 17:35:49 -08:00
parent 6135e38fce
commit 6cabd6283b
5 changed files with 125 additions and 7 deletions
-2
View File
@@ -107,8 +107,6 @@ const Metadata: React.FunctionComponent<IMetadataProps> = ({settings, metadata,
} else if (field.type === 'string') {
const textValue = parent[field.name];
console.log(textValue, parent, field)
let limit = -1;
if (field.name === 'title') {
limit = settings?.seo.title;
+2
View File
@@ -14,9 +14,11 @@ export interface ParsedFrontMatter {
}
export class FrontMatterParser {
public static currentContent: string | null = null;
public static fromFile(content: string): ParsedFrontMatter {
const format = getFormatOpts(this.getLanguage());
FrontMatterParser.currentContent = content;
const result = matter(content, { ...Engines, ...format });
// in the absent of a body when serializing an entry we use an empty one
// when calling `toFile`, so we don't want to add it when parsing.
+79 -2
View File
@@ -1,5 +1,6 @@
import * as yaml from 'yaml';
import * as toml from '@iarna/toml';
import { Format } from '.';
import { Format, FrontMatterParser } from '.';
export const getFormatOpts = (format: string): Format => {
const formats: { [prop: string]: Format} = {
@@ -20,6 +21,82 @@ export const Engines = {
stringify: (value: any) => {
return toml.stringify(value);
}
},
yaml: {
parse: (value: string) => {
return yaml.parse(value);
},
stringify: (obj: any, options?: any) => {
// Do our own parsing to keep the comments
if (FrontMatterParser.currentContent) {
const originalContent = FrontMatterParser.currentContent;
FrontMatterParser.currentContent = null;
const frontMatter = getMatter(originalContent);
if (frontMatter) {
const docYaml = yaml.parseDocument(frontMatter);
// Update all the new values
for (const key in obj) {
docYaml.set(key, obj[key]);
}
// Check if there are values to remove
for (const key in docYaml.toJSON()) {
if (!obj[key]) {
docYaml.delete(key);
}
}
return docYaml.toString();
}
}
return yaml.stringify(obj, options);
}
}
}
}
}
/**
* Retrieve the front matter from the content
* @param value
* @returns
*/
const getMatter = (value: string): string | null => {
const open = "---";
const close = '\n' + "---";
let str = value;
// get the length of the opening delimiter
const openLen = open.length;
if (!startsWith(str, open, openLen)) {
return null;
}
// if the next character after the opening delimiter is
// a character from the delimiter, then it's not a front-
// matter delimiter
if (str.charAt(openLen) === open.slice(-1)) {
return null;
}
// strip the opening delimiter
str = str.slice(openLen);
const len = str.length;
// get the index of the closing delimiter
let closeIndex = str.indexOf(close);
if (closeIndex === -1) {
closeIndex = len;
}
// get the raw front-matter block
return str.slice(0, closeIndex);
}
const startsWith = (str: string, substr: string, len: number) => {
if (typeof len !== 'number') len = substr.length;
return str.slice(0, len) === substr;
};