From 66c150e85fb26ef085dbf8e132579ca7a6eea068 Mon Sep 17 00:00:00 2001 From: Mara Date: Thu, 9 Nov 2023 12:54:55 +0100 Subject: [PATCH] feat(folderNote): support of automatically add `title` (or other) key with basename of file close #242 --- src/GitHub/upload.ts | 8 ++- src/conversion/compiler/embeds.ts | 27 ++++---- src/conversion/convert_text.ts | 107 +++++++++++++++++++----------- src/i18n/locales/en.json | 6 ++ src/i18n/locales/fr.json | 6 ++ src/settings.ts | 24 +++++++ src/settings/interface.ts | 12 +++- src/utils/data_validation_test.ts | 12 ++++ 8 files changed, 144 insertions(+), 58 deletions(-) diff --git a/src/GitHub/upload.ts b/src/GitHub/upload.ts index b8139302..7849407a 100644 --- a/src/GitHub/upload.ts +++ b/src/GitHub/upload.ts @@ -213,10 +213,11 @@ export default class Publisher { general: frontmatterSettings, repo: repo.frontmatter, }, - repository: repo.repo + repository: repo.repo, + filepath: getReceiptFolder(file, this.settings, repo.repo, this.plugin.app), }; text = await mainConverting(text, file, this.plugin.app, frontmatter, linkedFiles, this.plugin, multiProperties); - const path = getReceiptFolder(file, this.settings, repo.repo, this.plugin.app); + const path = multiProperties.filepath; const repoFrontmatter = Array.isArray(repo.frontmatter) ? repo.frontmatter : [repo.frontmatter]; @@ -236,7 +237,8 @@ export default class Publisher { general: frontmatterSettings, repo }, - repository: multiProperties.repository + repository: multiProperties.repository, + filepath: multiProperties.filepath, }; const deleted = await this.uploadOnMultipleRepo( diff --git a/src/conversion/compiler/embeds.ts b/src/conversion/compiler/embeds.ts index 3b1926ca..1de23cd1 100644 --- a/src/conversion/compiler/embeds.ts +++ b/src/conversion/compiler/embeds.ts @@ -21,7 +21,7 @@ import { LinkedNotes, MultiProperties} from "../../settings/interface"; import {isShared} from "../../utils/data_validation_test"; -import { addTagsToYAML } from "../convert_text"; +import { addToYaml } from "../convert_text"; import { createRelativePath, getTitleField, regexOnFileName } from "../file_path"; @@ -287,34 +287,31 @@ export async function convertInlineDataview( } const valueToAdd: string[] = []; for (const field of settings.conversion.tags.fields) { - const fieldValue = dataviewLinks[field]; + let fieldValue = dataviewLinks[field]; if (fieldValue) { if (fieldValue.constructor.name === "Link") { + fieldValue = fieldValue as Link; const stringifyField = dataviewExtract(fieldValue, settings); if (stringifyField) valueToAdd.push(stringifyField); - } else if (fieldValue.constructor.name === "Array") { + } else if (fieldValue instanceof Array) { for (const item of fieldValue) { let stringifyField = item; - if (item.constructor.name === "Link") { - stringifyField = dataviewExtract(item, settings); - valueToAdd.push(stringifyField); + if (item && item.constructor.name === "Link") { + stringifyField = dataviewExtract(item as Link, settings); + if (stringifyField) valueToAdd.push(stringifyField); } else if ( - !settings.conversion.tags.exclude.includes( - stringifyField.toString() - ) - ) { - valueToAdd.push(stringifyField.toString()); - } + stringifyField && !settings.conversion.tags.exclude.includes(stringifyField.toString() as string) + ) valueToAdd.push(stringifyField.toString() as string); } } else if ( - !settings.conversion.tags.exclude.includes(fieldValue.toString()) + !settings.conversion.tags.exclude.includes(fieldValue.toString() as string) ) { - valueToAdd.push(fieldValue.toString()); + valueToAdd.push(fieldValue.toString() as string); } } } if (valueToAdd.length > 0) { - return await addTagsToYAML(text, valueToAdd.filter(Boolean), settings); + return addToYaml(text, valueToAdd.filter(Boolean), settings); } return text; } diff --git a/src/conversion/convert_text.ts b/src/conversion/convert_text.ts index ba191bec..b4033027 100644 --- a/src/conversion/convert_text.ts +++ b/src/conversion/convert_text.ts @@ -7,6 +7,7 @@ import { stringifyYaml, TFile, } from "obsidian"; +import { isFolderNote } from "src/utils/data_validation_test"; import GithubPublisher from "../main"; import { @@ -49,38 +50,28 @@ export function addHardLineBreak( } } -/** - * Add the string list to the YAML frontmatter tags key - * If the tags key does not exist, it will be created - * @param {string} text the text to convert - * @param {string[]} toAdd the list of tags to add - * @param settings - * @returns {Promise} the converted text - */ - -export async function addTagsToYAML(text: string, toAdd: string[], settings: GitHubPublisherSettings): Promise { - const yaml = text.split("---")[1]; - const yamlObject = parseYaml(yaml); - if (yamlObject.tag) { +//eslint-disable-next-line @typescript-eslint/no-explicit-any +function tagsToYaml(toAdd: string[], settings: GitHubPublisherSettings, yaml: any) { + if (yaml.tag) { try { toAdd = [ ...new Set([ ...toAdd, - ...yamlObject.tag.map((tag: string) => + ...yaml.tag.map((tag: string) => tag.replaceAll("/", "_") ), ]), ]; - delete yamlObject.tag; + delete yaml.tag; } catch (e) { notif({ settings, e: true }, e); } } - if (yamlObject.tags) { + if (yaml.tags) { try { - yamlObject.tags = [ + yaml.tags = [ ...new Set([ - ...yamlObject.tags.map((tag: string) => + ...yaml.tags.map((tag: string) => tag.replaceAll("/", "_") ), ...toAdd, @@ -90,13 +81,62 @@ export async function addTagsToYAML(text: string, toAdd: string[], settings: Git notif({ settings, e: true }, e); } } else { - yamlObject.tags = toAdd; + yaml.tags = toAdd; + } + return yaml; +} + +/** + * Add the string list to the YAML frontmatter tags key + * If the tags key does not exist, it will be created + * @param {string} text the text to convert + * @param {string[]} toAdd the list of tags to add + * @param settings + * @returns {Promise} the converted text + */ + +export function addToYaml(text: string, toAdd: string[], settings: GitHubPublisherSettings, folderNoteParaMeters?: { properties: MultiProperties, file: TFile}): string { + const yaml = text.split("---")[1]; + let yamlObject = parseYaml(yaml); + if (toAdd.length > 0) { + yamlObject = tagsToYaml(toAdd, settings, yamlObject); + } + if (folderNoteParaMeters) { + yamlObject = titleToYaml(yamlObject, folderNoteParaMeters.properties, folderNoteParaMeters.file); } const returnToYaml = stringifyYaml(yamlObject); const fileContentsOnly = text.split("---").slice(2).join("---"); return `---\n${returnToYaml}---\n${fileContentsOnly}`; } +//eslint-disable-next-line @typescript-eslint/no-explicit-any +function titleToYaml(yaml: any, properties: MultiProperties, file: TFile) { + const settings = properties.settings.upload.folderNote.addTitle; + if (!settings) { + return yaml; + } + if (!yaml[settings.key] && isFolderNote(properties) && settings.enable) { + yaml[settings.key] = file.basename; + } + return yaml; +} + +function inlineTags(settings: GitHubPublisherSettings, file: TFile, metadataCache: MetadataCache, frontmatter: FrontMatterCache | undefined | null) { + if (!settings.conversion.tags.inline) { + return []; + } + const inlineTags = metadataCache.getFileCache(file)?.tags; + const inlineTagsInText = inlineTags + ? inlineTags.map((t) => t.tag.replace("#", "").replaceAll("/", "_")) + : []; + const frontmatterTags = parseFrontMatterTags(frontmatter); + + const yamlTags = frontmatterTags + ? frontmatterTags.map((t) => t.replace("#", "").replaceAll("/", "_")) + : []; + return [...new Set([...inlineTagsInText, ...yamlTags])]; +} + /** * Add inlines tags to frontmatter tags keys. * Duplicate tags will be removed. @@ -107,30 +147,17 @@ export async function addTagsToYAML(text: string, toAdd: string[], settings: Git * @param {string} text the text to convert * @return {Promise} the converted text */ -export async function addInlineTags( +export async function processYaml( settings: GitHubPublisherSettings, file: TFile, metadataCache: MetadataCache, frontmatter: FrontMatterCache | undefined | null, - text: string + text: string, + multiProperties: MultiProperties ): Promise { - if (!settings.conversion.tags.inline) { - return text; - } - const inlineTags = metadataCache.getFileCache(file)?.tags; - const inlineTagsInText = inlineTags - ? inlineTags.map((t) => t.tag.replace("#", "").replaceAll("/", "_")) - : []; - const frontmatterTags = parseFrontMatterTags(frontmatter); - - const yamlTags = frontmatterTags - ? frontmatterTags.map((t) => t.replace("#", "").replaceAll("/", "_")) - : []; - const toAdd = [...new Set([...inlineTagsInText, ...yamlTags])]; - if (toAdd.length > 0) { - return await addTagsToYAML(text, toAdd, settings); - } - return text; + const toAdd = inlineTags(settings, file, metadataCache, frontmatter); + const folderNoteParaMeters = { properties: multiProperties, file }; + return addToYaml(text, toAdd, settings, folderNoteParaMeters); } @@ -151,7 +178,7 @@ export async function mainConverting( if (properties.frontmatter.general.removeEmbed === "bake") text = await bakeEmbeds(file, new Set(), app, properties, null, linkedFiles); text = findAndReplaceText(text, properties.settings, false); - text = await addInlineTags(properties.settings, file, plugin.app.metadataCache, frontmatter, text); + text = await processYaml(properties.settings, file, plugin.app.metadataCache, frontmatter, text, properties); text = await convertToInternalGithub( text, linkedFiles, @@ -174,3 +201,5 @@ export async function mainConverting( return findAndReplaceText(text, properties.settings, true); } + + diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 6047d9db..3bdcc9af 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -506,6 +506,12 @@ "title": "File tree in repository", "yaml": "Property key" }, + "folderNote": { + "addTitle": { + "key": "Use a key other than \"title\"", + "title": "Automatically add the \"title\" key with the file name" + } + }, "frontmatterKey": { "desc": "Set the key where to get the folder's value.", "placeholder": "category", diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 2276aed2..298c57c2 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -505,6 +505,12 @@ "title": "Hiérarchie des dossiers", "yaml": "Valeur d'une clé de propriété" }, + "folderNote": { + "addTitle": { + "key": "Utiliser une autre clé que \"title\"", + "title": "Ajouter automatiquement la clé \"title\" avec le nom du fichier" + } + }, "frontmatterKey": { "desc": "Définir le nom de la clé où obtenir le dossier", "placeholder": "category", diff --git a/src/settings.ts b/src/settings.ts index 711b8b19..a8a6267e 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -524,6 +524,7 @@ export class GithubPublisherSettingsTab extends PluginSettingTab { }); if (uploadSettings.folderNote.enable) { + folderNoteSettings.addText((text) => { text.setPlaceholder("folderNote") .setValue(uploadSettings.folderNote.rename) @@ -533,6 +534,29 @@ export class GithubPublisherSettingsTab extends PluginSettingTab { }); }); + new Setting(this.settingsPage) + .setName(i18next.t("settings.upload.folderNote.addTitle.title")) + .addToggle((toggle) => { + toggle + .setValue(uploadSettings.folderNote.addTitle.enable) + .onChange(async (value) => { + uploadSettings.folderNote.addTitle.enable = value; + await this.plugin.saveSettings(); + this.renderSettingsPage(EnumbSettingsTabId.upload); + }); + }); + if (uploadSettings.folderNote.addTitle.enable) { + new Setting(this.settingsPage) + .setName(i18next.t("settings.upload.folderNote.addTitle.key")) + .addText((text) => { + text.setPlaceholder("title") + .setValue(uploadSettings.folderNote.addTitle.key) + .onChange(async (value) => { + uploadSettings.folderNote.addTitle.key = value; + await this.plugin.saveSettings(); + }); + }); + } } showHideBasedOnFolder(this.settings, frontmatterKeySettings, rootFolderSettings, folderNoteSettings); diff --git a/src/settings/interface.ts b/src/settings/interface.ts index 020540ce..f24c2190 100644 --- a/src/settings/interface.ts +++ b/src/settings/interface.ts @@ -90,6 +90,10 @@ export interface GitHubPublisherSettings { folderNote: { enable: boolean; rename: string; + addTitle: { + enable: boolean; + key: string; + }; } metadataExtractorPath: string; } @@ -176,6 +180,7 @@ export interface MultiProperties { repo: RepoFrontmatter | RepoFrontmatter[]; }, repository: Repository | null; + filepath: string; } export interface MonoProperties { @@ -185,6 +190,7 @@ export interface MonoProperties { repo: RepoFrontmatter }, repository: Repository | null; + filepath: string; } export interface MonoRepoProperties { @@ -204,7 +210,7 @@ export interface MultiRepoProperties { */ export const TOKEN_PATH:string = "%configDir%/plugins/%pluginID%/env"; -export const DEFAULT_SETTINGS: GitHubPublisherSettings = { +export const DEFAULT_SETTINGS: Partial = { github: { user: "", repo: "", @@ -241,6 +247,10 @@ export const DEFAULT_SETTINGS: GitHubPublisherSettings = { folderNote: { enable: false, rename: "index.md", + addTitle: { + enable: false, + key: "title", + } }, metadataExtractorPath: "", }, diff --git a/src/utils/data_validation_test.ts b/src/utils/data_validation_test.ts index dc6c79c6..36cfcbf0 100644 --- a/src/utils/data_validation_test.ts +++ b/src/utils/data_validation_test.ts @@ -403,4 +403,16 @@ export function forcePushAttachment(file: TFile, settings: GitHubPublisherSettin else if (ext.match(FIND_REGEX) && file.extension.match(new RegExp(ext))) return true; } return false; +} + +export function isFolderNote(properties: MultiProperties) { + const enabled = properties.settings.upload.folderNote.enable; + if (enabled) { + const model = properties.settings.upload.folderNote.rename; + const filepath = properties.filepath; + //get the file name aka split by / and get the last element + const filename = filepath.split("/").pop(); + return filename === model; + } + return false; } \ No newline at end of file