/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; 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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/valid-url/index.js var require_valid_url = __commonJS({ "node_modules/valid-url/index.js"(exports, module2) { (function(module3) { "use strict"; module3.exports.is_uri = is_iri; module3.exports.is_http_uri = is_http_iri; module3.exports.is_https_uri = is_https_iri; module3.exports.is_web_uri = is_web_iri; module3.exports.isUri = is_iri; module3.exports.isHttpUri = is_http_iri; module3.exports.isHttpsUri = is_https_iri; module3.exports.isWebUri = is_web_iri; var splitUri = function(uri) { var splitted = uri.match(/(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/); return splitted; }; function is_iri(value) { if (!value) { return; } if (/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i.test(value)) return; if (/%[^0-9a-f]/i.test(value)) return; if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value)) return; var splitted = []; var scheme = ""; var authority = ""; var path = ""; var query = ""; var fragment = ""; var out = ""; splitted = splitUri(value); scheme = splitted[1]; authority = splitted[2]; path = splitted[3]; query = splitted[4]; fragment = splitted[5]; if (!(scheme && scheme.length && path.length >= 0)) return; if (authority && authority.length) { if (!(path.length === 0 || /^\//.test(path))) return; } else { if (/^\/\//.test(path)) return; } if (!/^[a-z][a-z0-9\+\-\.]*$/.test(scheme.toLowerCase())) return; out += scheme + ":"; if (authority && authority.length) { out += "//" + authority; } out += path; if (query && query.length) { out += "?" + query; } if (fragment && fragment.length) { out += "#" + fragment; } return out; } function is_http_iri(value, allowHttps) { if (!is_iri(value)) { return; } var splitted = []; var scheme = ""; var authority = ""; var path = ""; var port = ""; var query = ""; var fragment = ""; var out = ""; splitted = splitUri(value); scheme = splitted[1]; authority = splitted[2]; path = splitted[3]; query = splitted[4]; fragment = splitted[5]; if (!scheme) return; if (allowHttps) { if (scheme.toLowerCase() != "https") return; } else { if (scheme.toLowerCase() != "http") return; } if (!authority) { return; } if (/:(\d+)$/.test(authority)) { port = authority.match(/:(\d+)$/)[0]; authority = authority.replace(/:\d+$/, ""); } out += scheme + ":"; out += "//" + authority; if (port) { out += port; } out += path; if (query && query.length) { out += "?" + query; } if (fragment && fragment.length) { out += "#" + fragment; } return out; } function is_https_iri(value) { return is_http_iri(value, true); } function is_web_iri(value) { return is_http_iri(value) || is_https_iri(value); } })(module2); } }); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => FrontmatterLinksPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian5 = require("obsidian"); // src/editor_plugin.ts var import_language = require("@codemirror/language"); var import_state = require("@codemirror/state"); var import_view2 = require("@codemirror/view"); // src/link_widget.ts var import_view = require("@codemirror/view"); var import_obsidian = require("obsidian"); var import_valid_url = __toESM(require_valid_url()); var FrontmatterLinkWidget = class extends import_view.WidgetType { constructor(linkSlice) { super(); this.linkSlice = linkSlice; } toDOM(view) { const aElement = document.createElement("a"); aElement.href = this.linkSlice.href; aElement.innerText = this.linkSlice.alias || this.linkSlice.href; if ((0, import_valid_url.isUri)(this.linkSlice.href)) { aElement.addClass(this.linkSlice.markdownLink ? "external-link" : "cm-url"); } else { aElement.addClass("internal-link"); if (!(app.metadataCache.getFirstLinkpathDest(this.linkSlice.href, "") instanceof import_obsidian.TFile) && !this.linkSlice.markdownLink) { aElement.addClass("is-unresolved"); } } return aElement; } }; // src/editor_plugin.ts var import_valid_url2 = __toESM(require_valid_url()); var import_obsidian2 = require("obsidian"); var FrontmatterLinksEditorPlugin = class { constructor(view) { this.linkSlices = new Array(); this.linkSlices = new Array(); this.decorations = this.buildDecorations(view); } update(update) { if (update.docChanged || update.viewportChanged || update.selectionSet) { this.decorations = this.buildDecorations(update.view); } } destroy() { } buildDecorations(view) { const builder = new import_state.RangeSetBuilder(); this.linkSlices = new Array(); this.findLinks(view, this.linkSlices); this.processLinks(view, builder); return builder.finish(); } findLinks(view, linkSlices) { const settings = app.plugins.plugins["frontmatter-links"].settings; let externalLinkFrom; let externalLinkTo; for (let { from, to } of view.visibleRanges) { (0, import_language.syntaxTree)(view.state).iterate({ from, to, enter(node) { if (externalLinkFrom === null) { if (node.name === "hmd-frontmatter") { externalLinkFrom = node.from; externalLinkTo = node.to; } } else { if (node.name === "atom_hmd-frontmatter" || node.name === "def_hmd-frontmatter") { let text = view.state.sliceDoc(externalLinkFrom, externalLinkTo); if ((0, import_valid_url2.isUri)(text)) { linkSlices.push({ originalText: text, href: text, from: externalLinkFrom, to: externalLinkTo }); } externalLinkFrom = null; } else { externalLinkTo = node.to; } } if (node.name === "hmd-frontmatter_string") { const text = view.state.sliceDoc(node.from + 1, node.to - 1); let match; let href; let alias; let markdownLink; if (match = text.match(/\[\[(.+)\|(.+)\]\]/m)) { href = match[1]; alias = match[2]; } else if (match = text.match(/\[\[(.+)\]\]/m)) { href = match[1]; } else if (match = text.match(/\[(.+)\]\((.+)\)/m)) { href = match[2]; alias = match[1]; markdownLink = true; } else if ((0, import_valid_url2.isUri)(text)) { href = text; } if (href) { linkSlices.push({ originalText: text, href, alias, from: node.from + (settings.hideQuotes ? 0 : 1), to: node.to - (settings.hideQuotes ? 0 : 1), markdownLink }); } } } }); } } processLinks(view, builder) { for (let linkSlice of this.linkSlices) { const cursorHead = view.state.selection.main.head; if (linkSlice.from - 1 <= cursorHead && cursorHead <= linkSlice.to + 1) { this.styleLink(view, builder, linkSlice); } else { builder.add(linkSlice.from, linkSlice.to, import_view2.Decoration.replace({ widget: new FrontmatterLinkWidget(linkSlice) })); } } } styleLink(view, builder, linkSlice) { const settings = app.plugins.plugins["frontmatter-links"].settings; const unresolved = !(app.metadataCache.getFirstLinkpathDest(linkSlice.href, "") instanceof import_obsidian2.TFile); const text = view.state.sliceDoc(linkSlice.from, linkSlice.to); let match; if (match = text.match(/\[\[(.+)\|(.+)\]\]/m)) { builder.add(linkSlice.from + (settings.hideQuotes ? 1 : 0), linkSlice.from + 2 + (settings.hideQuotes ? 1 : 0), import_view2.Decoration.mark({ class: "cm-formatting-link cm-formatting-link-start" })); builder.add(linkSlice.from + text.indexOf(match[1]), linkSlice.from + text.indexOf(match[1]) + match[1].length, import_view2.Decoration.mark({ class: "cm-link" + (unresolved ? " is-unresolved" : "") })); builder.add(linkSlice.from + text.indexOf(match[1]) + match[1].length, linkSlice.from + text.indexOf(match[1]) + match[1].length + 1, import_view2.Decoration.mark({ class: "cm-hmd-internal-link" })); builder.add(linkSlice.from + text.indexOf(match[2]), linkSlice.from + text.indexOf(match[2]) + match[2].length, import_view2.Decoration.mark({ class: "cm-link" + (unresolved ? " is-unresolved" : "") })); builder.add(linkSlice.to - 2 - (settings.hideQuotes ? 1 : 0), linkSlice.to - (settings.hideQuotes ? 1 : 0), import_view2.Decoration.mark({ class: "cm-formatting-link cm-formatting-link-end" })); } else if (match = text.match(/\[\[(.+)\]\]/m)) { builder.add(linkSlice.from + (settings.hideQuotes ? 1 : 0), linkSlice.from + 2 + (settings.hideQuotes ? 1 : 0), import_view2.Decoration.mark({ class: "cm-formatting-link cm-formatting-link-start" })); builder.add(linkSlice.from + text.indexOf(match[1]), linkSlice.from + text.indexOf(match[1]) + match[1].length, import_view2.Decoration.mark({ class: "cm-link" + (unresolved ? " is-unresolved" : "") })); builder.add(linkSlice.to - 2 - (settings.hideQuotes ? 1 : 0), linkSlice.to - (settings.hideQuotes ? 1 : 0), import_view2.Decoration.mark({ class: "cm-formatting-link cm-formatting-link-end" })); } else if (match = text.match(/\[(.+)\](\(.+\))/m)) { builder.add(linkSlice.from + (settings.hideQuotes ? 1 : 0), linkSlice.from + 1 + (settings.hideQuotes ? 1 : 0), import_view2.Decoration.mark({ class: "cm-formatting-link cm-formatting-link-start" })); builder.add(linkSlice.from + text.indexOf(match[1]), linkSlice.from + text.indexOf(match[1]) + match[1].length, import_view2.Decoration.mark({ class: "cm-link" })); builder.add(linkSlice.from + text.indexOf("]"), linkSlice.from + text.indexOf("]") + 1, import_view2.Decoration.mark({ class: "cm-formatting-link cm-formatting-link-end" })); builder.add(linkSlice.from + text.indexOf(match[2]), linkSlice.from + text.indexOf(match[2]) + match[2].length, import_view2.Decoration.mark({ class: (0, import_valid_url2.isUri)(linkSlice.href) ? "external-link" : "cm-url" })); } else if (match = text.match(/\"(.+)\"/m)) { builder.add(linkSlice.from + text.indexOf(match[1]), linkSlice.from + text.indexOf(match[1]) + match[1].length, import_view2.Decoration.mark({ class: "cm-url" })); } else if ((0, import_valid_url2.isUri)(text)) { builder.add(linkSlice.from, linkSlice.to, import_view2.Decoration.mark({ class: "cm-url" })); } } }; var FRONTMATTER_LINKS_EDITOR_PLUGIN = import_view2.ViewPlugin.fromClass(FrontmatterLinksEditorPlugin, { decorations: (value) => value.decorations }); // src/metadata_cache.ts var import_obsidian3 = require("obsidian"); var import_valid_url3 = __toESM(require_valid_url()); function onMetadataCacheResolve(file) { const cache = app.metadataCache.getFileCache(file); if (!cache) { return; } const frontmatter = cache.frontmatter; if (!frontmatter) { return; } addFrontmatterLinksToCache(file, frontmatter); } function addFrontmatterLinksToCache(file, frontmatter) { if (!frontmatter) { return; } for (let key of Object.keys(frontmatter)) { const value = frontmatter[key]; if (typeof value === "string") { const match = value.match(/\[\[(.+)\|.+\]\]/m) || value.match(/\[\[(.+)\]\]/m) || value.match(/\[.+\]\((.+)\)/m); if (!match) { continue; } let href = match[1]; if ((0, import_valid_url3.isUri)(href)) { continue; } let f = app.metadataCache.getFirstLinkpathDest(href, ""); let links; if (f instanceof import_obsidian3.TFile) { href = f.path; links = app.metadataCache.resolvedLinks; } else { links = app.metadataCache.unresolvedLinks; } if (links[file.path][href]) { links[file.path][href] += 1; } else { links[file.path][href] = 1; } } else if (typeof value === "object") { addFrontmatterLinksToCache(file, value); } } } // src/settings.ts var import_obsidian4 = require("obsidian"); var DEFAULT_SETTINGS = { hideQuotes: false, addToGraph: true, updateLinks: true }; var FrontmatterLinksSettingTab = class extends import_obsidian4.PluginSettingTab { constructor(app2, plugin) { super(app2, plugin); this.plugin = plugin; } display() { new import_obsidian4.Setting(this.containerEl).setName("Hide quotation marks").setDesc("Don't render quotation marks surrounding frontmatter links.").addToggle((component) => { component.setValue(this.plugin.settings.hideQuotes); component.onChange((value) => { this.plugin.settings.hideQuotes = value; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(this.containerEl).setName("Add to graph").setDesc("Add frontmatter link connections to the graph view.").addToggle((component) => { component.setValue(this.plugin.settings.addToGraph); component.onChange((value) => { app.metadataCache.initialize(); this.plugin.settings.addToGraph = value; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(this.containerEl).setName("Automatically update internal frontmatter links").setDesc("Turn on to update frontmatter links when a note is renamed.
'Automatically update internal links' in 'Files & Links' must also be enabled.").setDesc(createFragment((el) => { el.appendText("Turn on to update frontmatter links when a note is renamed."); el.createEl("br"); el.createEl("div", { cls: "mod-warning", text: "Disabled because it was causing issues. Will fix next week after finals. Sorry." }); })).addToggle((component) => { component.setValue(this.plugin.settings.updateLinks); component.onChange((value) => { this.plugin.settings.updateLinks = value; this.plugin.saveSettings(); }); }).setDisabled(true); } hide() { this.containerEl.empty(); } }; // src/main.ts var FrontmatterLinksPlugin = class extends import_obsidian5.Plugin { async onload() { await this.loadSettings(); this.addSettingTab(new FrontmatterLinksSettingTab(this.app, this)); this.registerEditorExtension(FRONTMATTER_LINKS_EDITOR_PLUGIN); if (this.settings.addToGraph) { app.metadataCache.initialize(); } const plugin = this; this.registerEvent(app.metadataCache.on("resolve", (file) => { if (!plugin.settings.addToGraph) { return; } onMetadataCacheResolve(file); })); this.registerEvent(app.vault.on("rename", (file, oldPath) => { if (plugin.settings.updateLinks && app.vault.getConfig("alwaysUpdateLinks")) { } })); } onunload() { } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); this.settings.updateLinks = false; this.saveSettings(); } async saveSettings() { this.saveData(this.settings); } }; /* nosourcemap */