mirror of
https://github.com/mara-li/obsidian-my-thesaurus.git
synced 2026-07-22 05:38:22 +00:00
feat: add commands to parse one file
This commit is contained in:
parent
13fd74421d
commit
76dc95ee2a
8 changed files with 115 additions and 19 deletions
|
|
@ -1,10 +1,16 @@
|
|||
{
|
||||
"command": {
|
||||
"active": "Add thesaurus tags to active file"
|
||||
},
|
||||
"error": {
|
||||
"csv": {
|
||||
"columns": "The columns doesn't correspond with the settings.",
|
||||
"header": "You can have only two column in your thesaurus. You have: {{- len}} columns.",
|
||||
"malformed": "Your CSV is malformed: {{- len}} columns found.",
|
||||
"separator": "The specified separator is invalid. You seems to use \"{{- sep}}\" as separator."
|
||||
},
|
||||
"file": {
|
||||
"empty": "The file {{- file}} is empty!"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
|
@ -19,11 +25,11 @@
|
|||
},
|
||||
"title": "Column title"
|
||||
},
|
||||
"excludedPath": {
|
||||
"desc": "Exclude files in theses paths when using the global command. ",
|
||||
"includedPaths": {
|
||||
"desc": "Includes files from its paths when using the global command.",
|
||||
"regex": "Regex are supported.",
|
||||
"separate": "Separate paths with coma, semicolon, spaces or newlines.",
|
||||
"title": "Excluded path"
|
||||
"title": "Included paths"
|
||||
},
|
||||
"separator": {
|
||||
"desc": "CSV column separator.",
|
||||
|
|
@ -38,5 +44,9 @@
|
|||
"title": "Thesaurus",
|
||||
"verify": "Verify validity of the file"
|
||||
}
|
||||
},
|
||||
"success": {
|
||||
"none": "No tag to add!",
|
||||
"title": "The tags has been added:"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,16 @@
|
|||
{
|
||||
"command": {
|
||||
"active": "Ajouter les tags du thésaurus au fichier actif"
|
||||
},
|
||||
"error": {
|
||||
"csv": {
|
||||
"columns": "Les colonnes du CSV fourni ne correspondent pas avec les colonnes des paramètres.",
|
||||
"header": "Vous ne pouvez avoir que deux colonnes dans votre thésaurus. Vous avez {{- len}} colonnes.",
|
||||
"malformed": "Votre CSV est mal formé : {{- len}} colonnes trouvées.",
|
||||
"separator": "Le séparateur spécifié n'est pas le bon. Vous semblez utiliser \"{{- sep}}\" comme séparateur."
|
||||
},
|
||||
"file": {
|
||||
"empty": "Le fichier {{- file}} est vide !"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
|
@ -19,11 +25,11 @@
|
|||
},
|
||||
"title": "Titre des colonnes"
|
||||
},
|
||||
"excludedPath": {
|
||||
"desc": "Exclus les fichiers depuis ses chemins lors d'utilisation de la commande globale.",
|
||||
"includedPaths": {
|
||||
"desc": "Inclus les fichiers depuis ses chemins lors d'utilisation de la commande globale.",
|
||||
"regex": "Les expressions régulières sont supportées.",
|
||||
"separate": "Séparer les chemins par une virgule, point virgule, un espace ou un retour à la ligne.",
|
||||
"title": "Fichier exclus"
|
||||
"separate": "Séparer les chemins par une virgule, point virgule ou un retour à la ligne.",
|
||||
"title": "Chemins inclus"
|
||||
},
|
||||
"separator": {
|
||||
"desc": "Séparateur des colonnes du fichier CSV.",
|
||||
|
|
@ -38,5 +44,9 @@
|
|||
"title": "Thesaurus",
|
||||
"verify": "Verifier la validité du fichier"
|
||||
}
|
||||
},
|
||||
"success": {
|
||||
"none": "Aucun tag à ajouter !",
|
||||
"title": "Les tags suivants ont bien été ajoutés :"
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import type { TFunction } from "i18next";
|
|||
|
||||
export interface MyThesaurusSettings {
|
||||
thesaurusPath: string;
|
||||
excludedPath: string[];
|
||||
includedPaths: string[];
|
||||
separator: Separator;
|
||||
columns: ColumnName;
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ export type Translation = TFunction<"translation", undefined>;
|
|||
|
||||
export const DEFAULT_SETTINGS: MyThesaurusSettings = {
|
||||
thesaurusPath: "",
|
||||
excludedPath: [],
|
||||
includedPaths: [],
|
||||
separator: ";",
|
||||
columns: {
|
||||
term: "term",
|
||||
|
|
|
|||
57
src/main.ts
57
src/main.ts
|
|
@ -1,14 +1,55 @@
|
|||
import i18next from "i18next";
|
||||
import { Plugin } from "obsidian";
|
||||
import { Notice, Plugin, type TFile, sanitizeHTMLToDom } from "obsidian";
|
||||
import { resources, translationLanguage } from "./i18n";
|
||||
|
||||
import { DEFAULT_SETTINGS, type MyThesaurusSettings } from "./interfaces";
|
||||
import { MyThesaurusSettingTab } from "./settings";
|
||||
import "uniformize";
|
||||
import { getTags, getThesaurus } from "./utils";
|
||||
|
||||
export default class MyThesaurus extends Plugin {
|
||||
settings!: MyThesaurusSettings;
|
||||
|
||||
async addTagsToNote(tags: string[], file: TFile) {
|
||||
const currentTags = this.app.metadataCache.getFileCache(file)?.tags || [];
|
||||
const newTags = [...new Set([...currentTags, ...tags])];
|
||||
if (newTags.length === 0) return;
|
||||
await this.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
||||
frontmatter.tags = newTags;
|
||||
});
|
||||
}
|
||||
|
||||
async parseFile(file: TFile) {
|
||||
const contents = await this.app.vault.read(file);
|
||||
const thesaurusFile = this.app.vault.getAbstractFileByPath(
|
||||
this.settings.thesaurusPath
|
||||
) as TFile;
|
||||
const thesaurusContents = await this.app.vault.read(thesaurusFile);
|
||||
if (contents.length === 0) {
|
||||
new Notice(i18next.t("error.file.empty", { file: file.name }));
|
||||
}
|
||||
try {
|
||||
const thesaurus = getThesaurus(
|
||||
thesaurusContents,
|
||||
this.settings.separator,
|
||||
i18next.t,
|
||||
this.settings.columns
|
||||
);
|
||||
const tags = getTags(contents, thesaurus);
|
||||
if (tags.length > 0) {
|
||||
await this.addTagsToNote(tags, file);
|
||||
const successMsg = sanitizeHTMLToDom(
|
||||
`<p>${i18next.t("success.title")}</p><ul>${tags.map((tag) => `<li>${tag}</li>`)}</ul>`
|
||||
);
|
||||
new Notice(successMsg);
|
||||
} else {
|
||||
new Notice(i18next.t("success.none"));
|
||||
}
|
||||
} catch (error) {
|
||||
new Notice((error as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
async onload() {
|
||||
console.log(`[${this.manifest.name}] Loaded`);
|
||||
await this.loadSettings();
|
||||
|
|
@ -21,6 +62,20 @@ export default class MyThesaurus extends Plugin {
|
|||
returnEmptyString: false,
|
||||
});
|
||||
this.addSettingTab(new MyThesaurusSettingTab(this.app, this));
|
||||
this.addCommand({
|
||||
id: "parse-file",
|
||||
name: i18next.t("command.active"),
|
||||
checkCallback: (checking) => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (file && file.extension == "md") {
|
||||
if (!checking) {
|
||||
this.parseFile(file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
import type { MyThesaurusSettings, Separator } from "./interfaces";
|
||||
import type MyThesaurus from "./main";
|
||||
import { FileSuggester } from "./searchFile";
|
||||
import { verifCSV } from "./utils";
|
||||
import { getThesaurus } from "./utils";
|
||||
|
||||
export class MyThesaurusSettingTab extends PluginSettingTab {
|
||||
plugin: MyThesaurus;
|
||||
|
|
@ -91,7 +91,7 @@ export class MyThesaurusSettingTab extends PluginSettingTab {
|
|||
}
|
||||
const content = await this.app.vault.read(file);
|
||||
try {
|
||||
verifCSV(
|
||||
getThesaurus(
|
||||
content,
|
||||
this.settings.separator,
|
||||
i18next.t,
|
||||
|
|
@ -110,16 +110,19 @@ export class MyThesaurusSettingTab extends PluginSettingTab {
|
|||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(i18next.t("settings.excludedPath.title"))
|
||||
.setName(i18next.t("settings.includedPaths.title"))
|
||||
.setHeading()
|
||||
.setDesc(
|
||||
sanitizeHTMLToDom(
|
||||
`${i18next.t("settings.excludedPath.desc")}<br>${i18next.t("settings.excludedPath.separate")}<br>${i18next.t("settings.excludedPath.regex")}`
|
||||
`${i18next.t("settings.includedPaths.desc")}<br>${i18next.t("settings.includedPaths.separate")}<br>${i18next.t("settings.includedPaths.regex")}`
|
||||
)
|
||||
)
|
||||
.addTextArea((text) => {
|
||||
text.setValue(this.settings.excludedPath.join("\n")).onChange(async (value) => {
|
||||
this.settings.excludedPath = value.split(/[\n,; ]+/).map((path) => path.trim());
|
||||
text.setValue(this.settings.includedPaths.join("\n")).onChange(async (value) => {
|
||||
this.settings.includedPaths = value
|
||||
.split(/[\n,;]+/)
|
||||
.map((path) => path.trim())
|
||||
.filter((path) => path.length > 0);
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
4
src/utils/index.ts
Normal file
4
src/utils/index.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { getThesaurus } from "./parse_csv";
|
||||
import { getTags } from "./parse_file";
|
||||
|
||||
export { getThesaurus, getTags };
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import type { ColumnName, Separator, Thesaurus, Translation } from "./interfaces";
|
||||
import type { ColumnName, Separator, Thesaurus, Translation } from "../interfaces";
|
||||
|
||||
function verifySeparator(header: string, sep: Separator): boolean {
|
||||
return header.includes(sep);
|
||||
}
|
||||
|
||||
function searchSeparator(header: string): Separator {
|
||||
return header.match(/[,;\t|]/)?.[0] as Separator;
|
||||
return header.match(/[,;\t\|]/)?.[0] as Separator;
|
||||
}
|
||||
|
||||
function getColumn(
|
||||
|
|
@ -33,7 +33,7 @@ function getColumn(
|
|||
return { indexKey, indexSynonyms };
|
||||
}
|
||||
|
||||
export function verifCSV(
|
||||
export function getThesaurus(
|
||||
fileContent: string,
|
||||
separator: Separator,
|
||||
ln: Translation,
|
||||
14
src/utils/parse_file.ts
Normal file
14
src/utils/parse_file.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import type { Thesaurus } from "../interfaces";
|
||||
|
||||
export function getTags(content: string, thesaurus: Thesaurus) {
|
||||
const tagsToAdd: string[] = [];
|
||||
|
||||
for (const tags of Object.keys(thesaurus)) {
|
||||
const synonyms = thesaurus[tags];
|
||||
const regex = new RegExp(`\\b(${[...synonyms].join("|")})\\b`, "gi");
|
||||
if (regex.test(content)) {
|
||||
tagsToAdd.push(tags);
|
||||
}
|
||||
}
|
||||
return tagsToAdd;
|
||||
}
|
||||
Loading…
Reference in a new issue