import { TFile, type Vault } from "obsidian"; export interface ImageReference { alt: string; path: string; fullMatch: string; } const IMAGE_PATTERN = /!\[([^\]]*)\]\(([^)]+)\)/g; export function extractImageReferences(content: string): ImageReference[] { const references: ImageReference[] = []; const matches = content.matchAll(IMAGE_PATTERN); for (const match of matches) { const [, alt, path] = match; if (isExternalUrl(path)) { continue; } references.push({ alt, path, fullMatch: match[0], }); } return references; } export function getAbsolutePath(vault: Vault, filePath: string, currentFilePath: string): string | null { let absolutePath: string; if (filePath.startsWith("./") || filePath.startsWith("../")) { absolutePath = resolveRelativePath(currentFilePath, filePath); } else if (filePath.startsWith("/")) { absolutePath = filePath.substring(1); } else { absolutePath = resolveRelativePath(currentFilePath, filePath); } const file = vault.getAbstractFileByPath(absolutePath); if (file instanceof TFile) { return absolutePath; } return null; } export function replaceImagePaths(content: string, pathMapping: Map): string { return content.replace(IMAGE_PATTERN, (fullMatch, alt, path) => { const newPath = pathMapping.get(path); if (newPath) { return `![${alt}](${newPath})`; } return fullMatch; }); } function isExternalUrl(path: string): boolean { return path.startsWith("http://") || path.startsWith("https://") || path.startsWith("data:"); } function resolveRelativePath(currentFilePath: string, relativePath: string): string { const currentParts = currentFilePath.split("/"); currentParts.pop(); const relativeParts = relativePath.split("/"); for (const part of relativeParts) { if (part === "..") { currentParts.pop(); } else if (part !== ".") { currentParts.push(part); } } return currentParts.join("/"); }