526f54a640
- Fix RangeSetBuilder ordering crash: inline and fenced-block decorations
are now merged and sorted before being added, instead of two unsorted
passes (crashed whenever a fenced block preceded inline code in a note).
- Add explicit @codemirror/state and @codemirror/view devDependencies
(previously only transitive via @codemirror/language).
- Add Reading View support for inline `date-calc:` spans via
registerMarkdownPostProcessor (previously Live Preview only), mirroring
the approach used by Dataview's inline queries.
- Fix verbose=false being silently truthy (non-empty string) in inline
key=value config, which meant it never actually disabled verbose output.
- Fix diff type auto-inference: from/to was dead code (countdown's check
always matched first); reordered so from+to or start+end infer diff.
- Implement documented but missing birthday label support: cfg.label,
falling back to frontmatter name ("Jane's age:"), then "Age:".
- Split main.ts (777 lines) into src/ modules per AGENTS.md conventions.
- Fix duplicated command-palette prefixes, move inline JS styles to
styles.css, fix package.json author, drop orphaned showArrow setting.
Verified: unit tests against the real bundled logic (mocked obsidian
module), a reproduction of the RangeSetBuilder crash against the real
@codemirror/state package, and live end-to-end testing in Obsidian via
CDP/Playwright (Tchernobyl vault).
71 lines
2.7 KiB
TypeScript
71 lines
2.7 KiB
TypeScript
import { Notice, Plugin } from "obsidian";
|
|
import { DEFAULT_SETTINGS, DateCalcSettings } from "./src/types";
|
|
import { processFencedBlock, processInlineCode } from "./src/calculate";
|
|
import { dateCalcLivePreview } from "./src/live-preview";
|
|
import { renderInlineResult } from "./src/widgets";
|
|
import { DateCalcSettingTab } from "./src/settings-tab";
|
|
|
|
export default class DateCalcPlugin extends Plugin {
|
|
settings: DateCalcSettings;
|
|
|
|
async onload() {
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
|
|
|
if (this.settings.debug) console.log("[date-calc] loaded");
|
|
|
|
// Live Preview: render inline code and fenced blocks via a CM6 decoration extension.
|
|
this.registerEditorExtension(dateCalcLivePreview(this.app, () => this.settings));
|
|
|
|
// Reading View: fenced ```date-calc``` blocks via Obsidian's codeblock processor.
|
|
this.registerMarkdownCodeBlockProcessor("date-calc", (source, el, ctx) => {
|
|
const result = processFencedBlock(source, this.app, ctx.sourcePath, this.settings);
|
|
el.empty();
|
|
el.createDiv({ cls: "date-calc-block", text: result.text });
|
|
if (result.tooltip) {
|
|
el.setAttribute("aria-label", result.tooltip);
|
|
}
|
|
});
|
|
|
|
// Reading View: inline `date-calc:` spans. Obsidian has no dedicated hook for
|
|
// these (unlike fenced blocks), so scan rendered <code> elements ourselves —
|
|
// same approach Dataview uses for its inline queries.
|
|
this.registerMarkdownPostProcessor((el, ctx) => {
|
|
const codeblocks = el.querySelectorAll("code");
|
|
for (let i = 0; i < codeblocks.length; i++) {
|
|
const codeblock = codeblocks.item(i);
|
|
// Skip <pre><code> (fenced blocks); those are handled above.
|
|
if (codeblock.parentElement?.nodeName.toLowerCase() === "pre") continue;
|
|
|
|
const raw = codeblock.innerText.trim();
|
|
const result = processInlineCode(raw, this.app, ctx.sourcePath, this.settings);
|
|
if (!result.text) continue;
|
|
|
|
codeblock.replaceWith(renderInlineResult(result.text, result.tooltip));
|
|
}
|
|
});
|
|
|
|
// Commands
|
|
this.addCommand({
|
|
id: "date-calc-toggle-debug",
|
|
name: "Toggle debug logging",
|
|
callback: async () => {
|
|
this.settings.debug = !this.settings.debug;
|
|
await this.saveData(this.settings);
|
|
new Notice(`Date Calc debug: ${this.settings.debug ? "ON" : "OFF"}`);
|
|
},
|
|
});
|
|
|
|
this.addCommand({
|
|
id: "date-calc-toggle-verbose",
|
|
name: "Toggle verbose output",
|
|
callback: async () => {
|
|
this.settings.verbose = !this.settings.verbose;
|
|
await this.saveData(this.settings);
|
|
new Notice(`Date Calc verbose: ${this.settings.verbose ? "ON" : "OFF"}`);
|
|
},
|
|
});
|
|
|
|
this.addSettingTab(new DateCalcSettingTab(this.app, this));
|
|
}
|
|
}
|