mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-07-21 00:52:41 +02:00
#242 - Keep comments at front matter root
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
Reference in New Issue
Block a user