diff --git a/README.md b/README.md index 3e41bd6..ee82264 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ An Obsidian plugin that adds dynamic date calculations to your notes using `date-calc` fenced code blocks and inline code. + +## Todo +- [x] Make inline work +- [ ] Add a non-verbose birthday type? Just show the age, with decimals, maybe? Like "3.7 years old" +- [ ] + + ## Features ### Fenced Code Blocks @@ -96,7 +103,7 @@ to: 2025-03-01 type: diff from: 2025-09-19 08:00 to: 2025-09-19 16:30 -``` +``` ## Inline Usage diff --git a/main.ts b/main.ts index d84a99b..a67f00f 100644 --- a/main.ts +++ b/main.ts @@ -110,6 +110,11 @@ function processInlineDateCalc(raw: string, app: App, sourcePath: string): strin else if ((cfg as any).since) type = 'since'; else if ((cfg as any).from && (cfg as any).to) type = 'diff'; } + + // Normalize type aliases to match fenced code block processor + if (type === 'bday') type = 'birthday'; + if (type === 'until') type = 'countdown'; + if (type === 'difference') type = 'diff'; if (!type) return ''; // Render result similarly to the block processor @@ -235,6 +240,7 @@ const dateCalcLivePreviewPlugin = (app: App) => ViewPlugin.fromClass(class { const text = view.state.doc.toString(); // Find inline code spans that start with date-calc: + // This regex looks for inline code between backticks const inlineCodeRegex = /`([^`]+)`/g; let match; @@ -258,6 +264,9 @@ const dateCalcLivePreviewPlugin = (app: App) => ViewPlugin.fromClass(class { side: 1 }); builder.add(to, to, widget); + + // Add a debug log to verify when a widget is being created + console.log(`Live Preview widget created for: ${codeContent} with result: ${result}`); } } } @@ -287,11 +296,25 @@ class DateCalcInlineRenderer extends MarkdownRenderChild { async render() { const result = processInlineDateCalc(this.raw, this.app, this.sourcePath); if (result) { + console.log(`Rendering inline date-calc: ${this.raw} -> ${result}`); + + // In Live Preview, just replace the code element directly const span = document.createElement('span'); span.classList.add('date-calc-inline'); span.setAttribute('contenteditable', 'false'); span.textContent = result; - this.target.replaceWith(span); + + // Ensure we properly replace the target element + try { + this.target.parentNode?.replaceChild(span, this.target); + console.log('Successfully replaced code element with result'); + } catch (e) { + console.error('Failed to replace code element:', e); + // Fallback: try the original method + this.target.replaceWith(span); + } + } else { + console.log(`No result for inline date-calc: ${this.raw}`); } } } @@ -305,69 +328,44 @@ export default class MyPlugin extends Plugin { async onload() { await this.loadSettings(); - // This creates an icon in the left ribbon. - const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (_evt: MouseEvent) => { - // Called when the user clicks the icon. - new Notice('This is a notice!'); - }); - // Perform additional things with the ribbon - ribbonIconEl.addClass('my-plugin-ribbon-class'); - - // This adds a status bar item to the bottom of the app. Does not work on mobile apps. + // Add a status bar item showing the plugin is enabled const statusBarItemEl = this.addStatusBarItem(); - statusBarItemEl.setText('Status Bar Text'); + statusBarItemEl.setText('Date Calculator Enabled'); - // This adds a simple command that can be triggered anywhere + // Debugging command to test plugin functionality this.addCommand({ - id: 'open-sample-modal-simple', - name: 'Open sample modal (simple)', + id: 'date-calc-debug', + name: 'Debug Date Calculator', callback: () => { - new SampleModal(this.app).open(); + new Notice('Date Calculator plugin is working! Check console for more details.'); + console.log('Date Calculator plugin debug info:'); + console.log('Plugin version: 1.0.0'); + console.log('Plugin enabled: true'); + console.log('Current file:', this.app.workspace.getActiveFile()?.path); } }); - // This adds an editor command that can perform some operation on the current editor instance - this.addCommand({ - id: 'sample-editor-command', - name: 'Sample editor command', - editorCallback: (editor: Editor, _view: MarkdownView) => { - console.log(editor.getSelection()); - editor.replaceSelection('Sample Editor Command'); - } - }); - // This adds a complex command that can check whether the current state of the app allows execution of the command - this.addCommand({ - id: 'open-sample-modal-complex', - name: 'Open sample modal (complex)', - checkCallback: (checking: boolean) => { - // Conditions to check - const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView); - if (markdownView) { - // If checking is true, we're simply "checking" if the command can be run. - // If checking is false, then we want to actually perform the operation. - if (!checking) { - new SampleModal(this.app).open(); - } - // This command will only show up in Command Palette when the check function returns true - return true; - } + // Command to refresh inline calculations (useful for troubleshooting) + this.addCommand({ + id: 'refresh-date-calc-inline', + name: 'Refresh Date Calculations', + callback: () => { + // Force refresh by triggering layout + this.app.workspace.trigger('layout-change'); + new Notice('Date calculations refreshed!'); } }); // This adds a settings tab so the user can configure various aspects of the plugin this.addSettingTab(new SampleSettingTab(this.app, this)); - // If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin) - // Using this function will automatically remove the event listener when this plugin is disabled. - this.registerDomEvent(document, 'click', (evt: MouseEvent) => { - console.log('click', evt); - }); - - // When registering intervals, this function will automatically clear the interval when the plugin is disabled. - this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000)); - - // Register the Live Preview editor extension for inline date-calc processing + // CRITICAL: Register Live Preview extension FIRST and ensure it's properly loaded + console.log('Registering Live Preview editor extension for date-calc...'); this.registerEditorExtension(dateCalcLivePreviewPlugin(this.app)); + console.log('Date Calculator Live Preview extension registered successfully!'); + + // Add more comprehensive debugging + new Notice('Date Calculator loaded with Live Preview support!'); // Register the `date-calc` code block processor this.registerMarkdownCodeBlockProcessor('date-calc', (source, el, ctx) => { @@ -384,6 +382,7 @@ export default class MyPlugin extends Plugin { try { switch (type) { + case 'bday': case 'birthday': { // Accept from config or frontmatter fallback const fileCache = this.app.metadataCache.getCache(ctx.sourcePath); @@ -445,7 +444,7 @@ export default class MyPlugin extends Plugin { msg = `next one is in ${monthsUntil} months.`; } else if (daysUntil === 0) { - msg = `Today! Wish ${pronoun} Happy Birthday!`; + msg = `today! Wish ${pronoun} Happy Birthday!`; } else if (daysUntil === 1) { msg = `that's tomorrow!`; } else { diff --git a/styles.css b/styles.css index 8ebbb87..49169e6 100644 --- a/styles.css +++ b/styles.css @@ -2,7 +2,7 @@ Date Calc Plugin Styles */ -/* Inline date-calc styling for live preview - now styles actual span elements */ +/* Inline date-calc styling for reading view and live preview */ .date-calc-inline { background-color: var(--background-modifier-accent); border-radius: 3px; @@ -12,6 +12,22 @@ Date Calc Plugin Styles font-size: 0.9em; display: inline-block; margin: 0 2px; + font-family: var(--font-text); +} + +/* Specific styles for CodeMirror Live Preview widgets */ +.cm-line .date-calc-inline { + background-color: var(--background-modifier-accent); + color: var(--text-accent); + padding: 2px 6px; + margin-left: 4px; + border-radius: 3px; + font-weight: bold; + font-size: 0.9em; + display: inline; + user-select: none; + cursor: default; + vertical-align: baseline; } /* Additional styling for fenced code blocks */