diff --git a/package.json b/package.json
index bb30564..1cb5722 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"@tailwindcss/typography": "^0.5.10",
"@types/jest-image-snapshot": "^6.2.1",
"@types/node": "^20.8.2",
+ "@types/ramda": "^0.29.10",
"autoprefixer": "^10.4.16",
"concurrently": "^8.2.2",
"http-server": "^14.1.1",
@@ -53,7 +54,8 @@
"@nostr-dev-kit/ndk-svelte-components": "^1.3.0",
"daisyui": "^4.4",
"dayjs": "^1.11.10",
- "parse-diff": "^0.11.1"
+ "parse-diff": "^0.11.1",
+ "ramda": "^0.29.1"
},
"resolutions": {
"jackspeak": "2.1.1"
diff --git a/src/lib/components/events/content/Kind317.svelte b/src/lib/components/events/content/Kind317.svelte
index f49a950..4f86c73 100644
--- a/src/lib/components/events/content/Kind317.svelte
+++ b/src/lib/components/events/content/Kind317.svelte
@@ -1,6 +1,7 @@
+
+
+ {#each fullContent as part, i}
+ {#if isParsedNewLine(part)}
+ {#if part.value.length > 1}
+
+ {/if}
+
+ {:else if isParsedText(part)}
+ {part.value}
+ {/if}
+ {/each}
+
diff --git a/src/lib/components/events/content/utils.ts b/src/lib/components/events/content/utils.ts
new file mode 100644
index 0000000..bc8f2b6
--- /dev/null
+++ b/src/lib/components/events/content/utils.ts
@@ -0,0 +1,96 @@
+import type { NDKTag } from "@nostr-dev-kit/ndk";
+import { nip19 } from "nostr-tools";
+import { identity, last, pluck } from "ramda";
+
+export const TOPIC = "topic";
+export const LINK = "link";
+export const LINKCOLLECTION = "link[]";
+export const HTML = "html";
+export const INVOICE = "invoice";
+export const NOSTR_NOTE = "nostr:note";
+export const NOSTR_NEVENT = "nostr:nevent";
+export const NOSTR_NPUB = "nostr:npub";
+export const NOSTR_NPROFILE = "nostr:nprofile";
+export const NOSTR_NADDR = "nostr:naddr";
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const first = (list: any) => (list ? list[0] : undefined);
+
+export const fromNostrURI = (s: string) => s.replace(/^[\w+]+:\/?\/?/, "");
+
+export const urlIsMedia = (url: string) =>
+ !url.match(/\.(apk|docx|xlsx|csv|dmg)/) && last(url.split("://"))?.includes("/");
+
+export type ContentArgs = {
+ content: string;
+ tags?: Array;
+};
+
+export type ParsedPart = ParsedNewLine | ParsedText;
+
+export const NEWLINE = "newline";
+
+export type ParsedNewLine = {
+ type: "newline",
+ value: string,
+};
+
+export const isParsedNewLine = (part: ParsedPart): part is ParsedNewLine => {
+ return part.type == "newline"
+};
+
+export const TEXT = "text";
+
+export type ParsedText = {
+ type: "text",
+ value: string,
+};
+
+export const isParsedText = (part: ParsedPart): part is ParsedText => {
+ return part.type == "text"
+};
+
+export const parseContent = ({ content, tags = [] }: ContentArgs): ParsedPart[] => {
+ const result: ParsedPart[] = [];
+ let text = content.trim();
+ let buffer = "";
+
+ const parseNewline = () => {
+ const newline = first(text.match(/^\n+/));
+
+ if (newline) {
+ return [NEWLINE, newline, newline];
+ }
+ };
+
+ while (text) {
+ // The order that this runs matters
+ const part =
+ parseNewline();
+
+ if (part) {
+ if (buffer) {
+ result.push({ type: "text", value: buffer });
+ buffer = "";
+ }
+
+ const [type, raw, value] = part;
+
+ result.push({ type, value });
+ text = text.slice(raw.length);
+ } else {
+ // Instead of going character by character and re-running all the above regular expressions
+ // a million times, try to match the next word and add it to the buffer
+ const match = first(text.match(/^[\w\d]+ ?/i)) || text[0];
+
+ buffer += match;
+ text = text.slice(match.length);
+ }
+ }
+
+ if (buffer) {
+ result.push({ type: TEXT, value: buffer });
+ }
+
+ return result;
+};
diff --git a/src/lib/wrappers/EventCard.svelte b/src/lib/wrappers/EventCard.svelte
index b83057b..5a64c8d 100644
--- a/src/lib/wrappers/EventCard.svelte
+++ b/src/lib/wrappers/EventCard.svelte
@@ -2,6 +2,7 @@
import EventWrapper from "$lib/components/events/EventWrapper.svelte";
import Kind19851985 from "$lib/components/events/content/Kind19851985.svelte";
import Kind317 from "$lib/components/events/content/Kind317.svelte";
+ import ParsedContent from "$lib/components/events/content/ParsedContent.svelte";
import type { User } from "$lib/components/users/type";
import { defaults as user_defaults } from "$lib/components/users/type";
import { patch_kind, pr_status_kind } from "$lib/kinds";
@@ -27,6 +28,6 @@
{:else if event.kind === pr_status_kind}
{:else}
- {event.content}
+
{/if}
diff --git a/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte b/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte
index e7efdd8..75e20be 100644
--- a/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte
+++ b/src/routes/repo/[repo_id]/pr/[pr_id]/+page.svelte
@@ -10,6 +10,7 @@
import Thread from "$lib/wrappers/Thread.svelte";
import PrDetails from "$lib/components/prs/PRDetails.svelte";
import Container from "$lib/components/Container.svelte";
+ import ParsedContent from "$lib/components/events/content/ParsedContent.svelte";
export let data: {
repo_id: string;
@@ -63,7 +64,9 @@
- {$selected_pr_full.summary.descritpion}
+