Skip to content

Commit

Permalink
Support absolute or relative paths.
Browse files Browse the repository at this point in the history
  • Loading branch information
lextoumbourou committed Apr 10, 2023
1 parent 5fcf570 commit 1227aff
Showing 1 changed file with 134 additions and 78 deletions.
212 changes: 134 additions & 78 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import {
FrontMatterCache,
CachedMetadata,
TFile,
Notice
Notice,
} from "obsidian";


const path = require("path");

interface BetterMarkdownLinksSettings {}
Expand All @@ -30,100 +29,157 @@ export default class BetterMarkdownLinksPlugin extends Plugin {
}

async updateBackLinks(file: TFile, oldPath: string) {
if (
!oldPath ||
!file.path.toLocaleLowerCase().endsWith(".md") ||
!(file instanceof TFile)
) {
return;
}

const cachedFile = this.app.metadataCache.getFileCache(file);
if (!cachedFile) {
return;
}
const title = this.getPageTitle(cachedFile);
const notes = this.getCachedNotesThatHaveLinkToFile(oldPath)

if (notes.length == 0) {
return
}

let updatedBacklinksCount = 0;

for (let note of notes) {
const fileContent = await this.app.vault.read(note);
const newFileContent = fileContent.replace(
/\[(.*?)\]\((.*?)\)/g,
(_, linkText, linkUrl) => {
linkUrl = decodeURIComponent(linkUrl);
if (path.basename(linkUrl) === path.basename(oldPath)) {
return `[${title}](${this.normalizePathForLink(file.path)})`;
}
return `[${linkText}](${linkUrl})`;
if (
!oldPath ||
!file.path.toLocaleLowerCase().endsWith(".md") ||
!(file instanceof TFile)
) {
return;
}

const cachedFile = this.app.metadataCache.getFileCache(file);
if (!cachedFile) {
return;
}
const title = this.getPageTitle(cachedFile, file.path);
const notes = this.getCachedNotesThatHaveLinkToFile(oldPath);

if (notes.length == 0) {
return;
}

let updatedBacklinksCount = 0;

for (let note of notes) {
const fileContent = await this.app.vault.read(note);
const newFileContent = fileContent.replace(
/\[(.*?)\]\((.*?)\)/g,
(_, linkText, linkUrl) => {
linkUrl = decodeURIComponent(linkUrl);
if (path.basename(linkUrl) === path.basename(oldPath)) {
const normedLink = this.normalizePathForLink(
file.path,
// @ts-ignore
this.app.vault.getConfig("newLinkFormat"),
path.dirname(note.path)
);
return `[${title}](${normedLink})`;
}
);

if (fileContent !== newFileContent) {
await this.app.vault.modify(note, newFileContent);
updatedBacklinksCount++;
return `[${linkText}](${linkUrl})`;
}
);

if (fileContent !== newFileContent) {
await this.app.vault.modify(note, newFileContent);
updatedBacklinksCount++;
}
}

if (updatedBacklinksCount > 0) {
new Notice(`${updatedBacklinksCount} backlink(s) updated.`);
};
};
if (updatedBacklinksCount > 0) {
new Notice(`${updatedBacklinksCount} backlink(s) updated.`);
}
}

getCachedNotesThatHaveLinkToFile(filePath: string): TFile[] {
let notes: TFile [] = [];
let allNotes = this.app.vault.getMarkdownFiles();
let notes: TFile[] = [];
let allNotes = this.app.vault.getMarkdownFiles();

if (allNotes) {
for (let note of allNotes) {
let notePath = note.path;
if (allNotes) {
for (let note of allNotes) {
let notePath = note.path;

if (note.path == filePath) {
continue;
if (note.path == filePath) {
continue;
}

let embeds = this.app.metadataCache.getCache(notePath)?.embeds;
if (embeds) {
for (let link_data of embeds) {
let embeds = this.app.metadataCache.getCache(notePath)?.embeds;
if (embeds) {
for (let link_data of embeds) {
let linkPath = link_data.link;
if (path.basename(linkPath) == path.basename(filePath)) {

const isSamePath = this.comparePaths(
linkPath,
filePath,
path.dirname(notePath),
//@ts-ignore
this.app.vault.getConfig("newLinkFormat")
);
if (isSamePath) {
notes.push(note);
}
}
}
}
}

let links = this.app.metadataCache.getCache(notePath)?.links;
if (links) {
for (let link_data of links) {
let links = this.app.metadataCache.getCache(notePath)?.links;
if (links) {
for (let link_data of links) {
let linkPath = link_data.link;
let linkBasePath = path.basename(linkPath);
let filePathBasePath = path.basename(filePath);

if (linkBasePath == filePathBasePath) {
const isSamePath = this.comparePaths(
linkPath,
filePath,
path.dirname(notePath),
//@ts-ignore
this.app.vault.getConfig("newLinkFormat")
);
if (isSamePath) {
notes.push(note);
}
}
}
}
}

return notes;
}

getPageTitle(cache: CachedMetadata): string {
const frontMatterTitle = cache.frontmatter && (cache.frontmatter as FrontMatterCache).title;
const firstHeading = cache.headings && (cache.headings[0] as HeadingCache).heading;
return frontMatterTitle || firstHeading || "";
}
}
}
}

return notes;
}

comparePaths(
linkPath: string,
filePath: string,
linkDir: string,
linkFormat: string
) {
const basePath = (this.app.vault.adapter as any).basePath;

filePath = path.resolve(basePath, filePath);
linkDir = path.resolve(basePath, linkDir);

if (linkFormat == "relative") {
linkPath = path.resolve(linkDir, linkPath);
}

linkPath = path.resolve(basePath, linkPath);

return linkPath == filePath;
}

normalizePathForLink(path: string): string {
path = path.replace(/\\/gi, "/"); //replace \ to /
path = path.replace(/ /gi, "%20"); //replace space to %20
return path;
}
getPageTitle(cache: CachedMetadata, filePath: string): string {
const frontMatterTitle =
cache.frontmatter && (cache.frontmatter as FrontMatterCache).title;
const firstHeading =
cache.headings && (cache.headings[0] as HeadingCache).heading;
return (
frontMatterTitle ||
firstHeading ||
path.basename(filePath).replace(".md", "")
);
}

normalizePathForLink(
pathToNorm: string,
linkFormat: string,
noteDir: string
): string {
if (linkFormat == "relative") {
const basePath = (this.app.vault.adapter as any).basePath;
noteDir = path.resolve(basePath, noteDir);
pathToNorm = path.resolve(basePath, pathToNorm);
pathToNorm = path.relative(noteDir, pathToNorm);
}

pathToNorm = pathToNorm.replace(/\\/gi, "/"); //replace \ to /
pathToNorm = pathToNorm.replace(/ /gi, "%20"); //replace space to %20

return pathToNorm;
}
}

0 comments on commit 1227aff

Please sign in to comment.