Skip to content

Commit

Permalink
Suppress re-rendering of callout widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
shunby committed Sep 24, 2024
1 parent fcb8c1b commit fbb0645
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@ import { Plugin } from "obsidian";
import { around } from "monkey-around";

type CalloutWidgetType = WidgetType & {
clazz?: string;
text?: string;
clazz: string;
text: string;
};

function isCallout(
widget: (WidgetType & { clazz?: unknown; text?: unknown }) | undefined
): widget is CalloutWidgetType {
return (
widget !== undefined &&
widget.clazz === "cm-callout" &&
typeof widget.text === "string"
);
}

function makeFootrefHTML(tag: string) {
const span1 = document.createElement("span");
span1.className =
Expand All @@ -27,17 +37,19 @@ function makeFootrefHTML(tag: string) {

// If `spec.widget` is a callout widget, replace its inner "[^tag]"s with HTML generated by `makeFootrefHTML`.
function modifyCallout(spec: Parameters<typeof Decoration.replace>[0]) {
const widget: CalloutWidgetType | undefined = spec.widget;
if (
widget &&
widget.clazz === "cm-callout" &&
widget.text &&
typeof widget.text === "string"
) {
const widget = spec.widget;
if (isCallout(widget)) {
const footrefRegex = /\[\^([^\]]+)\]/g;
widget.text = widget.text.replace(footrefRegex, (_, tag) =>
makeFootrefHTML(tag)
);

// Modifying `widget.text` causes an inconsistency between `widget.text` and the document,
// leading Obsidian to recreate the widget. The eq method tells that the recreated widget
// is equivallent to the original one, preventeing unnecessary re-rendering.
widget.eq = function (other) {
return isCallout(other) && this.text === other.text;
};
}
}

Expand Down

0 comments on commit fbb0645

Please sign in to comment.