mirror of
https://github.com/alberti42/obsidian-plugins-annotations.git
synced 2026-07-22 10:10:24 +00:00
Sorted alphabetically
This commit is contained in:
parent
bd81b45e62
commit
2b126c343f
6 changed files with 139 additions and 126 deletions
|
|
@ -15,7 +15,7 @@
|
|||
main
|
||||
= blocks:block* {
|
||||
const dictionary = blocks.reduce((acc, block) => {
|
||||
if(block){ addToDictionary(acc, block); }
|
||||
if(block){ addToDictionary(acc, block); }
|
||||
return acc;
|
||||
}, {});
|
||||
return dictionary;
|
||||
|
|
@ -27,20 +27,21 @@ block
|
|||
annotation_block
|
||||
= name:plugin_name tags:tag+ begin_cmd desc:description end_cmd {
|
||||
|
||||
const tags_dict = tags.reduce((acc, block) => {
|
||||
acc[block.tag] = block.arg;
|
||||
const tags_dict = tags.reduce((acc, block) => {
|
||||
acc[block.tag] = block.arg;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// check all mandatory tags are there
|
||||
let integral = true;
|
||||
for (let tag of mandatory_tags) {
|
||||
if(!(tag in tags_dict)) {
|
||||
for (let tag of mandatory_tags) {
|
||||
if(!(tag in tags_dict)) {
|
||||
integral = false;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(integral) {
|
||||
if(integral && desc.trim() !== '') {
|
||||
return {
|
||||
id: tags_dict['id'],
|
||||
name: name,
|
||||
|
|
@ -60,18 +61,18 @@ id_field
|
|||
|
||||
type_field
|
||||
= "<!--" _* "type:" _* type:valid_types _* "-->" newline+ { return { 'tag': 'type', 'arg': type }; }
|
||||
|
||||
|
||||
tag
|
||||
= id_field / type_field
|
||||
|
||||
|
||||
valid_types
|
||||
= $("markdown"i / "html"i / "text"i) { return text().toLowerCase(); }
|
||||
|
||||
begin_cmd
|
||||
= $("<!--" _* "BEGIN" _* "ANNOTATION" _* "-->" newline+)
|
||||
= $("<!--" _* "BEGIN" _* "ANNOTATION" _* "-->" newline*)
|
||||
|
||||
end_cmd
|
||||
= $(newline+ "<!--" _* "END" _* "ANNOTATION" _* "-->" newline+)
|
||||
= $(newline* "<!--" _* "END" _* "ANNOTATION" _* "-->" newline+)
|
||||
|
||||
description
|
||||
= $(!end_cmd .)*
|
||||
|
|
|
|||
15
src/main.ts
15
src/main.ts
|
|
@ -20,7 +20,8 @@ import { DEFAULT_SETTINGS_1_3_0, DEFAULT_SETTINGS_1_4_0 } from './defaults_legac
|
|||
import { DEFAULT_SETTINGS } from 'defaults';
|
||||
import { PluginsAnnotationsSettingTab } from 'settings_tab'
|
||||
import * as path from 'path';
|
||||
import { readAnnotationsFromFile, writeAnnotationsToFile } from 'manageAnnotations';
|
||||
import { readAnnotationsFromMdFile, writeAnnotationsToMdFile } from 'manageAnnotations';
|
||||
import { sortPluginAnnotationsByName } from 'utils';
|
||||
|
||||
export default class PluginsAnnotations extends Plugin {
|
||||
settings: PluginsAnnotationsSettings = {...DEFAULT_SETTINGS};
|
||||
|
|
@ -53,7 +54,7 @@ export default class PluginsAnnotations extends Plugin {
|
|||
this.app.vault.on('modify', (modifiedFile: TAbstractFile) => {
|
||||
if(this.settings.markdown_file_path !== '') {
|
||||
if (modifiedFile.path === this.settings.markdown_file_path) {
|
||||
readAnnotationsFromFile(this);
|
||||
readAnnotationsFromMdFile(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -138,7 +139,7 @@ export default class PluginsAnnotations extends Plugin {
|
|||
}
|
||||
|
||||
if(this.settings.markdown_file_path!=='') {
|
||||
readAnnotationsFromFile(this);
|
||||
await readAnnotationsFromMdFile(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +330,7 @@ export default class PluginsAnnotations extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
async renderAnnotation(annotation_div: HTMLDivElement, annoType:AnnotationType, desc:string) {
|
||||
async renderAnnotation(annotation_div: HTMLElement, annoType:AnnotationType, desc:string) {
|
||||
annotation_div.innerText = '';
|
||||
switch(annoType) {
|
||||
case AnnotationType.text: {
|
||||
|
|
@ -431,7 +432,7 @@ export default class PluginsAnnotations extends Plugin {
|
|||
selection.addRange(range);
|
||||
}
|
||||
} else {
|
||||
// Only update innerText if not clicking on a link
|
||||
// Only update annotation_div.innerText if not clicking on a link
|
||||
if (!clickedLink) {
|
||||
let preamble;
|
||||
switch(annoType) {
|
||||
|
|
@ -635,7 +636,7 @@ export default class PluginsAnnotations extends Plugin {
|
|||
this.saveTimeout = window.setTimeout(async () => {
|
||||
this.saveSettings(settings);
|
||||
if(this.settings.markdown_file_path!=='') {
|
||||
writeAnnotationsToFile(this);
|
||||
writeAnnotationsToMdFile(this);
|
||||
}
|
||||
this.saveTimeout = null;
|
||||
}, timeout_ms);
|
||||
|
|
@ -664,7 +665,7 @@ export default class PluginsAnnotations extends Plugin {
|
|||
const installedPluginIds = new Set(Object.keys(this.app.plugins.manifests));
|
||||
const uninstalledPlugins: PluginAnnotationDict = {};
|
||||
|
||||
for (const pluginId in this.settings.annotations) {
|
||||
for (const pluginId of sortPluginAnnotationsByName(this.settings.annotations)) {
|
||||
if (!installedPluginIds.has(pluginId)) {
|
||||
uninstalledPlugins[pluginId] = this.settings.annotations[pluginId];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export async function handleMarkdownFilePathChange(plugin: PluginsAnnotations, f
|
|||
return true;
|
||||
}
|
||||
|
||||
export async function readAnnotationsFromFile(plugin: PluginsAnnotations): Promise<void> {
|
||||
export async function readAnnotationsFromMdFile(plugin: PluginsAnnotations): Promise<void> {
|
||||
if(isWriting) return;
|
||||
|
||||
const filePath = plugin.settings.markdown_file_path;
|
||||
|
|
@ -70,7 +70,7 @@ export async function readAnnotationsFromFile(plugin: PluginsAnnotations): Promi
|
|||
|
||||
if(!file) {
|
||||
// If the file does not exist but we have annotation in memory, write them down
|
||||
writeAnnotationsToFile(plugin);
|
||||
writeAnnotationsToMdFile(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -86,14 +86,14 @@ export async function readAnnotationsFromFile(plugin: PluginsAnnotations): Promi
|
|||
} else {
|
||||
console.error("Unexpected error:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to read annotations from file:', error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export async function writeAnnotationsToFile(plugin: PluginsAnnotations) {
|
||||
export async function writeAnnotationsToMdFile(plugin: PluginsAnnotations) {
|
||||
if(!plugin.pluginNameToIdMap) return;
|
||||
const filePath = plugin.settings.markdown_file_path;
|
||||
if(filePath === "") return;
|
||||
|
|
@ -104,7 +104,7 @@ export async function writeAnnotationsToFile(plugin: PluginsAnnotations) {
|
|||
|
||||
const content: string[] = [header];
|
||||
for (const pluginId in annotations) {
|
||||
content.push(`# ${annotations[pluginId].name}\n\n<!-- id: ${pluginId} -->\n<!-- BEGIN ANNOTATION -->\n${annotations[pluginId].desc}\n<!-- END ANNOTATION -->\n`);
|
||||
content.push(`# ${annotations[pluginId].name}\n\n<!-- id: ${pluginId} -->\n<!-- type: ${annotations[pluginId].type} -->\n<!-- BEGIN ANNOTATION -->\n${annotations[pluginId].desc}\n<!-- END ANNOTATION -->\n`);
|
||||
}
|
||||
const content_concatenated = content.join('\n');
|
||||
|
||||
|
|
|
|||
167
src/peggy.mjs
167
src/peggy.mjs
|
|
@ -209,27 +209,28 @@ function peg$parse(input, options) {
|
|||
|
||||
var peg$f0 = function(blocks) {
|
||||
const dictionary = blocks.reduce((acc, block) => {
|
||||
if(block){ addToDictionary(acc, block); }
|
||||
if(block){ addToDictionary(acc, block); }
|
||||
return acc;
|
||||
}, {});
|
||||
return dictionary;
|
||||
};
|
||||
var peg$f1 = function(name, tags, desc) {
|
||||
|
||||
const tags_dict = tags.reduce((acc, block) => {
|
||||
acc[block.tag] = block.arg;
|
||||
const tags_dict = tags.reduce((acc, block) => {
|
||||
acc[block.tag] = block.arg;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// check all mandatory tags are there
|
||||
let integral = true;
|
||||
for (let tag of mandatory_tags) {
|
||||
if(!(tag in tags_dict)) {
|
||||
for (let tag of mandatory_tags) {
|
||||
if(!(tag in tags_dict)) {
|
||||
integral = false;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(integral) {
|
||||
if(integral && desc.trim() !== '') {
|
||||
return {
|
||||
id: tags_dict['id'],
|
||||
name: name,
|
||||
|
|
@ -928,21 +929,12 @@ function peg$parse(input, options) {
|
|||
if (s8 !== peg$FAILED) {
|
||||
s9 = [];
|
||||
s10 = peg$parsenewline();
|
||||
if (s10 !== peg$FAILED) {
|
||||
while (s10 !== peg$FAILED) {
|
||||
s9.push(s10);
|
||||
s10 = peg$parsenewline();
|
||||
}
|
||||
} else {
|
||||
s9 = peg$FAILED;
|
||||
}
|
||||
if (s9 !== peg$FAILED) {
|
||||
s2 = [s2, s3, s4, s5, s6, s7, s8, s9];
|
||||
s1 = s2;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
while (s10 !== peg$FAILED) {
|
||||
s9.push(s10);
|
||||
s10 = peg$parsenewline();
|
||||
}
|
||||
s2 = [s2, s3, s4, s5, s6, s7, s8, s9];
|
||||
s1 = s2;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
|
|
@ -975,82 +967,73 @@ function peg$parse(input, options) {
|
|||
s1 = peg$currPos;
|
||||
s2 = [];
|
||||
s3 = peg$parsenewline();
|
||||
if (s3 !== peg$FAILED) {
|
||||
while (s3 !== peg$FAILED) {
|
||||
s2.push(s3);
|
||||
s3 = peg$parsenewline();
|
||||
}
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
while (s3 !== peg$FAILED) {
|
||||
s2.push(s3);
|
||||
s3 = peg$parsenewline();
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
if (input.substr(peg$currPos, 4) === peg$c1) {
|
||||
s3 = peg$c1;
|
||||
peg$currPos += 4;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e1); }
|
||||
}
|
||||
if (s3 !== peg$FAILED) {
|
||||
s4 = [];
|
||||
if (input.substr(peg$currPos, 4) === peg$c1) {
|
||||
s3 = peg$c1;
|
||||
peg$currPos += 4;
|
||||
} else {
|
||||
s3 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e1); }
|
||||
}
|
||||
if (s3 !== peg$FAILED) {
|
||||
s4 = [];
|
||||
s5 = peg$parse_();
|
||||
while (s5 !== peg$FAILED) {
|
||||
s4.push(s5);
|
||||
s5 = peg$parse_();
|
||||
while (s5 !== peg$FAILED) {
|
||||
s4.push(s5);
|
||||
s5 = peg$parse_();
|
||||
}
|
||||
if (input.substr(peg$currPos, 3) === peg$c10) {
|
||||
s5 = peg$c10;
|
||||
peg$currPos += 3;
|
||||
} else {
|
||||
s5 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e11); }
|
||||
}
|
||||
if (s5 !== peg$FAILED) {
|
||||
s6 = [];
|
||||
}
|
||||
if (input.substr(peg$currPos, 3) === peg$c10) {
|
||||
s5 = peg$c10;
|
||||
peg$currPos += 3;
|
||||
} else {
|
||||
s5 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e11); }
|
||||
}
|
||||
if (s5 !== peg$FAILED) {
|
||||
s6 = [];
|
||||
s7 = peg$parse_();
|
||||
while (s7 !== peg$FAILED) {
|
||||
s6.push(s7);
|
||||
s7 = peg$parse_();
|
||||
while (s7 !== peg$FAILED) {
|
||||
s6.push(s7);
|
||||
s7 = peg$parse_();
|
||||
}
|
||||
if (input.substr(peg$currPos, 10) === peg$c9) {
|
||||
s7 = peg$c9;
|
||||
peg$currPos += 10;
|
||||
} else {
|
||||
s7 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e10); }
|
||||
}
|
||||
if (s7 !== peg$FAILED) {
|
||||
s8 = [];
|
||||
}
|
||||
if (input.substr(peg$currPos, 10) === peg$c9) {
|
||||
s7 = peg$c9;
|
||||
peg$currPos += 10;
|
||||
} else {
|
||||
s7 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e10); }
|
||||
}
|
||||
if (s7 !== peg$FAILED) {
|
||||
s8 = [];
|
||||
s9 = peg$parse_();
|
||||
while (s9 !== peg$FAILED) {
|
||||
s8.push(s9);
|
||||
s9 = peg$parse_();
|
||||
while (s9 !== peg$FAILED) {
|
||||
s8.push(s9);
|
||||
s9 = peg$parse_();
|
||||
}
|
||||
if (input.substr(peg$currPos, 3) === peg$c3) {
|
||||
s9 = peg$c3;
|
||||
peg$currPos += 3;
|
||||
}
|
||||
if (input.substr(peg$currPos, 3) === peg$c3) {
|
||||
s9 = peg$c3;
|
||||
peg$currPos += 3;
|
||||
} else {
|
||||
s9 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
||||
}
|
||||
if (s9 !== peg$FAILED) {
|
||||
s10 = [];
|
||||
s11 = peg$parsenewline();
|
||||
if (s11 !== peg$FAILED) {
|
||||
while (s11 !== peg$FAILED) {
|
||||
s10.push(s11);
|
||||
s11 = peg$parsenewline();
|
||||
}
|
||||
} else {
|
||||
s9 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
||||
s10 = peg$FAILED;
|
||||
}
|
||||
if (s9 !== peg$FAILED) {
|
||||
s10 = [];
|
||||
s11 = peg$parsenewline();
|
||||
if (s11 !== peg$FAILED) {
|
||||
while (s11 !== peg$FAILED) {
|
||||
s10.push(s11);
|
||||
s11 = peg$parsenewline();
|
||||
}
|
||||
} else {
|
||||
s10 = peg$FAILED;
|
||||
}
|
||||
if (s10 !== peg$FAILED) {
|
||||
s2 = [s2, s3, s4, s5, s6, s7, s8, s9, s10];
|
||||
s1 = s2;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s10 !== peg$FAILED) {
|
||||
s2 = [s2, s3, s4, s5, s6, s7, s8, s9, s10];
|
||||
s1 = s2;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab {
|
|||
}));
|
||||
|
||||
// Check if uninstalledPlugins is empty
|
||||
if (Object.keys(uninstalledPlugins).length === 0) {
|
||||
return;
|
||||
}
|
||||
if (Object.keys(uninstalledPlugins).length === 0) return;
|
||||
|
||||
const list_uninstalled_label = new Setting(containerEl)
|
||||
.setName('List of no longer installed plugins:')
|
||||
|
|
@ -45,7 +43,6 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab {
|
|||
Object.keys({...uninstalledPlugins}).forEach(pluginId => {
|
||||
const pluginSetting = new Setting(containerEl)
|
||||
.setName(`Plugin ${uninstalledPlugins[pluginId].name}`)
|
||||
.setDesc("Annotation: " + uninstalledPlugins[pluginId].desc)
|
||||
.addButton(button => button
|
||||
.setButtonText('Delete')
|
||||
.setCta()
|
||||
|
|
@ -61,15 +58,14 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab {
|
|||
list_uninstalled_label.settingEl.remove();
|
||||
}
|
||||
}));
|
||||
// Render the annotation inside the temporary div
|
||||
this.plugin.renderAnnotation(pluginSetting.descEl, uninstalledPlugins[pluginId].type, uninstalledPlugins[pluginId].desc);
|
||||
pluginSetting.descEl.classList.add('plugin-comment-annotation');
|
||||
pluginSetting.settingEl.classList.add('plugin-comment-uninstalled');
|
||||
});
|
||||
}
|
||||
|
||||
async display(): Promise<void> {
|
||||
await this.plugin.loadSettings();
|
||||
|
||||
const containerEl = this.containerEl;
|
||||
|
||||
const createPluginsPaneFragment = (): DocumentFragment => {
|
||||
return createFragment((frag) => {
|
||||
const em = frag.createEl('em');
|
||||
|
|
@ -81,8 +77,15 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab {
|
|||
});
|
||||
};
|
||||
|
||||
// Load annotations first
|
||||
await this.plugin.loadSettings();
|
||||
|
||||
// Clean container in the preference pane
|
||||
const containerEl = this.containerEl;
|
||||
containerEl.empty();
|
||||
|
||||
/* ====== Personal annotations ====== */
|
||||
|
||||
new Setting(containerEl).setName('Personal annotations').setHeading();
|
||||
const instructions = createFragment((frag) => {
|
||||
const div = document.createElement('div');
|
||||
|
|
@ -285,6 +288,14 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab {
|
|||
this.plugin.debouncedSaveAnnotations();
|
||||
}));
|
||||
|
||||
|
||||
/* ====== Backups ====== */
|
||||
|
||||
|
||||
|
||||
|
||||
/* ====== Personal annotations of no longer installed community plugins ====== */
|
||||
|
||||
this.createUninstalledPluginSettings(containerEl);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
21
src/utils.ts
21
src/utils.ts
|
|
@ -1,9 +1,10 @@
|
|||
// utils.ts
|
||||
|
||||
import PluginsAnnotations from "main";
|
||||
import { App, Modal, normalizePath, TAbstractFile, TFile, TFolder, Vault,
|
||||
AbstractInputSuggest, prepareFuzzySearch, SearchResult } from "obsidian";
|
||||
import * as path from "path";
|
||||
import { ParsedPath } from "types";
|
||||
import { ParsedPath, PluginAnnotationDict } from "types";
|
||||
|
||||
export function parseFilePath(filePath: string): ParsedPath {
|
||||
filePath = normalizePath(filePath);
|
||||
|
|
@ -15,7 +16,7 @@ export function parseFilePath(filePath: string): ParsedPath {
|
|||
const filename = extIndex !== -1 ? base.substring(0, extIndex) : base;
|
||||
const ext = extIndex !== -1 ? base.substring(extIndex) : '';
|
||||
|
||||
return { dir, base, filename, ext, path: filePath };
|
||||
return { dir: normalizePath(dir), base, filename, ext, path: filePath };
|
||||
}
|
||||
|
||||
// Helper function to show a confirmation dialog
|
||||
|
|
@ -118,4 +119,20 @@ export class FileSuggestion extends AbstractInputSuggest<TFile> {
|
|||
this.textInputEl.focus()
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sorting plugins annotations by name */
|
||||
|
||||
// Function to sort PluginAnnotationDict based on the name field
|
||||
export function sortPluginAnnotationsByName(annotations: PluginAnnotationDict): string[] {
|
||||
// Create an array of pairs [pluginId, name]
|
||||
const pluginArray = Object.entries(annotations).map(([pluginId, annotation]) => {
|
||||
return { pluginId, name: annotation.name };
|
||||
});
|
||||
|
||||
// Sort the array based on the 'name' field
|
||||
pluginArray.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
return pluginArray.map(item => item.pluginId);
|
||||
}
|
||||
Loading…
Reference in a new issue