diff --git a/src/annotation_control.ts b/src/annotation_control.ts index 907edff..6317426 100644 --- a/src/annotation_control.ts +++ b/src/annotation_control.ts @@ -10,66 +10,47 @@ export class annotationControl { private annotationDesc:string; private placeholder:string; private label:string; + private annotation_div: HTMLDivElement; - constructor(private plugin: PluginsAnnotations, annotation_container:HTMLDivElement, pluginId:string,private pluginName:string) { + constructor(private plugin: PluginsAnnotations, private annotation_container:HTMLDivElement, private pluginId:string, private pluginName:string) { this.clickedLink = false; - this.isPlaceholder = this.plugin.settings.annotations[pluginId] ? false : true; + this.isPlaceholder = (this.plugin.settings.annotations.hasOwnProperty(pluginId) && isPluginAnnotation(this.plugin.settings.annotations[pluginId])) ? false : true; this.label = Platform.isMobile ? this.plugin.settings.label_mobile : this.plugin.settings.label_desktop - - /*const label_div = document.createElement('div'); - label_div.addEventListener('click', (event:MouseEvent) => { - event.stopPropagation(); - }); - label_div.classList.add('plugin-comment-label') - const label = Platform.isMobile ? this.plugin.settings.label_mobile : this.plugin.settings.label_desktop - const tmp_div = document.createElement('div'); - this.renderAnnotation(tmp_div,label); - - // Get the first child of tmp_div (assumed to be a

element) - const firstChild = tmp_div.firstElementChild; - - if (firstChild && firstChild.tagName === 'P') { - // Move the content of the

element to label_div - label_div.innerHTML = firstChild.innerHTML; - - // Optionally, you can remove the

from tmp_div if needed - tmp_div.removeChild(firstChild); - }*/ - - const annotation_div = document.createElement('div'); - annotation_div.className = 'plugin-comment-annotation'; - - if(this.plugin.settings.editable) { - annotation_div.contentEditable = 'true'; - annotation_div.classList.add('plugin-comment-annotation-editable'); - } else { - annotation_div.contentEditable = 'false'; - annotation_div.classList.remove('plugin-comment-annotation-editable'); - } - this.placeholder = (this.plugin.settings.label_placeholder).replace(/\$\{plugin_name\}/g, pluginName); - if(!this.isPlaceholder && isPluginAnnotation(this.plugin.settings.annotations[pluginId])) { - const annotation = this.plugin.settings.annotations[pluginId]; - this.annotationDesc = annotation.desc; + console.log(pluginId, this.isPlaceholder); + + this.annotation_div = document.createElement('div'); + this.annotation_div.className = 'plugin-comment-annotation'; + + // Configure editable state + if(this.plugin.settings.editable) { + this.annotation_div.contentEditable = 'true'; + this.annotation_div.classList.add('plugin-comment-annotation-editable'); + } else { + this.annotation_div.contentEditable = 'false'; + this.annotation_div.classList.remove('plugin-comment-annotation-editable'); + } + + if(!this.isPlaceholder) { + this.annotationDesc = this.plugin.settings.annotations[pluginId].desc; } else { this.annotationDesc = this.placeholder.trim(); - - annotation_div.classList.add('plugin-comment-placeholder'); - if (this.plugin.settings.hide_placeholders) { // if it is a placeholder - if(this.plugin.settings.editable) { // if fields can be edited, set the placeholder tag - annotation_container.classList.add('plugin-comment-placeholder'); - } else { // if fields cannot be edited, just simply hide placeholders - annotation_container.classList.add('plugin-comment-hidden'); - } - } + this.setPlaceholderClasses(); } // Initial render - this.renderAnnotation(annotation_div); + this.renderAnnotation(); - annotation_div.addEventListener('mousedown', (event:MouseEvent) => { + // Add listeners + this.addEventListeners(); + + annotation_container.appendChild(this.annotation_div); + } + + addEventListeners() { + this.annotation_div.addEventListener('mousedown', (event:MouseEvent) => { if (event.target && (event.target as HTMLElement).tagName === 'A') { this.clickedLink = true; } else { @@ -78,7 +59,7 @@ export class annotationControl { }); // Prevent click event propagation to parent - annotation_div.addEventListener('click', (event:MouseEvent) => { + this.annotation_div.addEventListener('click', (event:MouseEvent) => { if(!this.plugin.settings.editable) { return; } else { @@ -86,85 +67,103 @@ export class annotationControl { } }); - annotation_div.addEventListener('focus', (event:FocusEvent) => { + this.annotation_div.addEventListener('focus', (event:FocusEvent) => { if(this.clickedLink) return; if (this.isPlaceholder) { + // If the user decided that the placeholder text needs to be cleared if (this.plugin.settings.delete_placeholder_string_on_insertion) { - annotation_div.innerText = ''; + this.annotation_div.innerText = ''; + } else { + // Remove HTML markups + const text = this.annotation_div.innerText; // text without html markup + this.annotation_div.innerText = text; // this removes all html markup for editing + // Force a DOM reflow by reading the offsetHeight (or another property) + // this.annotation_div.offsetHeight; } - annotation_div.classList.remove('plugin-comment-placeholder'); - if (this.plugin.settings.hide_placeholders) { - // we remove 'plugin-comment-placeholder' only when 'this.plugin.settings.hide_placeholders' is true - // when 'this.plugin.settings.hide_placeholders' is false, the class is not set and does not need to be removed. - annotation_container.classList.remove('plugin-comment-placeholder'); - } - - const text = annotation_div.innerText; // text without html markup - annotation_div.innerText = text; // this removes all html markup for editing - // Force a DOM reflow by reading the offsetHeight (or another property) - annotation_div.offsetHeight; + // Remove placeholder attributes when the div receives focus + this.removePlaceholderClasses(); - const range = document.createRange(); - range.selectNodeContents(annotation_div); - const selection = window.getSelection(); - if (selection) { - selection.removeAllRanges(); - selection.addRange(range); - } + // Select existing text + this.selectExistingText(); } else { - annotation_div.innerText = this.annotationDesc; // this removes all html markup for editing + // replaces the rendered content with the annotation containig template strings and Markdown links + this.annotation_div.innerText = this.annotationDesc; } }); - // Save the comment on input change and update inputTriggered status - annotation_div.addEventListener('input', (event: Event) => { - if(!this.plugin.settings.editable) return; - this.isPlaceholder = false; + this.annotation_div.addEventListener('input', (event: Event) => { + // If the user starts typing, it removes the state of placeholder if this was set + if(this.plugin.settings.editable) this.isPlaceholder = false; }); // Add placeholder class back if no changes are made - annotation_div.addEventListener('blur', (event:FocusEvent) => { + this.annotation_div.addEventListener('blur', (event:FocusEvent) => { if(!this.plugin.settings.editable) { return; } if(this.clickedLink) return; - const content = annotation_div.innerText.trim(); + const content = this.annotation_div.innerText.trim(); if (this.isPlaceholder || content === '') { // placeholder - annotation_div.innerHTML = this.placeholder; - delete this.plugin.settings.annotations[pluginId]; - annotation_div.classList.add('plugin-comment-placeholder'); - if (this.plugin.settings.hide_placeholders) { - annotation_container.classList.add('plugin-comment-placeholder'); - } this.isPlaceholder = true; this.annotationDesc = ''; + this.plugin.removeAnnotation(this.pluginId); + this.setPlaceholderClasses(); } else { this.isPlaceholder = false; - this.annotationDesc = content.trim(); - - this.plugin.settings.annotations[pluginId] = { + this.plugin.modifyAnnotation(this.pluginId, { desc: this.annotationDesc, - name: pluginName, - }; - annotation_div.classList.remove('plugin-comment-placeholder'); - - this.renderAnnotation(annotation_div); + name: this.pluginName, + }); + this.removePlaceholderClasses(); } + this.renderAnnotation(); this.plugin.debouncedSaveAnnotations(); }); - - // annotation_container.appendChild(label_div); - annotation_container.appendChild(annotation_div); } - async renderAnnotation(div: HTMLElement) { - div.innerText = ''; - const text = (this.label + this.annotationDesc).replace(/\$\{plugin_name\}/g, this.pluginName); - await MarkdownRenderer.renderMarkdown(text, div, '', this.plugin); - this.handleAnnotationLinks(div); + setPlaceholderClasses() { + this.annotation_div.classList.add('plugin-comment-placeholder'); + if (this.plugin.settings.hide_placeholders) { // if the user intends to hide placeholders + if(this.plugin.settings.editable) { // if fields can be edited, set the placeholder tag to the container + this.annotation_container.classList.add('plugin-comment-placeholder'); + } else { // if fields cannot be edited, just simply hide the container + this.annotation_container.classList.add('plugin-comment-hidden'); + } + } + } + + removePlaceholderClasses() { + this.annotation_div.classList.remove('plugin-comment-placeholder'); + if (this.plugin.settings.hide_placeholders) { + // we remove 'plugin-comment-placeholder' only when 'this.plugin.settings.hide_placeholders' is true + // when 'this.plugin.settings.hide_placeholders' is false, the class is not set and does not need to be removed. + this.annotation_container.classList.remove('plugin-comment-placeholder'); + } + } + + selectExistingText () { + const range = document.createRange(); + range.selectNodeContents(this.annotation_div); + const selection = window.getSelection(); + if (selection) { + selection.removeAllRanges(); + selection.addRange(range); + } + } + + async renderAnnotation() { + this.annotation_div.innerText = ''; + let desc = ''; + if(this.isPlaceholder) { + desc = this.placeholder; + } else { + desc = (this.label + this.annotationDesc).replace(/\$\{plugin_name\}/g, this.pluginName); + } + await MarkdownRenderer.renderMarkdown(desc, this.annotation_div, '', this.plugin); + this.handleAnnotationLinks(this.annotation_div); } // Helper function to parse links and add click listeners diff --git a/src/grammar.pegjs b/src/grammar.pegjs index 63d2412..5b50a10 100644 --- a/src/grammar.pegjs +++ b/src/grammar.pegjs @@ -26,7 +26,6 @@ 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; return acc; @@ -58,14 +57,11 @@ plugin_name id_field = "" !_ .)+ _* "-->" newline+ { return { 'tag': 'id', 'arg': id }; } -//type_field -// = "" newline+ { return { 'tag': 'type', 'arg': type }; } - -//valid_types -// = $("markdown"i / "html"i / "text"i) { return text().toLowerCase(); } +cmd_field + = "" .)* ":" _* arg:$(!(_* "-->") .)* _* "-->" newline+ { return { 'tag': cmd, 'arg': arg }; } tag - = id_field // / type_field + = id_field / cmd_field begin_cmd = $("" newline*) diff --git a/src/main.ts b/src/main.ts index 13e2e6a..8b3d517 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,26 +13,27 @@ import { // App, } from 'obsidian'; import { around } from 'monkey-around'; -import { isPluginsAnnotationsSettings, PluginAnnotationDict, PluginBackup, PluginsAnnotationsSettings } from './types'; +import { isPluginsAnnotationsSettings, PluginAnnotation, PluginAnnotationDict, PluginBackup, PluginsAnnotationsSettings } from './types'; import { PluginAnnotationDict_1_4_0, PluginsAnnotationsSettings_1_4_0, PluginsAnnotationsSettings_1_3_0, isPluginAnnotationDictFormat_1_3_0, isSettingsFormat_1_3_0, isSettingsFormat_1_4_0, parseAnnotation_1_4_0, PluginsAnnotationsSettings_1_5_0, PluginAnnotationDict_1_5_0, isPluginsAnnotationsSettings_1_5_0, } from 'types_legacy' import { DEFAULT_SETTINGS_1_3_0, DEFAULT_SETTINGS_1_4_0, DEFAULT_SETTINGS_1_5_0 } from './defaults_legacy'; import { DEFAULT_SETTINGS } from 'defaults'; import { PluginsAnnotationsSettingTab } from 'settings_tab' import * as path from 'path'; import { readAnnotationsFromMdFile, writeAnnotationsToMdFile } from 'manageAnnotations'; -import { backupSettings, delay, sortPluginAnnotationsByName } from 'utils'; +import { backupSettings, delay } from 'utils'; import { annotationControl } from 'annotation_control'; export default class PluginsAnnotations extends Plugin { settings: PluginsAnnotationsSettings = structuredClone(DEFAULT_SETTINGS); pluginNameToIdMap: Record = {}; pluginIdToNameMap: Record = {}; + sortedPluginIds: string[] = []; private mutationObserver: MutationObserver | null = null; private saveTimeout: number | null = null; private observedTab: SettingTab | null = null; private vaultPath: string | null = null; - + async onload() { // console.clear(); @@ -209,7 +210,7 @@ export default class PluginsAnnotations extends Plugin { // Merge loaded settings with default settings this.settings = Object.assign({}, structuredClone(DEFAULT_SETTINGS), importedSettings); - + if(forceSave || wasUpdated) { // if it requires to store the new settings, the .md file will be overwritten await this.saveSettings(); } else { // otherwise read from the md file @@ -217,6 +218,8 @@ export default class PluginsAnnotations extends Plugin { await readAnnotationsFromMdFile(this); } } + + this.sortPluginAnnotationsByName(); } // Store the path to the vault @@ -312,7 +315,7 @@ export default class PluginsAnnotations extends Plugin { // Triggered when pluginId has been uninstalled if (self.settings.automatic_remove && self.settings.annotations.hasOwnProperty(pluginId)) { // If automatic_remove is enabled and there is an annotation, remove the annotation - delete self.settings.annotations[pluginId]; + self.removeAnnotation(pluginId); self.debouncedSaveAnnotations(); } }; @@ -323,6 +326,30 @@ export default class PluginsAnnotations extends Plugin { this.register(removeMonkeyPatchForPlugins); } + removeAnnotation(pluginId: string) { + delete this.settings.annotations[pluginId]; + this.sortedPluginIds = this.sortedPluginIds.filter(item => item !== pluginId); + } + + modifyAnnotation(pluginId: string, annotation: PluginAnnotation) { + const alreadyExisted = this.settings.annotations.hasOwnProperty(pluginId); + this.settings.annotations[pluginId] = annotation; + if(!alreadyExisted) this.sortPluginAnnotationsByName(); + } + + sortPluginAnnotationsByName() { + // Create an array of pairs [pluginId, name] + const pluginArray = Object.entries(this.settings.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)); + + this.sortedPluginIds = pluginArray.map(item => item.pluginId); + } + + async observeTab(tab: SettingTab) { // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; @@ -547,7 +574,7 @@ export default class PluginsAnnotations extends Plugin { const installedPluginIds = new Set(Object.keys(this.app.plugins.manifests)); const uninstalledPlugins: PluginAnnotationDict = {}; - for (const pluginId of sortPluginAnnotationsByName(this.settings.annotations)) { + for (const pluginId of this.sortedPluginIds) { if (!installedPluginIds.has(pluginId)) { uninstalledPlugins[pluginId] = this.settings.annotations[pluginId]; } diff --git a/src/manageAnnotations.ts b/src/manageAnnotations.ts index a9d1f1b..b155e6b 100644 --- a/src/manageAnnotations.ts +++ b/src/manageAnnotations.ts @@ -2,7 +2,7 @@ import PluginsAnnotations from "main"; import { Platform, TFile } from "obsidian"; -import { createFolderIfNotExists, getFileCaseInsensitive, joinPaths, makePosixPathOScompatible, parseFilePath, showConfirmationDialog, sortPluginAnnotationsByName } from "utils"; +import { createFolderIfNotExists, getFileCaseInsensitive, joinPaths, makePosixPathOScompatible, parseFilePath, showConfirmationDialog } from "utils"; import { parse, SyntaxError } from "./peggy.mjs"; import { PluginAnnotationDict } from "types"; @@ -103,7 +103,7 @@ export async function writeAnnotationsToMdFile(plugin: PluginsAnnotations) { const header = 'Make changes only within the annotation blocks marked by `` and ``. Changes made anywhere else will be overwritten.\n' const content: string[] = [header]; - for (const pluginId of sortPluginAnnotationsByName(annotations)) { + for (const pluginId of plugin.sortedPluginIds) { content.push(`# ${annotations[pluginId].name}\n\n\n\n${annotations[pluginId].desc}\n\n`); } const content_concatenated = content.join('\n'); diff --git a/src/peggy.mjs b/src/peggy.mjs index 6e94e95..c17bd09 100644 --- a/src/peggy.mjs +++ b/src/peggy.mjs @@ -179,9 +179,10 @@ function peg$parse(input, options) { var peg$c1 = ""; - var peg$c4 = "BEGIN"; - var peg$c5 = "ANNOTATION"; - var peg$c6 = "END"; + var peg$c4 = ":"; + var peg$c5 = "BEGIN"; + var peg$c6 = "ANNOTATION"; + var peg$c7 = "END"; var peg$r0 = /^[^\n\r]/; var peg$r1 = /^[\n\r]/; @@ -192,12 +193,13 @@ function peg$parse(input, options) { var peg$e2 = peg$literalExpectation("id:", false); var peg$e3 = peg$literalExpectation("-->", false); var peg$e4 = peg$anyExpectation(); - var peg$e5 = peg$literalExpectation("BEGIN", false); - var peg$e6 = peg$literalExpectation("ANNOTATION", false); - var peg$e7 = peg$literalExpectation("END", false); - var peg$e8 = peg$classExpectation(["\n", "\r"], true, false); - var peg$e9 = peg$classExpectation(["\n", "\r"], false, false); - var peg$e10 = peg$classExpectation([" ", "\f", "\t", "\v", " ", "\xA0", "\u1680", ["\u2000", "\u200A"], "\u2028", "\u2029", "\u202F", "\u205F", "\u3000", "\uFEFF"], false, false); + var peg$e5 = peg$literalExpectation(":", false); + var peg$e6 = peg$literalExpectation("BEGIN", false); + var peg$e7 = peg$literalExpectation("ANNOTATION", false); + var peg$e8 = peg$literalExpectation("END", false); + var peg$e9 = peg$classExpectation(["\n", "\r"], true, false); + var peg$e10 = peg$classExpectation(["\n", "\r"], false, false); + var peg$e11 = peg$classExpectation([" ", "\f", "\t", "\v", " ", "\xA0", "\u1680", ["\u2000", "\u200A"], "\u2028", "\u2029", "\u202F", "\u205F", "\u3000", "\uFEFF"], false, false); var peg$f0 = function(blocks) { const dictionary = blocks.reduce((acc, block) => { @@ -207,7 +209,6 @@ function peg$parse(input, options) { return dictionary; }; var peg$f1 = function(name, tags, desc) { - const tags_dict = tags.reduce((acc, block) => { acc[block.tag] = block.arg; return acc; @@ -233,6 +234,7 @@ function peg$parse(input, options) { } }; var peg$f2 = function(id) { return { 'tag': 'id', 'arg': id }; }; + var peg$f3 = function(cmd, arg) { return { 'tag': cmd, 'arg': arg }; }; var peg$currPos = options.peg$currPos | 0; var peg$savedPos = peg$currPos; var peg$posDetailsCache = [{ line: 1, column: 1 }]; @@ -430,11 +432,11 @@ function peg$parse(input, options) { s1 = peg$parseplugin_name(); if (s1 !== peg$FAILED) { s2 = []; - s3 = peg$parseid_field(); + s3 = peg$parsetag(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); - s3 = peg$parseid_field(); + s3 = peg$parsetag(); } } else { s2 = peg$FAILED; @@ -721,6 +723,322 @@ function peg$parse(input, options) { return s0; } + function peg$parsecmd_field() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c1) { + s1 = peg$c1; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parse_(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parse_(); + } + s3 = peg$currPos; + s4 = []; + s5 = peg$currPos; + s6 = peg$currPos; + peg$silentFails++; + if (input.charCodeAt(peg$currPos) === 58) { + s7 = peg$c4; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + peg$silentFails--; + if (s7 === peg$FAILED) { + s6 = undefined; + } else { + peg$currPos = s6; + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s7 = peg$currPos; + peg$silentFails++; + if (input.substr(peg$currPos, 3) === peg$c3) { + s8 = peg$c3; + peg$currPos += 3; + } else { + s8 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + peg$silentFails--; + if (s8 === peg$FAILED) { + s7 = undefined; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + if (s7 !== peg$FAILED) { + if (input.length > peg$currPos) { + s8 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s8 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s8 !== peg$FAILED) { + s6 = [s6, s7, s8]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$currPos; + s6 = peg$currPos; + peg$silentFails++; + if (input.charCodeAt(peg$currPos) === 58) { + s7 = peg$c4; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + peg$silentFails--; + if (s7 === peg$FAILED) { + s6 = undefined; + } else { + peg$currPos = s6; + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s7 = peg$currPos; + peg$silentFails++; + if (input.substr(peg$currPos, 3) === peg$c3) { + s8 = peg$c3; + peg$currPos += 3; + } else { + s8 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + peg$silentFails--; + if (s8 === peg$FAILED) { + s7 = undefined; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + if (s7 !== peg$FAILED) { + if (input.length > peg$currPos) { + s8 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s8 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s8 !== peg$FAILED) { + s6 = [s6, s7, s8]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } + s3 = input.substring(s3, peg$currPos); + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c4; + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + if (s4 !== peg$FAILED) { + s5 = []; + s6 = peg$parse_(); + while (s6 !== peg$FAILED) { + s5.push(s6); + s6 = peg$parse_(); + } + s6 = peg$currPos; + s7 = []; + s8 = peg$currPos; + s9 = peg$currPos; + peg$silentFails++; + s10 = peg$currPos; + s11 = []; + s12 = peg$parse_(); + while (s12 !== peg$FAILED) { + s11.push(s12); + s12 = peg$parse_(); + } + if (input.substr(peg$currPos, 3) === peg$c3) { + s12 = peg$c3; + peg$currPos += 3; + } else { + s12 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + if (s12 !== peg$FAILED) { + s11 = [s11, s12]; + s10 = s11; + } else { + peg$currPos = s10; + s10 = peg$FAILED; + } + peg$silentFails--; + if (s10 === peg$FAILED) { + s9 = undefined; + } else { + peg$currPos = s9; + s9 = peg$FAILED; + } + if (s9 !== peg$FAILED) { + if (input.length > peg$currPos) { + s10 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s10 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s10 !== peg$FAILED) { + s9 = [s9, s10]; + s8 = s9; + } else { + peg$currPos = s8; + s8 = peg$FAILED; + } + } else { + peg$currPos = s8; + s8 = peg$FAILED; + } + while (s8 !== peg$FAILED) { + s7.push(s8); + s8 = peg$currPos; + s9 = peg$currPos; + peg$silentFails++; + s10 = peg$currPos; + s11 = []; + s12 = peg$parse_(); + while (s12 !== peg$FAILED) { + s11.push(s12); + s12 = peg$parse_(); + } + if (input.substr(peg$currPos, 3) === peg$c3) { + s12 = peg$c3; + peg$currPos += 3; + } else { + s12 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + if (s12 !== peg$FAILED) { + s11 = [s11, s12]; + s10 = s11; + } else { + peg$currPos = s10; + s10 = peg$FAILED; + } + peg$silentFails--; + if (s10 === peg$FAILED) { + s9 = undefined; + } else { + peg$currPos = s9; + s9 = peg$FAILED; + } + if (s9 !== peg$FAILED) { + if (input.length > peg$currPos) { + s10 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s10 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s10 !== peg$FAILED) { + s9 = [s9, s10]; + s8 = s9; + } else { + peg$currPos = s8; + s8 = peg$FAILED; + } + } else { + peg$currPos = s8; + s8 = peg$FAILED; + } + } + s6 = input.substring(s6, peg$currPos); + s7 = []; + s8 = peg$parse_(); + while (s8 !== peg$FAILED) { + s7.push(s8); + s8 = peg$parse_(); + } + if (input.substr(peg$currPos, 3) === peg$c3) { + s8 = peg$c3; + peg$currPos += 3; + } else { + s8 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + 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) { + peg$savedPos = s0; + s0 = peg$f3(s3, s6); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsetag() { + var s0; + + s0 = peg$parseid_field(); + if (s0 === peg$FAILED) { + s0 = peg$parsecmd_field(); + } + + return s0; + } + function peg$parsebegin_cmd() { var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; @@ -740,12 +1058,12 @@ function peg$parse(input, options) { s3.push(s4); s4 = peg$parse_(); } - if (input.substr(peg$currPos, 5) === peg$c4) { - s4 = peg$c4; + if (input.substr(peg$currPos, 5) === peg$c5) { + s4 = peg$c5; peg$currPos += 5; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } + if (peg$silentFails === 0) { peg$fail(peg$e6); } } if (s4 !== peg$FAILED) { s5 = []; @@ -754,12 +1072,12 @@ function peg$parse(input, options) { s5.push(s6); s6 = peg$parse_(); } - if (input.substr(peg$currPos, 10) === peg$c5) { - s6 = peg$c5; + if (input.substr(peg$currPos, 10) === peg$c6) { + s6 = peg$c6; peg$currPos += 10; } else { s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } + if (peg$silentFails === 0) { peg$fail(peg$e7); } } if (s6 !== peg$FAILED) { s7 = []; @@ -834,12 +1152,12 @@ function peg$parse(input, options) { s4.push(s5); s5 = peg$parse_(); } - if (input.substr(peg$currPos, 3) === peg$c6) { - s5 = peg$c6; + if (input.substr(peg$currPos, 3) === peg$c7) { + s5 = peg$c7; peg$currPos += 3; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } + if (peg$silentFails === 0) { peg$fail(peg$e8); } } if (s5 !== peg$FAILED) { s6 = []; @@ -848,12 +1166,12 @@ function peg$parse(input, options) { s6.push(s7); s7 = peg$parse_(); } - if (input.substr(peg$currPos, 10) === peg$c5) { - s7 = peg$c5; + if (input.substr(peg$currPos, 10) === peg$c6) { + s7 = peg$c6; peg$currPos += 10; } else { s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } + if (peg$silentFails === 0) { peg$fail(peg$e7); } } if (s7 !== peg$FAILED) { s8 = []; @@ -996,7 +1314,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -1005,7 +1323,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } } s3 = peg$parsenewline(); @@ -1023,7 +1341,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } if (s2 !== peg$FAILED) { while (s2 !== peg$FAILED) { @@ -1033,7 +1351,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } } } else { @@ -1058,7 +1376,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } if (s1 !== peg$FAILED) { while (s1 !== peg$FAILED) { @@ -1068,7 +1386,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } } } else { @@ -1086,7 +1404,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } + if (peg$silentFails === 0) { peg$fail(peg$e10); } } return s0; @@ -1104,7 +1422,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } + if (peg$silentFails === 0) { peg$fail(peg$e10); } } if (s3 !== peg$FAILED) { s2 = [s2, s3]; @@ -1134,7 +1452,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } + if (peg$silentFails === 0) { peg$fail(peg$e11); } } return s0; diff --git a/src/utils.ts b/src/utils.ts index 21539c3..1be5cc0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -146,23 +146,6 @@ export class FileSuggestion extends AbstractInputSuggest { } } - -/* 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); -} - - /* Download json settings */ export function downloadJson(data: unknown, filename = 'data.json') { diff --git a/styles/styles.css b/styles/styles.css index 93f6903..5a9e83f 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -7,13 +7,17 @@ box-sizing: border-box; /* Ensure padding is included in the element's total width and height */ } -.plugin-comment-annotation.plugin-comment-placeholder { - color: #CCCCCC; /* Standard placeholder color */ -} - .plugin-comment.plugin-comment-hidden, .plugin-comment.plugin-comment-placeholder { - display: none; + display: none; +} + +.plugin-comment-annotation:focus:empty:before { + content: "\00a0"; /* Non-breaking space to maintain height when focused */ +} + +.plugin-comment-annotation.plugin-comment-placeholder { + color: #CCCCCC; /* Standard placeholder color */ } .plugin-comment-annotation > p:first-child {