/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/main.ts var main_exports = {}; __export(main_exports, { VAULT_ROOT: () => VAULT_ROOT, default: () => LatexReferencer3 }); module.exports = __toCommonJS(main_exports); var import_obsidian36 = require("obsidian"); // node_modules/obsidian-mathlinks/lib/api/provider.js var import_obsidian2 = require("obsidian"); // node_modules/obsidian-mathlinks/lib/links/helper.js var import_obsidian = require("obsidian"); // node_modules/obsidian-mathlinks/lib/api/provider.js var Provider = class extends import_obsidian2.Component { constructor(mathLinks) { super(); this.mathLinks = mathLinks; this._enableInSourceMode = false; } get enableInSourceMode() { return this._enableInSourceMode; } set enableInSourceMode(enable) { this._enableInSourceMode = enable; this.mathLinks.update(); } onunload() { const providers = this.mathLinks.providers; let index = providers.findIndex(({ provider }) => provider === this); providers.splice(index, 1); this.mathLinks.update(); } }; // node_modules/obsidian-mathlinks/lib/api/index.js function addProvider(app, providerFactory) { if (!isPluginEnabled(app)) throw Error("MathLinks API: MathLinks is not enabled."); const mathLinks = app.plugins.plugins.mathlinks; const provider = providerFactory(mathLinks); mathLinks.registerProvider(provider); return provider; } function isPluginEnabled(app) { return app.plugins.enabledPlugins.has("mathlinks"); } function update(app, file) { if (!isPluginEnabled(app)) throw Error("MathLinks API: MathLinks is not enabled."); const mathlinks = app.plugins.plugins.mathlinks; mathlinks.update(file); } // node_modules/obsidian-quick-preview/lib/index.js function registerQuickPreview(app, component, suggestClass, itemNormalizer) { app.workspace.onLayoutReady(() => { const plugin = app.plugins.getPlugin("quick-preview"); if (!plugin) throw Error("Quick Preview API: Quick Preview is not enabled."); const uninstaller = plugin.patchSuggester(suggestClass, itemNormalizer); component.register(uninstaller); }); } // src/settings/profile.ts var import_obsidian3 = require("obsidian"); // src/env.ts var THEOREM_LIKE_ENV_IDs = [ "axiom", "definition", "lemma", "proposition", "theorem", "corollary", "claim", "assumption", "example", "exercise", "conjecture", "hypothesis", "remark" ]; var PROOF_LIKE_ENV_IDs = [ "proof", "solution" ]; var ENV_IDs = [...THEOREM_LIKE_ENV_IDs, ...PROOF_LIKE_ENV_IDs]; var THEOREM_LIKE_ENV_PREFIXES = [ "axm", "def", "lem", "prp", "thm", "cor", "clm", "asm", "exm", "exr", "cnj", "hyp", "rmk" ]; var THEOREM_LIKE_ENVs = {}; THEOREM_LIKE_ENV_IDs.forEach((id, index) => { THEOREM_LIKE_ENVs[id] = { id, prefix: THEOREM_LIKE_ENV_PREFIXES[index] }; }); var THEOREM_LIKE_ENV_PREFIX_ID_MAP = {}; THEOREM_LIKE_ENV_PREFIXES.forEach((prefix, index) => { THEOREM_LIKE_ENV_PREFIX_ID_MAP[prefix] = THEOREM_LIKE_ENV_IDs[index]; }); var THEOREM_LIKE_ENV_ID_PREFIX_MAP = {}; THEOREM_LIKE_ENV_IDs.forEach((id, index) => { THEOREM_LIKE_ENV_ID_PREFIX_MAP[id] = THEOREM_LIKE_ENV_PREFIXES[index]; }); // src/settings/profile.ts var PROOF_SETTING_KEYS = [ "begin", "end", "linkedBeginPrefix", "linkedBeginSuffix" ]; var DEFAULT_PROFILES = { "English": { id: "English", meta: { tags: ["en"] }, body: { theorem: { "axiom": "Axiom", "definition": "Definition", "lemma": "Lemma", "proposition": "Proposition", "theorem": "Theorem", "corollary": "Corollary", "claim": "Claim", "assumption": "Assumption", "example": "Example", "exercise": "Exercise", "conjecture": "Conjecture", "hypothesis": "Hypothesis", "remark": "Remark" }, proof: { begin: "Proof.", end: "\u25A1", linkedBeginPrefix: "Proof of ", linkedBeginSuffix: "." } } }, "\u65E5\u672C\u8A9E": { id: "\u65E5\u672C\u8A9E", meta: { tags: ["ja"] }, body: { theorem: { "axiom": "\u516C\u7406", "definition": "\u5B9A\u7FA9", "lemma": "\u88DC\u984C", "proposition": "\u547D\u984C", "theorem": "\u5B9A\u7406", "corollary": "\u7CFB", "claim": "\u4E3B\u5F35", "assumption": "\u4EEE\u5B9A", "example": "\u4F8B", "exercise": "\u6F14\u7FD2\u554F\u984C", "conjecture": "\u4E88\u60F3", "hypothesis": "\u4EEE\u8AAC", "remark": "\u6CE8" }, proof: { begin: "\u8A3C\u660E.", end: "\u25A1", linkedBeginPrefix: "", linkedBeginSuffix: "\u306E\u8A3C\u660E." } } } }; var ManageProfileModal = class extends import_obsidian3.Modal { constructor(plugin, helper, profileSetting) { super(plugin.app); this.plugin = plugin; this.helper = helper; this.profileSetting = profileSetting; } onOpen() { let { contentEl } = this; contentEl.empty(); this.titleEl.setText("Manage profiles"); new import_obsidian3.Setting(contentEl).setName("Add profile").addButton((button) => { button.setIcon("plus").onClick(() => { new AddProfileModal(this).open(); }); }); for (const id in this.plugin.extraSettings.profiles) { new import_obsidian3.Setting(contentEl).setName(id).addButton((editButton) => { editButton.setIcon("pencil").setTooltip("Edit").setCta().onClick(() => { new EditProfileModal( this.plugin.extraSettings.profiles[id], this ).open(); }); }).addButton((editButton) => { editButton.setIcon("copy").setTooltip("Copy").onClick(() => { const copied = JSON.parse(JSON.stringify(this.plugin.extraSettings.profiles[id])); copied.id = makeIdOfCopy(id, this.plugin.extraSettings.profiles); this.plugin.extraSettings.profiles[copied.id] = copied; this.open(); }); }).addButton((deleteButton) => { deleteButton.setIcon("trash-2").setTooltip("Delete").onClick(() => { new ConfirmProfileDeletionModal(id, this).open(); }); }); } } async onClose() { let { contentEl } = this; contentEl.empty(); await this.plugin.saveSettings(); this.plugin.indexManager.trigger("global-settings-updated"); this.profileSetting.settingEl.replaceWith( this.helper.addProfileSetting( this.plugin.settings[this.helper.file.path].profile ).settingEl ); } }; var EditProfileModal = class extends import_obsidian3.Modal { constructor(profile, parent) { super(parent.app); this.profile = profile; this.parent = parent; this.settingRefs = {}; } onOpen() { const { contentEl } = this; contentEl.empty(); this.titleEl.setText(`Edit profile`); new import_obsidian3.Setting(contentEl).setName("Name").addText((text) => { text.setValue(this.profile.id).onChange((value) => { this.profile.id = value; }); }); new import_obsidian3.Setting(contentEl).setName("Tags").setDesc('Comma-separated list of tags. Only lower-case alphabets or hyphens are allowed. Each tag is converted into a CSS class ".theorem-callout-".').addText((text) => { text.setValue(this.profile.meta.tags.join(", ")).onChange((value) => { const tags = value.split(",").map((item) => item.trim()); if (tags.every((tag) => { var _a; return (_a = tag.match(/^[a-z\-]+$/)) != null ? _a : !tag; })) { this.profile.meta.tags = tags; } else { new import_obsidian3.Notice("A tag can only contain lower-case alphabets or hyphens.", 5e3); } }); }); new import_obsidian3.Setting(contentEl).setName("Theorem-like environments").setHeading(); for (const envID of THEOREM_LIKE_ENV_IDs) { this.settingRefs[envID] = new import_obsidian3.Setting(contentEl).setName(envID).addText((text) => { var _a; text.setValue((_a = this.profile.body.theorem[envID]) != null ? _a : "").onChange((value) => { this.profile.body.theorem[envID] = value; }); }); } new import_obsidian3.Setting(contentEl).setName("Proofs").setHeading(); const prettyNames = [ "Beginning of proof", "Ending of proof", "Prefix", "Suffix" ]; for (let i = 0; i < PROOF_SETTING_KEYS.length; i++) { const key = PROOF_SETTING_KEYS[i]; const name = prettyNames[i]; this.settingRefs[key] = new import_obsidian3.Setting(contentEl).setName(name).addText((text) => { var _a; text.setValue((_a = this.profile.body.proof[key]) != null ? _a : "").onChange((value) => { this.profile.body.proof[key] = value; }); }); } const linkedProofHeading = new import_obsidian3.Setting(contentEl).setName("Linked proofs").setDesc(`For example, you can render \`${DEFAULT_SETTINGS.beginProof}\`@[[link to Theorem 1]] as "${DEFAULT_PROFILES[DEFAULT_SETTINGS.profile].body.proof.linkedBeginPrefix}Theorem 1${DEFAULT_PROFILES[DEFAULT_SETTINGS.profile].body.proof.linkedBeginSuffix}".`).setHeading().settingEl; contentEl.insertBefore(linkedProofHeading, this.settingRefs.linkedBeginPrefix.settingEl); } onClose() { const profiles = this.parent.plugin.extraSettings.profiles; for (const oldID in profiles) { const newID = profiles[oldID].id; if (newID != oldID) { profiles[newID] = profiles[oldID]; delete profiles[oldID]; const affected = getAffectedFiles(this.parent.plugin, oldID); updateProfile(this.parent.plugin, affected, newID); } } let { contentEl } = this; contentEl.empty(); this.parent.open(); } }; var ConfirmProfileDeletionModal = class extends import_obsidian3.Modal { constructor(id, parent) { super(parent.app); this.id = id; this.parent = parent; } onOpen() { let { contentEl } = this; contentEl.empty(); this.titleEl.setText("Delete profile"); contentEl.createDiv({ text: `Are you sure you want to delete the profile "${this.id}"?` }); const buttonContainerEl = contentEl.createDiv({ cls: "math-booster-button-container" }); new import_obsidian3.ButtonComponent(buttonContainerEl).setButtonText("Delete").setCta().onClick(() => { const affected = getAffectedFiles(this.parent.plugin, this.id); if (affected.length) { new UpdateProfileModal(this, this.id, affected).open(); } else { delete this.parent.plugin.extraSettings.profiles[this.id]; this.close(); } }); new import_obsidian3.ButtonComponent(buttonContainerEl).setButtonText("Cancel").onClick(() => { this.close(); }); } onClose() { let { contentEl } = this; contentEl.empty(); this.parent.open(); } }; var AddProfileModal = class extends import_obsidian3.Modal { constructor(parent) { super(parent.app); this.parent = parent; } onOpen() { let { contentEl } = this; contentEl.empty(); let id; this.titleEl.setText("Add profile"); const addProfileEl = contentEl.createDiv({ cls: "math-booster-add-profile" }); new import_obsidian3.TextComponent(addProfileEl).setPlaceholder("Enter name...").onChange((value) => { id = value; }); const buttonContainerEl = addProfileEl.createDiv({ cls: "math-booster-button-container" }); new import_obsidian3.ButtonComponent(buttonContainerEl).setButtonText("Add").setCta().onClick(() => { const newBody = { theorem: {} }; for (const envID of THEOREM_LIKE_ENV_IDs) { newBody.theorem[envID] = ""; } this.parent.plugin.extraSettings.profiles[id] = { id, meta: { tags: [] }, body: newBody }; new EditProfileModal(this.parent.plugin.extraSettings.profiles[id], this.parent).open(); this.close(); }); new import_obsidian3.ButtonComponent(buttonContainerEl).setButtonText("Cancel").onClick(() => { this.close(); }); } onClose() { let { contentEl } = this; contentEl.empty(); this.parent.open(); } }; var UpdateProfileModal = class extends import_obsidian3.Modal { constructor(parent, deletedID, affected) { super(parent.app); this.parent = parent; this.deletedID = deletedID; this.affected = affected; } onOpen() { let { contentEl } = this; contentEl.empty(); this.titleEl.setText("Update profiles"); contentEl.createDiv({ text: `The following ${this.affected.length > 1 ? this.affected.length : ""} local setting${this.affected.length > 1 ? "s are" : " is"} affected by the deletion of profile "${this.deletedID}." Select a new profile to be applied for them.` }); const profiles = this.parent.parent.plugin.extraSettings.profiles; const ids = Object.keys(profiles); let newProfileID; const buttonContainerEl = contentEl.createDiv({ cls: "math-booster-button-container" }); const dropdown = new import_obsidian3.DropdownComponent(buttonContainerEl); dropdown.addOption("", ""); for (const id of ids) { if (id != this.deletedID) { dropdown.addOption(id, id); } } newProfileID = dropdown.getValue(); dropdown.onChange((value) => { newProfileID = value; }); new import_obsidian3.ButtonComponent(buttonContainerEl).setButtonText("Confirm").setCta().onClick(async () => { updateProfile(this.parent.parent.plugin, this.affected, newProfileID); this.close(); }); new import_obsidian3.ButtonComponent(buttonContainerEl).setButtonText("Cancel").onClick(() => { this.close(); }); const listEl = contentEl.createEl("ul"); for (const path of this.affected) { listEl.createEl("li", { text: path == VAULT_ROOT ? "(Vault root)" : path }); } } onClose() { let { contentEl } = this; contentEl.empty(); delete this.parent.parent.plugin.extraSettings.profiles[this.parent.id]; this.parent.close(); } }; function getAffectedFiles(plugin, oldProfileId) { const affected = []; for (const path in plugin.settings) { const localSettings = plugin.settings[path]; if (localSettings.profile == oldProfileId) { affected.push(path); } } return affected; } function makeIdOfCopy(oldID, profiles) { let newId = `Copy of ${oldID}`; if (!(newId in profiles)) { return newId; } const ids = Object.keys(profiles); const numbers = ids.map((id) => { var _a, _b; return (_b = (_a = id.slice(oldID.length + 1).match(/\(([1-9][0-9]*)\)/)) == null ? void 0 : _a[1]) != null ? _b : "0"; }).map((numStr) => +numStr); const max = Math.max(...numbers); return `${newId} (${max + 1})`; } function updateProfile(plugin, paths, newID) { for (const path of paths) { const localSettings = plugin.settings[path]; if (newID) { localSettings.profile = newID; } else { delete localSettings.profile; } } } // src/settings/settings.ts var NUMBER_STYLES = [ "arabic", "alph", "Alph", "roman", "Roman" ]; var THEOREM_CALLOUT_STYLES = [ "Custom", "Plain", "Framed", "MathWiki", "Vivid" ]; var THEOREM_REF_FORMATS = [ "[type] [number] ([title])", "[type] [number]", "[title] ([type] [number]) if title exists, [type] [number] otherwise", "[title] if title exists, [type] [number] otherwise" ]; var LEAF_OPTIONS = [ "Current tab", "Split right", "Split down", "New tab", "New window" ]; var LEAF_OPTION_TO_ARGS = { "Current tab": [false], "Split right": ["split", "vertical"], "Split down": ["split", "horizontal"], "New tab": ["tab"], "New window": ["window"] }; var SEARCH_METHODS = [ "Fuzzy", "Simple" ]; var UNION_TYPE_MATH_CONTEXT_SETTING_KEYS = { "numberStyle": NUMBER_STYLES, "refFormat": THEOREM_REF_FORMATS, "noteMathLinkFormat": THEOREM_REF_FORMATS, "eqNumberStyle": NUMBER_STYLES, "theoremCalloutStyle": THEOREM_CALLOUT_STYLES }; var UNION_TYPE_EXTRA_SETTING_KEYS = { "searchMethod": SEARCH_METHODS, "suggestLeafOption": LEAF_OPTIONS }; var DEFAULT_SETTINGS = { profile: Object.keys(DEFAULT_PROFILES)[0], titleSuffix: ".", inferNumberPrefix: true, inferNumberPrefixFromProperty: "", inferNumberPrefixRegExp: "^[0-9]+(\\.[0-9]+)*", numberPrefix: "", numberSuffix: "", numberInit: 1, numberStyle: "arabic", numberDefault: "auto", refFormat: "[type] [number] ([title])", noteMathLinkFormat: "[title] if title exists, [type] [number] otherwise", ignoreMainTheoremCalloutWithoutTitle: false, numberOnlyReferencedEquations: true, inferEqNumberPrefix: true, inferEqNumberPrefixFromProperty: "", inferEqNumberPrefixRegExp: "^[0-9]+(\\.[0-9]+)*", eqNumberPrefix: "", eqNumberSuffix: "", eqNumberInit: 1, eqNumberStyle: "arabic", eqRefPrefix: "", eqRefSuffix: "", labelPrefix: "", lineByLine: true, theoremCalloutStyle: "Framed", theoremCalloutFontInherit: false, beginProof: "\\begin{proof}", endProof: "\\end{proof}", insertSpace: true }; var DEFAULT_EXTRA_SETTINGS = { foldDefault: "", noteTitleInTheoremLink: true, noteTitleInEquationLink: true, profiles: DEFAULT_PROFILES, showTheoremTitleinBuiltin: true, showTheoremContentinBuiltin: false, renderEquationinBuiltin: true, triggerSuggest: "\\ref", triggerTheoremSuggest: "\\tref", triggerEquationSuggest: "\\eqref", triggerSuggestActiveNote: "\\ref:a", triggerTheoremSuggestActiveNote: "\\tref:a", triggerEquationSuggestActiveNote: "\\eqref:a", triggerSuggestRecentNotes: "\\ref:r", triggerTheoremSuggestRecentNotes: "\\tref:r", triggerEquationSuggestRecentNotes: "\\eqref:r", triggerSuggestDataview: "\\ref:d", triggerTheoremSuggestDataview: "\\tref:d", triggerEquationSuggestDataview: "\\eqref:d", enableSuggest: true, enableTheoremSuggest: true, enableEquationSuggest: true, enableSuggestActiveNote: true, enableTheoremSuggestActiveNote: true, enableEquationSuggestActiveNote: true, enableSuggestRecentNotes: true, enableTheoremSuggestRecentNotes: true, enableEquationSuggestRecentNotes: true, enableSuggestDataview: true, enableTheoremSuggestDataview: true, enableEquationSuggestDataview: true, renderMathInSuggestion: true, suggestNumber: 20, searchMethod: "Fuzzy", upWeightRecent: 0.1, searchLabel: false, modifierToJump: "Mod", modifierToNoteLink: "Shift", showModifierInstruction: true, suggestLeafOption: "Current tab", // projectInfix: " > ", // projectSep: "/", importerNumThreads: 2, importerUtilization: 0.75, showTheoremCalloutEditButton: false, setOnlyTheoremAsMain: false, setLabelInModal: false, excludeExampleCallout: false, enableProof: true, enableMathPreviewInCalloutAndQuote: true, autocompleteDvQuery: "", searchModalQueryType: "both", searchModalRange: "recent", searchModalDvQuery: "" }; // src/settings/tab.ts var import_obsidian14 = require("obsidian"); // src/settings/helper.ts var import_obsidian8 = require("obsidian"); // src/utils/obsidian.ts var import_obsidian5 = require("obsidian"); var import_obsidian6 = require("obsidian"); // src/utils/editor.ts var import_obsidian4 = require("obsidian"); function locToEditorPosition(loc) { return { ch: loc.col, line: loc.line }; } function isLivePreview(state) { return state.field(import_obsidian4.editorLivePreviewField); } function isSourceMode(state) { return !isLivePreview(state); } function isEditingView(markdownView) { return markdownView.getMode() === "source"; } function nodeText(node, state) { return state.sliceDoc(node.from, node.to); } function nodeTextQuoteSymbolTrimmed(node, state, quoteLevel) { const quoteSymbolPattern = new RegExp(`((>\\s*){${quoteLevel}})(.*)`); const quoteSymbolMatch = nodeText(node, state).match(quoteSymbolPattern); if (quoteSymbolMatch) { return quoteSymbolMatch.slice(-1)[0]; } } function rangeSetSome(set, predicate) { const cursor = set.iter(); let index = 0; while (cursor.value) { if (predicate(cursor.value, index, set)) { return true; } cursor.next(); index++; } return false; } function hasOverlap(range1, range2) { return range1.from <= range2.to && range2.from <= range1.to; } function rangesHaveOverlap(ranges, from, to) { for (const range of ranges) { if (range.from <= to && range.to >= from) return true; } return false; } // src/utils/obsidian.ts function iterDescendantFiles(file, callback) { if (file instanceof import_obsidian6.TFile) { callback(file); } else if (file instanceof import_obsidian6.TFolder) { for (const child of file.children) { iterDescendantFiles(child, callback); } } } function getAncestors(file) { const ancestors = []; let ancestor = file; while (ancestor) { ancestors.push(ancestor); if (file instanceof import_obsidian6.TFolder && file.isRoot()) { break; } ancestor = ancestor.parent; } ancestors.reverse(); return ancestors; } function isEqualToOrChildOf(file1, file2) { if (file1 == file2) { return true; } if (file2 instanceof import_obsidian6.TFolder && file2.isRoot()) { return true; } let ancestor = file1.parent; while (true) { if (ancestor == file2) { return true; } if (ancestor) { if (ancestor.isRoot()) { return false; } ancestor = ancestor.parent; } } } function getFile(app) { var _a; return (_a = app.workspace.getActiveFile()) != null ? _a : app.vault.getRoot(); } function getSectionCacheFromPos(cache, pos, type) { if (cache.sections) { const sectionCache = Object.values(cache.sections).find( (sectionCache2) => sectionCache2.type == type && (sectionCache2.position.start.offset == pos || sectionCache2.position.end.offset == pos) ); return sectionCache; } } function getSectionCacheOfDOM(el, type, view, cache) { const pos = view.posAtDOM(el); return getSectionCacheFromPos(cache, pos, type); } function getSectionCacheFromMouseEvent(event, type, view, cache) { var _a; const pos = (_a = view.posAtCoords(event)) != null ? _a : view.posAtCoords(event, false); return getSectionCacheFromPos(cache, pos, type); } function getProperty(app, file, name) { var _a, _b; return (_b = (_a = app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b[name]; } function getPropertyLink(app, file, name) { const cache = app.metadataCache.getFileCache(file); if (cache == null ? void 0 : cache.frontmatterLinks) { for (const link of cache.frontmatterLinks) { if (link.key == name) { return link; } } } } function getPropertyOrLinkTextInProperty(app, file, name) { var _a, _b; return (_b = (_a = getPropertyLink(app, file, name)) == null ? void 0 : _a.link) != null ? _b : getProperty(app, file, name); } function generateBlockID(cache, length = 6) { let id = ""; while (true) { id = [...Array(length)].map(() => Math.floor(Math.random() * 16).toString(16)).join(""); if ((cache == null ? void 0 : cache.blocks) && id in cache.blocks) { continue; } else { break; } } return id; } function resolveLinktext(app, linktext, sourcePath) { const { path, subpath } = (0, import_obsidian5.parseLinktext)(linktext); const targetFile = app.metadataCache.getFirstLinkpathDest(path, sourcePath); if (!targetFile) return null; const targetCache = app.metadataCache.getFileCache(targetFile); if (!targetCache) return null; const result = (0, import_obsidian5.resolveSubpath)(targetCache, subpath); return { file: targetFile, subpathResult: result }; } function getMarkdownPreviewViewEl(view) { return Array.from(view.previewMode.containerEl.children).find((child) => child.matches(".markdown-preview-view")); } function getMarkdownSourceViewEl(view) { var _a; const firstCandidate = (_a = view.editor.cm) == null ? void 0 : _a.dom.parentElement; if (firstCandidate) return firstCandidate; const secondCandidate = view.previewMode.containerEl.previousSibling; if (secondCandidate instanceof HTMLElement && secondCandidate.matches(".markdown-source-view")) { return secondCandidate; } } async function openFileAndSelectPosition(app, file, position, ...leafArgs) { const leaf = app.workspace.getLeaf(...leafArgs); await leaf.openFile(file); if (leaf.view instanceof import_obsidian5.MarkdownView) { const editor = leaf.view.editor; const from = locToEditorPosition(position.start); const to = locToEditorPosition(position.end); editor.setSelection(from, to); editor.scrollIntoView({ from, to }, true); leaf.view.setEphemeralState({ line: position.start.line }); } } function isPdfExport(el) { var _a, _b; return ((_b = (_a = el.parentElement) == null ? void 0 : _a.classList.contains("print")) != null ? _b : false) && el.matches(".markdown-preview-view.markdown-rendered"); } function isPluginOlderThan(plugin, version) { return plugin.manifest.version.localeCompare(version, void 0, { numeric: true }) < 0; } function getModifierNameInPlatform(mod) { if (mod == "Mod") { return import_obsidian5.Platform.isMacOS || import_obsidian5.Platform.isIosApp ? "\u2318" : "ctrl"; } if (mod == "Shift") { return "shift"; } if (mod == "Alt") { return import_obsidian5.Platform.isMacOS || import_obsidian5.Platform.isIosApp ? "\u2325" : "alt"; } if (mod == "Meta") { return import_obsidian5.Platform.isMacOS || import_obsidian5.Platform.isIosApp ? "\u2318" : import_obsidian5.Platform.isWin ? "win" : "meta"; } return "ctrl"; } var MutationObservingChild = class extends import_obsidian5.Component { constructor(targetEl, callback, options) { super(); this.targetEl = targetEl; this.callback = callback; this.options = options; this.observer = new MutationObserver(callback); } onload() { this.observer.observe(this.targetEl, this.options); } onunload() { this.observer.disconnect(); } }; // src/utils/format.ts var ROMAN = [ "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" ]; function toRomanUpper(num) { var _a; const digits = String(num).split(""); let roman = ""; let i = 3; while (i--) { roman = ((_a = ROMAN[+digits.pop() + i * 10]) != null ? _a : "") + roman; } return Array(+digits.join("") + 1).join("M") + roman; } function toRomanLower(num) { return toRomanUpper(num).toLowerCase(); } var ALPH = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; function toAlphUpper(num) { return (num - 1).toString(26).split("").map((str) => ALPH[parseInt(str, 26)]).join(""); } function toAlphLower(num) { return toAlphUpper(num).toLowerCase(); } var CONVERTER = { "arabic": String, "alph": toAlphLower, "Alph": toAlphUpper, "roman": toRomanLower, "Roman": toRomanUpper }; function formatTheoremCalloutType(plugin, settings) { const profile = plugin.extraSettings.profiles[settings.profile]; return profile.body.theorem[settings.type]; } function formatTitleWithoutSubtitle(plugin, file, settings) { var _a, _b; let title = formatTheoremCalloutType(plugin, settings); if (settings.number) { if (settings.number == "auto") { if (settings._index !== void 0) { settings.numberInit = (_a = settings.numberInit) != null ? _a : 1; const num = +settings._index + +settings.numberInit; const style = (_b = settings.numberStyle) != null ? _b : DEFAULT_SETTINGS.numberStyle; title += ` ${getNumberPrefix(plugin.app, file, settings)}${CONVERTER[style](num)}${settings.numberSuffix}`; } } else { title += ` ${settings.number}`; } } return title; } function formatTitle(plugin, file, settings, noTitleSuffix = false) { let title = formatTitleWithoutSubtitle(plugin, file, settings); return addSubTitle(title, settings, noTitleSuffix); } function addSubTitle(mainTitle, settings, noTitleSuffix = false) { let title = mainTitle; if (settings.title) { title += ` (${settings.title})`; } if (!noTitleSuffix && settings.titleSuffix) { title += settings.titleSuffix; } return title; } function inferNumberPrefix(source, regExp) { const pattern = new RegExp(regExp); const match = source.match(pattern); if (match) { let prefix = match[0].trim(); if (!prefix.endsWith(".")) prefix += "."; return prefix; } } function getNumberPrefix(app, file, settings) { var _a; if (settings.numberPrefix) { return settings.numberPrefix; } const source = settings.inferNumberPrefixFromProperty ? getPropertyOrLinkTextInProperty(app, file, settings.inferNumberPrefixFromProperty) : file.basename; if (settings.inferNumberPrefix && source) { return (_a = inferNumberPrefix( source, settings.inferNumberPrefixRegExp )) != null ? _a : ""; } return ""; } function getEqNumberPrefix(app, file, settings) { var _a; if (settings.eqNumberPrefix) { return settings.eqNumberPrefix; } const source = settings.inferEqNumberPrefixFromProperty ? getPropertyOrLinkTextInProperty(app, file, settings.inferEqNumberPrefixFromProperty) : file.basename; if (settings.inferEqNumberPrefix && source) { const prefix = (_a = inferNumberPrefix( source, settings.inferEqNumberPrefixRegExp )) != null ? _a : ""; return prefix; } return ""; } function formatLabel(settings) { if (settings.label) { return settings.labelPrefix + THEOREM_LIKE_ENVs[settings.type].prefix + ":" + settings.label; } } // src/settings/helper.ts var TheoremCalloutSettingsHelper = class { constructor(contentEl, settings, defaultSettings, plugin, file) { this.contentEl = contentEl; this.settings = settings; this.defaultSettings = defaultSettings; this.plugin = plugin; this.file = file; } makeSettingPane() { var _a; const { contentEl } = this; new import_obsidian8.Setting(contentEl).setName("Type").addDropdown((dropdown) => { var _a2; for (const id of THEOREM_LIKE_ENV_IDs) { const envName = formatTheoremCalloutType(this.plugin, { type: id, profile: this.defaultSettings.profile }); dropdown.addOption(id, envName); if (this.defaultSettings.type) { dropdown.setValue(String(this.defaultSettings.type)); } } const initType = dropdown.getValue(); this.settings.type = initType; const numberSetting = new import_obsidian8.Setting(contentEl).setName("Number"); const numberSettingDescList = numberSetting.descEl.createEl("ul"); numberSettingDescList.createEl( "li", { text: '"auto" - automatically numbered' } ); numberSettingDescList.createEl( "li", { text: "blank - unnumbered" } ); numberSettingDescList.createEl( "li", { text: "otherwise - used as is" } ); numberSetting.addText((text) => { var _a3; text.setValue( (_a3 = this.defaultSettings.number) != null ? _a3 : this.defaultSettings.numberDefault ); this.settings.number = text.getValue(); text.onChange((value) => { this.settings.number = value; }); }); const titlePane = new import_obsidian8.Setting(contentEl).setName("Title").setDesc("You can include inline math in the title."); const labelPane = this.plugin.extraSettings.setLabelInModal ? new import_obsidian8.Setting(contentEl).setName("Pandoc label") : void 0; const labelPrefixEl = labelPane == null ? void 0 : labelPane.controlEl.createDiv({ text: THEOREM_LIKE_ENVs[this.settings.type].prefix + ":" + ((_a2 = this.defaultSettings.labelPrefix) != null ? _a2 : "") }); titlePane.addText((text) => { text.inputEl.classList.add("math-booster-title-form"); if (this.defaultSettings.title) { text.setValue(this.defaultSettings.title); } let labelTextComp; labelPane == null ? void 0 : labelPane.addText((text2) => { labelTextComp = text2; text2.inputEl.classList.add("math-booster-label-form"); if (this.defaultSettings.label) { text2.setValue(this.defaultSettings.label); } text2.onChange((value) => { this.settings.label = value; }); }); text.setPlaceholder("Ex) $\\sigma$-algebra").onChange((value) => { this.settings.title = value; if (this.plugin.extraSettings.setLabelInModal) { let labelInit = this.settings.title.replaceAll(" ", "-").replaceAll("'s", "").toLowerCase(); labelInit = labelInit.replaceAll(/[^a-z0-1\-]/g, ""); labelTextComp == null ? void 0 : labelTextComp.setValue(labelInit); this.settings.label = labelInit; } }); }); dropdown.onChange((value) => { this.settings.type = value; if (labelPrefixEl) { labelPrefixEl.textContent = THEOREM_LIKE_ENVs[this.settings.type].prefix + ":"; if (this.defaultSettings.labelPrefix) { labelPrefixEl.textContent += this.defaultSettings.labelPrefix; } } }); }); addFoldOptionSetting(contentEl, "Collapse", (fold) => { this.settings.fold = fold; }, (_a = this.defaultSettings.fold) != null ? _a : this.plugin.extraSettings.foldDefault); } }; var SettingsHelper = class extends import_obsidian8.Component { constructor(contentEl, settings, defaultSettings, plugin, allowUnset, addClear) { super(); this.contentEl = contentEl; this.settings = settings; this.defaultSettings = defaultSettings; this.plugin = plugin; this.allowUnset = allowUnset; this.addClear = addClear; this.settingRefs = {}; } addClearButton(name, setting, additionalCallback) { setting.addButton((button) => { button.setButtonText("Clear").onClick(async () => { delete this.settings[name]; additionalCallback(); }); }); } addDropdownSetting(name, options, prettyName, description, defaultValue, additionalOnChange) { const setting = new import_obsidian8.Setting(this.contentEl).setName(prettyName); if (description) { setting.setDesc(description); } setting.addDropdown((dropdown) => { var _a; if (this.allowUnset) { dropdown.addOption("", ""); } for (const option of options) { dropdown.addOption(option, option); } dropdown.setValue( defaultValue != null ? defaultValue : this.allowUnset ? this.settings[name] ? this.settings[name] : "" : (_a = this.settings[name]) != null ? _a : this.defaultSettings[name] ); dropdown.onChange(async (value) => { if (this.allowUnset && !value) { delete this.settings[name]; } else { Object.assign(this.settings, { [name]: value }); } additionalOnChange == null ? void 0 : additionalOnChange(); }); }); this.settingRefs[name] = setting; return setting; } addTextSetting(name, prettyName, description, number = false) { const setting = new import_obsidian8.Setting(this.contentEl).setName(prettyName); if (description) { setting.setDesc(description); } let textComponent; setting.addText((text) => { var _a, _b; textComponent = text; text.setPlaceholder(String((_a = this.defaultSettings[name]) != null ? _a : "")).setValue(String((_b = this.settings[name]) != null ? _b : "")).onChange((value) => { if (number) { Object.assign(this.settings, { [name]: +value }); } else { Object.assign(this.settings, { [name]: value }); } }); }); if (this.addClear) { this.addClearButton(name, setting, () => { var _a; textComponent.setPlaceholder(String((_a = this.defaultSettings[name]) != null ? _a : "")).setValue(""); }); } this.settingRefs[name] = setting; return setting; } addToggleSetting(name, prettyName, description, additionalOnChange) { const setting = new import_obsidian8.Setting(this.contentEl).setName(prettyName); if (description) { setting.setDesc(description); } let toggleComponent; setting.addToggle((toggle) => { toggleComponent = toggle; toggle.setValue(this.defaultSettings[name]); if (typeof this.settings[name] == "boolean") { toggle.setValue(this.settings[name]); } toggle.onChange((value) => { Object.assign(this.settings, { [name]: value }); additionalOnChange == null ? void 0 : additionalOnChange(); }); }); if (this.addClear) { this.addClearButton(name, setting, () => { toggleComponent.setValue(this.defaultSettings[name]); }); } this.settingRefs[name] = setting; return setting; } addSliderSetting(name, limits, prettyName, description) { const setting = new import_obsidian8.Setting(this.contentEl).setName(prettyName); if (description) { setting.setDesc(description); } let sliderComponent; setting.addSlider((slider) => { sliderComponent = slider; slider.setLimits(limits.min, limits.max, limits.step).setDynamicTooltip().setValue(this.defaultSettings[name]); if (typeof this.settings[name] == "number") { slider.setValue(this.settings[name]); } slider.onChange((value) => { Object.assign(this.settings, { [name]: value }); }); }); if (this.addClear) { this.addClearButton(name, setting, () => { sliderComponent.setValue(this.defaultSettings[name]); }); } this.settingRefs[name] = setting; return setting; } addHeading(text, cls) { const setting = new import_obsidian8.Setting(this.contentEl).setName(text).setHeading(); if (cls) setting.settingEl.classList.add(...cls); return setting; } }; var MathContextSettingsHelper = class extends SettingsHelper { constructor(contentEl, settings, defaultSettings, plugin, file) { const isRoot = file instanceof import_obsidian8.TFolder && file.isRoot(); super(contentEl, settings, defaultSettings, plugin, !isRoot, !isRoot); this.file = file; } onload() { this.addHeading("Theorem callouts - general"); this.addProfileSetting(); const styleSetting = this.addDropdownSetting("theoremCalloutStyle", THEOREM_CALLOUT_STYLES, "Style", void 0, void 0, () => this.plugin.forceRerender()); styleSetting.descEl.replaceChildren( 'Choose between your custom style and preset styles. You might need to reopen the notes or reload the app to see the changes. See the documentation for how to customize the appearance of theorem callouts. "Custom" is recommended, since it will give you the most control. You can view the CSS snippets for all the preset styles in the documentation or README on GitHub. The preset styles are only for a trial purpose, and they might not work well with some non-default themes.' ); this.addToggleSetting("theoremCalloutFontInherit", "Don't override the app's font setting when using preset styles", "You will need to reload the note to see the changes."); this.addTextSetting("titleSuffix", "Title suffix", 'Ex) "" > Definition 2 (Group) / "." > Definition 2 (Group).'); this.addTextSetting("labelPrefix", "Pandoc label prefix", 'Useful for ensuring no label collision. Ex) When "Pandoc label prefix" = "foo:", A theorem with "Pandoc label" = "bar" is assigned "thm:foo:bar."'); this.addHeading("Theorem callouts - numbering"); this.addToggleSetting( "inferNumberPrefix", "Infer prefix from note title or properties", `Automatically infer a prefix from the note title or properties. See the documentation (Settings > Prefix inference) for an example.` ); this.addTextSetting("inferNumberPrefixFromProperty", "Use property as source", "If set, use this property as the source of prefix inference. If not set, the note title will be used as the source."); this.addTextSetting("inferNumberPrefixRegExp", "Regular expression for parsing"); this.addTextSetting("numberPrefix", "Manual prefix", 'Even if "Infer prefix from note title or properties" is turned on, the inferred prefix will be overwritten by the value set here.'); this.addTextSetting("numberSuffix", "Suffix"); this.addTextSetting("numberInit", "Initial count"); this.addDropdownSetting("numberStyle", NUMBER_STYLES, "Style"); this.addTextSetting("numberDefault", 'Default value for the "Number" field of "Insert theorem callout" modal'); this.addHeading("Theorem callouts - referencing"); this.addDropdownSetting("refFormat", THEOREM_REF_FORMATS, "Format"); this.addDropdownSetting( "noteMathLinkFormat", THEOREM_REF_FORMATS, 'Format for a note that has its "main" theorem callout', `When a theorem callout is set as main by a markdown comment "%% main %%", this format will be used for links to the note containing that theorem callout.` ); this.addToggleSetting("ignoreMainTheoremCalloutWithoutTitle", 'Ignore a "main" theorem callout without its own title'); this.addHeading("Equations - numbering", ["equation-heading"]); this.addToggleSetting("numberOnlyReferencedEquations", "Number only referenced equations"); this.addToggleSetting( "inferEqNumberPrefix", "Infer prefix from note title or properties", `Automatically infer a prefix from the note title or properties. See the documentation (Settings > Prefix inference) for an example.` ); this.addTextSetting("inferEqNumberPrefixFromProperty", "Use property as source", "If set, use this property as the source of prefix inference. If not set, the note title will be used as the source."); this.addTextSetting("inferEqNumberPrefixRegExp", "Regular expression for parsing"); this.addTextSetting("eqNumberPrefix", "Manual prefix", 'Even if "Infer prefix from note title" is turned on, the inferred prefix will be overwritten by the value set here.'); this.addTextSetting("eqNumberSuffix", "Suffix"); this.addTextSetting("eqNumberInit", "Initial count"); this.addDropdownSetting("eqNumberStyle", NUMBER_STYLES, "Style"); this.addToggleSetting("lineByLine", "Number line by line in align"); this.addHeading("Equations - referencing"); this.addTextSetting("eqRefPrefix", "Prefix"); this.addTextSetting("eqRefSuffix", "Suffix"); this.addHeading("Proofs (experimental)", ["proof-heading"]); this.addTextSetting("beginProof", "Beginning of a proof"); this.addTextSetting("endProof", "End of a proof"); this.addHeading("Search & link auto-completion - general").then(async (setting) => { setting.descEl.addClass("math-booster-new-feature"); await import_obsidian8.MarkdownRenderer.render(this.plugin.app, "**NOTE:** If you have the [**Quick Preview**](https://github.com/RyotaUshio/obsidian-quick-preview) plugin installed, holding down `Alt`/`Option` _(by default)_ will trigger a quick preview of the selected suggestion with the context around it.", setting.descEl, "", this); }); this.addToggleSetting("insertSpace", "Append whitespace after inserted link"); } addProfileSetting(defaultValue) { const profileSetting = this.addDropdownSetting("profile", Object.keys(this.plugin.extraSettings.profiles), "Profile", "A profile defines the displayed name of each environment.", defaultValue); new import_obsidian8.ButtonComponent(profileSetting.controlEl).setButtonText("Manage profiles").onClick(() => { new ManageProfileModal(this.plugin, this, profileSetting).open(); }); profileSetting.controlEl.classList.add("math-booster-profile-setting"); return profileSetting; } }; var ExtraSettingsHelper = class extends SettingsHelper { onload() { this.settingRefs["foldDefault"] = addFoldOptionSetting( this.contentEl, 'Default collapsibility when using the "Insert theorem callout" command', (fold) => { this.settings.foldDefault = fold; }, this.defaultSettings.foldDefault ); this.addToggleSetting("noteTitleInTheoremLink", "Show the note title at the head of a link to a theorem", 'If turned on, a link to "Theorem 1" will look like "Note title > Theorem 1".'); this.addToggleSetting("noteTitleInEquationLink", "Show the note title at the head of a link to an equation", 'If turned on, a link to "Eq.(1)" will look like "Note title > Eq.(1)".'); this.addToggleSetting("excludeExampleCallout", `Don't treat "> [!example]" as a theorem callout`, `If turned on, a callout of the form "> [!example]" will be treated as Obsidian's built-in "Example" callout, and you will need to type "> [!exm]" instead to insert a theorem callout of "Example" type.`); this.addToggleSetting("showTheoremCalloutEditButton", "Show an edit button on a theorem callout"); this.addToggleSetting("setOnlyTheoremAsMain", "If a note has only one theorem callout, automatically set it as main", `Regardless of this setting, putting "%% main %%" or "%% main: true %%" in a theorem callout will set it as main one of the note, which means any link to that note will be displayed with the theorem's title. Enabling this option implicitly sets a theorem callout as main when it's the only one in the note.`); this.addToggleSetting("setLabelInModal", "Show LaTeX/Pandoc label input form in theorem callout insert/edit modal"); this.addToggleSetting("enableMathPreviewInCalloutAndQuote", "Render equations inside callouts & add multi-line equation support to blockquotes", void 0, () => this.plugin.updateEditorExtensions()).then(async (setting) => { setting.descEl.addClass("math-booster-new-feature"); await import_obsidian8.MarkdownRenderer.render(this.plugin.app, "**NOTE:** This feature is planned to be removed from this plugin, and instead, it will be available as a separate plugin [**Better Math in Callouts & Blockquotes**](https://github.com/RyotaUshio/obsidian-math-in-callout), featuring a bunch of improvements. Currently awaiting for approval by the Obsidian team.", setting.descEl, "", this); }); this.addToggleSetting("enableProof", "Enable proof environment", `For example, you can replace a pair of inline codes \`${DEFAULT_SETTINGS.beginProof}\` & \`${DEFAULT_SETTINGS.endProof}\` with "${DEFAULT_PROFILES[DEFAULT_SETTINGS.profile].body.proof.begin}" & "${DEFAULT_PROFILES[DEFAULT_SETTINGS.profile].body.proof.end}". You can style it with CSS snippets. See the documentation for the details.`, () => this.plugin.updateEditorExtensions()); this.addSliderSetting("suggestNumber", { min: 1, max: 50, step: 1 }, "Number of suggestions", "Specify how many items are suggested at one time. Set it to a smaller value if you have a performance issue when equation suggestions with math rendering on."); this.addToggleSetting("renderMathInSuggestion", "Render math in equation suggestions", "Turn this off if you have a performance issue and reducing the number of suggestions doesn't fix it."); this.addDropdownSetting("searchMethod", ["Fuzzy", "Simple"], "Search method", "Fuzzy search is more flexible, but simple search is lighter-weight."); this.addToggleSetting("searchLabel", "Include theorem callout label for search target"); this.addSliderSetting("upWeightRecent", { min: 0, max: 0.5, step: 0.01 }, "Up-weight recently opened notes by", 'It takes effect only if "Search only recently opened notes" is turned off.'); this.addDropdownSetting("modifierToJump", ["Mod", "Ctrl", "Meta", "Shift", "Alt"], "Modifier key for jumping to suggestion", "Press Enter and this modifier key to jump to the currently selected suggestion. Changing this option requires to reloading " + this.plugin.manifest.name + " to take effect."); this.addDropdownSetting("modifierToNoteLink", ["Mod", "Ctrl", "Meta", "Shift", "Alt"], "Modifier key for insert link to note", "Press Enter and this modifier key to insert a link to the note containing the currently selected item. Changing this option requires to reloading " + this.plugin.manifest.name + " to take effect."); this.addToggleSetting("showModifierInstruction", "Show modifier key instruction", `Show the instruction for the modifier key at the bottom of suggestion box. Changing this option requires to reloading ${this.plugin.manifest.name} to take effect.`); const list = this.settingRefs.modifierToJump.descEl.createEl("ul"); list.createEl("li", { text: "Mod is Cmd on MacOS and Ctrl on other OS." }); list.createEl("li", { text: "Meta is Cmd on MacOS and Win key on Windows." }); this.addDropdownSetting("suggestLeafOption", LEAF_OPTIONS, "Opening option", "Specify how to open the selected suggestion."); this.addHeading("Enhance Obsidian's built-in link auto-completion (experimental)").setDesc(`Configure how this plugin modifies the appearance of Obsidian's built-in link auto-completion (the one that pops up when you type "[["). This feature dives deep into Obsidian's internals, so it might break when Obsidian is updated. If you encounter any issue, please report it on GitHub.`); this.addToggleSetting("showTheoremTitleinBuiltin", "Show theorem title"); this.addToggleSetting("showTheoremContentinBuiltin", "Show theorem content", 'Only effective when "Show theorem title" is turned on.'); this.addToggleSetting("renderEquationinBuiltin", "Render equation").then(async (setting) => { setting.descEl.addClass("math-booster-new-feature"); await import_obsidian8.MarkdownRenderer.render(this.plugin.app, "**NOTE:** This feature is planned to be removed from this plugin, and instead, it will be available as a separate plugin [**Rendered Block Link Suggestions**](https://github.com/RyotaUshio/obsidian-rendered-block-link-suggestions), which supports all types of blocks not limited to display math. Currently awaiting for approval by the Obsidian team.", setting.descEl, "", this); }); this.addHeading("Configure this plugin's custom editor link auto-completion").setDesc(`It is recommended to turn off unnecessary auto-completions to improve performance.`); this.addTextSetting("autocompleteDvQuery", "Dataview query for editor link auto-completion", "Only LIST queries are supported."); this.addHeading("Theorem & equation suggestion"); this.addHeading("From entire vault", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableSuggest", "Enable"); this.addTextSetting("triggerSuggest", "Trigger"); this.addHeading("From recently opened notes", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableSuggestRecentNotes", "Enable"); this.addTextSetting("triggerSuggestRecentNotes", "Trigger"); this.addHeading("From active note", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableSuggestActiveNote", "Enable"); this.addTextSetting("triggerSuggestActiveNote", "Trigger"); this.addHeading("From Dataview query", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableSuggestDataview", "Enable"); this.addTextSetting("triggerSuggestDataview", "Trigger"); this.addHeading("Theorem suggestion", ["editor-suggest-setting-heading"]); this.addHeading("From entire vault", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableTheoremSuggest", "Enable"); this.addTextSetting("triggerTheoremSuggest", "Trigger"); this.addHeading("From recently opened notes", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableTheoremSuggestRecentNotes", "Enable"); this.addTextSetting("triggerTheoremSuggestRecentNotes", "Trigger"); this.addHeading("From active note", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableTheoremSuggestActiveNote", "Enable"); this.addTextSetting("triggerTheoremSuggestActiveNote", "Trigger"); this.addHeading("From Dataview query", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableTheoremSuggestDataview", "Enable"); this.addTextSetting("triggerTheoremSuggestDataview", "Trigger"); this.addHeading("Equation suggestion", ["editor-suggest-setting-heading"]); this.addHeading("From entire vault", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableEquationSuggest", "Enable"); this.addTextSetting("triggerEquationSuggest", "Trigger"); this.addHeading("From recently opened notes", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableEquationSuggestRecentNotes", "Enable"); this.addTextSetting("triggerEquationSuggestRecentNotes", "Trigger"); this.addHeading("From active note", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableEquationSuggestActiveNote", "Enable"); this.addTextSetting("triggerEquationSuggestActiveNote", "Trigger"); this.addHeading("From Dataview query", ["editor-suggest-setting-indented-heading"]); this.addToggleSetting("enableEquationSuggestDataview", "Enable"); this.addTextSetting("triggerEquationSuggestDataview", "Trigger"); this.addHeading("Indexing"); this.addSliderSetting("importerNumThreads", { min: 1, max: 10, step: 1 }, "Indexer threads", "The maximum number of thread used for indexing."); this.addSliderSetting("importerUtilization", { min: 0.1, max: 1, step: 0.01 }, "Indexer CPU utilization", "The CPU utilization that indexer threads should use."); } }; function addFoldOptionSetting(el, name, onChange, defaultValue) { return new import_obsidian8.Setting(el).setName(name).addDropdown((dropdown) => { dropdown.addOption("", "Unfoldable"); dropdown.addOption("+", "Foldable & expanded by default"); dropdown.addOption("-", "Foldable & folded by default"); dropdown.setValue(defaultValue != null ? defaultValue : DEFAULT_EXTRA_SETTINGS.foldDefault); dropdown.onChange(onChange); }); } // src/settings/modals.ts var import_obsidian12 = require("obsidian"); // src/utils/plugin.ts var import_obsidian10 = require("obsidian"); // src/index/utils/normalizers.ts function getFileTitle(path) { if (path.includes("/")) path = path.substring(path.lastIndexOf("/") + 1); if (path.endsWith(".md")) path = path.substring(0, path.length - 3); return path; } // src/index/expression/link.ts var Link = class _Link { /** Create a link to a specific file. */ static file(path, embed = false, display) { return new _Link({ path, embed, display, subpath: void 0, type: "file" }); } /** Infer the type of the link from the full internal link path. */ static infer(linkpath, embed = false, display) { if (linkpath.includes("#^")) { let split = linkpath.split("#^"); return _Link.block(split[0], split[1], embed, display); } else if (linkpath.includes("#")) { let split = linkpath.split("#"); return _Link.header(split[0], split[1], embed, display); } else return _Link.file(linkpath, embed, display); } /** Create a link to a specific file and header in that file. */ static header(path, header, embed, display) { return new _Link({ path, embed, display, subpath: header, //normalizeHeaderForLink(header), type: "header" }); } /** Create a link to a specific file and block in that file. */ static block(path, blockId, embed, display) { return new _Link({ path, embed, display, subpath: blockId, type: "block" }); } /** Load a link from it's raw JSON representation. */ static fromObject(object) { return new _Link(object); } /** Create a link by parsing it's interior part (inside of the '[[]]'). */ static parseInner(rawlink) { let [link, display] = splitOnUnescapedPipe(rawlink); return _Link.infer(link, false, display); } constructor(fields) { Object.assign(this, fields); } /** Update this link with a new path. */ withPath(path) { return new _Link(Object.assign({}, this, { path })); } /** Return a new link which points to the same location but with a new display value. */ withDisplay(display) { return new _Link(Object.assign({}, this, { display })); } /** Return a new link which has the given embedded status. */ withEmbed(embed) { if (this.embed == embed) return this; return new _Link(Object.assign({}, this, { embed })); } /** Convert a file link into a link to a specific header. */ withHeader(header) { return _Link.header(this.path, header, this.embed, this.display); } /** Convert a file link into a link to a specificb lock. */ withBlock(block) { return _Link.block(this.path, block, this.embed, this.display); } /** Checks for link equality (i.e., that the links are pointing to the same exact location). */ equals(other) { if (other == void 0 || other == null) return false; return this.path == other.path && this.type == other.type && this.subpath == other.subpath; } /** Convert this link to it's markdown representation. */ toString() { return this.markdown(); } /** Convert this link to a raw object which is serialization-friendly. */ toObject() { return { path: this.path, type: this.type, subpath: this.subpath, display: this.display, embed: this.embed }; } /** Convert any link into a link to its file. */ toFile() { return _Link.file(this.path, this.embed, this.display); } /** Convert this link into an embedded link. */ toEmbed() { return this.withEmbed(true); } /** Convert this link into a non-embedded link. */ fromEmbed() { return this.withEmbed(false); } /** Convert this link to markdown so it can be rendered. */ markdown() { let result = (this.embed ? "!" : "") + "[[" + this.obsidianLink(); result += this.displayOrDefault(); result += "]]"; return result; } /** Obtain the display for this link, or return a simple default display. */ displayOrDefault() { if (this.display) { return this.display; } else { let result = getFileTitle(this.path); if (this.type == "header" || this.type == "block") result += " > " + this.subpath; return result; } } /** Convert the inner part of the link to something that Obsidian can open / understand. */ obsidianLink() { var _a, _b; const escaped = this.path.replace("|", "\\|"); if (this.type == "header") return escaped + "#" + ((_a = this.subpath) == null ? void 0 : _a.replace("|", "\\|")); if (this.type == "block") return escaped + "#^" + ((_b = this.subpath) == null ? void 0 : _b.replace("|", "\\|")); else return escaped; } /** The stripped name of the file this link points to. */ fileName() { return getFileTitle(this.path); } }; function splitOnUnescapedPipe(link) { let pipe = -1; while ((pipe = link.indexOf("|", pipe + 1)) >= 0) { if (pipe > 0 && link[pipe - 1] == "\\") continue; return [link.substring(0, pipe).replace(/\\\|/g, "|"), link.substring(pipe + 1)]; } return [link.replace(/\\\|/g, "|"), void 0]; } // src/index/expression/literal.ts var Literals; ((Literals2) => { Literals2.DEFAULT_TO_STRING = { nullRepresentation: "-", dateFormat: "MMMM dd, yyyy", dateTimeFormat: "h:mm a - MMMM dd, yyyy" }; function toString(field, setting = Literals2.DEFAULT_TO_STRING, recursive = false) { let wrapped = wrapValue(field); if (!wrapped) return setting.nullRepresentation; switch (wrapped.type) { case "null": return setting.nullRepresentation; case "string": return wrapped.value; case "number": case "boolean": return "" + wrapped.value; case "link": return wrapped.value.markdown(); case "function": return ""; case "array": let result = ""; if (recursive) result += "["; result += wrapped.value.map((f) => toString(f, setting, true)).join(", "); if (recursive) result += "]"; return result; case "object": return "{ " + Object.entries(wrapped.value).map((e) => e[0] + ": " + toString(e[1], setting, true)).join(", ") + " }"; } } Literals2.toString = toString; function wrapValue(val) { if (isNull(val)) return { type: "null", value: val }; else if (isNumber(val)) return { type: "number", value: val }; else if (isString(val)) return { type: "string", value: val }; else if (isBoolean(val)) return { type: "boolean", value: val }; else if (isArray(val)) return { type: "array", value: val }; else if (isLink(val)) return { type: "link", value: val }; else if (isFunction(val)) return { type: "function", value: val }; else if (isObject(val)) return { type: "object", value: val }; else return void 0; } Literals2.wrapValue = wrapValue; function mapLeaves(val, func) { if (isObject(val)) { let result = {}; for (let [key, value] of Object.entries(val)) result[key] = mapLeaves(value, func); return result; } else if (isArray(val)) { let result = []; for (let value of val) result.push(mapLeaves(value, func)); return result; } else { return func(val); } } Literals2.mapLeaves = mapLeaves; function compare(val1, val2, linkNormalizer) { var _a, _b; if (val1 === void 0) val1 = null; if (val2 === void 0) val2 = null; if (val1 === null && val2 === null) return 0; else if (val1 === null) return -1; else if (val2 === null) return 1; let wrap1 = wrapValue(val1); let wrap2 = wrapValue(val2); if (wrap1 === void 0 && wrap2 === void 0) return 0; else if (wrap1 === void 0) return -1; else if (wrap2 === void 0) return 1; if (wrap1.type != wrap2.type) return wrap1.type.localeCompare(wrap2.type); if (wrap1.value === wrap2.value) return 0; switch (wrap1.type) { case "string": return wrap1.value.localeCompare(wrap2.value); case "number": if (wrap1.value < wrap2.value) return -1; else if (wrap1.value == wrap2.value) return 0; return 1; case "null": return 0; case "boolean": if (wrap1.value == wrap2.value) return 0; else return wrap1.value ? 1 : -1; case "link": let link1 = wrap1.value; let link2 = wrap2.value; let normalize = linkNormalizer != null ? linkNormalizer : (x) => x; let pathCompare = normalize(link1.path).localeCompare(normalize(link2.path)); if (pathCompare != 0) return pathCompare; let typeCompare = link1.type.localeCompare(link2.type); if (typeCompare != 0) return typeCompare; if (link1.subpath && !link2.subpath) return 1; if (!link1.subpath && link2.subpath) return -1; if (!link1.subpath && !link2.subpath) return 0; return ((_a = link1.subpath) != null ? _a : "").localeCompare((_b = link2.subpath) != null ? _b : ""); case "array": let f1 = wrap1.value; let f2 = wrap2.value; for (let index = 0; index < Math.min(f1.length, f2.length); index++) { let comp = compare(f1[index], f2[index]); if (comp != 0) return comp; } return f1.length - f2.length; case "object": let o1 = wrap1.value; let o2 = wrap2.value; let k1 = Array.from(Object.keys(o1)); let k2 = Array.from(Object.keys(o2)); k1.sort(); k2.sort(); let keyCompare = compare(k1, k2); if (keyCompare != 0) return keyCompare; for (let key of k1) { let comp = compare(o1[key], o2[key]); if (comp != 0) return comp; } return 0; case "function": return 0; } } Literals2.compare = compare; function typeOf(val) { var _a; return (_a = wrapValue(val)) == null ? void 0 : _a.type; } Literals2.typeOf = typeOf; function isTruthy(field) { let wrapped = wrapValue(field); if (!wrapped) return false; switch (wrapped.type) { case "number": return wrapped.value != 0; case "string": return wrapped.value.length > 0; case "boolean": return wrapped.value; case "link": return !!wrapped.value.path; case "object": return Object.keys(wrapped.value).length > 0; case "array": return wrapped.value.length > 0; case "null": return false; case "function": return true; } } Literals2.isTruthy = isTruthy; function deepCopy(field) { if (field === null || field === void 0) return field; if (Literals2.isArray(field)) { return [].concat(field.map((v) => deepCopy(v))); } else if (Literals2.isObject(field)) { let result = {}; for (let [key, value] of Object.entries(field)) result[key] = deepCopy(value); return result; } else { return field; } } Literals2.deepCopy = deepCopy; function isString(val) { return typeof val == "string"; } Literals2.isString = isString; function isNumber(val) { return typeof val == "number"; } Literals2.isNumber = isNumber; function isNull(val) { return val === null || val === void 0; } Literals2.isNull = isNull; function isArray(val) { return Array.isArray(val); } Literals2.isArray = isArray; function isBoolean(val) { return typeof val === "boolean"; } Literals2.isBoolean = isBoolean; function isLink(val) { return val instanceof Link; } Literals2.isLink = isLink; function isObject(val) { return val !== void 0 && typeof val == "object" && !isArray(val) && // !isDuration(val) && // !isDate(val) && !isLink(val) && !isNull(val); } Literals2.isObject = isObject; function isFunction(val) { return typeof val == "function"; } Literals2.isFunction = isFunction; })(Literals || (Literals = {})); var Groupings; ((Groupings2) => { function isElementGroup(entry) { return Literals.isObject(entry) && Object.keys(entry).length == 2 && "key" in entry && "rows" in entry; } Groupings2.isElementGroup = isElementGroup; function isGrouping(entry) { for (let element of entry) if (!isElementGroup(element)) return false; return true; } Groupings2.isGrouping = isGrouping; function count(elements) { if (isGrouping(elements)) { let result = 0; for (let subgroup of elements) result += count(subgroup.rows); return result; } else { return elements.length; } } Groupings2.count = count; })(Groupings || (Groupings = {})); // src/index/typings/indexable.ts var LINKABLE_TYPE = "linkable"; var FILE_TYPE = "file"; var LINKBEARING_TYPE = "links"; // src/index/typings/markdown.ts var NOOP_NORMALIZER = (x) => x; var _MarkdownPage = class _MarkdownPage { constructor(init) { // Use static types for all markdown files. this.$types = _MarkdownPage.TYPES; this.$typename = "Page"; /** * All child markdown sections of this markdown file. The initial section before any content is special and is * named with the title of the file. */ this.$sections = []; Object.assign(this, init); } // Markdown file IDs are always just the full path. get $id() { return this.$path; } // The file of a file is... it's file. get $file() { return this.$path; } /** Create a markdown file from the given raw values. */ static from(raw, normalizer = NOOP_NORMALIZER) { const sections = raw.$sections.map((sect) => MarkdownSection.from(sect, raw.$path, normalizer)); const blocks = /* @__PURE__ */ new Map(); for (const section of sections) { for (const block of section.$blocks) { if (block.$blockId) blocks.set(block.$blockId, block); } } return new _MarkdownPage({ $path: raw.$path, $extension: raw.$extension, $position: raw.$position, $links: raw.$links.map(normalizer), $sections: sections, $blocks: blocks }); } /** Return the number of lines in the document. */ get $lineCount() { return this.$position.end; } /** The name of the file. */ get $name() { return getFileTitle(this.$path); } /** A link to this file. */ get $link() { return Link.file(this.$path); } /** Convert this page into it's partial representation for saving. */ partial() { return { $path: this.$path, $extension: this.$extension, $position: this.$position, $links: this.$links, $sections: this.$sections.map((sect) => sect.partial()) }; } getBlockByLineNumber(line) { const section = this.$sections.find((section2) => section2.$position.start <= line && line <= section2.$position.end); const block = section == null ? void 0 : section.$blocks.find((block2) => block2.$position.start <= line && line <= block2.$position.end); return block; } getBlockByOffset(offset) { for (const section of this.$sections) { for (const block of section.$blocks) { if (block.$pos.start.offset <= offset && offset <= block.$pos.end.offset) return block; } } } static isMarkdownPage(object) { return object !== void 0 && "$typename" in object && object.$typename === "Page"; } }; /** All of the types that a markdown file is. */ _MarkdownPage.TYPES = [FILE_TYPE, "markdown", "page", LINKABLE_TYPE, LINKBEARING_TYPE]; var MarkdownPage = _MarkdownPage; var _MarkdownSection = class _MarkdownSection { constructor(init) { /** Path of the file that this section is in. */ this.$types = _MarkdownSection.TYPES; this.$typename = "Section"; Object.assign(this, init); } /** Convert raw markdown section data to the appropriate class. */ static from(raw, file, normalizer = NOOP_NORMALIZER) { const blocks = raw.$blocks.map((block) => MarkdownBlock.from(block, file, normalizer)); return new _MarkdownSection({ $file: file, $id: _MarkdownSection.readableId(file, raw.$title, raw.$ordinal), $ordinal: raw.$ordinal, $title: raw.$title, $level: raw.$level, $position: raw.$position, $links: raw.$links.map(normalizer), $blocks: blocks }); } /** Obtain the number of lines in the section. */ get $lineCount() { return this.$position.end - this.$position.start; } /** Alias for title which allows searching over pages and sections by 'name'. */ get $name() { return this.$title; } /** Return a link to this section. */ get $link() { return Link.header(this.$file, this.$title); } partial() { return { $ordinal: this.$ordinal, $title: this.$title, $level: this.$level, $position: this.$position, $links: this.$links, $blocks: this.$blocks.map((block) => block.partial()) }; } /** Generate a readable ID for this section using the first 8 characters of the string and the ordinal. */ static readableId(file, title, ordinal) { const first8 = title.substring(0, Math.min(title.length, 8)).replace(/[^A-Za-z0-9-_]+/gi, "-"); return `${file}/section${ordinal}/${first8}`; } static isMarkdownSection(object) { return object !== void 0 && "$typename" in object && object.$typename === "Section"; } }; /** All of the types that a markdown section is. */ _MarkdownSection.TYPES = ["markdown", "section", LINKABLE_TYPE, LINKBEARING_TYPE]; var MarkdownSection = _MarkdownSection; var _MarkdownBlock = class _MarkdownBlock { constructor(init) { this.$types = _MarkdownBlock.TYPES; this.$typename = "Block"; Object.assign(this, init); } static from(object, file, normalizer = NOOP_NORMALIZER) { if (object.$type === "theorem") { return TheoremCalloutBlock.from(object, file, normalizer); } else if (object.$type === "equation") { return EquationBlock.from(object, file, normalizer); } return new _MarkdownBlock({ $file: file, $id: _MarkdownBlock.readableId(file, object.$ordinal), $ordinal: object.$ordinal, $position: object.$position, $pos: object.$pos, $links: object.$links.map(normalizer), $blockId: object.$blockId, $type: object.$type }); } /** If this block has a block ID, the link to this block. */ get $link() { if (this.$blockId) return Link.block(this.$file, this.$blockId); else return void 0; } partial() { return { $ordinal: this.$ordinal, $position: this.$position, $pos: this.$pos, $links: this.$links, $blockId: this.$blockId, $type: this.$type }; } /** Generate a readable ID for this block using the ordinal of the block. */ static readableId(file, ordinal) { return `${file}/block${ordinal}`; } static isMarkdownBlock(object) { return object !== void 0 && object.$types.includes("block"); } }; _MarkdownBlock.TYPES = ["markdown", "block", LINKBEARING_TYPE]; var MarkdownBlock = _MarkdownBlock; var MathBlock = class extends MarkdownBlock { static isMathBlock(object) { return object !== void 0 && object.$types.includes("block-math-booster"); } }; var _TheoremCalloutBlock = class _TheoremCalloutBlock extends MathBlock { constructor(init) { super(init); this.$types = _TheoremCalloutBlock.TYPES; this.$typename = "Theorem Callout Block"; this.$type = "theorem"; } /** e.g. Theorem 1.1 (Cauchy-Schwarz) -> "theorem" */ get $theoremType() { return this.$settings.type; } get $numberSpec() { return this.$settings.number; } /** e.g. Theorem 1.1 (Cauchy-Schwarz) -> "Cauchy-Schwarz" */ get $theoremSubtitle() { return this.$settings.title; } /** e.g. "Theorem 1.1 (Cauchy-Schwarz)" */ get $printName() { return this.$theoremSubtitle ? `${this.$theoremMainTitle} (${this.$theoremSubtitle})` : this.$theoremMainTitle; } static from(object, file, normalizer = NOOP_NORMALIZER) { return new _TheoremCalloutBlock({ $file: file, $id: MarkdownBlock.readableId(file, object.$ordinal), $ordinal: object.$ordinal, $position: object.$position, $pos: object.$pos, $links: object.$links.map(normalizer), $blockId: object.$blockId, $type: object.$type, $settings: object.$settings, $label: object.$label, $display: object.$display, $main: object.$main, $v1: object.$v1 }); } partial() { return Object.assign(super.partial(), { $settings: this.$settings, $label: this.$label, $display: this.$display, $main: this.$main, $v1: this.$v1 }); } static isTheoremCalloutBlock(object) { return object !== void 0 && object.$types.includes("block-theorem"); } }; _TheoremCalloutBlock.TYPES = ["markdown", "block", "block-math-booster", "block-theorem", LINKBEARING_TYPE]; var TheoremCalloutBlock = _TheoremCalloutBlock; var _EquationBlock = class _EquationBlock extends MathBlock { constructor(init) { super(init); this.$types = _EquationBlock.TYPES; this.$typename = "Equation Block"; this.$type = "equation"; this.$printName = null; } static from(object, file, normalizer = NOOP_NORMALIZER) { return new _EquationBlock({ $file: file, $id: MarkdownBlock.readableId(file, object.$ordinal), $ordinal: object.$ordinal, $position: object.$position, $pos: object.$pos, $links: object.$links.map(normalizer), $blockId: object.$blockId, $type: object.$type, $mathText: object.$mathText, $manualTag: object.$manualTag, $label: object.$label, $display: object.$display }); } partial() { return Object.assign(super.partial(), { $mathText: this.$mathText, $manualTag: this.$manualTag, $label: this.$label, $display: this.$display }); } static isEquationBlock(object) { return object !== void 0 && object.$types.includes("block-equation"); } }; _EquationBlock.TYPES = ["markdown", "block", "block-math-booster", "block-equation"]; var EquationBlock = _EquationBlock; // src/file-io.ts var import_obsidian9 = require("obsidian"); // src/utils/general.ts function splitIntoLines(text) { return text.split(/\r?\n/); } function capitalize(text) { return text.charAt(0).toUpperCase() + text.slice(1); } function insertAt(array, item, index) { array.splice(index, 0, item); } // src/file-io.ts var FileIO = class { constructor(plugin, file) { this.plugin = plugin; this.file = file; } }; var ActiveNoteIO = class extends FileIO { /** * File IO for the currently active markdown view. * Uses the Editor interface instead of Vault. * (See https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines#Prefer+the+Editor+API+instead+of+%60Vault.modify%60) * @param editor */ constructor(plugin, file, editor) { super(plugin, file); this.editor = editor; } async setLine(lineNumber, text) { this.editor.setLine(lineNumber, text); } async setRange(position, text) { const from = locToEditorPosition(position.start); const to = locToEditorPosition(position.end); this.editor.replaceRange(text, from, to); } async insertLine(lineNumber, text) { this.editor.replaceRange(text + "\n", { line: lineNumber, ch: 0 }); } async getLine(lineNumber) { return this.editor.getLine(lineNumber); } async getRange(position) { const from = locToEditorPosition(position.start); const to = locToEditorPosition(position.end); const text = this.editor.getRange(from, to); return text; } }; var NonActiveNoteIO = class extends FileIO { /** * File IO for non-active (= currently not opened / currently opened but not focused) notes. * Uses the Vault interface instead of Editor. */ constructor(plugin, file) { super(plugin, file); this._data = null; } async setLine(lineNumber, text) { this.plugin.app.vault.process(this.file, (data) => { const lines = splitIntoLines(data); lines[lineNumber] = text; return lines.join("\n"); }); } async setRange(position, text) { this.plugin.app.vault.process(this.file, (data) => { return data.slice(0, position.start.offset) + text + data.slice(position.end.offset + 1, data.length); }); } async insertLine(lineNumber, text) { this.plugin.app.vault.process(this.file, (data) => { const lines = splitIntoLines(data); insertAt(lines, text, lineNumber); return lines.join("\n"); }); } async getLine(lineNumber) { const data = await this.plugin.app.vault.cachedRead(this.file); const lines = splitIntoLines(data); return lines[lineNumber]; } async getRange(position) { const content = await this.plugin.app.vault.cachedRead(this.file); return content.slice(position.start.offset, position.end.offset); } }; function getIO(plugin, file, activeMarkdownView) { activeMarkdownView = activeMarkdownView != null ? activeMarkdownView : plugin.app.workspace.getActiveViewOfType(import_obsidian9.MarkdownView); if (activeMarkdownView && activeMarkdownView.file == file && isEditingView(activeMarkdownView)) { return new ActiveNoteIO(plugin, file, activeMarkdownView.editor); } else { return new NonActiveNoteIO(plugin, file); } } // src/utils/plugin.ts function resolveSettings(settings, plugin, currentFile) { const resolvedSettings = Object.assign({}, DEFAULT_SETTINGS); const ancestors = getAncestors(currentFile); for (const ancestor of ancestors) { Object.assign(resolvedSettings, plugin.settings[ancestor.path]); } Object.assign(resolvedSettings, settings); return resolvedSettings; } function getProfile(plugin, file) { const settings = resolveSettings(void 0, plugin, file); const profile = plugin.extraSettings.profiles[settings.profile]; return profile; } function staticifyEqNumber(plugin, file) { const page = plugin.indexManager.index.load(file.path); if (!MarkdownPage.isMarkdownPage(page)) { new import_obsidian10.Notice(`Failed to fetch the metadata of file ${file.path}.`); return; } const io = getIO(plugin, file); for (const block of page.$blocks.values()) { if (block instanceof EquationBlock && block.$printName !== null) { io.setRange( block.$pos, `$$ ${block.$mathText} \\tag{${block.$printName.slice(1, -1)}} $$` ); } } } async function insertBlockIdIfNotExist(plugin, targetFile, cache, block, length = 6) { if (!(cache == null ? void 0 : cache.sections)) return; if (block.$blockId) return { id: block.$blockId, lineAdded: 0 }; const id = generateBlockID(cache, length); const io = getIO(plugin, targetFile); await io.insertLine(block.$position.end + 1, "^" + id); await io.insertLine(block.$position.end + 1, ""); return { id, lineAdded: 2 }; } function increaseQuoteLevel(content) { let lines = content.split("\n"); lines = lines.map((line) => "> " + line); return lines.join("\n"); } function insertDisplayMath(editor) { var _a, _b, _c; const cursorPos = editor.getCursor(); const line = editor.getLine(cursorPos.line).trimStart(); const nonQuoteMatch = line.match(/[^>\s]/); const head = (_a = nonQuoteMatch == null ? void 0 : nonQuoteMatch.index) != null ? _a : line.length; const quoteLevel = (_c = (_b = line.slice(0, head).match(/>\s*/g)) == null ? void 0 : _b.length) != null ? _c : 0; let insert = "$$\n" + "> ".repeat(quoteLevel) + "\n" + "> ".repeat(quoteLevel) + "$$"; editor.replaceRange(insert, cursorPos); cursorPos.line += 1; cursorPos.ch = quoteLevel * 2; editor.setCursor(cursorPos); } async function rewriteTheoremCalloutFromV1ToV2(plugin, file) { const { app, indexManager } = plugin; const page = await indexManager.reload(file); await app.vault.process(file, (data) => convertTheoremCalloutFromV1ToV2(data, page)); } var convertTheoremCalloutFromV1ToV2 = (data, page) => { const lines = data.split("\n"); const newLines = [...lines]; let lineAdded = 0; for (const section of page.$sections) { for (const block of section.$blocks) { if (!TheoremCalloutBlock.isTheoremCalloutBlock(block)) continue; if (!block.$v1) continue; const newHeadLines = [generateTheoremCalloutFirstLine({ type: block.$settings.type, number: block.$settings.number, title: block.$settings.title })]; const legacySettings = block.$settings; if (legacySettings.label) newHeadLines.push(`> %% label: ${legacySettings.label} %%`); if (legacySettings.setAsNoteMathLink) newHeadLines.push(`> %% main %%`); newLines.splice(block.$position.start + lineAdded, 1, ...newHeadLines); lineAdded += newHeadLines.length - 1; } } return newLines.join("\n"); }; function generateTheoremCalloutFirstLine(config) { var _a; const metadata = config.number === "auto" ? "" : config.number === "" ? "|*" : `|${config.number}`; let firstLine = `> [!${config.type}${metadata}]${(_a = config.fold) != null ? _a : ""}${config.title ? " " + config.title : ""}`; if (config.label) firstLine += ` > %% label: ${config.label} %%`; return firstLine; } function insertTheoremCallout(editor, config) { const selection = editor.getSelection(); const cursorPos = editor.getCursor(); const firstLine = generateTheoremCalloutFirstLine(config); if (selection) { const nLines = splitIntoLines(selection).length; editor.replaceSelection(firstLine + "\n" + increaseQuoteLevel(selection)); cursorPos.line += nLines; } else { editor.replaceRange(firstLine + "\n> ", cursorPos); cursorPos.line += 1; } if (config.label) cursorPos.line += 1; cursorPos.ch = 2; editor.setCursor(cursorPos); } function isTheoremCallout(plugin, type) { if (plugin.extraSettings.excludeExampleCallout && type === "example") return false; return THEOREM_LIKE_ENV_IDs.includes(type) || THEOREM_LIKE_ENV_PREFIXES.includes(type) || type === "math"; } function insertProof(plugin, editor, context) { var _a; const settings = resolveSettings(void 0, plugin, (_a = context.file) != null ? _a : getFile(plugin.app)); const cursor = editor.getCursor(); editor.replaceRange(`\`${settings.beginProof}\` \`${settings.endProof}\``, cursor); editor.setCursor({ line: cursor.line + 1, ch: 0 }); } // src/settings/modals.ts var MathSettingModal = class extends import_obsidian12.Modal { constructor(app, plugin, callback) { super(app); this.plugin = plugin; this.callback = callback; } onClose() { this.contentEl.empty(); } addButton(buttonText) { const { contentEl } = this; new import_obsidian12.Setting(contentEl).addButton((btn) => { btn.setButtonText(buttonText).setCta().onClick(() => { this.close(); if (this.callback) { this.callback(this.settings); } }); btn.buttonEl.classList.add("insert-math-item-button"); }); const button = contentEl.querySelector(".insert-math-item-button"); const settingTextboxes = contentEl.querySelectorAll("input"); if (button) { settingTextboxes.forEach((textbox) => { this.plugin.registerDomEvent(textbox, "keypress", (event) => { if (event.key === "Enter") { button.click(); } }); }); } } }; var TheoremCalloutModal = class extends MathSettingModal { constructor(app, plugin, file, callback, buttonText, headerText, currentCalloutSettings) { super(app, plugin, callback); this.file = file; this.buttonText = buttonText; this.headerText = headerText; this.currentCalloutSettings = currentCalloutSettings; } resolveDefaultSettings(currentFile) { if (this.currentCalloutSettings === void 0) { this.defaultSettings = resolveSettings(this.currentCalloutSettings, this.plugin, currentFile); } else { this.defaultSettings = resolveSettings(this.currentCalloutSettings, this.plugin, currentFile); } } onOpen() { var _a; this.settings = (_a = this.currentCalloutSettings) != null ? _a : {}; const { contentEl } = this; contentEl.empty(); this.resolveDefaultSettings(this.file); if (this.headerText) { this.titleEl.setText(this.headerText); } const helper = new TheoremCalloutSettingsHelper(contentEl, this.settings, this.defaultSettings, this.plugin, this.file); helper.makeSettingPane(); new import_obsidian12.Setting(contentEl).setName("Open local settings for the current note").addButton((button) => { button.setButtonText("Open").onClick(() => { const modal = new ContextSettingModal( this.app, this.plugin, this.file, void 0, this ); modal.open(); }); }); this.addButton(this.buttonText); } }; var ContextSettingModal = class extends MathSettingModal { constructor(app, plugin, file, callback, parent) { super(app, plugin, callback); this.file = file; this.parent = parent; this.component = new import_obsidian12.Component(); } onOpen() { const { contentEl } = this; contentEl.empty(); this.component.load(); this.titleEl.setText("Local settings for " + this.file.path); contentEl.createDiv({ text: "If you want the change to apply to the entire vault, go to the plugin settings.", cls: ["setting-item-description", "math-booster-setting-item-description"] }); if (this.plugin.settings[this.file.path] === void 0) { this.plugin.settings[this.file.path] = {}; } const defaultSettings = this.file.parent ? resolveSettings(void 0, this.plugin, this.file.parent) : DEFAULT_SETTINGS; const contextSettingsHelper = new MathContextSettingsHelper(contentEl, this.plugin.settings[this.file.path], defaultSettings, this.plugin, this.file); this.component.addChild(contextSettingsHelper); this.addButton("Save"); } onClose() { super.onClose(); this.plugin.saveSettings(); this.plugin.indexManager.trigger("local-settings-updated", this.file); if (this.parent) { this.parent.open(); } this.component.unload(); } }; var FileSuggestModal = class extends import_obsidian12.FuzzySuggestModal { constructor(app, plugin) { super(app); this.plugin = plugin; } getItems() { return this.app.vault.getAllLoadedFiles().filter(this.filterCallback.bind(this)); } getItemText(file) { return file.path; } filterCallback(abstractFile) { if (abstractFile instanceof import_obsidian12.TFile && abstractFile.extension != "md") { return false; } if (abstractFile instanceof import_obsidian12.TFolder && abstractFile.isRoot()) { return false; } for (const path of this.plugin.excludedFiles) { const file = this.app.vault.getAbstractFileByPath(path); if (file && isEqualToOrChildOf(abstractFile, file)) { return false; } } return true; } }; var LocalContextSettingsSuggestModal = class extends FileSuggestModal { constructor(app, plugin, settingTab) { super(app, plugin); this.settingTab = settingTab; } onChooseItem(file, evt) { const modal = new ContextSettingModal(this.app, this.plugin, file); modal.open(); } }; var FileExcludeSuggestModal = class extends FileSuggestModal { constructor(app, plugin, manageModal) { super(app, plugin); this.manageModal = manageModal; } onChooseItem(file, evt) { this.plugin.excludedFiles.push(file.path); this.manageModal.newDisplay(); } filterCallback(abstractFile) { for (const path in this.plugin.settings) { if (path == abstractFile.path) { return false; } } return super.filterCallback(abstractFile); } }; var ExcludedFileManageModal = class extends import_obsidian12.Modal { constructor(app, plugin) { super(app); this.plugin = plugin; } onOpen() { this.newDisplay(); } async newDisplay() { await this.plugin.saveSettings(); const { contentEl } = this; contentEl.empty(); contentEl.createEl("h3", { text: "Excluded files/folders" }); new import_obsidian12.Setting(contentEl).setName("The files/folders in this list and their descendants will be excluded from suggestion for local settings.").addButton((btn) => { btn.setIcon("plus").onClick((event) => { new FileExcludeSuggestModal(this.app, this.plugin, this).open(); }); }); if (this.plugin.excludedFiles.length) { const list = contentEl.createEl("ul"); for (const path of this.plugin.excludedFiles) { const item = list.createEl("li").createDiv(); new import_obsidian12.Setting(item).setName(path).addExtraButton((btn) => { btn.setIcon("x").onClick(async () => { this.plugin.excludedFiles.remove(path); this.newDisplay(); await this.plugin.saveSettings(); }); }); } } } onClose() { const { contentEl } = this; contentEl.empty(); } }; // src/settings/tab.ts var MathSettingTab = class extends import_obsidian14.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; this.component = new import_obsidian14.Component(); } addRestoreDefaultsButton() { new import_obsidian14.Setting(this.containerEl).addButton((btn) => { btn.setButtonText("Restore defaults"); btn.onClick(async () => { Object.assign(this.plugin.settings[VAULT_ROOT], DEFAULT_SETTINGS); Object.assign(this.plugin.extraSettings, DEFAULT_EXTRA_SETTINGS); this.display(); }); }); } display() { const { containerEl } = this; containerEl.empty(); this.component.load(); containerEl.createEl("h4", { text: "Global" }); const root = this.app.vault.getRoot(); const globalHelper = new MathContextSettingsHelper( this.containerEl, this.plugin.settings[VAULT_ROOT], DEFAULT_SETTINGS, this.plugin, root ); this.component.addChild(globalHelper); const extraHelper = new ExtraSettingsHelper( this.containerEl, this.plugin.extraSettings, this.plugin.extraSettings, this.plugin, false, false ); this.component.addChild(extraHelper); const heading = extraHelper.addHeading("Equations - general"); const numberingHeading = this.containerEl.querySelector(".equation-heading"); this.containerEl.insertBefore( heading.settingEl, numberingHeading ); this.containerEl.insertAfter( extraHelper.settingRefs.enableMathPreviewInCalloutAndQuote.settingEl, heading.settingEl ); this.containerEl.insertAfter( extraHelper.settingRefs.enableProof.settingEl, this.containerEl.querySelector(".proof-heading") ); this.containerEl.insertAfter( extraHelper.settingRefs.showTheoremCalloutEditButton.settingEl, globalHelper.settingRefs.profile.settingEl ); this.containerEl.insertAfter( extraHelper.settingRefs.excludeExampleCallout.settingEl, globalHelper.settingRefs.profile.settingEl ); this.containerEl.insertBefore( extraHelper.settingRefs.foldDefault.settingEl, globalHelper.settingRefs.labelPrefix.settingEl ); this.containerEl.insertBefore( extraHelper.settingRefs.setOnlyTheoremAsMain.settingEl, globalHelper.settingRefs.labelPrefix.settingEl ); this.containerEl.insertBefore( extraHelper.settingRefs.setLabelInModal.settingEl, globalHelper.settingRefs.labelPrefix.settingEl ); this.containerEl.insertAfter( extraHelper.settingRefs.noteTitleInTheoremLink.settingEl, globalHelper.settingRefs.refFormat.settingEl ); this.containerEl.insertAfter( extraHelper.settingRefs.noteTitleInEquationLink.settingEl, globalHelper.settingRefs.eqRefSuffix.settingEl ); this.containerEl.insertBefore( globalHelper.settingRefs.insertSpace.settingEl, extraHelper.settingRefs.searchMethod.settingEl ); this.addRestoreDefaultsButton(); containerEl.createEl("h4", { text: "Local" }); new import_obsidian14.Setting(containerEl).setName("Local settings").setDesc('You can set up local (i.e. file-specific or folder-specific) settings, which have more precedence than the global settings. Local settings can be configured in various ways; here in the plugin settings, right-clicking in the file explorer, the "Open local settings for the current file" command, and the "Open local settings for the current file" button in the theorem callout settings pop-ups.').addButton((btn) => { btn.setButtonText("Search files & folders").onClick(() => { new LocalContextSettingsSuggestModal(this.app, this.plugin, this).open(); }); }); new import_obsidian14.Setting(containerEl).setName("Excluded files").setDesc("You can make your search results more visible by excluding certain files or folders.").addButton((btn) => { btn.setButtonText("Manage").onClick(() => { new ExcludedFileManageModal(this.app, this.plugin).open(); }); }); } async hide() { super.hide(); await this.plugin.saveSettings(); this.plugin.indexManager.trigger("global-settings-updated"); this.plugin.updateLinkAutocomplete(); this.component.unload(); } }; // src/cleveref.ts var CleverefProvider = class extends Provider { constructor(mathLinks, plugin) { super(mathLinks); this.plugin = plugin; this.app = plugin.app; this.index = plugin.indexManager.index; } provide(parsedLinktext, targetFile, targetSubpathResult) { var _a, _b; const { path, subpath } = parsedLinktext; if (targetFile === null) return null; const page = this.index.load(targetFile.path); if (!MarkdownPage.isMarkdownPage(page)) return null; if (!subpath) return (_a = page.$refName) != null ? _a : null; const processedPath = path ? (_b = page.$refName) != null ? _b : path : ""; if (targetSubpathResult === null) return null; if (targetSubpathResult.type === "block") { const block = page.$blocks.get(targetSubpathResult.block.id); if (MathBlock.isMathBlock(block)) { if (block.$display) return path && this.shouldShowNoteTitle(block) ? processedPath + " > " + block.$display : block.$display; if (block.$refName) return path && this.shouldShowNoteTitle(block) ? processedPath + " > " + block.$refName : block.$refName; } } else { if (path && page.$refName) { return processedPath + " > " + subpath; } } return null; } shouldShowNoteTitle(block) { if (TheoremCalloutBlock.isTheoremCalloutBlock(block)) return this.plugin.extraSettings.noteTitleInTheoremLink; if (EquationBlock.isEquationBlock(block)) return this.plugin.extraSettings.noteTitleInEquationLink; return true; } }; // src/theorem-callouts/renderer.ts var import_obsidian16 = require("obsidian"); // src/utils/render.ts var import_obsidian15 = require("obsidian"); function renderTextWithMath(source) { const elements = []; const mathPattern = /\$(.*?[^\s])\$/g; let result; let textFrom = 0; let textTo = 0; while ((result = mathPattern.exec(source)) !== null) { const mathString = result[1]; textTo = result.index; if (textTo > textFrom) { elements.push(source.slice(textFrom, textTo)); } textFrom = mathPattern.lastIndex; const mathJaxEl = (0, import_obsidian15.renderMath)(mathString, false); const mathSpan = createSpan({ cls: ["math", "math-inline", "is-loaded"] }); mathSpan.replaceChildren(mathJaxEl); elements.push(mathSpan); } if (textFrom < source.length) { elements.push(source.slice(textFrom)); } return elements; } async function renderMarkdown(markdown, sourcePath, component) { const el = createSpan(); await import_obsidian15.MarkdownRenderer.renderMarkdown(markdown, el, sourcePath, component); for (const child of el.children) { if (child.tagName == "P") { return child.childNodes; } } } // src/utils/parse.ts var THEOREM_CALLOUT_PATTERN = new RegExp( `> *\\[\\! *(?${THEOREM_LIKE_ENV_IDs.join("|")}|${THEOREM_LIKE_ENV_PREFIXES.join("|")}|math) *(\\|(?.*?))?\\](?[+-])?(? .*)?`, "i" ); function parseTheoremCalloutMetadata(metadata) { let number = metadata.trim(); if (!number) number = "auto"; else if (number === "*") number = ""; return number; } function readTheoremCalloutSettings(line, excludeExample = false) { var _a, _b, _c, _d, _e; const rawSettings = (_a = line.match(THEOREM_CALLOUT_PATTERN)) == null ? void 0 : _a.groups; if (!rawSettings) return; let type = rawSettings.type.trim().toLowerCase(); if (type === "math" && rawSettings.number) { const settings = JSON.parse(rawSettings.number); settings.legacy = true; return settings; } if (excludeExample && type === "example") return void 0; if (type.length <= 4) { type = THEOREM_LIKE_ENV_PREFIX_ID_MAP[type]; } const number = parseTheoremCalloutMetadata((_b = rawSettings.number) != null ? _b : ""); let title = (_c = rawSettings.title) == null ? void 0 : _c.trim(); if (title === "") title = void 0; const fold = (_e = (_d = rawSettings.fold) == null ? void 0 : _d.trim()) != null ? _e : ""; return { type, number, title, fold, legacy: false }; } function _readTheoremCalloutSettings(callout, excludeExample = false) { let type = callout.type; if (callout.type === "math" && callout.metadata) { const settings = JSON.parse(callout.metadata); settings.legacy = true; return settings; } if (excludeExample && callout.type === "example") return void 0; if (callout.type.length <= 4) { type = THEOREM_LIKE_ENV_PREFIX_ID_MAP[callout.type]; } const number = parseTheoremCalloutMetadata(callout.metadata); return { type, number, legacy: false }; } function parseLatexComment(line) { const match = line.match(/(?<!\\)%/); if ((match == null ? void 0 : match.index) !== void 0) { return { nonComment: line.substring(0, match.index), comment: line.substring(match.index + 1) }; } return { nonComment: line, comment: "" }; } // src/theorem-callouts/renderer.ts var createTheoremCalloutPostProcessor = (plugin) => async (element, context) => { var _a; const file = (_a = plugin.app.vault.getAbstractFileByPath(context.sourcePath)) != null ? _a : plugin.app.workspace.getActiveFile(); if (!(file instanceof import_obsidian16.TFile)) return null; const pdf = isPdfExport(element); let index = 0; for (const calloutEl of element.querySelectorAll(`.callout`)) { const type = calloutEl.getAttribute("data-callout").toLowerCase(); if (isTheoremCallout(plugin, type)) { if (pdf) { const settings = readSettingsFromEl(calloutEl); if ((settings == null ? void 0 : settings.number) === "auto") calloutEl.setAttribute("data-theorem-index", String(index++)); } const theoremCallout = new TheoremCalloutRenderer(calloutEl, context, file, plugin); context.addChild(theoremCallout); } } }; var TheoremCalloutRenderer = class _TheoremCalloutRenderer extends import_obsidian16.MarkdownRenderChild { constructor(containerEl, context, file, plugin) { super(containerEl); this.context = context; this.file = file; this.plugin = plugin; /** The info on which the last DOM update was based on. Used to reduce redundant updates. */ this.info = null; /** Set to the linktext when this theorem callout is inside an embed or a hover page preview. */ this.linktext = null; this.editButton = null; this.app = plugin.app; this.index = plugin.indexManager.index; this.addChild(this.observer = new MutationObservingChild(this.containerEl, (mutations) => { for (const mutation of mutations) { if (mutation.oldValue !== this.containerEl.getAttribute("data-theorem-index")) { this.update(); } } }, { attributeFilter: ["data-theorem-index"], attributeOldValue: true })); this.registerEvent(this.plugin.indexManager.on("index-updated", (file2) => { if (file2.path === this.file.path) { this.update(); } })); this.plugin.addChild(this); this.register(() => this.removeEditButton()); this.registerEvent(this.plugin.indexManager.on("global-settings-updated", () => { if (this.plugin.extraSettings.showTheoremCalloutEditButton) { this.addEditButton(); } else { this.removeEditButton(); } })); } getPage() { const page = this.plugin.indexManager.index.load(this.context.sourcePath); if (MarkdownPage.isMarkdownPage(page)) return page; return null; } isLivePreview() { return this.containerEl.closest("[src]") === null && this.containerEl.closest(".markdown-source-view.is-live-preview") !== null; } onload() { this.update(); } update() { const existingMainTitleEl = this.containerEl.querySelector(".theorem-callout-main-title"); if (existingMainTitleEl && this.isLivePreview()) { const settings = readSettingsFromEl(this.containerEl); if (!settings) return null; const livePreviewIndex = this.containerEl.getAttribute("data-theorem-index"); if (livePreviewIndex !== null) settings._index = +livePreviewIndex; const resolvedSettings = resolveSettings(settings, this.plugin, this.file); const newMainTitle = formatTitleWithoutSubtitle(this.plugin, this.file, resolvedSettings); existingMainTitleEl.setText(newMainTitle); this.info = null; return; } let block = this.getTheoremCalloutInfoFromIndex(); let info = block != null ? block : this.getTheoremCalloutInfoFromEl(); if (!info) { this.info = null; return; } ; if (!this.info || _TheoremCalloutRenderer.areDifferentInfo(info, this.info)) { this.renderTitle(info, existingMainTitleEl); this.addCssClasses(info); this.addEditButton(); this.info = info; } setTimeout(() => { if (this.containerEl.closest(".hover-popover.hover-editor")) return; const update2 = this.correctEmbedOrHoverPagePreview(block, info); if (update2) { block = update2.block; this.info = info = update2.info; } }); } correctEmbedOrHoverPagePreview(block, info) { var _a, _b; let linktext = (_a = this.containerEl.closest("[src]")) == null ? void 0 : _a.getAttribute("src"); if (!linktext) { const hoverEl = this.containerEl.closest(".hover-popover:not(.hover-editor)"); if (hoverEl) { linktext = this.plugin.lastHoverLinktext; if (!linktext) { const update2 = this.correctHoverWithoutSrc(); if (update2) { block = update2.block; this.info = info = update2.info; } return; } } } if (linktext) { this.linktext = linktext; const { file, subpathResult: result } = (_b = resolveLinktext(this.app, linktext, this.context.sourcePath)) != null ? _b : {}; if (!file || !result) return; if (result.type === "block") { if (result.block.id !== (block == null ? void 0 : block.blockId)) { const page = this.getPage(); if (!page) return; const _block = page.$blocks.get(result.block.id); if (TheoremCalloutBlock.isTheoremCalloutBlock(_block)) { info = block = this.blockToInfo(_block); if (!this.info || _TheoremCalloutRenderer.areDifferentInfo(info, this.info)) { this.renderTitle(info); this.addCssClasses(info); } } } } else if (result.type === "heading") { const _block = this.findTheoremCalloutBlock(result.start.line); if (_block) { info = block = this.blockToInfo(_block); if (!this.info || _TheoremCalloutRenderer.areDifferentInfo(info, this.info)) { this.renderTitle(info); this.addCssClasses(info); } } } } this.addEditButton(); return { block, info }; } correctHoverWithoutSrc() { const block = null; const info = this.getTheoremCalloutInfoFromEl(); if (!info) return; if (!this.info || _TheoremCalloutRenderer.areDifferentInfo(info, this.info)) { this.renderTitle(info); this.addCssClasses(info); } this.removeEditButton(); return { block, info }; } /** Find the corresponding TheoremCalloutBlock object from the index. */ findTheoremCalloutBlock(lineOffset = 0) { var _a; const page = this.getPage(); if (!page) return null; const info = this.context.getSectionInfo(this.containerEl); if (!info) return null; const block = (_a = page.getBlockByLineNumber(info.lineStart + lineOffset)) != null ? _a : page.getBlockByLineNumber(info.lineEnd + lineOffset); if (!TheoremCalloutBlock.isTheoremCalloutBlock(block)) return null; return block; } blockToInfo(block) { let theoremSubtitleEl = null; if (block.$theoremSubtitle) { theoremSubtitleEl = createSpan({ cls: "theorem-callout-subtitle" }); const subtitle = renderTextWithMath(`(${block.$theoremSubtitle})`); theoremSubtitleEl.replaceChildren(...subtitle); } return { theoremType: block.$theoremType, theoremMainTitle: block.$theoremMainTitle, theoremSubtitleEl, titleSuffix: block.$titleSuffix, blockId: block.$blockId }; } getTheoremCalloutInfoFromIndex() { const block = this.findTheoremCalloutBlock(); if (!block) return null; return this.blockToInfo(block); } // this method is expected to be called for live preview only getTheoremCalloutInfoFromEl() { const settings = readSettingsFromEl(this.containerEl); if (!settings) return null; const livePreviewIndex = this.containerEl.getAttribute("data-theorem-index"); if (livePreviewIndex !== null) settings._index = +livePreviewIndex; const resolvedSettings = resolveSettings(settings, this.plugin, this.file); let theoremSubtitleEl = this.containerEl.querySelector(".theorem-callout-subtitle"); if (theoremSubtitleEl === null) { const titleInnerEl = this.containerEl.querySelector(".callout-title-inner"); if (titleInnerEl == null ? void 0 : titleInnerEl.childNodes.length) { if (titleInnerEl.textContent !== capitalize(settings.type) && titleInnerEl.textContent !== capitalize(THEOREM_LIKE_ENV_ID_PREFIX_MAP[settings.type])) { theoremSubtitleEl = createSpan({ cls: "theorem-callout-subtitle" }); theoremSubtitleEl.replaceChildren("(", ...titleInnerEl.childNodes, ")"); } } } return { theoremType: settings.type, theoremMainTitle: formatTitleWithoutSubtitle(this.plugin, this.file, resolvedSettings), theoremSubtitleEl, titleSuffix: resolvedSettings.titleSuffix }; } renderTitle(info, existingMainTitleEl) { const titleInner = this.containerEl.querySelector(".callout-title-inner"); if (!titleInner) throw Error(`${this.plugin.manifest.name}: Failed to find the title element of a theorem callout.`); const newMainTitleEl = createSpan({ text: info.theoremMainTitle, cls: "theorem-callout-main-title" }); if (existingMainTitleEl) { existingMainTitleEl.replaceWith(newMainTitleEl); return; } const titleElements = [newMainTitleEl]; if (info.theoremSubtitleEl) { titleElements.push(" ", info.theoremSubtitleEl); } if (info.titleSuffix) { titleElements.push(info.titleSuffix); } titleInner.replaceChildren(...titleElements); } addCssClasses(info) { this.containerEl.classList.forEach((cls, _, list) => { if (cls.startsWith("theorem-callout")) list.remove(cls); }); this.containerEl.classList.add("theorem-callout"); const resolvedSettings = resolveSettings(void 0, this.plugin, this.file); const profile = this.plugin.extraSettings.profiles[resolvedSettings.profile]; for (const tag of profile.meta.tags) { this.containerEl.classList.add("theorem-callout-" + tag); } this.containerEl.classList.add("theorem-callout-" + info.theoremType); this.containerEl.toggleClass(`theorem-callout-${resolvedSettings.theoremCalloutStyle.toLowerCase()}`, resolvedSettings.theoremCalloutStyle != "Custom"); this.containerEl.toggleClass("theorem-callout-font-family-inherit", resolvedSettings.theoremCalloutStyle != "Custom" && resolvedSettings.theoremCalloutFontInherit); } removeEditButton() { if (this.editButton) { this.editButton.remove(); this.editButton = null; } } addEditButton() { if (!this.plugin.extraSettings.showTheoremCalloutEditButton) return; if (this.editButton) return; const button = new import_obsidian16.ExtraButtonComponent(this.containerEl).setIcon("settings-2").setTooltip("Edit theorem callout settings"); this.editButton = button.extraSettingsEl; this.editButton.addClass("theorem-callout-setting-button"); button.extraSettingsEl.addEventListener("click", async (ev) => { ev.stopPropagation(); const io = getIO(this.plugin, this.file); const lineNumber = this.getLineNumber(ev); if (lineNumber === null) return; const line = await io.getLine(lineNumber); new TheoremCalloutModal( this.app, this.plugin, this.file, async (settings) => { if (lineNumber !== void 0) { await io.setLine(lineNumber, generateTheoremCalloutFirstLine(settings)); } else { new import_obsidian16.Notice( `${this.plugin.manifest.name}: Could not find the line number to overwrite. Retry later.`, 5e3 ); } }, "Confirm", "Edit theorem callout settings", readTheoremCalloutSettings(line, this.plugin.extraSettings.excludeExampleCallout) ).open(); }); } getLineNumber(event) { var _a, _b, _c; let lineOffset = 0; if (this.linktext !== null) { const { subpathResult } = (_a = resolveLinktext(this.app, this.linktext, this.context.sourcePath)) != null ? _a : {}; if (subpathResult) lineOffset = subpathResult.start.line; } const info = this.context.getSectionInfo(this.containerEl); if (info) return lineOffset + info.lineStart; const cache = this.app.metadataCache.getFileCache(this.file); if (!cache) return null; const view = this.app.workspace.getActiveViewOfType(import_obsidian16.MarkdownView); if (!view) return null; if (isEditingView(view) && this.file.path === ((_b = view.file) == null ? void 0 : _b.path) && view.editor.cm) { let sec = (_c = getSectionCacheOfDOM(this.containerEl, "callout", view.editor.cm, cache)) != null ? _c : getSectionCacheFromMouseEvent(event, "callout", view.editor.cm, cache); if (sec) return sec.position.start.line; } return null; } static areDifferentInfo(info1, info2) { return info1.theoremMainTitle !== info2.theoremMainTitle; } }; function readSettingsFromEl(calloutEl) { var _a; let type = (_a = calloutEl.getAttribute("data-callout")) == null ? void 0 : _a.trim().toLowerCase(); if (type === void 0) return null; const metadata = calloutEl.getAttribute("data-callout-metadata"); if (metadata === null) return null; if (type === "math") { const settings = JSON.parse(metadata); delete settings["_index"]; return settings; } if (type.length <= 4) { type = THEOREM_LIKE_ENV_PREFIX_ID_MAP[type]; } const number = parseTheoremCalloutMetadata(metadata); const title = ""; return { type, number, title }; } // src/theorem-callouts/view-plugin.ts var import_view = require("@codemirror/view"); var createTheoremCalloutNumberingViewPlugin = (plugin) => import_view.ViewPlugin.fromClass( class { constructor(view) { this.view = view; this.index = plugin.indexManager.index; setTimeout(() => this._update(view)); } update(update2) { this._update(update2.view); } _update(view) { var _a; const infos = view.state.field(plugin.theoremCalloutsField); for (const calloutEl of view.contentDOM.querySelectorAll(".callout.theorem-callout")) { const pos = view.posAtDOM(calloutEl); const iter = infos.iter(pos); if (iter.from !== pos) continue; const index = (_a = iter.value) == null ? void 0 : _a.index; if (typeof index === "number") calloutEl.setAttribute("data-theorem-index", String(index)); else calloutEl.removeAttribute("data-theorem-index"); } } } ); // src/equations/reading-view.ts var import_obsidian19 = require("obsidian"); // src/equations/common.ts var import_obsidian18 = require("obsidian"); function replaceMathTag(displayMathEl, equation, settings) { if (equation.$manualTag) return; const taggedText = getMathTextWithTag(equation, settings.lineByLine); if (taggedText) { const mjxContainerEl = (0, import_obsidian18.renderMath)(taggedText, true); if (equation.$printName !== null) { displayMathEl.setAttribute("width", "full"); displayMathEl.style.cssText = mjxContainerEl.style.cssText; } else { displayMathEl.removeAttribute("width"); displayMathEl.removeAttribute("style"); } displayMathEl.replaceChildren(...mjxContainerEl.childNodes); } } function getMathTextWithTag(equation, lineByLine) { if (equation.$printName !== null) { const tagResult = equation.$printName.match(/^\((.*)\)$/); if (tagResult) { const tagContent = tagResult[1]; return insertTagInMathText(equation.$mathText, tagContent, lineByLine); } } return equation.$mathText; } function insertTagInMathText(text, tagContent, lineByLine) { if (!lineByLine) return text + `\\tag{${tagContent}}`; const alignResult = text.match(/^\s*\\begin\{align\}([\s\S]*)\\end\{align\}\s*$/); if (!alignResult) return text + `\\tag{${tagContent}}`; const envStack = []; let alignContent = alignResult[1].split("\n").map((line) => parseLatexComment(line).nonComment).join("\n"); let index = 1; alignContent = alignContent.split("\\\\").map((alignLine) => { const pattern = /\\(?<which>begin|end)\{(?<env>.*?)\}/g; let result; while (result = pattern.exec(alignLine)) { const { which, env } = result.groups; if (which === "begin") envStack.push(env); else if (envStack.last() === env) envStack.pop(); } if (envStack.length || !alignLine.trim() || alignLine.contains("\\nonumber")) return alignLine; return alignLine + `\\tag{${tagContent}-${index++}}`; }).join("\\\\"); if (index <= 2) return text + `\\tag{${tagContent}}`; return "\\begin{align}" + alignContent + "\\end{align}"; } // src/equations/reading-view.ts var createEquationNumberProcessor = (plugin) => async (el, ctx) => { if (isPdfExport(el)) preprocessForPdfExport(plugin, el, ctx); const sourceFile = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath); if (!(sourceFile instanceof import_obsidian19.TFile)) return; const mjxContainerElements = el.querySelectorAll('mjx-container.MathJax[display="true"]'); for (const mjxContainerEl of mjxContainerElements) { ctx.addChild( new EquationNumberRenderer(mjxContainerEl, plugin, sourceFile, ctx) ); } (0, import_obsidian19.finishRenderMath)(); }; function preprocessForPdfExport(plugin, el, ctx) { try { const topLevelMathDivs = el.querySelectorAll(':scope > div.math.math-block > mjx-container.MathJax[display="true"]'); const page = plugin.indexManager.index.getMarkdownPage(ctx.sourcePath); if (!page) { new import_obsidian19.Notice(`${plugin.manifest.name}: Failed to fetch the metadata for PDF export; equation numbers will not be displayed in the exported PDF.`); return; } let equationIndex = 0; for (const section of page.$sections) { for (const block of section.$blocks) { if (!EquationBlock.isEquationBlock(block)) continue; const div = topLevelMathDivs[equationIndex++]; if (block.$printName) div.setAttribute("data-equation-id", block.$id); } } if (topLevelMathDivs.length != equationIndex) { new import_obsidian19.Notice(`${plugin.manifest.name}: Something unexpected occured while preprocessing for PDF export. Equation numbers might not be displayed properly in the exported PDF.`); } } catch (err) { new import_obsidian19.Notice(`${plugin.manifest.name}: Something unexpected occured while preprocessing for PDF export. See the developer console for the details. Equation numbers might not be displayed properly in the exported PDF.`); console.error(err); } } var EquationNumberRenderer = class extends import_obsidian19.MarkdownRenderChild { constructor(containerEl, plugin, file, context) { super(containerEl); this.plugin = plugin; this.file = file; this.context = context; this.app = plugin.app; this.index = this.plugin.indexManager.index; this.registerEvent(this.plugin.indexManager.on("index-initialized", () => { setTimeout(() => this.update()); })); this.registerEvent(this.plugin.indexManager.on("index-updated", (file2) => { setTimeout(() => { if (file2.path === this.file.path) this.update(); }); })); } getEquationCache(lineOffset = 0) { var _a; const info = this.context.getSectionInfo(this.containerEl); const page = this.index.getMarkdownPage(this.file.path); if (!info || !page) return null; const block = (_a = page.getBlockByLineNumber(info.lineStart + lineOffset)) != null ? _a : page.getBlockByLineNumber(info.lineEnd + lineOffset); if (EquationBlock.isEquationBlock(block)) return block; return null; } async onload() { setTimeout(() => this.update()); } onunload() { (0, import_obsidian19.finishRenderMath)(); } update() { const id = this.containerEl.getAttribute("data-equation-id"); const equation = id ? this.index.getEquationBlock(id) : this.getEquationCacheCaringHoverAndEmbed(); if (!equation) return; const settings = resolveSettings(void 0, this.plugin, this.file); replaceMathTag(this.containerEl, equation, settings); } getEquationCacheCaringHoverAndEmbed() { var _a, _b; const equation = this.getEquationCache(); let linktext = (_a = this.containerEl.closest("[src]")) == null ? void 0 : _a.getAttribute("src"); if (!linktext) { const hoverEl = this.containerEl.closest(".hover-popover:not(.hover-editor)"); if (hoverEl) { linktext = this.plugin.lastHoverLinktext; } } if (linktext) { const { file, subpathResult } = (_b = resolveLinktext(this.app, linktext, this.context.sourcePath)) != null ? _b : {}; if (!file || !subpathResult) return null; const page = this.index.load(file.path); if (!MarkdownPage.isMarkdownPage(page)) return null; if (subpathResult.type === "block") { const block = page.$blocks.get(subpathResult.block.id); if (!EquationBlock.isEquationBlock(block)) return null; return block; } else { return this.getEquationCache(subpathResult.start.line); } } return equation; } }; // src/equations/live-preview.ts var import_state = require("@codemirror/state"); var import_view2 = require("@codemirror/view"); var import_obsidian21 = require("obsidian"); function createEquationNumberPlugin(plugin) { const { app, indexManager: { index } } = plugin; const forceUpdateEffect = import_state.StateEffect.define(); plugin.registerEvent(plugin.indexManager.on("index-updated", (file) => { app.workspace.iterateAllLeaves((leaf) => { var _a, _b; if (leaf.view instanceof import_obsidian21.MarkdownView && ((_a = leaf.view.file) == null ? void 0 : _a.path) === file.path && leaf.view.getMode() === "source") { (_b = leaf.view.editor.cm) == null ? void 0 : _b.dispatch({ effects: forceUpdateEffect.of(null) }); } }); })); return import_view2.ViewPlugin.fromClass(class { constructor(view) { this.file = view.state.field(import_obsidian21.editorInfoField).file; this.page = null; this.settings = DEFAULT_SETTINGS; if (this.file) { this.settings = resolveSettings(void 0, plugin, this.file); const page = index.load(this.file.path); if (MarkdownPage.isMarkdownPage(page)) { this.page = page; this.updateEquationNumber(view, this.page); } } } updateFile(state) { this.file = state.field(import_obsidian21.editorInfoField).file; if (this.file) this.settings = resolveSettings(void 0, plugin, this.file); } async updatePage(file) { const page = index.load(file.path); if (MarkdownPage.isMarkdownPage(page)) this.page = page; if (!this.page) { this.page = await plugin.indexManager.reload(file); } return this.page; } update(update2) { if (!this.file) this.updateFile(update2.state); if (!this.file) return; if (update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdateEffect)))) { this.settings = resolveSettings(void 0, plugin, this.file); this.updatePage(this.file).then((updatedPage) => this.updateEquationNumber(update2.view, updatedPage)); } else if (update2.geometryChanged) { if (this.page) this.updateEquationNumber(update2.view, this.page); else this.updatePage(this.file).then((updatedPage) => this.updateEquationNumber(update2.view, updatedPage)); } } async updateEquationNumber(view, page) { var _a, _b; const mjxContainerElements = view.contentDOM.querySelectorAll(':scope > .cm-embed-block.math > mjx-container.MathJax[display="true"]'); for (const mjxContainerEl of mjxContainerElements) { const mightBeClosingDollars = (_b = (_a = mjxContainerEl.parentElement) == null ? void 0 : _a.previousElementSibling) == null ? void 0 : _b.lastElementChild; const isBeingEdited = mightBeClosingDollars == null ? void 0 : mightBeClosingDollars.matches("span.cm-formatting-math-end"); if (isBeingEdited) continue; const pos = view.posAtDOM(mjxContainerEl); let block; try { const line = view.state.doc.lineAt(pos).number - 1; block = page.getBlockByLineNumber(line); } catch (err) { block = page.getBlockByOffset(pos); } if (!(block instanceof EquationBlock)) continue; if (mjxContainerEl.getAttribute("data-equation-print-name") !== block.$printName) { replaceMathTag(mjxContainerEl, block, this.settings); } if (block.$printName !== null) mjxContainerEl.setAttribute("data-equation-print-name", block.$printName); else mjxContainerEl.removeAttribute("data-equation-print-name"); } (0, import_obsidian21.finishRenderMath)(); } destroy() { (0, import_obsidian21.finishRenderMath)(); } }); } // src/render-math-in-callouts.ts var import_obsidian23 = require("obsidian"); var import_state3 = require("@codemirror/state"); var import_view3 = require("@codemirror/view"); var import_language2 = require("@codemirror/language"); // src/theorem-callouts/state-field.ts var import_state2 = require("@codemirror/state"); var import_language = require("@codemirror/language"); var import_obsidian22 = require("obsidian"); var CALLOUT = /HyperMD-callout_HyperMD-quote_HyperMD-quote-([1-9][0-9]*)/; var TheoremCalloutInfo = class extends import_state2.RangeValue { constructor(index) { super(); this.index = index; } }; var createTheoremCalloutsField = (plugin) => import_state2.StateField.define({ create(state) { if (!state.field(import_obsidian22.editorInfoField).file) return import_state2.RangeSet.empty; const ranges = getTheoremCalloutInfos(plugin, state, state.doc, 0, 0); return import_state2.RangeSet.of(ranges); }, update(value, tr) { if (!tr.state.field(import_obsidian22.editorInfoField).file) return import_state2.RangeSet.empty; if (!tr.docChanged) return value; let minChangedPosition = tr.newDoc.length - 1; const changeDesc = tr.changes.desc; changeDesc.iterChangedRanges((fromA, toA, fromB, toB) => { if (fromB < minChangedPosition) { minChangedPosition = fromB; } }); value = value.map(changeDesc); let init = 0; value.between(0, minChangedPosition, (from, to, info) => { if (to < minChangedPosition && info.index !== null) init = info.index + 1; }); const updatedRanges = getTheoremCalloutInfos(plugin, tr.state, tr.newDoc, minChangedPosition, init); return value.update({ add: updatedRanges, filter: () => false, filterFrom: minChangedPosition }); } }); function getTheoremCalloutInfos(plugin, state, doc, from, init) { var _a; const ranges = []; const tree = (_a = (0, import_language.ensureSyntaxTree)(state, doc.length)) != null ? _a : (0, import_language.syntaxTree)(state); let theoremIndex = init; tree.iterate({ from, to: doc.length, enter(node) { var _a2; if (node.name === "Document") return; if (((_a2 = node.node.parent) == null ? void 0 : _a2.name) !== "Document") return false; const text = doc.sliceString(node.from, node.to); const match = node.name.match(CALLOUT); if (!match) return false; const settings = readTheoremCalloutSettings(text, plugin.extraSettings.excludeExampleCallout); if (!settings) return false; const value = new TheoremCalloutInfo(settings.number === "auto" ? theoremIndex++ : null); const range = value.range(node.from, node.to); ranges.push(range); return false; } }); return ranges; } // src/render-math-in-callouts.ts var DISPLAY_MATH_BEGIN = "formatting_formatting-math_formatting-math-begin_keyword_math_math-block"; var INLINE_MATH_BEGIN = "formatting_formatting-math_formatting-math-begin_keyword_math"; var MATH_END = "formatting_formatting-math_formatting-math-end_keyword_math_math-"; var ERROR_MATH = "error_math"; var BLOCKQUOTE = /HyperMD-quote_HyperMD-quote-([1-9][0-9]*)/; var MathPreviewWidget = class extends import_view3.WidgetType { /** It is critical to pass a MathInfo object with a PRE-RENDERED MathJax element * for decreasing the number of the expensive renderMath() calls */ constructor(info) { super(); this.info = info; } toDOM(view) { this.info.mathEl.classList.add("math-booster-preview"); if (this.info.display) { const containerEl = createDiv({ cls: ["HyperMD-quote", "HyperMD-quote-1", "HyperMD-quote-lazy", "cm-line", "math-booster-preview-container"] }); containerEl.createEl("img", { cls: "cm-widgetBuffer", attr: { "aria-hidden": "true" } }); const cmEmbedBlockEl = containerEl.createDiv({ cls: ["math", "math-block", "cm-embed-block"], attr: { contenteditable: false } }); cmEmbedBlockEl.appendChild(this.info.mathEl); const editButton = new import_obsidian23.ExtraButtonComponent(cmEmbedBlockEl).setIcon("code-2").setTooltip("Edit this block"); editButton.extraSettingsEl.addEventListener("click", (ev) => { ev.stopPropagation(); view.dispatch({ selection: { anchor: this.info.from + 2, head: this.info.to - 2 } }); }); editButton.extraSettingsEl.classList.add("math-booster-preview-edit-button"); return containerEl; } return this.info.mathEl; } ignoreEvent(event) { return false; } }; var MathInfo = class extends import_state3.RangeValue { // whether this.overlap has changed in the last update constructor(mathText, display, from, to, insideCallout) { super(); this.mathText = mathText; this.display = display; this.from = from; this.to = to; this.insideCallout = insideCallout; // whether this math has an overlap with the main selection this.overlapChanged = true; this.render(); } async render() { this.mathEl = (0, import_obsidian23.renderMath)(this.mathText, this.display); } toWidget() { return new MathPreviewWidget(this); } toDecoration(which) { return import_view3.Decoration[which]({ widget: this.toWidget(), block: this.display, side: which == "widget" ? 1 : void 0 // To fix https://github.com/RyotaUshio/obsidian-latex-theorem-equation-referencer/issues/173 }); } }; function buildMathInfoSet(state) { const tree = (0, import_language2.syntaxTree)(state); const builder = new import_state3.RangeSetBuilder(); let from = -1; let mathText; let insideMath = false; let display; let quoteContentStart = 0; let insideCallout = false; let lastCalloutPos; tree.iterate({ enter(node) { var _a, _b, _c; if (((_a = node.node.parent) == null ? void 0 : _a.name) == "Document") { if (insideCallout) { if (node.from == lastCalloutPos + 1 && node.name.match(BLOCKQUOTE)) { lastCalloutPos = node.to; } else { insideCallout = false; } } if (node.name.match(CALLOUT)) { insideCallout = true; lastCalloutPos = node.to; } } if (nodeText(node, state).trim() == ">" && node.from < quoteContentStart) { return; } if (insideMath) { if (node.name == MATH_END) { builder.add( from, node.to, new MathInfo(mathText, display, from, node.to, insideCallout) ); insideMath = false; display = void 0; } else if (display && node.name == ERROR_MATH && nodeText(node, state) == "$") { builder.add( from, from + 2, // 2 = "$$".length new MathInfo(mathText, false, from, from + 2, insideCallout) ); insideMath = false; display = void 0; } else { const match = node.name.match(BLOCKQUOTE); if (match) { const quoteLevel = +match[1]; if (node.node.firstChild) { quoteContentStart = node.node.firstChild.to; mathText += (_b = nodeTextQuoteSymbolTrimmed(node.node.firstChild, state, quoteLevel)) != null ? _b : ""; } } else { if (node.name.contains("math")) { mathText += nodeText(node, state); } } } } else { const match = (_c = node.node.parent) == null ? void 0 : _c.name.match(BLOCKQUOTE); if (match) { if (node.name == DISPLAY_MATH_BEGIN) { insideMath = true; display = true; from = node.from; mathText = ""; } else if (node.name == INLINE_MATH_BEGIN) { insideMath = true; display = false; from = node.from; mathText = ""; } } } } }); if (insideMath && display && from >= 0) { builder.add( from, from + 2, // 2 = "$$".length new MathInfo("", false, from, from + 2, insideCallout) ); } return builder.finish(); } var mathPreviewInfoField = import_state3.StateField.define({ create(state) { return { mathInfoSet: buildMathInfoSet(state), // RangeSet.empty, isInCalloutsOrQuotes: false, hasOverlappingMath: false, hasOverlappingDisplayMath: false, rerendered: false }; }, update(prev, transaction) { const isInCalloutsOrQuotes = isInBlockquoteOrCallout(transaction.state); const range = transaction.state.selection.main; const cursor = prev.mathInfoSet.iter(); let hasOverlappingMath = false; let hasOverlappingDisplayMath = false; while (cursor.value) { if (range.from <= cursor.to && cursor.from <= range.to) { hasOverlappingMath = true; if (cursor.value.display) { hasOverlappingDisplayMath = true; } break; } cursor.next(); } let mathInfoSet; let rerendered = false; if (!prev.mathInfoSet.size) { mathInfoSet = buildMathInfoSet(transaction.state); rerendered = true; } else if (isInCalloutsOrQuotes) { if (!prev.isInCalloutsOrQuotes || prev.hasOverlappingMath && !hasOverlappingMath) { mathInfoSet = buildMathInfoSet(transaction.state); rerendered = true; } else if (transaction.docChanged) { if (involvesDollar(transaction) || hasOverlappingDisplayMath) { mathInfoSet = buildMathInfoSet(transaction.state); rerendered = true; } else { mathInfoSet = prev.mathInfoSet.map(transaction.changes.desc); } } else { mathInfoSet = prev.mathInfoSet; } } else { mathInfoSet = prev.mathInfoSet; } const oldCursor = prev.mathInfoSet.iter(); const newCursor = mathInfoSet.iter(); while (oldCursor.value && newCursor.value) { const oldOverlap = oldCursor.value.overlap; const newOverlap = hasOverlap(range, newCursor); newCursor.value.overlapChanged = oldOverlap != newOverlap; newCursor.value.overlap = newOverlap; oldCursor.next(); newCursor.next(); } return { mathInfoSet, isInCalloutsOrQuotes, hasOverlappingMath, hasOverlappingDisplayMath, rerendered }; } }); var inlineMathPreview = import_view3.ViewPlugin.fromClass( class { constructor(view) { this.buildDecorations(view); } update(update2) { if (update2.docChanged || update2.viewportChanged || overlapStateChanged(update2.state)) { this.buildDecorations(update2.view); } } buildDecorations(view) { if (isSourceMode(view.state)) { this.decorations = import_view3.Decoration.none; return; } const field = view.state.field(mathPreviewInfoField); if (!field.isInCalloutsOrQuotes) { this.decorations = import_view3.Decoration.none; return; } const range = view.state.selection.main; const builder = new import_state3.RangeSetBuilder(); for (const { from, to } of view.visibleRanges) { field.mathInfoSet.between( from, to, (from2, to2, value) => { if (value.insideCallout && !value.display && !hasOverlap(range, { from: from2, to: to2 })) { builder.add( from2, to2, value.toDecoration("replace") ); } } ); } this.decorations = builder.finish(); } }, { decorations: (instance) => instance.decorations } ); var displayMathPreviewForCallout = import_state3.StateField.define({ create(state) { return import_view3.Decoration.none; }, update(value, transaction) { const builder = new import_state3.RangeSetBuilder(); const range = transaction.state.selection.main; const field = transaction.state.field(mathPreviewInfoField); if (isSourceMode(transaction.state)) { return import_view3.Decoration.none; } if (!transaction.docChanged && !overlapStateChanged(transaction.state)) { return value; } field.mathInfoSet.between( 0, transaction.state.doc.length, (from, to, value2) => { if (value2.display) { if (!hasOverlap(range, { from, to })) { if (value2.insideCallout && field.isInCalloutsOrQuotes) { builder.add(from, to, value2.toDecoration("replace")); } } else { builder.add(to, to, value2.toDecoration("widget")); } } } ); return builder.finish(); }, provide(field) { return import_view3.EditorView.decorations.from(field); } }); var hideDisplayMathPreviewInQuote = import_view3.ViewPlugin.fromClass( class { constructor(view) { this.impl(view); } update(update2) { this.impl(update2.view); } impl(view) { const field = view.state.field(mathPreviewInfoField); for (const vanillaObsidianMathPreview of view.contentDOM.querySelectorAll( `.cm-line:not(.HyperMD-quote) .math.math-block.cm-embed-block > mjx-container.MathJax[display="true"]:not(.math-booster-preview)` )) { const pos = view.posAtDOM(vanillaObsidianMathPreview); if (rangeSetSome(field.mathInfoSet, (info) => info.from - 1 <= pos && pos <= info.to)) { const cmWidgetBuffer = vanillaObsidianMathPreview.previousSibling; if (cmWidgetBuffer instanceof HTMLElement && cmWidgetBuffer.matches(".cm-widget-buffer")) { cmWidgetBuffer.remove(); } vanillaObsidianMathPreview.remove(); } } } } ); function isInBlockquoteOrCallout(state) { const range = state.selection.main; const tree = (0, import_language2.syntaxTree)(state); let foundQuote = false; tree.iterate({ enter(node) { const match = node.name.match(BLOCKQUOTE); if (match) { if (node.from <= range.to && range.from <= node.to) { foundQuote = true; return false; } } } }); return foundQuote; } function involvesDollar(transaction) { let ret = false; transaction.changes.iterChanges( (fromA, toA, fromB, toB, inserted) => { const textBefore = transaction.startState.sliceDoc(fromA, toA); const dollarEdited = textBefore.contains("$"); const dollarInserted = inserted.toString().contains("$"); ret = ret || dollarEdited || dollarInserted; } ); return ret; } function overlapStateChanged(state) { const infoSet = state.field(mathPreviewInfoField).mathInfoSet; return rangeSetSome(infoSet, (info) => info.overlapChanged); } var displayMathPreviewForQuote = import_view3.ViewPlugin.fromClass( class { constructor(view) { this.impl(view); } update(update2) { this.impl(update2.view); } impl(view) { if (isSourceMode(view.state)) { return; } const range = view.state.selection.main; const field = view.state.field(mathPreviewInfoField); let mjxInQuote = Array.from( view.contentDOM.querySelectorAll( '.HyperMD-quote.cm-line .math.math-block.cm-embed-block > mjx-container.MathJax:has( > mjx-math[display="true"]):not(.math-booster-preview)' ) ); const mjxPositions = mjxInQuote.map((el) => view.posAtDOM(el)); for (const { from, to } of view.visibleRanges) { field.mathInfoSet.between( from, to, (from2, to2, value) => { if (!hasOverlap(range, { from: from2, to: to2 })) { if (value.display && !value.insideCallout) { for (let i = 0; i < mjxInQuote.length; i++) { const mjx = mjxInQuote[i]; const pos = mjxPositions[i]; if (from2 - 1 <= pos && pos <= to2) { value.mathEl.classList.add("math-booster-preview"); mjx.replaceWith(value.mathEl); } } } } } ); } } } ); // src/index/manager.ts var import_obsidian25 = require("obsidian"); // src/index/utils/deferred.ts function deferred() { let resolve; let reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); const deferred2 = promise; deferred2.resolve = resolve; deferred2.reject = reject; return deferred2; } // src/index/web-worker/importer.ts var import_obsidian24 = require("obsidian"); // src/index/web-worker/transferable.ts var Transferable; ((Transferable2) => { function transferable(value2) { if (value2 instanceof Map) { let copied = /* @__PURE__ */ new Map(); for (let [key, val] of value2.entries()) copied.set(transferable(key), transferable(val)); return copied; } else if (value2 instanceof Set) { let copied = /* @__PURE__ */ new Set(); for (let val of value2) copied.add(transferable(val)); return copied; } let wrapped = Literals.wrapValue(value2); if (wrapped === void 0) throw Error("Unrecognized transferable value: " + value2); switch (wrapped.type) { case "null": case "number": case "string": case "boolean": return wrapped.value; case "array": return wrapped.value.map((v) => transferable(v)); case "link": return { "$transfer-type": "link", value: transferable(wrapped.value.toObject()) }; case "object": let result = {}; for (let key of Object.getOwnPropertyNames(wrapped.value)) result[key] = transferable(wrapped.value[key]); return result; } } Transferable2.transferable = transferable; function value(transferable2) { if (transferable2 === null) { return null; } else if (transferable2 === void 0) { return void 0; } else if (transferable2 instanceof Map) { let real = /* @__PURE__ */ new Map(); for (let [key, val] of transferable2.entries()) real.set(value(key), value(val)); return real; } else if (transferable2 instanceof Set) { let real = /* @__PURE__ */ new Set(); for (let val of transferable2) real.add(value(val)); return real; } else if (Array.isArray(transferable2)) { return transferable2.map((v) => value(v)); } else if (typeof transferable2 === "object") { if ("$transfer-type" in transferable2) { switch (transferable2["$transfer-type"]) { case "link": return Link.fromObject(value(transferable2.value)); default: throw Error(`Unrecognized transfer type '${transferable2["$transfer-type"]}'`); } } let result = {}; for (let [key, val] of Object.entries(transferable2)) result[key] = value(val); return result; } return transferable2; } Transferable2.value = value; })(Transferable || (Transferable = {})); // inline-worker:__inline-worker function inlineWorker(scriptText) { let blob = new Blob([scriptText], { type: "text/javascript" }); let url = URL.createObjectURL(blob); let worker = new Worker(url); URL.revokeObjectURL(url); return worker; } // src/index/web-worker/importer.worker.ts function Worker2() { return inlineWorker('var de=Object.create;var te=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,ve=Object.prototype.hasOwnProperty;var ke=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var be=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of me(e))!ve.call(r,i)&&i!==t&&te(r,i,{get:()=>e[i],enumerable:!(n=ye(e,i))||n.enumerable});return r};var xe=(r,e,t)=>(t=r!=null?de(ge(r)):{},be(e||!r||!r.__esModule?te(t,"default",{value:r,enumerable:!0}):t,r));var ae=ke(L=>{"use strict";var we=L&&L.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,i){n.__proto__=i}||function(n,i){for(var o in i)Object.prototype.hasOwnProperty.call(i,o)&&(n[o]=i[o])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}}();Object.defineProperty(L,"__esModule",{value:!0});L.EmptyBTree=L.asSet=L.simpleComparator=L.defaultComparator=void 0;function ie(r,e){if(Number.isFinite(r)&&Number.isFinite(e))return r-e;var t=typeof r,n=typeof e;if(t!==n)return t<n?-1:1;if(t==="object"){if(r===null)return e===null?0:-1;if(e===null)return 1;if(r=r.valueOf(),e=e.valueOf(),t=typeof r,n=typeof e,t!==n)return t<n?-1:1}return r<e?-1:r>e?1:r===e?0:Number.isNaN(r)?Number.isNaN(e)?0:-1:Number.isNaN(e)?1:Array.isArray(r)?0:Number.NaN}L.defaultComparator=ie;function Ee(r,e){return r>e?1:r<e?-1:0}L.simpleComparator=Ee;var P=function(){function r(e,t,n){this._root=J,this._size=0,this._maxNodeSize=n>=4?Math.min(n,256):32,this._compare=t||ie,e&&this.setPairs(e)}return Object.defineProperty(r.prototype,"size",{get:function(){return this._size},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"length",{get:function(){return this._size},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"isEmpty",{get:function(){return this._size===0},enumerable:!1,configurable:!0}),r.prototype.clear=function(){this._root=J,this._size=0},r.prototype.forEach=function(e,t){var n=this;return t!==void 0&&(e=e.bind(t)),this.forEachPair(function(i,o){return e(o,i,n)})},r.prototype.forEachPair=function(e,t){var n=this.minKey(),i=this.maxKey();return this.forRange(n,i,!0,e,t)},r.prototype.get=function(e,t){return this._root.get(e,t,this)},r.prototype.set=function(e,t,n){this._root.isShared&&(this._root=this._root.clone());var i=this._root.set(e,t,n,this);return i===!0||i===!1?i:(this._root=new Oe([this._root,i]),!0)},r.prototype.has=function(e){return this.forRange(e,e,!0,void 0)!==0},r.prototype.delete=function(e){return this.editRange(e,e,!0,ne)!==0},r.prototype.with=function(e,t,n){var i=this.clone();return i.set(e,t,n)||n?i:this},r.prototype.withPairs=function(e,t){var n=this.clone();return n.setPairs(e,t)!==0||t?n:this},r.prototype.withKeys=function(e,t){for(var n=this.clone(),i=!1,o=0;o<e.length;o++)i=n.set(e[o],void 0,!1)||i;return t&&!i?this:n},r.prototype.without=function(e,t){return this.withoutRange(e,e,!0,t)},r.prototype.withoutKeys=function(e,t){var n=this.clone();return n.deleteKeys(e)||!t?n:this},r.prototype.withoutRange=function(e,t,n,i){var o=this.clone();return o.deleteRange(e,t,n)===0&&i?this:o},r.prototype.filter=function(e,t){var n=this.greedyClone(),i;return n.editAll(function(o,s,a){if(!e(o,s,a))return i=se}),!i&&t?this:n},r.prototype.mapValues=function(e){var t={},n=this.greedyClone();return n.editAll(function(i,o,s){return t.value=e(o,i,s),t}),n},r.prototype.reduce=function(e,t){for(var n=0,i=t,o=this.entries(this.minKey(),j),s;!(s=o.next()).done;)i=e(i,s.value,n++,this);return i},r.prototype.entries=function(e,t){var n=this.findPath(e);if(n===void 0)return N();var i=n.nodequeue,o=n.nodeindex,s=n.leaf,a=t!==void 0?1:0,f=e===void 0?-1:s.indexOf(e,0,this._compare)-1;return N(function(){e:for(;;)switch(a){case 0:if(++f<s.keys.length)return{done:!1,value:[s.keys[f],s.values[f]]};a=2;continue;case 1:if(++f<s.keys.length)return t[0]=s.keys[f],t[1]=s.values[f],{done:!1,value:t};a=2;case 2:for(var l=-1;;){if(++l>=i.length){a=3;continue e}if(++o[l]<i[l].length)break}for(;l>0;l--)i[l-1]=i[l][o[l]].children,o[l-1]=0;s=i[0][o[0]],f=-1,a=t!==void 0?1:0;continue;case 3:return{done:!0,value:void 0}}})},r.prototype.entriesReversed=function(e,t,n){if(e===void 0&&(e=this.maxKey(),n=void 0,e===void 0))return N();var i=this.findPath(e)||this.findPath(this.maxKey()),o=i.nodequeue,s=i.nodeindex,a=i.leaf;O(!o[0]||a===o[0][s[0]],"wat!");var f=a.indexOf(e,0,this._compare);!n&&f<a.keys.length&&this._compare(a.keys[f],e)<=0&&f++;var l=t!==void 0?1:0;return N(function(){e:for(;;)switch(l){case 0:if(--f>=0)return{done:!1,value:[a.keys[f],a.values[f]]};l=2;continue;case 1:if(--f>=0)return t[0]=a.keys[f],t[1]=a.values[f],{done:!1,value:t};l=2;case 2:for(var c=-1;;){if(++c>=o.length){l=3;continue e}if(--s[c]>=0)break}for(;c>0;c--)o[c-1]=o[c][s[c]].children,s[c-1]=o[c-1].length-1;a=o[0][s[0]],f=a.keys.length,l=t!==void 0?1:0;continue;case 3:return{done:!0,value:void 0}}})},r.prototype.findPath=function(e){var t=this._root,n,i;if(t.isLeaf)n=re,i=re;else{n=[],i=[];for(var o=0;!t.isLeaf;o++){if(n[o]=t.children,i[o]=e===void 0?0:t.indexOf(e,0,this._compare),i[o]>=n[o].length)return;t=n[o][i[o]]}n.reverse(),i.reverse()}return{nodequeue:n,nodeindex:i,leaf:t}},r.prototype.diffAgainst=function(e,t,n,i){if(e._compare!==this._compare)throw new Error("Tree comparators are not the same.");if(this.isEmpty||e.isEmpty)return this.isEmpty&&e.isEmpty?void 0:this.isEmpty?n===void 0?void 0:r.stepToEnd(r.makeDiffCursor(e),n):t===void 0?void 0:r.stepToEnd(r.makeDiffCursor(this),t);for(var o=this._compare,s=r.makeDiffCursor(this),a=r.makeDiffCursor(e),f=!0,l=!0,c=r.compare(s,a,o);f&&l;){var p=r.compare(s,a,o),v=s.leaf,d=s.internalSpine,x=s.levelIndices,k=a.leaf,y=a.internalSpine,u=a.levelIndices;if(v||k){if(c!==0){if(p===0){if(v&&k&&i){var h=v.values[x[x.length-1]],b=k.values[u[u.length-1]];if(!Object.is(h,b)){var m=i(s.currentKey,h,b);if(m&&m.break)return m.break}}}else if(p>0){if(k&&n){var g=k.values[u[u.length-1]],m=n(a.currentKey,g);if(m&&m.break)return m.break}}else if(t&&v&&c!==0){var h=v.values[x[x.length-1]],m=t(s.currentKey,h);if(m&&m.break)return m.break}}}else if(!v&&!k&&p===0){var E=d.length-1,T=y.length-1,_=d[E][x[E]],S=y[T][u[T]];if(S===_){c=0,f=r.step(s,!0),l=r.step(a,!0);continue}}c=p,p<0?f=r.step(s):l=r.step(a)}if(f&&t)return r.finishCursorWalk(s,a,o,t);if(l&&n)return r.finishCursorWalk(a,s,o,n)},r.finishCursorWalk=function(e,t,n,i){var o=r.compare(e,t,n);if(o===0){if(!r.step(e))return}else o<0&&O(!1,"cursor walk terminated early");return r.stepToEnd(e,i)},r.stepToEnd=function(e,t){for(var n=!0;n;){var i=e.leaf,o=e.levelIndices,s=e.currentKey;if(i){var a=i.values[o[o.length-1]],f=t(s,a);if(f&&f.break)return f.break}n=r.step(e)}},r.makeDiffCursor=function(e){var t=e._root,n=e.height;return{height:n,internalSpine:[[t]],levelIndices:[0],leaf:void 0,currentKey:t.maxKey()}},r.step=function(e,t){var n=e.internalSpine,i=e.levelIndices,o=e.leaf;if(t===!0||o){var s=i.length;if(t===!0||i[s-1]===0){var a=n.length;if(a===0)return!1;for(var f=a-1,l=f;l>=0;){if(i[l]>0)return l<s-1&&(e.leaf=void 0,i.pop()),l<f&&(e.internalSpine=n.slice(0,l+1)),e.currentKey=n[l][--i[l]].maxKey(),!0;l--}return!1}else{var c=--i[s-1];return e.currentKey=o.keys[c],!0}}else{var p=n.length,v=p-1,d=n[v][i[v]];if(d.isLeaf){e.leaf=d;var c=i[p]=d.values.length-1;e.currentKey=d.keys[c]}else{var x=d.children;n[p]=x;var k=x.length-1;i[p]=k,e.currentKey=x[k].maxKey()}return!0}},r.compare=function(e,t,n){var i=e.height,o=e.currentKey,s=e.levelIndices,a=t.height,f=t.currentKey,l=t.levelIndices,c=n(f,o);if(c!==0)return c;var p=i<a?i:a,v=s.length-(i-p),d=l.length-(a-p);return v-d},r.prototype.keys=function(e){var t=this.entries(e,j);return N(function(){var n=t.next();return n.value&&(n.value=n.value[0]),n})},r.prototype.values=function(e){var t=this.entries(e,j);return N(function(){var n=t.next();return n.value&&(n.value=n.value[1]),n})},Object.defineProperty(r.prototype,"maxNodeSize",{get:function(){return this._maxNodeSize},enumerable:!1,configurable:!0}),r.prototype.minKey=function(){return this._root.minKey()},r.prototype.maxKey=function(){return this._root.maxKey()},r.prototype.clone=function(){this._root.isShared=!0;var e=new r(void 0,this._compare,this._maxNodeSize);return e._root=this._root,e._size=this._size,e},r.prototype.greedyClone=function(e){var t=new r(void 0,this._compare,this._maxNodeSize);return t._root=this._root.greedyClone(e),t._size=this._size,t},r.prototype.toArray=function(e){e===void 0&&(e=2147483647);var t=this.minKey(),n=this.maxKey();return t!==void 0?this.getRange(t,n,!0,e):[]},r.prototype.keysArray=function(){var e=[];return this._root.forRange(this.minKey(),this.maxKey(),!0,!1,this,0,function(t,n){e.push(t)}),e},r.prototype.valuesArray=function(){var e=[];return this._root.forRange(this.minKey(),this.maxKey(),!0,!1,this,0,function(t,n){e.push(n)}),e},r.prototype.toString=function(){return this.toArray().toString()},r.prototype.setIfNotPresent=function(e,t){return this.set(e,t,!1)},r.prototype.nextHigherPair=function(e,t){return t=t||[],e===void 0?this._root.minPair(t):this._root.getPairOrNextHigher(e,this._compare,!1,t)},r.prototype.nextHigherKey=function(e){var t=this.nextHigherPair(e,j);return t&&t[0]},r.prototype.nextLowerPair=function(e,t){return t=t||[],e===void 0?this._root.maxPair(t):this._root.getPairOrNextLower(e,this._compare,!1,t)},r.prototype.nextLowerKey=function(e){var t=this.nextLowerPair(e,j);return t&&t[0]},r.prototype.getPairOrNextLower=function(e,t){return this._root.getPairOrNextLower(e,this._compare,!0,t||[])},r.prototype.getPairOrNextHigher=function(e,t){return this._root.getPairOrNextHigher(e,this._compare,!0,t||[])},r.prototype.changeIfPresent=function(e,t){return this.editRange(e,e,!0,function(n,i){return{value:t}})!==0},r.prototype.getRange=function(e,t,n,i){i===void 0&&(i=67108863);var o=[];return this._root.forRange(e,t,n,!1,this,0,function(s,a){return o.push([s,a]),o.length>i?Le:void 0}),o},r.prototype.setPairs=function(e,t){for(var n=0,i=0;i<e.length;i++)this.set(e[i][0],e[i][1],t)&&n++;return n},r.prototype.forRange=function(e,t,n,i,o){var s=this._root.forRange(e,t,n,!1,this,o||0,i);return typeof s=="number"?s:s.break},r.prototype.editRange=function(e,t,n,i,o){var s=this._root;s.isShared&&(this._root=s=s.clone());try{var a=s.forRange(e,t,n,!0,this,o||0,i);return typeof a=="number"?a:a.break}finally{for(var f=void 0;s.keys.length<=1&&!s.isLeaf;)f||(f=s.isShared),this._root=s=s.keys.length===0?J:s.children[0];f&&(s.isShared=!0)}},r.prototype.editAll=function(e,t){return this.editRange(this.minKey(),this.maxKey(),!0,e,t)},r.prototype.deleteRange=function(e,t,n){return this.editRange(e,t,n,ne)},r.prototype.deleteKeys=function(e){for(var t=0,n=0;t<e.length;t++)this.delete(e[t])&&n++;return n},Object.defineProperty(r.prototype,"height",{get:function(){for(var e=this._root,t=-1;e;)t++,e=e.isLeaf?void 0:e.children[0];return t},enumerable:!1,configurable:!0}),r.prototype.freeze=function(){var e=this;e.clear=e.set=e.editRange=function(){throw new Error("Attempted to modify a frozen BTree")}},r.prototype.unfreeze=function(){delete this.clear,delete this.set,delete this.editRange},Object.defineProperty(r.prototype,"isFrozen",{get:function(){return this.hasOwnProperty("editRange")},enumerable:!1,configurable:!0}),r.prototype.checkValid=function(){var e=this._root.checkValid(0,this,0);O(e===this.size,"size mismatch: counted ",e,"but stored",this.size)},r}();L.default=P;function Te(r){return r}L.asSet=Te;Symbol&&Symbol.iterator&&(P.prototype[Symbol.iterator]=P.prototype.entries);P.prototype.where=P.prototype.filter;P.prototype.setRange=P.prototype.setPairs;P.prototype.add=P.prototype.set;function N(r){r===void 0&&(r=function(){return{done:!0,value:void 0}});var e={next:r};return Symbol&&Symbol.iterator&&(e[Symbol.iterator]=function(){return this}),e}var oe=function(){function r(e,t){e===void 0&&(e=[]),this.keys=e,this.values=t||w,this.isShared=void 0}return Object.defineProperty(r.prototype,"isLeaf",{get:function(){return this.children===void 0},enumerable:!1,configurable:!0}),r.prototype.maxKey=function(){return this.keys[this.keys.length-1]},r.prototype.indexOf=function(e,t,n){for(var i=this.keys,o=0,s=i.length,a=s>>1;o<s;){var f=n(i[a],e);if(f<0)o=a+1;else if(f>0)s=a;else{if(f===0)return a;if(e===e)return i.length;throw new Error("BTree: NaN was used as a key")}a=o+s>>1}return a^t},r.prototype.minKey=function(){return this.keys[0]},r.prototype.minPair=function(e){if(this.keys.length!==0)return e[0]=this.keys[0],e[1]=this.values[0],e},r.prototype.maxPair=function(e){if(this.keys.length!==0){var t=this.keys.length-1;return e[0]=this.keys[t],e[1]=this.values[t],e}},r.prototype.clone=function(){var e=this.values;return new r(this.keys.slice(0),e===w?e:e.slice(0))},r.prototype.greedyClone=function(e){return this.isShared&&!e?this:this.clone()},r.prototype.get=function(e,t,n){var i=this.indexOf(e,-1,n._compare);return i<0?t:this.values[i]},r.prototype.getPairOrNextLower=function(e,t,n,i){var o=this.indexOf(e,-1,t),s=o<0?~o-1:n?o:o-1;if(s>=0)return i[0]=this.keys[s],i[1]=this.values[s],i},r.prototype.getPairOrNextHigher=function(e,t,n,i){var o=this.indexOf(e,-1,t),s=o<0?~o:n?o:o+1,a=this.keys;if(s<a.length)return i[0]=a[s],i[1]=this.values[s],i},r.prototype.checkValid=function(e,t,n){var i=this.keys.length,o=this.values.length;return O(this.values===w?i<=o:i===o,"keys/values length mismatch: depth",e,"with lengths",i,o,"and baseIndex",n),O(e==0||i>0,"empty leaf at depth",e,"and baseIndex",n),i},r.prototype.set=function(e,t,n,i){var o=this.indexOf(e,-1,i._compare);if(o<0){if(o=~o,i._size++,this.keys.length<i._maxNodeSize)return this.insertInLeaf(o,e,t,i);var s=this.splitOffRightSide(),a=this;return o>this.keys.length&&(o-=this.keys.length,a=s),a.insertInLeaf(o,e,t,i),s}else return n!==!1&&(t!==void 0&&this.reifyValues(),this.keys[o]=e,this.values[o]=t),!1},r.prototype.reifyValues=function(){return this.values===w?this.values=this.values.slice(0,this.keys.length):this.values},r.prototype.insertInLeaf=function(e,t,n,i){if(this.keys.splice(e,0,t),this.values===w){for(;w.length<i._maxNodeSize;)w.push(void 0);if(n===void 0)return!0;this.values=w.slice(0,this.keys.length-1)}return this.values.splice(e,0,n),!0},r.prototype.takeFromRight=function(e){var t=this.values;e.values===w?t!==w&&t.push(void 0):(t=this.reifyValues(),t.push(e.values.shift())),this.keys.push(e.keys.shift())},r.prototype.takeFromLeft=function(e){var t=this.values;e.values===w?t!==w&&t.unshift(void 0):(t=this.reifyValues(),t.unshift(e.values.pop())),this.keys.unshift(e.keys.pop())},r.prototype.splitOffRightSide=function(){var e=this.keys.length>>1,t=this.keys.splice(e),n=this.values===w?w:this.values.splice(e);return new r(t,n)},r.prototype.forRange=function(e,t,n,i,o,s,a){var f=o._compare,l,c;if(t===e){if(!n||(c=(l=this.indexOf(e,-1,f))+1,l<0))return s}else l=this.indexOf(e,0,f),c=this.indexOf(t,-1,f),c<0?c=~c:n===!0&&c++;var p=this.keys,v=this.values;if(a!==void 0)for(var d=l;d<c;d++){var x=p[d],k=a(x,v[d],s++);if(k!==void 0){if(i===!0){if(x!==p[d]||this.isShared===!0)throw new Error("BTree illegally changed or cloned in editRange");k.delete?(this.keys.splice(d,1),this.values!==w&&this.values.splice(d,1),o._size--,d--,c--):k.hasOwnProperty("value")&&(v[d]=k.value)}if(k.break!==void 0)return k}}else s+=c-l;return s},r.prototype.mergeSibling=function(e,t){if(this.keys.push.apply(this.keys,e.keys),this.values===w){if(e.values===w)return;this.values=this.values.slice(0,this.keys.length)}this.values.push.apply(this.values,e.reifyValues())},r}(),Oe=function(r){we(e,r);function e(t,n){var i=this;if(!n){n=[];for(var o=0;o<t.length;o++)n[o]=t[o].maxKey()}return i=r.call(this,n)||this,i.children=t,i}return e.prototype.clone=function(){for(var t=this.children.slice(0),n=0;n<t.length;n++)t[n].isShared=!0;return new e(t,this.keys.slice(0))},e.prototype.greedyClone=function(t){if(this.isShared&&!t)return this;for(var n=new e(this.children.slice(0),this.keys.slice(0)),i=0;i<n.children.length;i++)n.children[i]=n.children[i].greedyClone(t);return n},e.prototype.minKey=function(){return this.children[0].minKey()},e.prototype.minPair=function(t){return this.children[0].minPair(t)},e.prototype.maxPair=function(t){return this.children[this.children.length-1].maxPair(t)},e.prototype.get=function(t,n,i){var o=this.indexOf(t,0,i._compare),s=this.children;return o<s.length?s[o].get(t,n,i):void 0},e.prototype.getPairOrNextLower=function(t,n,i,o){var s=this.indexOf(t,0,n),a=this.children;if(s>=a.length)return this.maxPair(o);var f=a[s].getPairOrNextLower(t,n,i,o);return f===void 0&&s>0?a[s-1].maxPair(o):f},e.prototype.getPairOrNextHigher=function(t,n,i,o){var s=this.indexOf(t,0,n),a=this.children,f=a.length;if(!(s>=f)){var l=a[s].getPairOrNextHigher(t,n,i,o);return l===void 0&&s<f-1?a[s+1].minPair(o):l}},e.prototype.checkValid=function(t,n,i){var o=this.keys.length,s=this.children.length;O(o===s,"keys/children length mismatch: depth",t,"lengths",o,s,"baseIndex",i),O(o>1||t>0,"internal node has length",o,"at depth",t,"baseIndex",i);for(var a=0,f=this.children,l=this.keys,c=0,p=0;p<s;p++)a+=f[p].checkValid(t+1,n,i+a),c+=f[p].keys.length,O(a>=c,"wtf",i),O(p===0||f[p-1].constructor===f[p].constructor,"type mismatch, baseIndex:",i),f[p].maxKey()!=l[p]&&O(!1,"keys[",p,"] =",l[p],"is wrong, should be ",f[p].maxKey(),"at depth",t,"baseIndex",i),p===0||n._compare(l[p-1],l[p])<0||O(!1,"sort violation at depth",t,"index",p,"keys",l[p-1],l[p]);var v=c===0;return(v||c>n.maxNodeSize*s)&&O(!1,v?"too few":"too many","children (",c,a,") at depth",t,"maxNodeSize:",n.maxNodeSize,"children.length:",s,"baseIndex:",i),a},e.prototype.set=function(t,n,i,o){var s=this.children,a=o._maxNodeSize,f=o._compare,l=Math.min(this.indexOf(t,0,f),s.length-1),c=s[l];if(c.isShared&&(s[l]=c=c.clone()),c.keys.length>=a){var p;l>0&&(p=s[l-1]).keys.length<a&&f(c.keys[0],t)<0?(p.isShared&&(s[l-1]=p=p.clone()),p.takeFromRight(c),this.keys[l-1]=p.maxKey()):(p=s[l+1])!==void 0&&p.keys.length<a&&f(c.maxKey(),t)<0&&(p.isShared&&(s[l+1]=p=p.clone()),p.takeFromLeft(c),this.keys[l]=s[l].maxKey())}var v=c.set(t,n,i,o);if(v===!1)return!1;if(this.keys[l]=c.maxKey(),v===!0)return!0;if(this.keys.length<a)return this.insert(l+1,v),!0;var d=this.splitOffRightSide(),x=this;return f(v.maxKey(),this.maxKey())>0&&(x=d,l-=this.keys.length),x.insert(l+1,v),d},e.prototype.insert=function(t,n){this.children.splice(t,0,n),this.keys.splice(t,0,n.maxKey())},e.prototype.splitOffRightSide=function(){var t=this.children.length>>1;return new e(this.children.splice(t),this.keys.splice(t))},e.prototype.takeFromRight=function(t){this.keys.push(t.keys.shift()),this.children.push(t.children.shift())},e.prototype.takeFromLeft=function(t){this.keys.unshift(t.keys.pop()),this.children.unshift(t.children.pop())},e.prototype.forRange=function(t,n,i,o,s,a,f){var l=s._compare,c=this.keys,p=this.children,v=this.indexOf(t,0,l),d=v,x=Math.min(n===t?v:this.indexOf(n,0,l),c.length-1);if(o){if(d<=x)try{for(;d<=x;d++){p[d].isShared&&(p[d]=p[d].clone());var k=p[d].forRange(t,n,i,o,s,a,f);if(c[d]=p[d].maxKey(),typeof k!="number")return k;a=k}}finally{var y=s._maxNodeSize>>1;for(v>0&&v--,d=x;d>=v;d--)p[d].keys.length<=y&&(p[d].keys.length!==0?this.tryMerge(d,s._maxNodeSize):(c.splice(d,1),p.splice(d,1)));p.length!==0&&p[0].keys.length===0&&O(!1,"emptiness bug")}}else for(;d<=x;d++){var k=p[d].forRange(t,n,i,o,s,a,f);if(typeof k!="number")return k;a=k}return a},e.prototype.tryMerge=function(t,n){var i=this.children;return t>=0&&t+1<i.length&&i[t].keys.length+i[t+1].keys.length<=n?(i[t].isShared&&(i[t]=i[t].clone()),i[t].mergeSibling(i[t+1],n),i.splice(t+1,1),this.keys.splice(t+1,1),this.keys[t]=i[t].maxKey(),!0):!1},e.prototype.mergeSibling=function(t,n){var i=this.keys.length;this.keys.push.apply(this.keys,t.keys);var o=t.children;if(this.children.push.apply(this.children,o),t.isShared&&!this.isShared)for(var s=0;s<o.length;s++)o[s].isShared=!0;this.tryMerge(i-1,n)},e}(oe),w=[],se={delete:!0},ne=function(){return se},Le={break:!0},J=function(){var r=new oe;return r.isShared=!0,r}(),re=[],j=[];function O(r){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];if(!r)throw e.unshift("B+ tree"),new Error(e.join(" "))}L.EmptyBTree=function(){var r=new P;return r.freeze(),r}()});function M(r){return r.includes("/")&&(r=r.substring(r.lastIndexOf("/")+1)),r.endsWith(".md")&&(r=r.substring(0,r.length-3)),r}var $=class r{static file(e,t=!1,n){return new r({path:e,embed:t,display:n,subpath:void 0,type:"file"})}static infer(e,t=!1,n){if(e.includes("#^")){let i=e.split("#^");return r.block(i[0],i[1],t,n)}else if(e.includes("#")){let i=e.split("#");return r.header(i[0],i[1],t,n)}else return r.file(e,t,n)}static header(e,t,n,i){return new r({path:e,embed:n,display:i,subpath:t,type:"header"})}static block(e,t,n,i){return new r({path:e,embed:n,display:i,subpath:t,type:"block"})}static fromObject(e){return new r(e)}static parseInner(e){let[t,n]=_e(e);return r.infer(t,!1,n)}constructor(e){Object.assign(this,e)}withPath(e){return new r(Object.assign({},this,{path:e}))}withDisplay(e){return new r(Object.assign({},this,{display:e}))}withEmbed(e){return this.embed==e?this:new r(Object.assign({},this,{embed:e}))}withHeader(e){return r.header(this.path,e,this.embed,this.display)}withBlock(e){return r.block(this.path,e,this.embed,this.display)}equals(e){return e==null||e==null?!1:this.path==e.path&&this.type==e.type&&this.subpath==e.subpath}toString(){return this.markdown()}toObject(){return{path:this.path,type:this.type,subpath:this.subpath,display:this.display,embed:this.embed}}toFile(){return r.file(this.path,this.embed,this.display)}toEmbed(){return this.withEmbed(!0)}fromEmbed(){return this.withEmbed(!1)}markdown(){let e=(this.embed?"!":"")+"[["+this.obsidianLink();return e+=this.displayOrDefault(),e+="]]",e}displayOrDefault(){if(this.display)return this.display;{let e=M(this.path);return(this.type=="header"||this.type=="block")&&(e+=" > "+this.subpath),e}}obsidianLink(){var t,n;let e=this.path.replace("|","\\\\|");return this.type=="header"?e+"#"+((t=this.subpath)==null?void 0:t.replace("|","\\\\|")):this.type=="block"?e+"#^"+((n=this.subpath)==null?void 0:n.replace("|","\\\\|")):e}fileName(){return M(this.path)}};function _e(r){let e=-1;for(;(e=r.indexOf("|",e+1))>=0;)if(!(e>0&&r[e-1]=="\\\\"))return[r.substring(0,e).replace(/\\\\\\|/g,"|"),r.substring(e+1)];return[r.replace(/\\\\\\|/g,"|"),void 0]}var W=xe(ae());var C=["axiom","definition","lemma","proposition","theorem","corollary","claim","assumption","example","exercise","conjecture","hypothesis","remark"],Se=["proof","solution"],De=[...C,...Se],I=["axm","def","lem","prp","thm","cor","clm","asm","exm","exr","cnj","hyp","rmk"],Pe={};C.forEach((r,e)=>{Pe[r]={id:r,prefix:I[e]}});var q={};I.forEach((r,e)=>{q[r]=C[e]});var Re={};C.forEach((r,e)=>{Re[r]=I[e]});var $e=new RegExp(`> *\\\\[\\\\! *(?<type>${C.join("|")}|${I.join("|")}|math) *(\\\\|(?<number>.*?))?\\\\](?<fold>[+-])?(?<title> .*)?`,"i");function Ne(r){let e=r.trim();return e?e==="*"&&(e=""):e="auto",e}function ue(r,e=!1){var a,f,l,c,p;let t=(a=r.match($e))==null?void 0:a.groups;if(!t)return;let n=t.type.trim().toLowerCase();if(n==="math"&&t.number){let v=JSON.parse(t.number);return v.legacy=!0,v}if(e&&n==="example")return;n.length<=4&&(n=q[n]);let i=Ne((f=t.number)!=null?f:""),o=(l=t.title)==null?void 0:l.trim();o===""&&(o=void 0);let s=(p=(c=t.fold)==null?void 0:c.trim())!=null?p:"";return{type:n,number:i,title:o,fold:s,legacy:!1}}function le(r){var e,t;return(t=(e=r.match(/\\$\\$([\\s\\S]*)\\$\\$/))==null?void 0:e[1].trim())!=null?t:r}function fe(r){let e=r.match(new RegExp("(?<!\\\\\\\\)%"));return(e==null?void 0:e.index)!==void 0?{nonComment:r.substring(0,e.index),comment:r.substring(e.index+1)}:{nonComment:r,comment:""}}function pe(r){let e=[],t=/%%([\\s\\S]*?)%%/g,n;for(;n=t.exec(r);)for(let i of n[1].split(`\n`))i=i.trim(),i&&e.push(i);return e}function G(r){var t;let e=(t=r.match(new RegExp("^(?<key>.*?):(?<value>.*)$")))==null?void 0:t.groups;return e?{[e.key.trim()]:e.value.trim()}:null}function ce(r,e,t,n){var v,d,x,k;let i=e.split(`\n`),o=!i.some(y=>y.trim()!==""),s=(v=t.headings)!=null?v:[];s.sort((y,u)=>y.position.start.line-u.position.start.line);let a=new W.default(void 0,(y,u)=>y-u);for(let y=0;y<s.length;y++){let u=s[y],h=u.position.start.line,b=y==s.length-1?i.length-1:s[y+1].position.start.line-1;a.set(h,{$ordinal:y+1,$title:u.heading,$level:u.level,$position:{start:h,end:b},$blocks:[],$links:[]})}let f=a.getPairOrNextHigher(0);if(!f&&!o||f&&!Ce(i,0,f[1].$position.start)){let y=f?f[1].$position.start-1:i.length;a.set(0,{$ordinal:0,$title:M(r),$level:1,$position:{start:0,end:y},$blocks:[],$links:[]})}let l=new W.default(void 0,(y,u)=>y-u),c=1;for(let y of t.sections||[]){if(y.type==="heading")continue;let u=y.position.start.line,h=y.position.end.line,b=null,m=!1;if(y.type==="callout"){let g=ue(i[u],n);b=g!=null?g:null,m=!!(g!=null&&g.legacy)}if(y.type==="math"){let g=le(Ke(e,y)),E=g.match(/\\\\tag\\{(.*)\\}/),T={};for(let _ of g.split(`\n`)){let{comment:S}=fe(_);S&&Object.assign(T,G(S))}l.set(u,{$ordinal:c++,$position:{start:u,end:h},$pos:y.position,$links:[],$blockId:y.id,$manualTag:(d=E==null?void 0:E[1])!=null?d:null,$mathText:g,$type:"equation",$label:T.label,$display:T.display})}else if(b){let g=i.slice(u+1,h+1).join(`\n`),E=pe(g),T={};for(let _ of E)_.startsWith(">")&&(_=_.slice(1).trim()),_&&(_==="main"?T.main="true":Object.assign(T,G(_)));l.set(u,{$ordinal:c++,$position:{start:u,end:h},$pos:y.position,$links:[],$blockId:y.id,$settings:b,$type:"theorem",$label:T.label,$display:T.display,$main:T.main==="true",$v1:m})}else l.set(u,{$ordinal:c++,$position:{start:u,end:h},$pos:y.position,$links:[],$blockId:y.id,$type:y.type})}for(let y of l.values()){let u=a.getPairOrNextLower(y.$position.start);u&&u[1].$position.end>=y.$position.end&&u[1].$blocks.push(y)}let p=[];for(let y of(x=t.links)!=null?x:[]){let u=$.infer(y.link),h=y.position.start.line;F(p,u);let b=a.getPairOrNextLower(h);b&&b[1].$position.end>=h&&F(b[1].$links,u);let m=l.getPairOrNextLower(h);m&&m[1].$position.end>=h&&F(m[1].$links,u);let g=l.getPairOrNextHigher(h);g&&g[1].$position.end>=h&&F(g[1].$links,u)}for(let y of(k=t.frontmatterLinks)!=null?k:[]){let u=$.infer(y.link,!1,y.displayText);F(p,u)}return{$path:r,$links:p,$sections:a.valuesArray(),$extension:"md",$position:{start:0,end:i.length}}}function Ce(r,e,t){for(let n=e;n<t;n++)if(r[n].trim()!=="")return!1;return!0}function F(r,e){r.find(t=>t.equals(e))||r.push(e)}function Ke(r,e){return r.slice(e.position.start.offset,e.position.end.offset)}var z;(y=>{y.DEFAULT_TO_STRING={nullRepresentation:"-",dateFormat:"MMMM dd, yyyy",dateTimeFormat:"h:mm a - MMMM dd, yyyy"};function e(u,h=y.DEFAULT_TO_STRING,b=!1){let m=t(u);if(!m)return h.nullRepresentation;switch(m.type){case"null":return h.nullRepresentation;case"string":return m.value;case"number":case"boolean":return""+m.value;case"link":return m.value.markdown();case"function":return"<function>";case"array":let g="";return b&&(g+="["),g+=m.value.map(E=>e(E,h,!0)).join(", "),b&&(g+="]"),g;case"object":return"{ "+Object.entries(m.value).map(E=>E[0]+": "+e(E[1],h,!0)).join(", ")+" }"}}y.toString=e;function t(u){return c(u)?{type:"null",value:u}:l(u)?{type:"number",value:u}:f(u)?{type:"string",value:u}:v(u)?{type:"boolean",value:u}:p(u)?{type:"array",value:u}:d(u)?{type:"link",value:u}:k(u)?{type:"function",value:u}:x(u)?{type:"object",value:u}:void 0}y.wrapValue=t;function n(u,h){if(x(u)){let b={};for(let[m,g]of Object.entries(u))b[m]=n(g,h);return b}else if(p(u)){let b=[];for(let m of u)b.push(n(m,h));return b}else return h(u)}y.mapLeaves=n;function i(u,h,b){var E,T;if(u===void 0&&(u=null),h===void 0&&(h=null),u===null&&h===null)return 0;if(u===null)return-1;if(h===null)return 1;let m=t(u),g=t(h);if(m===void 0&&g===void 0)return 0;if(m===void 0)return-1;if(g===void 0)return 1;if(m.type!=g.type)return m.type.localeCompare(g.type);if(m.value===g.value)return 0;switch(m.type){case"string":return m.value.localeCompare(g.value);case"number":return m.value<g.value?-1:m.value==g.value?0:1;case"null":return 0;case"boolean":return m.value==g.value?0:m.value?1:-1;case"link":let _=m.value,S=g.value,A=b!=null?b:R=>R,U=A(_.path).localeCompare(A(S.path));if(U!=0)return U;let X=_.type.localeCompare(S.type);return X!=0?X:_.subpath&&!S.subpath?1:!_.subpath&&S.subpath?-1:!_.subpath&&!S.subpath?0:((E=_.subpath)!=null?E:"").localeCompare((T=S.subpath)!=null?T:"");case"array":let V=m.value,H=g.value;for(let R=0;R<Math.min(V.length,H.length);R++){let K=i(V[R],H[R]);if(K!=0)return K}return V.length-H.length;case"object":let Y=m.value,Q=g.value,B=Array.from(Object.keys(Y)),Z=Array.from(Object.keys(Q));B.sort(),Z.sort();let ee=i(B,Z);if(ee!=0)return ee;for(let R of B){let K=i(Y[R],Q[R]);if(K!=0)return K}return 0;case"function":return 0}}y.compare=i;function o(u){var h;return(h=t(u))==null?void 0:h.type}y.typeOf=o;function s(u){let h=t(u);if(!h)return!1;switch(h.type){case"number":return h.value!=0;case"string":return h.value.length>0;case"boolean":return h.value;case"link":return!!h.value.path;case"object":return Object.keys(h.value).length>0;case"array":return h.value.length>0;case"null":return!1;case"function":return!0}}y.isTruthy=s;function a(u){if(u==null)return u;if(y.isArray(u))return[].concat(u.map(h=>a(h)));if(y.isObject(u)){let h={};for(let[b,m]of Object.entries(u))h[b]=a(m);return h}else return u}y.deepCopy=a;function f(u){return typeof u=="string"}y.isString=f;function l(u){return typeof u=="number"}y.isNumber=l;function c(u){return u==null}y.isNull=c;function p(u){return Array.isArray(u)}y.isArray=p;function v(u){return typeof u=="boolean"}y.isBoolean=v;function d(u){return u instanceof $}y.isLink=d;function x(u){return u!==void 0&&typeof u=="object"&&!p(u)&&!d(u)&&!c(u)}y.isObject=x;function k(u){return typeof u=="function"}y.isFunction=k})(z||(z={}));var he;(n=>{function r(i){return z.isObject(i)&&Object.keys(i).length==2&&"key"in i&&"rows"in i}n.isElementGroup=r;function e(i){for(let o of i)if(!r(o))return!1;return!0}n.isGrouping=e;function t(i){if(e(i)){let o=0;for(let s of i)o+=t(s.rows);return o}else return i.length}n.count=t})(he||(he={}));var D;(t=>{function r(n){if(n instanceof Map){let o=new Map;for(let[s,a]of n.entries())o.set(r(s),r(a));return o}else if(n instanceof Set){let o=new Set;for(let s of n)o.add(r(s));return o}let i=z.wrapValue(n);if(i===void 0)throw Error("Unrecognized transferable value: "+n);switch(i.type){case"null":case"number":case"string":case"boolean":return i.value;case"array":return i.value.map(s=>r(s));case"link":return{"$transfer-type":"link",value:r(i.value.toObject())};case"object":let o={};for(let s of Object.getOwnPropertyNames(i.value))o[s]=r(i.value[s]);return o}}t.transferable=r;function e(n){if(n===null)return null;if(n===void 0)return;if(n instanceof Map){let i=new Map;for(let[o,s]of n.entries())i.set(e(o),e(s));return i}else if(n instanceof Set){let i=new Set;for(let o of n)i.add(e(o));return i}else{if(Array.isArray(n))return n.map(i=>e(i));if(typeof n=="object"){if("$transfer-type"in n)switch(n["$transfer-type"]){case"link":return $.fromObject(e(n.value));default:throw Error(`Unrecognized transfer type \'${n["$transfer-type"]}\'`)}let i={};for(let[o,s]of Object.entries(n))i[o]=e(s);return i}}return n}t.value=e})(D||(D={}));onmessage=r=>{try{let e=D.value(r.data);if(e.type==="markdown"){let t=ce(e.path,e.contents,e.metadata,e.excludeExampleCallout);postMessage(D.transferable({type:"markdown",result:t}))}else postMessage({$error:"Unsupported import method."})}catch(e){postMessage({$error:e.message})}};\n'); } // src/index/web-worker/importer.ts var DEFAULT_THROTTLE = { workers: 2, utilization: 0.75 }; var MathImporter = class extends import_obsidian24.Component { constructor(plugin, vault, metadataCache, throttle) { super(); this.plugin = plugin; this.vault = vault; this.metadataCache = metadataCache; this.workers = /* @__PURE__ */ new Map(); this.shutdown = false; this.nextWorkerId = 0; this.throttle = throttle != null ? throttle : () => DEFAULT_THROTTLE; this.queue = []; this.outstanding = /* @__PURE__ */ new Map(); } /** * Queue the given file for importing. Multiple import requests for the same file in a short time period will be de-bounced * and all be resolved by a single actual file reload. */ import(file) { let existing = this.outstanding.get(file.path); if (existing) return existing; let promise = new Promise((resolve, reject) => { this.queue.push([file, resolve, reject]); }); this.outstanding.set(file.path, promise); this.schedule(); return promise; } /** Reset any active throttles on the importer (such as if the utilization changes). */ unthrottle() { for (let worker of this.workers.values()) { worker.availableAt = Date.now(); } } /** Poll from the queue and execute if there is an available worker. */ schedule() { if (this.queue.length == 0 || this.shutdown) return; const worker = this.availableWorker(); if (!worker) return; const [file, resolve, reject] = this.queue.shift(); worker.active = [file, resolve, reject, Date.now()]; this.vault.cachedRead(file).then( (c) => worker.worker.postMessage( Transferable.transferable({ type: "markdown", path: file.path, contents: c, metadata: this.metadataCache.getFileCache(file), excludeExampleCallout: this.plugin.extraSettings.excludeExampleCallout }) ) ); } /** Finish the parsing of a file, potentially queueing a new file. */ finish(worker, data) { let [file, resolve, reject] = worker.active; if ("$error" in data) reject(data["$error"]); else resolve(data); this.outstanding.delete(file.path); if (this.workers.size > this.throttle().workers) { this.workers.delete(worker.id); terminate(worker); } else { const now = Date.now(); const start = worker.active[3]; const throttle = Math.max(0.1, this.throttle().utilization) - 1; const delay = (now - start) * throttle; worker.active = void 0; if (delay <= 1e-10) { worker.availableAt = now; this.schedule(); } else { worker.availableAt = now + delay; setTimeout(this.schedule.bind(this), delay); } } } /** Obtain an available worker, returning undefined if one does not exist. */ availableWorker() { const now = Date.now(); for (let worker of this.workers.values()) { if (!worker.active && worker.availableAt <= now) { return worker; } } if (this.workers.size < this.throttle().workers) { let worker = this.newWorker(); this.workers.set(worker.id, worker); return worker; } return void 0; } /** Create a new worker bound to this importer. */ newWorker() { let worker = { id: this.nextWorkerId++, availableAt: Date.now(), worker: new Worker2() }; worker.worker.onmessage = (evt) => this.finish(worker, Transferable.value(evt.data)); return worker; } /** Reject all outstanding promises and close all workers on close. */ onunload() { for (let worker of this.workers.values()) { terminate(worker); } for (let [_file, _success, reject] of this.queue) { reject("Terminated"); } this.shutdown = true; } }; function terminate(worker) { worker.worker.terminate(); if (worker.active) worker.active[2]("Terminated"); worker.active = void 0; } // src/index/storage/inverted.ts var _InvertedIndex = class _InvertedIndex { constructor() { this.inverted = /* @__PURE__ */ new Map(); } /** Set the key to the given values. */ set(key, values) { for (let value of values) { if (!this.inverted.has(value)) this.inverted.set(value, /* @__PURE__ */ new Set()); this.inverted.get(value).add(key); } } /** Get all keys that map to the given value. */ get(value) { var _a; return (_a = this.inverted.get(value)) != null ? _a : _InvertedIndex.EMPTY_SET; } /** Delete a key from the set of associated values. */ delete(key, values) { for (let value of values) { const set = this.inverted.get(value); if (set) { set.delete(key); } if (set && set.size == 0) { this.inverted.delete(value); } } } clear() { this.inverted.clear(); } }; _InvertedIndex.EMPTY_SET = /* @__PURE__ */ new Set(); var InvertedIndex = _InvertedIndex; // src/index/math-index.ts var MathIndex = class { /** Tracks the existence of fields (indexed by normalized key name). */ // private fields: Map<string, FieldIndex>; // irrelevant because we are not going to search/query /** * Quick searches for objects in folders. This index only tracks top-level objects - it is expanded recursively to * find child objects. */ // private folder: FolderIndex; // irrelevant because we are not going to search/query constructor(plugin, vault, metadataCache) { this.plugin = plugin; this.vault = vault; this.metadataCache = metadataCache; this.revision = 0; this.ids = /* @__PURE__ */ new Set(); this.objects = /* @__PURE__ */ new Map(); this.children = /* @__PURE__ */ new Map(); this.types = new InvertedIndex(); this.links = new InvertedIndex(); } /** Update the revision of the datastore due to an external update. */ touch() { this.revision += 1; } /** Load an object by ID or list of IDs. */ load(id) { if (Array.isArray(id)) { return id.map((a) => this.load(a)).filter((obj) => obj !== void 0); } return this.objects.get(id); } /** * Store the given object, making it immediately queryable. Storing an object * takes ownership over it, and index-specific variables (prefixed via '$') may be * added to the object. */ store(object, substorer) { this._recursiveStore(object, this.revision++, substorer, void 0); } /** Recursively store objects using a potential subindexer. */ _recursiveStore(object, revision, substorer, parent) { if (Array.isArray(object)) { for (let element of object) { this._recursiveStore(element, revision, substorer, parent); } return; } this._deleteRecursive(object.$id); object.$revision = revision; object.$parent = parent; this.ids.add(object.$id); this.objects.set(object.$id, object); if (parent) { if (!this.children.has(parent.$id)) this.children.set(parent.$id, /* @__PURE__ */ new Set()); this.children.get(parent.$id).add(object.$id); } this._index(object); substorer == null ? void 0 : substorer(object, (incoming, subindex) => this._recursiveStore(incoming, revision, subindex, object)); } /** Delete an object by ID from the index, recursively deleting any child objects as well. */ delete(id) { if (this._deleteRecursive(id)) { this.revision++; return true; } return false; } /** Internal method that does not bump the revision. */ _deleteRecursive(id) { const object = this.objects.get(id); if (!object) { return false; } const children = this.children.get(id); if (children) { for (let child of children) { this._deleteRecursive(child); } this.children.delete(id); } this._unindex(object); this.ids.delete(id); this.objects.delete(id); return true; } /** Add the given indexable to the appropriate indices. */ _index(object) { this.types.set(object.$id, object.$types); if (object.$types.contains(LINKBEARING_TYPE) && iterableExists(object, "$links")) { this.links.set( object.$id, object.$links.map((link) => link.obsidianLink()) ); } } /** Remove the given indexable from all indices. */ _unindex(object) { this.types.delete(object.$id, object.$types); if (object.$types.contains(LINKBEARING_TYPE) && iterableExists(object, "$links")) { this.links.delete( object.$id, object.$links.map((link) => link.obsidianLink()) ); } } /** Completely clear the datastore of all values. */ clear() { this.ids.clear(); this.objects.clear(); this.children.clear(); this.types.clear(); this.links.clear(); this.revision++; } /** Get all the backlinks to the given linkable. */ getBacklinks(object) { const normalizedLink = object.$link.obsidianLink(); return this.links.get(normalizedLink); } /** Check if the given linkable object has any backlinks. */ isLinked(object) { return this.getBacklinks(object).size > 0; } /** * Update $printName and $refName of theorems and equations. * Additionally, set $main of a theorem callout to true if it is the only one in the file, if configured as such. * Fiinally, set $refName of the page to the refName of the main theorem, if it exists. * * Warning: This function doesn't trigger MathLinks.update(), so you have to call it by yourself! */ updateNames(file) { const settings = resolveSettings(void 0, this.plugin, file); let blockOrdinal = 1; let block; let theorems = []; let autoNumberedTheoremCount = 0; let mainTheorem = null; const equationNumberInit = +settings.eqNumberInit; let equationCount = 0; const eqPrefix = getEqNumberPrefix(this.plugin.app, file, settings); const eqSuffix = settings.eqNumberSuffix; while (block = this.load(`${file.path}/block${blockOrdinal++}`)) { if (TheoremCalloutBlock.isTheoremCalloutBlock(block)) { theorems.push(block); if (block.$main) mainTheorem = block; const resolvedSettings = Object.assign({}, settings, block.$settings); if (block.$settings.number == "auto") { block.$index = autoNumberedTheoremCount; resolvedSettings._index = autoNumberedTheoremCount++; } const mainTitle = formatTitleWithoutSubtitle(this.plugin, file, resolvedSettings); const refName = this.formatMathLink(file, resolvedSettings, "refFormat"); block.$theoremMainTitle = mainTitle; block.$refName = refName; block.$titleSuffix = settings.titleSuffix; } else if (EquationBlock.isEquationBlock(block)) { let printName = null; let refName = null; if (block.$manualTag) { printName = `(${block.$manualTag})`; } else if (!settings.numberOnlyReferencedEquations || block.$link && this.isLinked(block)) { block.$index = equationCount; printName = "(" + eqPrefix + CONVERTER[settings.eqNumberStyle](equationNumberInit + equationCount) + eqSuffix + ")"; equationCount++; } if (printName !== null) refName = settings.eqRefPrefix + printName + settings.eqRefSuffix; block.$printName = printName; block.$refName = refName; } } if (this.plugin.extraSettings.setOnlyTheoremAsMain && theorems.length == 1) { theorems[0].$main = true; mainTheorem = theorems[0]; } const page = this.load(file.path); if (MarkdownPage.isMarkdownPage(page)) { if (mainTheorem) { const resolvedSettings = Object.assign({}, settings, mainTheorem.$settings); resolvedSettings._index = mainTheorem.$index; if (!resolvedSettings.ignoreMainTheoremCalloutWithoutTitle || mainTheorem.$theoremSubtitle) page.$refName = this.formatMathLink(file, resolvedSettings, "noteMathLinkFormat"); } } this.plugin.indexManager.trigger("index-updated", file); } formatMathLink(file, resolvedSettings, key) { const refFormat = resolvedSettings[key]; if (refFormat == "[type] [number] ([title])") { return formatTitle(this.plugin, file, resolvedSettings, true); } if (refFormat == "[type] [number]") { return formatTitleWithoutSubtitle(this.plugin, file, resolvedSettings); } if (refFormat == "[title] if title exists, [type] [number] otherwise") { return resolvedSettings.title ? resolvedSettings.title : formatTitleWithoutSubtitle(this.plugin, file, resolvedSettings); } const typePlusNumber = formatTitleWithoutSubtitle(this.plugin, file, resolvedSettings); return resolvedSettings.title ? `${resolvedSettings.title} (${typePlusNumber})` : typePlusNumber; } getByType(type) { return this.types.get(type); } getMarkdownPage(path) { const page = this.load(path); return MarkdownPage.isMarkdownPage(page) ? page : null; } getTheoremCalloutBlock(id) { const block = this.load(id); return TheoremCalloutBlock.isTheoremCalloutBlock(block) ? block : null; } getEquationBlock(id) { const block = this.load(id); return EquationBlock.isEquationBlock(block) ? block : null; } }; function iterableExists(object, key) { return key in object && object[key] !== void 0 && Symbol.iterator in object[key]; } // src/index/manager.ts var MathIndexManager = class extends import_obsidian25.Component { constructor(plugin, settings) { super(); this.plugin = plugin; this.settings = settings; const { app } = plugin; this.app = app; this.vault = app.vault; this.metadataCache = app.metadataCache; this.events = new import_obsidian25.Events(); this.index = new MathIndex(plugin, app.vault, app.metadataCache); this.initialized = false; this.addChild( this.importer = new MathImporter(this.plugin, app.vault, app.metadataCache, () => { return { workers: settings.importerNumThreads, utilization: Math.max(0.1, Math.min(1, settings.importerUtilization)) }; }) ); } /** Obtain the current index revision, for determining if anything has changed. */ get revision() { return this.index.revision; } /** Initialize datacore by scanning persisted caches and all available files, and queueing parses as needed. */ initialize() { this.registerEvent(this.metadataCache.on("resolve", (file) => this.updateLinked(file))); this.registerEvent(this.vault.on("rename", this.rename, this)); this.registerEvent( this.vault.on("delete", async (file) => { if (file instanceof import_obsidian25.TFile) { await this.updateLinkedOnDeltion(file); } if (file.path in this.plugin.settings) { delete this.plugin.settings[file.path]; } this.plugin.excludedFiles.remove(file.path); }) ); this.registerEvent( this.on("local-settings-updated", async (file) => { iterDescendantFiles(file, (descendantFile) => { if (descendantFile.extension === "md") { this.index.updateNames(descendantFile); update(this.app, descendantFile); } ; }); }) ); this.registerEvent( this.on("global-settings-updated", () => { const init2 = new MathIndexInitializer(this); init2.finished().then(() => { this.removeChild(init2); this.index.touch(); this.trigger("update", this.revision); }); this.addChild(init2); }) ); const init = this.initializer = new MathIndexInitializer(this); init.finished().then((stats) => { this.initialized = true; this.initializer = void 0; this.removeChild(init); const durationSecs = (stats.durationMs / 1e3).toFixed(3); console.log( `${this.plugin.manifest.name}: Imported all theorems and equations in the vault in ${durationSecs}s (${stats.imported} notes imported, ${stats.skipped} notes skipped).` ); this.index.touch(); this.trigger("update", this.revision); this.trigger("index-initialized"); update(this.app); }); this.addChild(init); } async rename(file, oldPath) { if (!(file instanceof import_obsidian25.TFile)) return; this.plugin.settings[file.path] = structuredClone(this.plugin.settings[oldPath]); delete this.plugin.settings[oldPath]; this.plugin.excludedFiles.remove(oldPath); this.plugin.excludedFiles.push(file.path); this.index.delete(oldPath); await this.reload(file); this.index.updateNames(file); update(this.app); } /** Queue a file for reloading; this is done asynchronously in the background and may take a few seconds. */ async reload(file) { const result = await this.importer.import(file); if (result.type === "error") { throw new Error(`Failed to import file '${file.name}: ${result.$error}`); } else if (result.type === "markdown") { const parsed = MarkdownPage.from(result.result, (link) => { const rpath = this.metadataCache.getFirstLinkpathDest(link.path, result.result.$path); if (rpath) return link.withPath(rpath.path); else return link; }); this.index.store(parsed, (object, store) => { store(object.$sections, (section, store2) => { store2(section.$blocks); }); }); this.trigger("update", this.revision); this.trigger("index-updated", file); return parsed; } throw new Error("Encountered unrecognized import result type: " + result.type); } /** Given an array of TFiles, this function does two things: * 1. It reloads (re-imports) each file in the array. * 2. It re-computes the theorem/equation numbers for all the files containing blocks * that each file in the array previously linked to. *   EDIT: Wow, I forgot to update the files that each file in the array newly links to. * * This should be named like updateOldAndNewLinkDestinations. */ async updateLinked(file) { const toBeUpdated = /* @__PURE__ */ new Set([file]); const oldPage = this.index.load(file.path); if (MarkdownPage.isMarkdownPage(oldPage)) { for (const link of oldPage.$links) { if (link.type === "block") { const linkedFile = this.vault.getAbstractFileByPath(link.path); if (linkedFile instanceof import_obsidian25.TFile) { toBeUpdated.add(linkedFile); } } } } const newPage = await this.reload(file); for (const link of newPage.$links) { if (link.type === "block") { const linkedFile = this.vault.getAbstractFileByPath(link.path); if (linkedFile instanceof import_obsidian25.TFile) { toBeUpdated.add(linkedFile); } } } toBeUpdated.forEach((fileToBeUpdated) => { this.index.updateNames(fileToBeUpdated); update(this.app, fileToBeUpdated); }); this.trigger("update", this.revision); } async updateLinkedOnDeltion(file) { const toBeUpdated = /* @__PURE__ */ new Set(); const oldPage = this.index.load(file.path); if (MarkdownPage.isMarkdownPage(oldPage)) { for (const link of oldPage.$links) { if (link.type === "block") { const linkedFile = this.vault.getAbstractFileByPath(link.path); if (linkedFile instanceof import_obsidian25.TFile) { toBeUpdated.add(linkedFile); } } } } this.index.delete(file.path); toBeUpdated.forEach((fileToBeUpdated) => { this.index.updateNames(fileToBeUpdated); }); this.trigger("update", this.revision); update(this.app); } on(evt, callback, context) { return this.events.on(evt, callback, context); } /** Unsubscribe from an event using the event and original callback. */ off(evt, callback) { this.events.off(evt, callback); } /** Unsubscribe from an event using the event reference. */ offref(ref) { this.events.offref(ref); } /** Trigger an event. */ trigger(evt, ...args) { this.events.trigger(evt, ...args); } }; var _MathIndexInitializer = class _MathIndexInitializer extends import_obsidian25.Component { constructor(manager) { super(); this.manager = manager; this.active = false; this.queue = this.manager.vault.getMarkdownFiles(); this.files = this.queue.length; this.start = Date.now(); this.current = []; this.done = deferred(); this.initialized = this.imported = this.skipped = 0; } async onload() { this.active = true; this.runNext(); } /** Promise which resolves when the initialization completes. */ finished() { return this.done; } /** Cancel initialization. */ onunload() { if (this.active) { this.active = false; this.done.reject("Initialization was cancelled before completing."); } } /** Poll for another task to execute from the queue. */ runNext() { if (!this.active || this.current.length >= _MathIndexInitializer.BATCH_SIZE) { return; } const next = this.queue.pop(); if (next) { this.current.push(next); this.init(next).then((result) => this.handleResult(next, result)).catch((result) => this.handleResult(next, result)); this.runNext(); } else if (!next && this.current.length == 0) { this.active = false; this.manager.vault.getMarkdownFiles().forEach((file) => this.manager.index.updateNames(file)); update(this.manager.app); this.done.resolve({ durationMs: Date.now() - this.start, files: this.files, imported: this.imported, skipped: this.skipped }); } } /** Process the result of an initialization and queue more runs. */ handleResult(file, result) { this.current.remove(file); this.initialized++; if (result.status === "skipped") this.skipped++; else if (result.status === "imported") this.imported++; this.runNext(); } /** Initialize a specific file. */ async init(file) { try { const metadata = this.manager.metadataCache.getFileCache(file); if (!metadata) return { status: "skipped" }; await this.manager.reload(file); return { status: "imported" }; } catch (ex) { console.log(`${this.manager.plugin.manifest.name}: Failed to import file: `, ex); return { status: "skipped" }; } } }; /** Number of concurrent operations the initializer will perform. */ _MathIndexInitializer.BATCH_SIZE = 8; var MathIndexInitializer = _MathIndexInitializer; // src/notice.ts var import_obsidian27 = require("obsidian"); var RenameNoticeModal = class extends import_obsidian27.Modal { constructor(plugin) { super(plugin.app); this.plugin = plugin; this.component = new import_obsidian27.Component(); } onOpen() { this.plugin.addChild(this.component); const { contentEl, titleEl } = this; contentEl.empty(); titleEl.setText("Math Booster has been renamed"); import_obsidian27.MarkdownRenderer.render( this.app, `Starting from version 2.2.0, Math Booster has been renamed to ***LaTeX-like Theorem & Equation Referencer*** for better clarity and discoverability. While the display name in the community plugin browser may still reflect the previous version, it will be updated shortly. A big thank you for those who shared their ideas [here](https://github.com/RyotaUshio/obsidian-math-booster/issues/210)! > [!warning] > If you have custom CSS snippets with CSS classes <code>.math-booster-*</code>, don't worry, they still work! > > But I do recommend you to replace them with <code>.latex-referencer-*</code> as the old class names might be removed in the future.`, contentEl, "", this.component ); new import_obsidian27.Setting(contentEl).addButton((button) => { button.setCta().setButtonText("Okay, I got it").onClick(() => this.close()); }).then((setting) => setting.settingEl.style.border = "none"); } onClose() { this.contentEl.empty(); this.component.unload(); } }; var DependencyNotificationModal = class extends import_obsidian27.Modal { constructor(plugin, dependenciesOK, v1) { super(plugin.app); this.plugin = plugin; this.dependenciesOK = dependenciesOK; this.v1 = v1; this.component = new import_obsidian27.Component(); } async onOpen() { this.plugin.addChild(this.component); const { contentEl, titleEl } = this; contentEl.empty(); titleEl.setText(`${this.plugin.manifest.name} ${this.plugin.manifest.version}`); if (!this.dependenciesOK) this.showDependencies(); if (this.v1) this.showMigrationGuild(); } showDependencies() { this.contentEl.createDiv({ text: `${this.plugin.manifest.name} requires the following plugin to work properly.`, attr: { style: "margin-bottom: 1em;" } }); for (const depenedency of Object.values(this.plugin.dependencies)) { const depPlugin = this.app.plugins.getPlugin(depenedency.id); const isValid = depPlugin && !isPluginOlderThan(depPlugin, depenedency.version); const setting = new import_obsidian27.Setting(this.contentEl).setName(depenedency.name).addExtraButton((button) => { button.setIcon(isValid ? "checkmark" : "cross"); const el = button.extraSettingsEl; el.addClass("math-booster-dependency-validation"); el.removeClass(isValid ? "invalid" : "valid"); el.addClass(isValid ? "valid" : "invalid"); }); setting.descEl.createDiv( { text: `Required version: ${depenedency.version}+ / ` + (depPlugin ? `Currently installed: ${depPlugin.manifest.version}` : `Not installed or enabled`) } ); } } async showMigrationGuild() { this.contentEl.createEl("h3", { text: "Migration from version 1" }); import_obsidian27.MarkdownRenderer.render( this.app, `LaTeX-like Theorem & Equation Referencer (formerly called Math Booster) version 2 introduces a [new format for theorem callouts](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/theorem-callouts/theorem-callouts.html). To fully enjoy version 2, click the button below to convert the old theorem format to the new one. Alternatively, you can do it later by running the command "Migrate from version 1".`, this.contentEl.createDiv(), "", this.component ); new import_obsidian27.Setting(this.contentEl).addButton((button) => { button.setButtonText("Convert").setCta().onClick(() => { this.close(); new MigrationModal(this.plugin).open(); }); }).addButton((button) => button.setButtonText("Not now").onClick(() => this.close())).then((setting) => setting.settingEl.style.border = "none"); const descEl = this.contentEl.createDiv({ cls: "math-booster-version-2-release-note-modal" }); await import_obsidian27.MarkdownRenderer.render( this.app, `### What's new in version 2 - [New format for theorem callouts](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/theorem-callouts/theorem-callouts.html): - *much cleaner*, - *more intuitive*, - *more keyboard-friendly*, - and *less plugin-dependent* than the previous format - New indexing mechanism: - no longer blocks UI - no longer hard-codes theorem indices in notes directly - [Enhancing Obsidian's built-in link autocomplete](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/search-&-link-autocomplete/enhancing-obsidian's-built-in-link-autocomplete.html): now equations are rendered in the built-in autocomplete as well. - [Custom link autocomplete](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/search-&-link-autocomplete/custom-link-autocomplete.html) improvements: filter theorems & equations (*entire vault/recent notes/active note*) - [Search modal](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/search-&-link-autocomplete/search-modal.html): more control & flexibility than editor autocomplete, including *Dataview queries* - Adding metadata to [theorems](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/theorem-callouts/theorem-callouts.html) and [equations](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/equations.html) with comments - Theorem numbers and [equation numbers](https://ryotaushio.github.io/obsidian-latex-theorem-equation-referencer/equations.html) now can be displayed *almost everywhere*: ##### Version 1: | | Theorem number | Equation number | | ------------------ | -------------- | --------------- | | Reading view | \u2705 | \u2705 | | Live preview | \u2705 | \u2705 | | Embeds | \u2705 | | | Hover page preview | \u2705 | | | PDF export | \u2705 | | ##### **\u{1F389} Version 2:** | | Theorem number | Equation number | | ------------------ | -------------- | --------------- | | Reading view | \u2705 | \u2705 | | Live preview | \u2705 | \u2705 | | Embeds | \u2705 | \u2705 | | Hover page preview | \u2705 | \u2705 | | PDF export | \u2705 | \u2705 | ### No longer supported - ["Show backlinks" right-click menu](https://github.com/RyotaUshio/obsidian-latex-theorem-equation-referencer/blob/1.0.4/docs/backlinks.md) - Use [Strange New Worlds](https://github.com/TfTHacker/obsidian42-strange-new-worlds) instead. - [Projects](https://github.com/RyotaUshio/obsidian-latex-theorem-equation-referencer/blob/1.0.4/docs/projects.md) - might be supported later with some improvements `, descEl, "", this.component ); descEl.querySelectorAll(".copy-code-button").forEach((el) => el.remove()); } onClose() { this.contentEl.empty(); this.component.unload(); } }; var MigrationModal = class extends import_obsidian27.Modal { constructor(plugin) { super(plugin.app); this.plugin = plugin; this.component = new import_obsidian27.Component(); this.plugin.addChild(this.component); } async onOpen() { var _a; let { contentEl, modalEl, titleEl } = this; contentEl.empty(); (_a = modalEl.querySelector(".modal-close-button")) == null ? void 0 : _a.remove(); titleEl.setText("Convert theorem callouts' format from v1 to v2"); const descEl = contentEl.createDiv(); await import_obsidian27.MarkdownRenderer.render( this.app, ` In order to enjoy LaTeX-like Theorem & Equation Referencer, you need to convert the old theorem format from Math Booster version 1: \`\`\`md > [!math|{"type":"theorem","number":"auto","title":"Main result","label":"main-result","_index":0}] Theorem 1 (Main result). \`\`\` to the new format: \`\`\`md > [!theorem] Main result > %% label: main-result %% \`\`\` > [!WARNING] > **MAKE SURE YOU HAVE A BACKUP OF YOUR VAULT BEFORE CONTINUING. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY ARISING FROM THIS OPERATION.** `, descEl, "", this.component ); descEl.querySelectorAll(".copy-code-button").forEach((el) => el.remove()); await new Promise((resolve) => { new import_obsidian27.Setting(contentEl).setName("Are you sure to proceed?").addButton((button) => { button.setButtonText("Yes").setWarning().onClick(() => resolve()); }).addButton((button) => { button.setButtonText("No").onClick(() => this.close()); }); }); if (!this.app.metadataCache.initialized || !this.plugin.indexManager.initialized) { new import_obsidian27.Notice("Obsidian is still indexing the vault. Try again after the cache is fully initialized."); return; } contentEl.empty(); const waitForCacheRefresh = new import_obsidian27.Setting(contentEl).setName("Preparing the fresh cache..."); await new Promise((resolve) => { waitForCacheRefresh.addProgressBar((bar) => { let progress = 0; const timer = window.setInterval(() => { bar.setValue(progress++); if (progress >= 100) { window.clearInterval(timer); resolve(); } }, 3 * 10); }); }); waitForCacheRefresh.setName("Preparing the fresh cache... Done!"); const converting = new import_obsidian27.Setting(contentEl).setName("Converting..."); await new Promise((resolve) => { converting.addProgressBar(async (bar) => { const files = this.app.vault.getMarkdownFiles(); let done = 0; const all = files.length; for (const file of files) { await rewriteTheoremCalloutFromV1ToV2(this.plugin, file); bar.setValue(done++ / all * 100); } bar.setValue(100); resolve(); }); }); converting.setName("Converting... Done!"); new import_obsidian27.Setting(contentEl).addButton((button) => { button.setButtonText("Close").setCta().onClick(() => this.close()); }); } onClose() { this.contentEl.empty(); this.component.unload(); } }; // src/search/editor-suggest.ts var import_obsidian32 = require("obsidian"); // src/search/core.ts var import_obsidian30 = require("obsidian"); // src/search/modal.ts var import_obsidian29 = require("obsidian"); var MathSearchModal = class extends import_obsidian29.SuggestModal { constructor(plugin) { super(plugin.app); this.plugin = plugin; this.app = plugin.app; this.core = new WholeVaultTheoremEquationSearchCore(this); this.core.setScope(); this.setPlaceholder("Type here..."); this.queryType = this.plugin.extraSettings.searchModalQueryType; this.range = this.plugin.extraSettings.searchModalRange; this.topEl = this.modalEl.createDiv({ cls: "math-booster-modal-top" }); this.modalEl.insertBefore(this.topEl, this.modalEl.firstChild); this.inputEl.addClass("math-booster-search-input"); this.limit = this.plugin.extraSettings.suggestNumber; new import_obsidian29.Setting(this.topEl).setName("Query type").addDropdown((dropdown) => { dropdown.addOption("both", "Theorems and equations").addOption("theorem", "Theorems").addOption("equation", "Equations"); dropdown.setValue(this.plugin.extraSettings.searchModalQueryType); dropdown.onChange((value) => { this.queryType = value; this.resetCore(); this.onInput(); this.plugin.extraSettings.searchModalQueryType = value; this.plugin.saveSettings(); }); }); new import_obsidian29.Setting(this.topEl).setName("Search range").addDropdown((dropdown) => { dropdown.addOption("vault", "Vault").addOption("recent", "Recent notes").addOption("active", "Active note").addOption("dataview", "Dataview query"); dropdown.setValue(this.plugin.extraSettings.searchModalRange); dropdown.onChange((value) => { this.range = value; this.resetCore(); this.onInput(); this.plugin.extraSettings.searchModalRange = value; this.plugin.saveSettings(); }); }); this.dvQueryField = new import_obsidian29.Setting(this.topEl).setName("Dataview query").setDesc("Only LIST queries are supported.").then((setting) => { setting.controlEl.style.width = "60%"; }).addTextArea((text) => { text.inputEl.addClass("math-booster-dv-query"); text.inputEl.style.width = "100%"; text.setValue(this.plugin.extraSettings.searchModalDvQuery).setPlaceholder("LIST ...").onChange((dvQuery) => { if (this.core instanceof DataviewQuerySearchCore) { this.core.dvQuery = dvQuery; this.onInput(); this.plugin.extraSettings.searchModalDvQuery = dvQuery; this.plugin.saveSettings(); } }); }); this.modalEl.insertBefore(this.inputEl, this.modalEl.firstChild); this.resetCore(); } resetCore() { const core = MathSearchCore.getCore(this); if (core) this.core = core; if (this.range === "dataview") { if (!core) { this.dvQueryField.setDisabled(true); this.dvQueryField.setDesc("Retry after enabling Dataview.").then((setting) => setting.descEl.style.color = "#ea5555"); } this.dvQueryField.settingEl.show(); } else this.dvQueryField.settingEl.hide(); } get dvQuery() { return this.dvQueryField.components[0].getValue(); } getContext() { const view = this.app.workspace.getActiveViewOfType(import_obsidian29.MarkdownView); if (!(view == null ? void 0 : view.file)) return null; const start = view.editor.getCursor("from"); const end = view.editor.getCursor("to"); return { file: view.file, editor: view.editor, start, end }; } getSelectedItem() { return this.chooser.values[this.chooser.selectedItem]; } getSuggestions(query) { return this.core.getSuggestions(query); } renderSuggestion(value, el) { this.core.renderSuggestion(value, el); } onChooseSuggestion(item, evt) { this.core.selectSuggestion(item, evt); } }; // src/search/core.ts var MathSearchCore = class { constructor(parent) { this.parent = parent; this.plugin = parent.plugin; this.app = this.plugin.app; this.index = this.plugin.indexManager.index; this.scope = parent.scope; } static getCore(parent) { var _a; const { app, range, queryType, dvQuery } = parent; if (range === "dataview") { const dv = (_a = app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (!dv) return null; return new DataviewQuerySearchCore(parent, queryType, dv, dvQuery); } if (range === "vault") { if (queryType === "both") return new WholeVaultTheoremEquationSearchCore(parent); else if (queryType === "theorem") return new WholeVaultTheoremSearchCore(parent); else if (queryType === "equation") return new WholeVaultEquationSearchCore(parent); } else if (range === "recent") return new RecentNotesSearchCore(parent, queryType); else if (range === "active") return new ActiveNoteSearchCore(parent, queryType); return null; } setScope() { this.scope.register([this.plugin.extraSettings.modifierToJump], "Enter", () => { const context = this.parent.getContext(); if (context) { const { editor, start, end } = context; editor.replaceRange("", start, end); } const item = this.parent.getSelectedItem(); const file = this.app.vault.getAbstractFileByPath(item.$file); if (!(file instanceof import_obsidian30.TFile)) return; openFileAndSelectPosition(this.app, file, item.$pos, ...LEAF_OPTION_TO_ARGS[this.plugin.extraSettings.suggestLeafOption]); if (this.parent instanceof MathSearchModal) this.parent.close(); return false; }); this.scope.register([this.plugin.extraSettings.modifierToNoteLink], "Enter", () => { const item = this.parent.getSelectedItem(); this.selectSuggestionImpl(item, true); if (this.parent instanceof MathSearchModal) this.parent.close(); return false; }); if (this.plugin.extraSettings.showModifierInstruction) { this.parent.setInstructions([ { command: "\u2191\u2193", purpose: "to navigate" }, { command: "\u21B5", purpose: "to insert link" }, { command: `${getModifierNameInPlatform(this.plugin.extraSettings.modifierToNoteLink)} + \u21B5`, purpose: "to insert link to note" }, { command: `${getModifierNameInPlatform(this.plugin.extraSettings.modifierToJump)} + \u21B5`, purpose: "to jump" } ]); } } async getSuggestions(query) { const ids = await this.getUnsortedSuggestions(); const results = this.gradeSuggestions(ids, query); this.postProcessResults(results); (0, import_obsidian30.sortSearchResults)(results); return results.map((result) => result.block); } postProcessResults(results) { } gradeSuggestions(ids, query) { var _a; const callback = (this.plugin.extraSettings.searchMethod == "Fuzzy" ? import_obsidian30.prepareFuzzySearch : import_obsidian30.prepareSimpleSearch)(query); const results = []; for (const id of ids) { const block = this.index.load(id); let text = `${block.$printName} ${block.$file}}`; if (block.$type === "theorem") { text += ` ${block.$settings.type}`; if (this.plugin.extraSettings.searchLabel) { const file = this.app.vault.getAbstractFileByPath(block.$file); if (file instanceof import_obsidian30.TFile) { const resolvedSettings = resolveSettings(block.$settings, this.plugin, file); text += ` ${(_a = formatLabel(resolvedSettings)) != null ? _a : ""}`; } } } else if (block.$type === "equation") { text += " " + block.$mathText; } const result = callback(text); if (result) { results.push({ match: result, block }); } } return results; } renderSuggestion(block, el) { const baseEl = el.createDiv({ cls: "math-booster-search-item" }); if (block.$printName) { const children = renderTextWithMath(block.$printName); baseEl.createDiv().replaceChildren(...children); } const smallEl = baseEl.createEl( "small", { text: `${getFileTitle(block.$file)}, line ${block.$position.start + 1}`, cls: "math-booster-search-item-description" } ); if (block.$type === "equation") { if (this.plugin.extraSettings.renderMathInSuggestion) { const mjxContainerEl = (0, import_obsidian30.renderMath)(block.$mathText, true); baseEl.insertBefore(mjxContainerEl, smallEl); } else { const mathTextEl = createDiv({ text: block.$mathText }); baseEl.insertBefore(mathTextEl, smallEl); } } } selectSuggestion(item, evt) { this.selectSuggestionImpl(item, false); (0, import_obsidian30.finishRenderMath)(); } async selectSuggestionImpl(block, insertNoteLink) { const context = this.parent.getContext(); if (!context) return; const fileContainingBlock = this.app.vault.getAbstractFileByPath(block.$file); const cache = this.app.metadataCache.getCache(block.$file); if (!(fileContainingBlock instanceof import_obsidian30.TFile) || !cache) return; const { editor, start, end, file } = context; const settings = resolveSettings(void 0, this.plugin, file); let success = false; const result = await insertBlockIdIfNotExist(this.plugin, fileContainingBlock, cache, block); if (result) { const { id, lineAdded } = result; let linktext = ""; if (fileContainingBlock != file) { linktext += this.app.metadataCache.fileToLinktext(fileContainingBlock, file.path); } if (!insertNoteLink) { linktext += `#^${id}`; } const link = `[[${linktext}]]`; const insertText = link + (settings.insertSpace ? " " : ""); if (fileContainingBlock == file) { editor.replaceRange( insertText, { line: start.line + lineAdded, ch: start.ch }, { line: end.line + lineAdded, ch: end.ch } ); } else { editor.replaceRange(insertText, start, end); } success = true; } if (!success) { new import_obsidian30.Notice(`${this.plugin.manifest.name}: Failed to read cache. Retry again later.`, 5e3); } } }; var WholeVaultSearchCore = class extends MathSearchCore { postProcessResults(results) { results.forEach((result) => { if (this.app.workspace.getLastOpenFiles().contains(result.block.$file)) { result.match.score += this.plugin.extraSettings.upWeightRecent; } }); } }; var WholeVaultTheoremEquationSearchCore = class extends WholeVaultSearchCore { async getUnsortedSuggestions() { return this.index.getByType("block-math-booster"); } }; var WholeVaultTheoremSearchCore = class extends WholeVaultSearchCore { async getUnsortedSuggestions() { return this.index.getByType("block-theorem"); } }; var WholeVaultEquationSearchCore = class extends WholeVaultSearchCore { async getUnsortedSuggestions() { return this.index.getByType("block-equation"); } }; var PartialSearchCore = class extends MathSearchCore { constructor(parent, type) { super(parent); this.type = type; } filterBlock(block) { if (this.type === "theorem") return TheoremCalloutBlock.isTheoremCalloutBlock(block); if (this.type === "equation") return EquationBlock.isEquationBlock(block); return MathBlock.isMathBlock(block); } async getUnsortedSuggestions() { const ids = []; const pages = (await this.getPaths()).map((path) => this.index.load(path)); for (const page of pages) { if (!MarkdownPage.isMarkdownPage(page)) continue; for (const section of page.$sections) { for (const block of section.$blocks) { if (this.filterBlock(block)) ids.push(block.$id); } } } return ids; } }; var RecentNotesSearchCore = class extends PartialSearchCore { async getPaths() { return this.app.workspace.getLastOpenFiles(); } }; var ActiveNoteSearchCore = class extends PartialSearchCore { async getPaths() { var _a; const path = (_a = this.app.workspace.getActiveFile()) == null ? void 0 : _a.path; return (path == null ? void 0 : path.endsWith(".md")) ? [path] : []; } }; var DataviewQuerySearchCore = class extends PartialSearchCore { constructor(parent, type, dv, dvQuery) { super(parent, type); this.dv = dv; this.dvQuery = dvQuery != null ? dvQuery : ""; } async getPaths() { const result = await this.dv.query(this.dvQuery); if (result.successful && result.value.type === "list") { const links = result.value.values; return links.map((link) => link.path); } return []; } }; // src/search/editor-suggest.ts var LinkAutocomplete = class extends import_obsidian32.EditorSuggest { /** * @param type The type of the block to search for. See: index/typings/markdown.ts */ constructor(plugin) { super(plugin.app); this.plugin = plugin; this.setTriggers(); this.core = new WholeVaultTheoremEquationSearchCore(this); this.core.setScope(); } get dvQuery() { return this.plugin.extraSettings.autocompleteDvQuery; } getContext() { return this.context; } getSelectedItem() { return this.suggestions.values[this.suggestions.selectedItem]; } onTrigger(cursor, editor) { for (const [trigger, { range, queryType }] of this.triggers) { const text = editor.getLine(cursor.line); const index = text.lastIndexOf(trigger); if (index >= 0) { const query = text.slice(index + trigger.length); if (query.startsWith("[[")) return null; this.queryType = queryType; this.range = range; const core = MathSearchCore.getCore(this); if (!core) return null; this.core = core; this.limit = this.plugin.extraSettings.suggestNumber; return { start: { line: cursor.line, ch: index }, end: cursor, query }; } } return null; } getSuggestions(context) { return this.core.getSuggestions(context.query); } renderSuggestion(block, el) { this.core.renderSuggestion(block, el); } selectSuggestion(item, evt) { this.core.selectSuggestion(item, evt); } setTriggers() { const unsortedTriggers = {}; if (this.plugin.extraSettings.enableSuggest) { unsortedTriggers[this.plugin.extraSettings.triggerSuggest] = { range: "vault", queryType: "both" }; } if (this.plugin.extraSettings.enableTheoremSuggest) { unsortedTriggers[this.plugin.extraSettings.triggerTheoremSuggest] = { range: "vault", queryType: "theorem" }; } if (this.plugin.extraSettings.enableEquationSuggest) { unsortedTriggers[this.plugin.extraSettings.triggerEquationSuggest] = { range: "vault", queryType: "equation" }; } if (this.plugin.extraSettings.enableSuggestRecentNotes) { unsortedTriggers[this.plugin.extraSettings.triggerSuggestRecentNotes] = { range: "recent", queryType: "both" }; } if (this.plugin.extraSettings.enableTheoremSuggestRecentNotes) { unsortedTriggers[this.plugin.extraSettings.triggerTheoremSuggestRecentNotes] = { range: "recent", queryType: "theorem" }; } if (this.plugin.extraSettings.enableEquationSuggestRecentNotes) { unsortedTriggers[this.plugin.extraSettings.triggerEquationSuggestRecentNotes] = { range: "recent", queryType: "equation" }; } if (this.plugin.extraSettings.enableSuggestActiveNote) { unsortedTriggers[this.plugin.extraSettings.triggerSuggestActiveNote] = { range: "active", queryType: "both" }; } if (this.plugin.extraSettings.enableTheoremSuggestActiveNote) { unsortedTriggers[this.plugin.extraSettings.triggerTheoremSuggestActiveNote] = { range: "active", queryType: "theorem" }; } if (this.plugin.extraSettings.enableEquationSuggestActiveNote) { unsortedTriggers[this.plugin.extraSettings.triggerEquationSuggestActiveNote] = { range: "active", queryType: "equation" }; } if (this.plugin.extraSettings.enableSuggestDataview) { unsortedTriggers[this.plugin.extraSettings.triggerSuggestDataview] = { range: "dataview", queryType: "both" }; } if (this.plugin.extraSettings.enableTheoremSuggestDataview) { unsortedTriggers[this.plugin.extraSettings.triggerTheoremSuggestDataview] = { range: "dataview", queryType: "theorem" }; } if (this.plugin.extraSettings.enableEquationSuggestDataview) { unsortedTriggers[this.plugin.extraSettings.triggerEquationSuggestDataview] = { range: "dataview", queryType: "equation" }; } const sortedTriggers = /* @__PURE__ */ new Map(); Object.entries(unsortedTriggers).sort((a, b) => b[0].length - a[0].length).forEach(([k, v]) => sortedTriggers.set(k, v)); this.triggers = sortedTriggers; } }; // src/patches/link-completion.ts var import_obsidian33 = require("obsidian"); // node_modules/monkey-around/mjs/index.js function around(obj, factories) { const removers = Object.keys(factories).map((key) => around1(obj, key, factories[key])); return removers.length === 1 ? removers[0] : function() { removers.forEach((r) => r()); }; } function around1(obj, method, createWrapper) { const original = obj[method], hadOwn = obj.hasOwnProperty(method); let current = createWrapper(original); if (original) Object.setPrototypeOf(current, original); Object.setPrototypeOf(wrapper, current); obj[method] = wrapper; return remove; function wrapper(...args) { if (current === original && obj[method] === wrapper) remove(); return current.apply(this, args); } function remove() { if (obj[method] === wrapper) { if (hadOwn) obj[method] = original; else delete obj[method]; } if (current === original) return; current = original; Object.setPrototypeOf(wrapper, original || Function); } } // src/patches/link-completion.ts var patchLinkCompletion = (plugin) => { const suggest = plugin.app.workspace.editorSuggest.suggests[0]; if (!Object.hasOwn(suggest, "suggestManager")) new import_obsidian33.Notice(`Failed to patch Obsidian's built-in link completion. Please reload ${plugin.manifest.name}.`); const prototype = suggest.constructor.prototype; plugin.register(around(prototype, { renderSuggestion(old) { return function(item, el) { var _a, _b; old.call(this, item, el); if (plugin.extraSettings.showTheoremTitleinBuiltin && item.type === "block" && item.node.type === "callout" && isTheoremCallout(plugin, item.node.callout.type)) { let title = (_b = (_a = item.node.children.find((child) => child.type === "callout-title")) == null ? void 0 : _a.children.map((child) => child.value).join("")) != null ? _b : ""; const content = item.display.slice(title.length); const page = plugin.indexManager.index.load(item.file.path); if (MarkdownPage.isMarkdownPage(page)) { const block = page.getBlockByLineNumber(item.node.position.start.line - 1); if (TheoremCalloutBlock.isTheoremCalloutBlock(block)) { renderInSuggestionTitleEl(el, (suggestionTitleEl) => { el.addClass("math-booster", "suggestion-item-theorem-callout"); suggestionTitleEl.replaceChildren(); const children = renderTextWithMath(block.$printName); suggestionTitleEl.createDiv().replaceChildren(...children); if (plugin.extraSettings.showTheoremContentinBuiltin && content) suggestionTitleEl.createDiv({ text: content }); }); return; } } const parsed = _readTheoremCalloutSettings({ type: item.node.callout.type, metadata: item.node.callout.data }, plugin.extraSettings.excludeExampleCallout); if (parsed) { const { type, number } = parsed; if (title === capitalize(type)) title = ""; const formattedTitle = formatTitle(plugin, item.file, resolveSettings({ type, number, title }, plugin, item.file), true); renderInSuggestionTitleEl(el, (suggestionTitleEl) => { el.addClass("math-booster", "suggestion-item-theorem-callout"); suggestionTitleEl.replaceChildren(); const children = renderTextWithMath(formattedTitle); suggestionTitleEl.createDiv().replaceChildren(...children); if (plugin.extraSettings.showTheoremContentinBuiltin && content) suggestionTitleEl.createDiv({ text: content }); }); return; } } else if (plugin.extraSettings.renderEquationinBuiltin && item.type === "block" && item.node.type === "math") { renderInSuggestionTitleEl(el, (suggestionTitleEl) => { el.addClass("math-booster", "suggestion-item-equation"); suggestionTitleEl.replaceChildren(); suggestionTitleEl.appendChild((0, import_obsidian33.renderMath)(item.node.value, true)); }); return; } }; } })); }; function renderInSuggestionTitleEl(el, cb) { const suggestionTitleEl = el.querySelector(".suggestion-title"); if (suggestionTitleEl) cb(suggestionTitleEl); } // src/patches/page-preview.ts var patchPagePreview = (plugin) => { const { app } = plugin; plugin.register( // @ts-ignore around(app.internalPlugins.plugins["page-preview"].instance.constructor.prototype, { onLinkHover(old) { return function(parent, targetEl, linktext, ...args) { old.call(this, parent, targetEl, linktext, ...args); plugin.lastHoverLinktext = linktext; }; } }) ); }; // src/proof/live-preview.ts var import_obsidian34 = require("obsidian"); var import_state4 = require("@codemirror/state"); var import_view4 = require("@codemirror/view"); var import_language3 = require("@codemirror/language"); // src/proof/common.ts function makeProofClasses(which, profile) { return [ "math-booster-" + which + "-proof", // deprecated "latex-referencer-" + which + "-proof", ...profile.meta.tags.map((tag) => "math-booster-" + which + "-proof-" + tag), // deprecated ...profile.meta.tags.map((tag) => "latex-referencer-" + which + "-proof-" + tag) ]; } function makeProofElement(which, profile) { return createSpan({ text: profile.body.proof[which], cls: makeProofClasses(which, profile) }); } // src/proof/live-preview.ts var INLINE_CODE = "inline-code"; var LINK_BEGIN = "formatting-link_formatting-link-start"; var LINK = "hmd-internal-link"; var LINK_END = "formatting-link_formatting-link-end"; var ProofWidget = class extends import_view4.WidgetType { constructor(plugin, profile) { super(); this.plugin = plugin; this.profile = profile; this.containerEl = null; } eq(other) { return this.profile.id === other.profile.id; } toDOM() { var _a; return (_a = this.containerEl) != null ? _a : this.containerEl = this.initDOM(); } ignoreEvent(event) { return false; } }; var BeginProofWidget = class _BeginProofWidget extends ProofWidget { constructor(plugin, profile, display, linktext, sourcePath) { super(plugin, profile); this.display = display; this.linktext = linktext; this.sourcePath = sourcePath; } eq(other) { return this.profile.id === other.profile.id && this.display === other.display && this.linktext === other.linktext && this.sourcePath == other.sourcePath; } initDOM() { let display = this.linktext ? `${this.profile.body.proof.linkedBeginPrefix} [[${this.linktext}]]${this.profile.body.proof.linkedBeginSuffix}` : this.display; if (display) { const el = createSpan({ cls: makeProofClasses("begin", this.profile) }); _BeginProofWidget.renderDisplay(el, display, this.sourcePath, this.plugin); return el; } return makeProofElement("begin", this.profile); } static async renderDisplay(el, display, sourcePath, plugin) { const children = await renderMarkdown(display, sourcePath, plugin); if (children) { el.replaceChildren(...children); } } }; var EndProofWidget = class extends ProofWidget { initDOM() { return makeProofElement("end", this.profile); } }; var createProofDecoration = (plugin) => import_view4.ViewPlugin.fromClass( class { constructor(view) { this.decorations = this.makeDeco(view); } update(update2) { if (update2.docChanged || update2.viewportChanged || update2.selectionSet) { if (update2.view.composing) { this.decorations = this.decorations.map(update2.changes); } else { this.decorations = this.makeDeco(update2.view); } } } makeDeco(view) { var _a; const { state } = view; const { app } = plugin; const tree = (0, import_language3.syntaxTree)(state); const ranges = state.selection.ranges; const file = state.field(import_obsidian34.editorInfoField).file; const sourcePath = (_a = file == null ? void 0 : file.path) != null ? _a : ""; const settings = resolveSettings(void 0, plugin, file != null ? file : app.vault.getRoot()); const profile = plugin.extraSettings.profiles[settings.profile]; const builder = new import_state4.RangeSetBuilder(); for (const { from, to } of view.visibleRanges) { tree.iterate({ from, to, enter(node) { var _a2, _b, _c, _d, _e, _f; if (node.name !== INLINE_CODE) return; let start = -1; let end = -1; let display = null; let linktext = null; const text = nodeText(node, state); if (text.startsWith(settings.beginProof)) { const rest = text.slice(settings.beginProof.length); if (!rest) { start = node.from - 1; end = node.to + 1; display = null; } else { const match = rest.match(/^\[(.*)\]$/); if (match) { start = node.from - 1; end = node.to + 1; display = match[1]; } } if (start === -1 || end === -1) return; if (state.sliceDoc(node.to + 1, node.to + 2) == "@") { const next = (_a2 = node.node.nextSibling) == null ? void 0 : _a2.nextSibling; const afterNext = (_c = (_b = node.node.nextSibling) == null ? void 0 : _b.nextSibling) == null ? void 0 : _c.nextSibling; const afterAfterNext = (_f = (_e = (_d = node.node.nextSibling) == null ? void 0 : _d.nextSibling) == null ? void 0 : _e.nextSibling) == null ? void 0 : _f.nextSibling; if ((next == null ? void 0 : next.name) === LINK_BEGIN && (afterNext == null ? void 0 : afterNext.name) === LINK && (afterAfterNext == null ? void 0 : afterAfterNext.name) === LINK_END) { linktext = nodeText(afterNext, state); end = afterAfterNext.to; } } if (!rangesHaveOverlap(ranges, start, end)) { builder.add( start, end, import_view4.Decoration.replace({ widget: new BeginProofWidget(plugin, profile, display, linktext, sourcePath) }) ); } } else if (text === settings.endProof) { start = node.from - 1; end = node.to + 1; if (!rangesHaveOverlap(ranges, start, end)) { builder.add( start, end, import_view4.Decoration.replace({ widget: new EndProofWidget(plugin, profile) }) ); } } } }); } return builder.finish(); } }, { decorations: (instance) => instance.decorations } ); // src/proof/reading-view.ts var import_obsidian35 = require("obsidian"); var createProofProcessor = (plugin) => (element, context) => { if (!plugin.extraSettings.enableProof) return; const { app } = plugin; const file = app.vault.getAbstractFileByPath(context.sourcePath); if (!(file instanceof import_obsidian35.TFile)) return; const settings = resolveSettings(void 0, plugin, file); const codes = element.querySelectorAll("code"); for (const code of codes) { const text = code.textContent; if (!text) continue; if (text.startsWith(settings.beginProof)) { const rest = text.slice(settings.beginProof.length); let displayMatch; if (!rest) { context.addChild(new ProofRenderer(app, plugin, code, "begin", file)); } else if (displayMatch = rest.match(/^\[(.*)\]$/)) { const display = displayMatch[1]; context.addChild(new ProofRenderer(app, plugin, code, "begin", file, display)); } } else if (code.textContent == settings.endProof) { context.addChild(new ProofRenderer(app, plugin, code, "end", file)); } } }; function parseAtSignLink(codeEl) { const next = codeEl.nextSibling; const afterNext = next == null ? void 0 : next.nextSibling; const afterAfterNext = afterNext == null ? void 0 : afterNext.nextSibling; if (afterNext) { if (next.nodeType == Node.TEXT_NODE && next.textContent == "@" && afterNext instanceof HTMLElement && afterNext.matches("a.original-internal-link") && afterAfterNext instanceof HTMLElement && afterAfterNext.matches("a.mathLink-internal-link")) { return { atSign: next, links: [afterNext, afterAfterNext] }; } } } var ProofRenderer = class extends import_obsidian35.MarkdownRenderChild { constructor(app, plugin, containerEl, which, file, display) { super(containerEl); this.app = app; this.plugin = plugin; this.which = which; this.file = file; this.display = display; this.atSignParseResult = parseAtSignLink(this.containerEl); } onload() { this.update(); this.registerEvent( this.plugin.indexManager.on("local-settings-updated", (file) => { if (file == this.file) { this.update(); } }) ); this.registerEvent( this.plugin.indexManager.on("global-settings-updated", () => { this.update(); }) ); } update() { const settings = resolveSettings(void 0, this.plugin, this.file); const profile = this.plugin.extraSettings.profiles[settings.profile]; if (this.atSignParseResult) { const { atSign, links } = this.atSignParseResult; const newEl2 = createSpan({ cls: makeProofClasses(this.which, profile) }); newEl2.replaceChildren(profile.body.proof.linkedBeginPrefix, ...links, profile.body.proof.linkedBeginSuffix); this.containerEl.replaceWith(newEl2); this.containerEl = newEl2; atSign.textContent = ""; return; } if (this.display) { this.renderDisplay(profile); return; } const newEl = makeProofElement(this.which, profile); this.containerEl.replaceWith(newEl); this.containerEl = newEl; } async renderDisplay(profile) { if (this.display) { const children = await renderMarkdown(this.display, this.file.path, this.plugin); if (children) { const el = createSpan({ cls: makeProofClasses(this.which, profile) }); el.replaceChildren(...children); this.containerEl.replaceWith(el); this.containerEl = el; } } } }; // src/main.ts var VAULT_ROOT = "/"; var LatexReferencer3 = class extends import_obsidian36.Plugin { constructor() { super(...arguments); this.dependencies = { "mathlinks": { id: "mathlinks", name: "MathLinks", version: "0.5.3" } }; } async onload() { const data = await this.loadData(); const first = data === null; const { version } = data != null ? data : {}; await this.loadSettings(); await this.saveSettings(); this.addSettingTab(new MathSettingTab(this.app, this)); this.app.workspace.onLayoutReady(async () => { var _a; const dependenciesOK = Object.keys(this.dependencies).every((id) => this.checkDependency(id)); const v1 = !first && ((_a = version == null ? void 0 : version.startsWith("1.")) != null ? _a : true); if (v1 || version.localeCompare("2.2.0", void 0, { numeric: true }) < 0) { new RenameNoticeModal(this).open(); } if (!dependenciesOK || v1) { new DependencyNotificationModal(this, dependenciesOK, v1).open(); } }); this.addChild(this.indexManager = new MathIndexManager(this, this.extraSettings)); this.app.workspace.onLayoutReady(async () => this.indexManager.initialize()); (window["mathIndex"] = this.indexManager.index) && this.register(() => delete window["mathIndex"]); this.app.workspace.onLayoutReady(() => { this.addChild( addProvider(this.app, (mathLinks) => new CleverefProvider(mathLinks, this)) ); }); this.registerEvent( this.indexManager.on("local-settings-updated", async (file) => { this.app.workspace.iterateRootLeaves((leaf) => { if (leaf.view instanceof import_obsidian36.MarkdownView) { this.setProfileTagAsCSSClass(leaf.view); } }); }) ); this.registerEvent( this.indexManager.on("global-settings-updated", async () => { this.app.workspace.iterateRootLeaves((leaf) => { if (leaf.view instanceof import_obsidian36.MarkdownView) { this.setProfileTagAsCSSClass(leaf.view); } }); }) ); this.app.workspace.onLayoutReady(() => { this.app.workspace.iterateRootLeaves((leaf) => { if (leaf.view instanceof import_obsidian36.MarkdownView) { this.setProfileTagAsCSSClass(leaf.view); } }); }); this.registerEvent( this.app.workspace.on("active-leaf-change", (leaf) => { if ((leaf == null ? void 0 : leaf.view) instanceof import_obsidian36.MarkdownView) { this.setProfileTagAsCSSClass(leaf.view); } }) ); this.registerCommands(); this.editorExtensions = []; this.registerEditorExtension(this.editorExtensions); this.updateEditorExtensions(); this.updateLinkAutocomplete(); this.app.workspace.onLayoutReady(() => patchLinkCompletion(this)); const itemNormalizer = (item) => { return { linktext: item.$file, sourcePath: "", line: item.$position.start }; }; registerQuickPreview(this.app, this, LinkAutocomplete, itemNormalizer); registerQuickPreview(this.app, this, MathSearchModal, itemNormalizer); this.registerMarkdownPostProcessor(createTheoremCalloutPostProcessor(this)); this.registerMarkdownPostProcessor(createEquationNumberProcessor(this)); this.app.workspace.onLayoutReady(() => this.forceRerender()); this.registerMarkdownPostProcessor(createProofProcessor(this)); this.lastHoverLinktext = null; this.app.workspace.onLayoutReady(() => patchPagePreview(this)); this.registerEvent( this.app.workspace.on("file-menu", (menu, file) => { menu.addSeparator().addItem((item) => { item.setTitle(`${this.manifest.name}: Open local settings`).onClick(() => { new ContextSettingModal(this.app, this, file).open(); }); }).addSeparator(); }) ); } async loadSettings() { this.settings = { [VAULT_ROOT]: JSON.parse(JSON.stringify(DEFAULT_SETTINGS)) }; this.extraSettings = JSON.parse(JSON.stringify(DEFAULT_EXTRA_SETTINGS)); this.excludedFiles = []; const loadedData = await this.loadData(); if (loadedData) { const { settings, extraSettings, excludedFiles // dumpedProjects } = loadedData; for (const path in settings) { if (path != VAULT_ROOT) { this.settings[path] = {}; } for (const _key in DEFAULT_SETTINGS) { const key = _key; let val = settings[path][key]; if (val !== void 0) { if (key in UNION_TYPE_MATH_CONTEXT_SETTING_KEYS) { const allowableValues = UNION_TYPE_MATH_CONTEXT_SETTING_KEYS[key]; if (!(allowableValues == null ? void 0 : allowableValues.includes(val))) { val = DEFAULT_SETTINGS[key]; } } if (typeof val == typeof DEFAULT_SETTINGS[key]) { this.settings[path][key] = val; } } } } for (const _key in DEFAULT_EXTRA_SETTINGS) { const key = _key; let val = extraSettings[key]; if (val !== void 0) { if (key in UNION_TYPE_EXTRA_SETTING_KEYS) { const allowableValues = UNION_TYPE_EXTRA_SETTING_KEYS[key]; if (!(allowableValues == null ? void 0 : allowableValues.includes(val))) { val = DEFAULT_EXTRA_SETTINGS[key]; } } if (typeof val == typeof DEFAULT_EXTRA_SETTINGS[key]) { this.extraSettings[key] = val; } } } this.excludedFiles = excludedFiles; } } async saveSettings() { await this.saveData({ version: this.manifest.version, settings: this.settings, extraSettings: this.extraSettings, excludedFiles: this.excludedFiles // dumpedProjects: this.projectManager.dump(), }); } updateLinkAutocomplete() { const suggestManager = this.app.workspace.editorSuggest; for (const suggest of suggestManager.suggests) { if (suggest instanceof LinkAutocomplete) suggestManager.removeSuggest(suggest); } this.registerEditorSuggest(new LinkAutocomplete(this)); } /** * Return true if the required plugin with the specified id is enabled and its version matches the requriement. * @param id * @returns */ checkDependency(id) { if (!this.app.plugins.enabledPlugins.has(id)) { return false; } const depPlugin = this.app.plugins.getPlugin(id); if (depPlugin) { return !isPluginOlderThan(depPlugin, this.dependencies[id].version); } return false; } setProfileTagAsCSSClass(view) { if (!view.file) return; const profile = getProfile(this, view.file); const classes = [ ...profile.meta.tags.map((tag) => `math-booster-${tag}`), // deprecated ...profile.meta.tags.map((tag) => `latex-referencer-${tag}`) ]; for (const el of [getMarkdownSourceViewEl(view), getMarkdownPreviewViewEl(view)]) { if (el) { el.classList.forEach((cls) => { if (cls.startsWith("math-booster-") || cls.startsWith("latex-referencer-")) { el.classList.remove(cls); } }); el == null ? void 0 : el.addClass(...classes); } } } updateEditorExtensions() { this.editorExtensions.length = 0; this.editorExtensions.push(this.theoremCalloutsField = createTheoremCalloutsField(this)); this.editorExtensions.push(createTheoremCalloutNumberingViewPlugin(this)); this.editorExtensions.push(createEquationNumberPlugin(this)); document.body.toggleClass("math-booster-preview-enabled", this.extraSettings.enableMathPreviewInCalloutAndQuote); if (this.extraSettings.enableMathPreviewInCalloutAndQuote) { this.editorExtensions.push(mathPreviewInfoField); this.editorExtensions.push(inlineMathPreview); this.editorExtensions.push(displayMathPreviewForCallout); this.editorExtensions.push(displayMathPreviewForQuote); this.editorExtensions.push(hideDisplayMathPreviewInQuote); } if (this.extraSettings.enableProof) { this.editorExtensions.push(createProofDecoration(this)); } this.app.workspace.updateOptions(); } registerCommands() { this.addCommand({ id: "insert-display-math", name: "Insert display math", editorCallback: insertDisplayMath }); this.addCommand({ id: "insert-theorem-callout", name: "Insert theorem callout", editorCheckCallback: (checking, editor, context) => { if (!context.file) return false; if (!checking) { new TheoremCalloutModal( this.app, this, context.file, (config) => { insertTheoremCallout(editor, config); }, "Insert", "Insert theorem callout" ).open(); } return true; } }); this.addCommand({ id: "search", name: "Search", callback: () => { new MathSearchModal(this).open(); } }); this.addCommand({ id: "open-local-settings-for-current-note", name: "Open local settings for the current note", callback: () => { const view = this.app.workspace.getActiveViewOfType(import_obsidian36.MarkdownView); if (view == null ? void 0 : view.file) { new ContextSettingModal(this.app, this, view.file).open(); } } }); this.addCommand({ id: "insert-proof", name: "Insert proof", editorCallback: (editor, context) => insertProof(this, editor, context) }); this.addCommand({ id: "convert-equation-number-to-tag", name: "Convert equation numbers in the current note to static \\tag{}", callback: () => { const file = this.app.workspace.getActiveFile(); if (file) staticifyEqNumber(this, file); } }); this.addCommand({ id: "migrate-from-v1", name: "Migrate from version 1", callback: () => { new MigrationModal(this).open(); } }); } forceRerender() { setTimeout(async () => { for (const leaf of this.app.workspace.getLeavesOfType("markdown")) { const view = leaf.view; const state = view.getEphemeralState(); view.previewMode.rerender(true); view.setEphemeralState(state); } }, 800); } };