#102 - Support comma separated arrays in front matter

This commit is contained in:
Elio Struyf
2021-09-15 16:42:07 +02:00
parent 73c35e3b44
commit 0429eaa9ed
6 changed files with 71 additions and 33 deletions
+4
View File
@@ -156,6 +156,10 @@
"type": "array",
"markdownDescription": "Specifies the categories which can be used in the Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.taxonomy.categories)"
},
"frontMatter.taxonomy.commaSeparatedFields": {
"type": "array",
"markdownDescription": "Specify the fields that are comma seperated arrays in your front matter. [Check in the docs](https://frontmatter.codes/docs/settings#frontMatter.taxonomy.commaSeparatedFields)"
},
"frontMatter.taxonomy.dateFormat": {
"type": "string",
"markdownDescription": "Specify the date format for your articles. Check [date-fns formating](https://date-fns.org/v2.0.1/docs/format) for more information. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.taxonomy.dateformat)"
-1
View File
@@ -93,7 +93,6 @@ export class Article {
ArticleHelper.update(editor, article);
} catch (e) {
Notifications.error(`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`);
console.log(e.message);
}
}
+1
View File
@@ -7,6 +7,7 @@ export const SETTING_TAXONOMY_CATEGORIES = "taxonomy.categories";
export const SETTING_DATE_FORMAT = "taxonomy.dateFormat";
export const SETTING_DATE_FIELD = "taxonomy.dateField";
export const SETTING_MODIFIED_FIELD = "taxonomy.modifiedField";
export const SETTING_COMMA_SEPARATED_FIELDS = "taxonomy.commaSeparatedFields";
export const SETTING_SLUG_PREFIX = "taxonomy.slugPrefix";
export const SETTING_SLUG_SUFFIX = "taxonomy.slugSuffix";
+61 -29
View File
@@ -1,11 +1,12 @@
import * as vscode from 'vscode';
import * as matter from "gray-matter";
import * as fs from "fs";
import { CONFIG_KEY, DefaultFields, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES } from '../constants';
import { DefaultFields, SETTING_COMMA_SEPARATED_FIELDS, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES } from '../constants';
import { DumpOptions } from 'js-yaml';
import { TomlEngine, getFmLanguage, getFormatOpts } from './TomlEngine';
import { SettingsHelper } from '.';
import { parse } from 'date-fns';
import { Notifications } from './Notifications';
export class ArticleHelper {
@@ -14,18 +15,9 @@ export class ArticleHelper {
*
* @param editor
*/
public static getFrontMatter(editor: vscode.TextEditor) {
const language: string = getFmLanguage();
const langOpts = getFormatOpts(language);
let article: matter.GrayMatterFile<string> | null = matter(editor.document.getText(), {
...TomlEngine,
...langOpts
});
if (article && article.data) {
return article;
}
return null;
public static getFrontMatter(editor: vscode.TextEditor) {
const fileContents = editor.document.getText();
return ArticleHelper.parseFile(fileContents);
}
/**
@@ -34,19 +26,7 @@ export class ArticleHelper {
*/
public static getFrontMatterByPath(filePath: string) {
const file = fs.readFileSync(filePath, { encoding: "utf-8" });
if (file) {
const language: string = getFmLanguage();
const langOpts = getFormatOpts(language);
let article: matter.GrayMatterFile<string> | null = matter(file, {
...TomlEngine,
...langOpts
});
if (article && article.data) {
return article;
}
}
return null;
return ArticleHelper.parseFile(file);
}
/**
@@ -58,15 +38,22 @@ export class ArticleHelper {
public static async update(editor: vscode.TextEditor, article: matter.GrayMatterFile<string>) {
const config = SettingsHelper.getConfig();
const removeQuotes = config.get(SETTING_REMOVE_QUOTES) as string[];
const commaSeparated = config.get<string[]>(SETTING_COMMA_SEPARATED_FIELDS);
let newMarkdown = this.stringifyFrontMatter(article.content, article.data);
let newMarkdown = this.stringifyFrontMatter(article.content, Object.assign({}, article.data));
// Check for field where quotes need to be removed
if (removeQuotes && removeQuotes.length) {
for (const toRemove of removeQuotes) {
if (article && article.data && article.data[toRemove]) {
newMarkdown = newMarkdown.replace(`'${article.data[toRemove]}'`, article.data[toRemove]);
newMarkdown = newMarkdown.replace(`"${article.data[toRemove]}"`, article.data[toRemove]);
if (commaSeparated?.includes(toRemove)) {
const textToReplace = article.data[toRemove].join(", ");
newMarkdown = newMarkdown.replace(`'${textToReplace}'`, textToReplace);
newMarkdown = newMarkdown.replace(`"${textToReplace}"`, textToReplace);
} else {
newMarkdown = newMarkdown.replace(`'${article.data[toRemove]}'`, article.data[toRemove]);
newMarkdown = newMarkdown.replace(`"${article.data[toRemove]}"`, article.data[toRemove]);
}
}
}
}
@@ -84,12 +71,21 @@ export class ArticleHelper {
public static stringifyFrontMatter(content: string, data: any) {
const config = SettingsHelper.getConfig();
const indentArray = config.get(SETTING_INDENT_ARRAY) as boolean;
const commaSeparated = config.get<string[]>(SETTING_COMMA_SEPARATED_FIELDS);
const language = getFmLanguage();
const langOpts = getFormatOpts(language);
const spaces = vscode.window.activeTextEditor?.options?.tabSize;
if (commaSeparated) {
for (const key of commaSeparated) {
if (data[key] && typeof data[key] === "object") {
data[key] = data[key].join(", ");
}
}
}
return matter.stringify(content, data, ({
...TomlEngine,
...langOpts,
@@ -130,4 +126,40 @@ export class ArticleHelper {
}
return;
}
/**
* Parse a markdown file and its front matter
* @param fileContents
* @returns
*/
private static parseFile(fileContents: string): matter.GrayMatterFile<string> | null {
try {
const config = SettingsHelper.getConfig();
const commaSeparated = config.get<string[]>(SETTING_COMMA_SEPARATED_FIELDS);
if (fileContents) {
const language: string = getFmLanguage();
const langOpts = getFormatOpts(language);
let article: matter.GrayMatterFile<string> | null = matter(fileContents, {
...TomlEngine,
...langOpts
});
if (article?.data) {
if (commaSeparated) {
for (const key of commaSeparated) {
if (article?.data[key] && typeof article.data[key] === "string") {
article.data[key] = article.data[key].split(",").map((s: string) => s.trim());
}
}
}
return article;
}
}
} catch (error: any) {
Notifications.error(`There seems to be an issue parsing your Front Matter. ERROR: ${error.message || error}`);
}
return null;
}
}
+3 -2
View File
@@ -94,12 +94,13 @@ export const Metadata: React.FunctionComponent<IMetadataProps> = ({settings, met
unsetFocus={unsetFocus}
disableConfigurable />
}
{
(settings && settings.tags && settings.tags.length > 0) && (
(settings) && (
<TagPicker type={TagType.tags}
icon={<TagIcon />}
crntSelected={metadata.tags as string[] || []}
options={settings.tags}
options={settings?.tags || []}
freeform={settings.freeform}
focussed={focusElm === TagType.tags}
unsetFocus={unsetFocus} />
+2 -1
View File
@@ -1,5 +1,5 @@
import { Template } from './../commands/Template';
import { SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, SETTING_AUTO_UPDATE_DATE, SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_PREVIEW_HOST, SETTING_DATE_FORMAT, SETTING_DATE_FIELD, SETTING_MODIFIED_FIELD } from './../constants/settings';
import { SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, SETTING_AUTO_UPDATE_DATE, SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_PREVIEW_HOST, SETTING_DATE_FORMAT, SETTING_DATE_FIELD, SETTING_MODIFIED_FIELD, SETTING_COMMA_SEPARATED_FIELDS } from './../constants/settings';
import * as os from 'os';
import { PanelSettings, CustomScript } from './../models/PanelSettings';
import { CancellationToken, Disposable, Uri, Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext, window, workspace, commands, env as vscodeEnv } from "vscode";
@@ -344,6 +344,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
writingSettingsEnabled: this.isWritingSettingsEnabled() || false,
fmHighlighting: config.get(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT),
preview: Preview.getSettings(),
commaSeparatedFields: config.get(SETTING_COMMA_SEPARATED_FIELDS) || [],
} as PanelSettings
});
}