Add the profile page for users

This commit is contained in:
dtonon 2026-08-26 14:48:41 +01:00
parent bcbc70ecb8
commit f40680cbf9
13 changed files with 517 additions and 76 deletions

View file

@ -1,17 +1,38 @@
// Plain-text excerpt of a markdown body for description meta tags: the first
// paragraph that isn't a heading or a bare media URL, trimmed to `max` chars.
export function excerpt(markdown: string, max = 160): string {
const lines = markdown.split("\n").map((l) => l.trim());
const line = lines.find(
(l) => l && !l.startsWith("#") && !/^https?:\/\/\S+$/.test(l),
);
if (!line) return "";
const text = line
// Markdown inline syntax reduced to plain text.
function stripInline(text: string): string {
return text
.replace(/!\[[^\]]*\]\([^)]*\)/g, "") // images
.replace(/\[([^\]]*)\]\([^)]*\)/g, "$1") // links → label
.replace(/[*_`~]+/g, "")
.replace(/nostr:([a-z0-9]{12})[a-z0-9]*/g, "@$1…") // keep a short handle
.replace(/\s+/g, " ")
.trim();
}
function truncate(text: string, max: number): string {
return text.length > max ? text.slice(0, max - 1).trimEnd() + "…" : text;
}
function isProse(line: string): boolean {
return !!line && !line.startsWith("#") && !/^https?:\/\/\S+$/.test(line);
}
// Plain-text excerpt of a markdown body for description meta tags: the first
// paragraph that isn't a heading or a bare media URL, trimmed to `max` chars.
export function excerpt(markdown: string, max = 160): string {
const line = markdown
.split("\n")
.map((l) => l.trim())
.find(isProse);
return line ? truncate(stripInline(line), max) : "";
}
// The whole body flattened to one plain-text line, trimmed to `max` chars.
// Headings, bare media URLs, code fences and block markers are dropped.
export function summarize(markdown: string, max = 200): string {
const lines = markdown
.split("\n")
.map((l) => l.trim().replace(/^(?:>\s*|[-*+]\s+|\d+[.)]\s+)+/, ""))
.filter((l) => isProse(l) && !l.startsWith("```"));
return truncate(stripInline(lines.join(" ")), max);
}