|
| 1 | +import type { App } from "obsidian"; |
| 2 | + |
| 3 | +// Matches [[Note]], [[Note|Alias]], [[Note#Heading]], [[Note#Heading|Alias]] |
| 4 | +const WIKILINK_RE = /\[\[([^\]|#]+)(?:#([^\]|]+))?(?:\|([^\]]+))?\]\]/g; |
| 5 | + |
| 6 | +function titleToSlug(title: string): string { |
| 7 | + return title |
| 8 | + .toLowerCase() |
| 9 | + .trim() |
| 10 | + .replace(/\s+/g, "-") |
| 11 | + .replace(/[^a-z0-9-]/g, ""); |
| 12 | +} |
| 13 | + |
| 14 | +/** |
| 15 | + * Resolves Obsidian wikilinks to standard markdown links. |
| 16 | + * |
| 17 | + * For each [[Note]] or [[Note|Alias]]: |
| 18 | + * - if the linked note has a published `url` in its frontmatter, use it. |
| 19 | + * - Otherwise, return the display text without a link |
| 20 | +* TODO: return relative url to current note publication? |
| 21 | + */ |
| 22 | +export function resolveWikilinks( |
| 23 | + markdown: string, |
| 24 | + app: App, |
| 25 | +): string { |
| 26 | + return markdown.replace( |
| 27 | + WIKILINK_RE, |
| 28 | + (_match, noteName: string, heading: string | undefined, alias: string | undefined) => { |
| 29 | + const displayText = (alias ?? noteName).trim(); |
| 30 | + const name = noteName.trim(); |
| 31 | + |
| 32 | + const files = app.vault.getMarkdownFiles(); |
| 33 | + const file = files.find( |
| 34 | + (f) => f.basename === name || f.path === name + ".md" |
| 35 | + ); |
| 36 | + |
| 37 | + let baseUrl: string | undefined; |
| 38 | + |
| 39 | + if (file) { |
| 40 | + const fm = app.metadataCache.getFileCache(file)?.frontmatter; |
| 41 | + if (!fm?.atDocument || !fm?.url) { |
| 42 | + return displayText; |
| 43 | + } |
| 44 | + baseUrl = fm.url as string; |
| 45 | + } |
| 46 | + |
| 47 | + // if (!baseUrl && gardenBaseUrl) { |
| 48 | + // const base = gardenBaseUrl.replace(/\/$/, ""); |
| 49 | + // baseUrl = `${base}/notes/${titleToSlug(name)}`; |
| 50 | + // } |
| 51 | + |
| 52 | + if (!baseUrl) { |
| 53 | + return displayText; |
| 54 | + } |
| 55 | + |
| 56 | + const url = heading ? `${baseUrl}#${titleToSlug(heading)}` : baseUrl; |
| 57 | + return `[${displayText}](${url})`; |
| 58 | + } |
| 59 | + ); |
| 60 | +} |
0 commit comments