#352 - Custom placeholders now support scripting

This commit is contained in:
Elio Struyf
2022-07-21 18:38:53 +03:00
parent 9445ce6d37
commit 7badfda41b
10 changed files with 70 additions and 19 deletions

View File

@@ -4,6 +4,7 @@
### 🎨 Enhancements
- [#352](https://github.com/estruyf/vscode-front-matter/issues/352): Custom placeholders now support scripting
- [#370](https://github.com/estruyf/vscode-front-matter/issues/370): Define the tags and categories as reserved keywords for custom taxonomy
- [#372](https://github.com/estruyf/vscode-front-matter/issues/372): Rename Taxonomy tab to Taxonomies
- [#374](https://github.com/estruyf/vscode-front-matter/issues/374): Hide the front matter section to use the panel instead

View File

@@ -2,7 +2,7 @@ import { DEFAULT_CONTENT_TYPE } from './../constants/ContentType';
import { isValidFile } from './../helpers/isValidFile';
import { SETTING_AUTO_UPDATE_DATE, SETTING_MODIFIED_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_CONTENT_PLACEHOLDERS, TelemetryEvent } from './../constants';
import * as vscode from 'vscode';
import { Field, TaxonomyType } from "../models";
import { CustomPlaceholder, Field, TaxonomyType } from "../models";
import { format } from "date-fns";
import { ArticleHelper, Settings, SlugHelper } from '../helpers';
import { Notifications } from '../helpers/Notifications';
@@ -225,8 +225,8 @@ export class Article {
}
// Update the fields containing a custom placeholder that depends on slug
const placeholders = Settings.get<{id: string, value: string}[]>(SETTING_CONTENT_PLACEHOLDERS);
const customPlaceholders = placeholders?.filter(p => p.value.includes("{{slug}}"));
const placeholders = Settings.get<CustomPlaceholder[]>(SETTING_CONTENT_PLACEHOLDERS);
const customPlaceholders = placeholders?.filter(p => p.value && p.value.includes("{{slug}}"));
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
for (const customPlaceholder of (customPlaceholders || [])) {
const customPlaceholderFields = contentType.fields.filter(f => f.default === `{{${customPlaceholder.id}}}`);

View File

@@ -175,7 +175,7 @@ export class Template {
}
if (frontMatter.data) {
frontMatter.data = ArticleHelper.updatePlaceholders(frontMatter.data, titleValue);
frontMatter.data = await ArticleHelper.updatePlaceholders(frontMatter.data, titleValue, newFilePath);
frontMatter = Article.updateDate(frontMatter);

View File

@@ -1,3 +1,4 @@
import { CustomPlaceholder } from './../models/CustomPlaceholder';
import { Uri, workspace } from 'vscode';
import { MarkdownFoldingProvider } from './../providers/MarkdownFoldingProvider';
import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from './../constants/ContentType';
@@ -22,6 +23,8 @@ import { fromMarkdown } from 'mdast-util-from-markdown';
import { Link, Parent } from 'mdast-util-from-markdown/lib';
import { Content } from 'mdast';
import { processKnownPlaceholders } from './PlaceholderHelper';
import { CustomScript } from './CustomScript';
import { Folders } from '../commands/Folders';
export class ArticleHelper {
private static notifiedFiles: string[] = [];
@@ -368,7 +371,7 @@ export class ArticleHelper {
* @param title
* @returns
*/
public static updatePlaceholders(data: any, title: string) {
public static async updatePlaceholders(data: any, title: string, filePath: string) {
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
const fmData = Object.assign({}, data);
@@ -384,7 +387,7 @@ export class ArticleHelper {
}
fmData[fieldName] = processKnownPlaceholders(fmData[fieldName], title, dateFormat);
fmData[fieldName] = this.processCustomPlaceholders(fmData[fieldName], title);
fmData[fieldName] = await this.processCustomPlaceholders(fmData[fieldName], title, filePath);
}
return fmData;
@@ -396,16 +399,44 @@ export class ArticleHelper {
* @param title
* @returns
*/
public static processCustomPlaceholders(value: string, title: string) {
public static async processCustomPlaceholders(value: string, title: string, filePath: string) {
if (value && typeof value === "string") {
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
const placeholders = Settings.get<{id: string, value: string}[]>(SETTING_CONTENT_PLACEHOLDERS);
const placeholders = Settings.get<CustomPlaceholder[]>(SETTING_CONTENT_PLACEHOLDERS);
if (placeholders && placeholders.length > 0) {
for (const placeholder of placeholders) {
if (value.includes(`{{${placeholder.id}}}`)) {
let placeHolderValue = placeholder.value || "";
if (placeholder.script) {
const wsFolder = Folders.getWorkspaceFolder();
const script = { title: placeholder.id, script: placeholder.script, command: placeholder.command };
let output: string | any = await CustomScript.executeScript(script, wsFolder?.fsPath || "", `'${filePath}' '${title}'`);
if (output) {
// Check if the output needs to be parsed
if (output.includes("{") && output.includes("}")) {
try {
output = JSON.parse(output);
} catch (e) {
// Do nothing
}
} else {
output = output.split("\n");
}
placeHolderValue = output;
}
}
const regex = new RegExp(`{{${placeholder.id}}}`, "g");
const updatedValue = processKnownPlaceholders(placeholder.value, title, dateFormat);
value = value.replace(regex, updatedValue);
const updatedValue = processKnownPlaceholders(placeHolderValue, title, dateFormat);
if (value === `{{${placeholder.id}}}`) {
value = updatedValue;
} else {
value = value.replace(regex, updatedValue);
}
}
}
}

View File

@@ -526,7 +526,7 @@ export class ContentType {
}
}
let data: any = this.processFields(contentType, titleValue, templateData?.data || {});
let data: any = await this.processFields(contentType, titleValue, templateData?.data || {}, newFilePath);
data = ArticleHelper.updateDates(Object.assign({}, data));
@@ -553,7 +553,7 @@ export class ContentType {
* @param contentType
* @param data
*/
private static processFields(obj: IContentType | Field, titleValue: string, data: any) {
private static async processFields(obj: IContentType | Field, titleValue: string, data: any, filePath: string) {
if (obj.fields) {
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
@@ -561,19 +561,19 @@ export class ContentType {
if (field.name === "title") {
if (field.default) {
data[field.name] = processKnownPlaceholders(field.default, titleValue, dateFormat);
data[field.name] = ArticleHelper.processCustomPlaceholders(data[field.name], titleValue);
data[field.name] = await ArticleHelper.processCustomPlaceholders(data[field.name], titleValue, filePath);
} else {
data[field.name] = titleValue;
}
} else {
if (field.type === "fields") {
data[field.name] = this.processFields(field, titleValue, {});
data[field.name] = await this.processFields(field, titleValue, {}, filePath);
} else {
const defaultValue = field.default;
if (typeof defaultValue === "string") {
data[field.name] = processKnownPlaceholders(defaultValue, titleValue, dateFormat);
data[field.name] = ArticleHelper.processCustomPlaceholders(data[field.name], titleValue);
data[field.name] = await ArticleHelper.processCustomPlaceholders(data[field.name], titleValue, filePath);
} else {
data[field.name] = typeof defaultValue !== "undefined" ? defaultValue : "";
}

View File

@@ -246,7 +246,7 @@ export class CustomScript {
* @param args
* @returns
*/
private static async executeScript(script: ICustomScript, wsPath: string, args: string): Promise<string> {
public static async executeScript(script: ICustomScript, wsPath: string, args: string): Promise<string> {
return new Promise((resolve, reject) => {
// Check the command to use
@@ -264,6 +264,11 @@ export class CustomScript {
reject(error.message);
}
if (stdout && stdout.endsWith(`\n`)) {
// Remove empty line at the end of the string
stdout = stdout.slice(0, -1);
}
resolve(stdout);
});
});

View File

@@ -322,11 +322,18 @@ export class DataListener extends BaseListener {
}
}
private static updatePlaceholder(field: string, value: string, title: string) {
/**
* Update the placeholder
* @param field
* @param value
* @param title
*/
private static async updatePlaceholder(field: string, value: string, title: string) {
if (field && value) {
const crntFile = window.activeTextEditor?.document;
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
value = processKnownPlaceholders(value, title || "", dateFormat);
value = ArticleHelper.processCustomPlaceholders(value, title || "");
value = await ArticleHelper.processCustomPlaceholders(value, title || "", crntFile?.uri.fsPath || "");
}
this.sendMsg(Command.updatePlaceholder, { field, value });

View File

@@ -0,0 +1,6 @@
export interface CustomPlaceholder {
id: string;
value?: string;
script?: string;
command?: string
}

View File

@@ -118,7 +118,7 @@ export interface CustomScript {
output?: "notification" | "editor";
outputType?: string;
type?: ScriptType;
command?: CommandType;
command?: CommandType | string;
}
export interface PreviewSettings {

View File

@@ -1,6 +1,7 @@
export * from './BlockFieldData';
export * from './Choice';
export * from './ContentFolder';
export * from './CustomPlaceholder';
export * from './CustomTaxonomyData';
export * from './DashboardData';
export * from './DataFile';