From 0a54f0106bcee76ffa6fcef4ea9c201d2cb341c3 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Mon, 12 May 2025 20:47:58 +0200 Subject: [PATCH] Implement wiki links --- src/lib/utils/markdown/basicMarkdownParser.ts | 47 +++++++++++++++---- src/lib/utils/markdown/markdownTestfile.md | 8 +++- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/lib/utils/markdown/basicMarkdownParser.ts b/src/lib/utils/markdown/basicMarkdownParser.ts index 377a83d..f53d731 100644 --- a/src/lib/utils/markdown/basicMarkdownParser.ts +++ b/src/lib/utils/markdown/basicMarkdownParser.ts @@ -36,12 +36,10 @@ function replaceAlexandriaNostrLinks(text: string): string { // Regex for 64-char hex const hexPattern = /\b[a-fA-F0-9]{64}\b/; - // 1. Replace Markdown links ONLY if they match the criteria + // 1. Alexandria/localhost Markdown links text = text.replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g, (match, _label, url) => { if (alexandriaPattern.test(url)) { - // Ignore d-tag URLs if (/[?&]d=/.test(url)) return match; - // Convert hexid in URL to nevent if present const hexMatch = url.match(hexPattern); if (hexMatch) { try { @@ -51,22 +49,18 @@ function replaceAlexandriaNostrLinks(text: string): string { return match; } } - // Or use bech32 if present const bech32Match = url.match(bech32Pattern); if (bech32Match) { return `nostr:${bech32Match[0]}`; } } - // For all other links, leave the markdown link untouched return match; }); - // 2. Replace bare Alexandria/localhost URLs only if they contain a Nostr identifier (not d-tag) + // 2. Alexandria/localhost bare URLs and non-Alexandria/localhost URLs with Nostr identifiers text = text.replace(/https?:\/\/[^\s)\]]+/g, (url) => { if (alexandriaPattern.test(url)) { - // Ignore d-tag URLs if (/[?&]d=/.test(url)) return url; - // Convert hexid in URL to nevent if present const hexMatch = url.match(hexPattern); if (hexMatch) { try { @@ -76,12 +70,25 @@ function replaceAlexandriaNostrLinks(text: string): string { return url; } } - // Or use bech32 if present const bech32Match = url.match(bech32Pattern); if (bech32Match) { return `nostr:${bech32Match[0]}`; } } + // For non-Alexandria/localhost URLs, append (View here: nostr:) if a Nostr identifier is present + const hexMatch = url.match(hexPattern); + if (hexMatch) { + try { + const nevent = nip19.neventEncode({ id: hexMatch[0] }); + return `${url} (View here: nostr:${nevent})`; + } catch { + return url; + } + } + const bech32Match = url.match(bech32Pattern); + if (bech32Match) { + return `${url} (View here: nostr:${bech32Match[0]})`; + } return url; }); @@ -124,6 +131,25 @@ function stripTrackingParams(url: string): string { } } +function normalizeDTag(input: string): string { + return input + .toLowerCase() + .replace(/[^\p{L}\p{N}]/gu, '-') + .replace(/-+/g, '-') + .replace(/^-|-$/g, ''); +} + +function replaceWikilinks(text: string): string { + // [[target page]] or [[target page|display text]] + return text.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, (_match, target, label) => { + const normalized = normalizeDTag(target.trim()); + const display = (label || target).trim(); + const url = `https://next-alexandria.gitcitadel.eu/publication?d=${normalized}`; + // Output as a clickable with the [[display]] format + return `[[${display}]]`; + }); +} + function processBasicFormatting(content: string): string { if (!content) return ''; @@ -292,6 +318,9 @@ export async function parseBasicMarkdown(text: string): Promise { // Process Nostr identifiers last processedText = await processNostrIdentifiers(processedText); + // Replace wikilinks + processedText = replaceWikilinks(processedText); + return processedText; } catch (error) { console.error('Error in parseBasicMarkdown:', error); diff --git a/src/lib/utils/markdown/markdownTestfile.md b/src/lib/utils/markdown/markdownTestfile.md index 78176fa..715c45d 100644 --- a/src/lib/utils/markdown/markdownTestfile.md +++ b/src/lib/utils/markdown/markdownTestfile.md @@ -14,6 +14,8 @@ It is _only_ a test, for __sure__. I just wanted to see if the markdown renders This file is full of ~errors~ opportunities to ~~mess up the formatting~~ check your markdown parser. +You can even learn about [[mirepoix]], [[nkbip-03]], or [[roman catholic church|catholics]] + npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z wrote this. That's the same person as this one with a nostr prefix nostr:npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z and nprofile1qydhwumn8ghj7argv4nx7un9wd6zumn0wd68yvfwvdhk6tcpr3mhxue69uhkx6rjd9ehgurfd3kzumn0wd68yvfwvdhk6tcqyr7jprhgeregx7q2j4fgjmjgy0xfm34l63pqvwyf2acsd9q0mynuzp4qva3. That is a different person from npub1s3ht77dq4zqnya8vjun5jp3p44pr794ru36d0ltxu65chljw8xjqd975wz. > This is important information @@ -85,12 +87,14 @@ And a nonsense one with a prefix: nostr:naddrwhatever -And some Nostr addresses that should be ignored: +And some Nostr addresses that should be preserved and have a internal link appended: https://lumina.rocks/note/note1sd0hkhxr49jsetkcrjkvf2uls5m8frkue6f5huj8uv4964p2d8fs8dn68z https://primal.net/e/nevent1qqsqum7j25p9z8vcyn93dsd7edx34w07eqav50qnde3vrfs466q558gdd02yr +https://primal.net/p/nprofile1qqs06gywary09qmcp2249ztwfq3ue8wxhl2yyp3c39thzp55plvj0sgjn9mdk + URL with a tracking parameter, no Markdown: https://example.com?utm_source=newsletter1&utm_medium=email&utm_campaign=sale @@ -109,6 +113,8 @@ And within a Markdown tag: [Markdown link title](http://alexandria.gitcitadel.co And to localhost: http://localhost:4173/publication?id=c36b54991e459221f444612d88ea94ef5bb4a1b93863ef89b1328996746f6d25 +http://localhost:4173/profile?id=nprofile1qqs99d9qw67th0wr5xh05de4s9k0wjvnkxudkgptq8yg83vtulad30gxyk5sf + You can even include code inline, like `
` or ```