mirror of
https://github.com/anotherhadi/blog.git
synced 2026-05-20 21:42:33 +02:00
Notes edit and remove tests
Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { getCollection, render } from "astro:content";
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import { Shield, ChevronLeft, List, PanelRight } from "@lucide/astro";
|
||||
import Author from "../../components/Author.astro";
|
||||
import { getCategory, extractInlineHashtags } from "../../utils/notes";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const notes = await getCollection("notes");
|
||||
@@ -17,12 +18,6 @@ const { Content } = await render(entry);
|
||||
|
||||
const allNotes = await getCollection("notes");
|
||||
const sortedNotes = allNotes.sort((a, b) => a.data.title.localeCompare(b.data.title));
|
||||
function getCategory(n: { id: string; data: { category?: string } }): string {
|
||||
if (n.data.category) return n.data.category;
|
||||
const parts = n.id.split("/");
|
||||
return parts.length > 1 ? parts[0] : "General";
|
||||
}
|
||||
|
||||
const categories = [...new Set(allNotes.map(getCategory))].sort();
|
||||
|
||||
function formatDate(date: Date) {
|
||||
@@ -30,7 +25,8 @@ function formatDate(date: Date) {
|
||||
}
|
||||
|
||||
function extractLinks(body: string): string[] {
|
||||
const re = /\(\/notes\/([^)#\s]+)\)/g;
|
||||
// Capture slug before optional #fragment: (/notes/slug) or (/notes/slug#section)
|
||||
const re = /\(\/notes\/([^)#\s]+)(?:#[^)\s]*)?\)/g;
|
||||
const ids: string[] = [];
|
||||
let m;
|
||||
while ((m = re.exec(body)) !== null) ids.push(m[1]);
|
||||
@@ -57,22 +53,28 @@ const graphEdges = [
|
||||
...backlinks.map((n) => ({ from: n.id, to: entry.id })),
|
||||
];
|
||||
|
||||
function extractInlineHashtags(body: string): string[] {
|
||||
const re = /#(\w+)/g;
|
||||
const tags: string[] = [];
|
||||
let m;
|
||||
while ((m = re.exec(body)) !== null) tags.push(m[1].toLowerCase());
|
||||
return [...new Set(tags)];
|
||||
// Mirrors github-slugger exactly: keeps _, keeps unicode letters/numbers, spaces → hyphens
|
||||
function slugify(text: string) {
|
||||
return text
|
||||
.toLowerCase()
|
||||
.replace(/[^\p{L}\p{N}\s_-]/gu, "") // keep letters (unicode), numbers, spaces, _, -
|
||||
.trim()
|
||||
.replace(/ +/g, "-"); // spaces → hyphens (github-slugger does exactly this)
|
||||
}
|
||||
|
||||
function slugify(text: string) {
|
||||
return text.toLowerCase().replace(/`[^`]*`/g, "").replace(/[^\w\s-]/g, "").trim().replace(/[\s_]+/g, "-");
|
||||
}
|
||||
const headings: { depth: number; text: string; id: string }[] = [];
|
||||
const headingRe = /^(#{2,4}) (.+)$/gm;
|
||||
let hm;
|
||||
while ((hm = headingRe.exec(entry.body ?? "")) !== null) {
|
||||
const raw = hm[2].trim().replace(/\*\*|__|\*|_|`/g, "");
|
||||
// Strip markdown formatting while preserving literal _ (word-internal underscores like my_var)
|
||||
// Paired markers are stripped to their content; lone * are removed; _ only stripped at word boundaries
|
||||
const raw = hm[2].trim()
|
||||
.replace(/`[^`]*`/g, "") // `code` → remove
|
||||
.replace(/\*\*(.*?)\*\*/g, "$1") // **bold** → text
|
||||
.replace(/(?<!\p{L}\p{N})__(.*?)__(?!\p{L}\p{N})/gu, "$1") // __bold__ → text
|
||||
.replace(/\*(.*?)\*/g, "$1") // *italic* → text
|
||||
.replace(/(?<!\p{L}\p{N})_(.*?)_(?!\p{L}\p{N})/gu, "$1") // _italic_ → text
|
||||
.replace(/[*]/g, ""); // orphan * markers
|
||||
headings.push({ depth: hm[1].length, text: raw, id: slugify(raw) });
|
||||
}
|
||||
---
|
||||
@@ -271,6 +273,8 @@ while ((hm = headingRe.exec(entry.body ?? "")) !== null) {
|
||||
<canvas
|
||||
id="note-graph"
|
||||
height="190"
|
||||
role="img"
|
||||
aria-label="Graph of linked notes"
|
||||
style="width:100%; display:block; background: oklch(2% 0 0); cursor:default;"
|
||||
></canvas>
|
||||
{graphNodes.length <= 1 && (
|
||||
|
||||
Reference in New Issue
Block a user