Skip to content

Commit 48fe849

Browse files
committed
replace wikilinks with markdown links
1 parent abb281b commit 48fe849

5 files changed

Lines changed: 69 additions & 5 deletions

File tree

src/commands/publishDocument.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Notice, TFile } from "obsidian";
22
import type AtmospherePlugin from "../main";
3-
import { createDocument, putDocument, getPublication, markdownToLeafletContent, stripMarkdown, markdownToPcktContent, buildDocumentUrl } from "../lib";
3+
import { createDocument, putDocument, getPublication, markdownToLeafletContent, stripMarkdown, markdownToPcktContent, buildDocumentUrl, resolveWikilinks } from "../lib";
44
import { PublicationSelection, SelectPublicationModal } from "../components/selectPublicationModal";
55
import { type ResourceUri, } from "@atcute/lexicons";
66
import { SiteStandardDocument, SiteStandardPublication } from "@atcute/standard-site";
@@ -137,15 +137,17 @@ async function buildDocumentRecord(plugin: AtmospherePlugin, file: TFile): Promi
137137
throw new Error("Missing publication URI.");
138138
}
139139

140+
const resolved = resolveWikilinks(content, plugin.app);
141+
140142
// TODO: determine which lexicon to use for rich content
141143
// for now just check url
142-
let textContent = stripMarkdown(content);
144+
let textContent = stripMarkdown(resolved);
143145

144146
let richContent: PubLeafletContent.Main | BlogPcktContent.Main | null = null;
145147
if (pub?.url.contains("leaflet.pub")) {
146-
richContent = markdownToLeafletContent(content)
148+
richContent = markdownToLeafletContent(resolved)
147149
} else if (pub?.url.contains("pckt.blog")) {
148-
richContent = markdownToPcktContent(content)
150+
richContent = markdownToPcktContent(resolved)
149151
}
150152

151153
let record = {

src/lib.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export {
3838
stripMarkdown,
3939
markdownToLeafletContent,
4040
markdownToPcktContent,
41+
resolveWikilinks,
4142
} from "./lib/markdown";
4243

4344
export type ATRecord<T> = Record & { value: T };

src/lib/markdown/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@ export type { Root, RootContent };
5252

5353
export { markdownToPcktContent, pcktContentToMarkdown } from "./pckt";
5454
export { markdownToLeafletContent, leafletContentToMarkdown } from "./leaflet";
55+
export { resolveWikilinks } from "./wikilinks";
5556

src/lib/markdown/wikilinks.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
}

src/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export async function fetchOgImage(url: string): Promise<string | undefined> {
2828
);
2929
imageCache.set(url, match?.[1] ?? "");
3030
return match?.[1];
31-
} catch (e) {
31+
} catch {
3232
return undefined;
3333
}
3434
}

0 commit comments

Comments
 (0)