// --------------------------------------------------------------------------- // Source-reference helpers (browser-only) // // These functions access `window` and `document` and therefore can only run in // the browser. They are intentionally NOT marked "use client" because they are // plain utility functions, not React components or hooks. Any React component // that calls them must itself be a client component. // --------------------------------------------------------------------------- import { BOOK_NAMES, CC_LILAS } from "@/lib/constants"; import { buildHighlightUrl } from "@/lib/text-highlight"; /** * Parse the current page URL into a human-readable source reference. * Returns { title, detail, url } or null if on a non-content page. */ export function getSourceReference(): { title: string; detail: string | null; url: string; } | null { const url = window.location.href; const path = window.location.pathname; const parts = path.split("/").filter(Boolean); // /books/bg/1/1 → Bhagavad-gītā As It Is, Chapter 1, Verse 1 if (parts[0] === "books" && parts.length >= 2) { const code = parts[1]; const bookName = BOOK_NAMES[code] || code.toUpperCase(); // Verse-based: /books/bg/[chapter]/[verse] if (code === "bg" && parts.length >= 4) { return { title: bookName, detail: `Chapter ${parts[2]}, Verse ${parts[3]}`, url, }; } // SB: /books/sb/[canto]/[chapter]/[verse] if (code === "sb" && parts.length >= 5) { return { title: bookName, detail: `Canto ${parts[2]}, Chapter ${parts[3]}, Verse ${parts[4]}`, url, }; } // CC: /books/cc/[lila]/[chapter]/[verse] if (code === "cc" && parts.length >= 5) { const lila = CC_LILAS[parts[2]] || parts[2]; return { title: bookName, detail: `${lila}, Chapter ${parts[3]}, Verse ${parts[4]}`, url, }; } // CC lila index: /books/cc/[lila] if (code === "cc" && parts.length === 3) { const lila = CC_LILAS[parts[2]] || parts[2]; return { title: bookName, detail: lila, url }; } // SB1962: /books/sb1962/[chapter]/[verse] if (code === "sb1962" && parts.length >= 4) { return { title: bookName, detail: `Chapter ${parts[2]}, Verse ${parts[3]}`, url, }; } // ISO/NOI: /books/iso/[mantra] if ((code === "iso" || code === "noi") && parts.length >= 3) { const num = parts[2]; const label = code === "iso" ? "Mantra" : "Text"; return { title: bookName, detail: `${label} ${num}`, url }; } // BS/MM/NBS: /books/{code}/[chapter]/[verse] if ( (code === "bs" || code === "mm" || code === "nbs") && parts.length >= 4 ) { return { title: bookName, detail: `Chapter ${parts[2]}, Verse ${parts[3]}`, url, }; } // KB: /books/kb/[volume]/[slug] if (code === "kb" && parts.length >= 4) { return { title: bookName, detail: `Volume ${parts[2]}, Chapter ${parts[3]}`, url, }; } // Generic prose: /books/{code}/[chapter] if (parts.length >= 3) { const chSlug = parts[2]; const chNum = parseInt(chSlug, 10); const detail = isNaN(chNum) ? chSlug.replace(/-/g, " ") : `Chapter ${chNum}`; return { title: bookName, detail, url }; } // Book index page return { title: bookName, detail: null, url }; } // /letters/[slug] if ( parts[0] === "letters" && parts.length === 2 && parts[1] !== "year" && parts[1] !== "recipient" && parts[1] !== "location" ) { // h1 contains "Letter to Mukunda" — use it as the title const h1 = document.querySelector("h1"); const title = h1?.textContent?.trim() || "Letter"; // The
sibling after h1 contains "15 January, 1968 · Calcutta" const metaP = document.querySelector( "header p.text-muted-foreground, header p[class*='muted']", ); const meta = metaP?.textContent?.trim() || null; return { title, detail: meta, url }; } // /essays/[slug] if (parts[0] === "essays" && parts.length === 2) { const h1 = document.querySelector("h1"); const title = h1?.textContent?.trim() || parts[1].replace(/-/g, " "); return { title, detail: "Essay by Śrīla Prabhupāda", url }; } // /journals/[slug]/[chapter] if (parts[0] === "journals" && parts.length >= 3) { const backLink = document.querySelector("header a[href^='/journals/']"); const parentTitle = backLink?.textContent?.replace(/^←\s*/, "").trim() || "Journal"; const h1 = document.querySelector("h1"); const chapterTitle = h1?.textContent?.trim() || null; return { title: parentTitle, detail: chapterTitle, url }; } // /magazines/[slug]/[issue] if (parts[0] === "magazines" && parts.length >= 3) { const backLink = document.querySelector("header a[href^='/magazines/']"); const parentTitle = backLink?.textContent?.replace(/^←\s*/, "").trim() || "Magazine"; const h1 = document.querySelector("h1"); const issueTitle = h1?.textContent?.trim() || null; return { title: parentTitle, detail: issueTitle, url }; } // /other-documents/[slug]/[chapter] if (parts[0] === "other-documents" && parts.length >= 3) { const backLink = document.querySelector( "header a[href^='/other-documents/']", ); const parentTitle = backLink?.textContent?.replace(/^←\s*/, "").trim() || "Document"; const h1 = document.querySelector("h1"); const chapterTitle = h1?.textContent?.trim() || null; return { title: parentTitle, detail: chapterTitle, url }; } // /glossary — general if (parts[0] === "glossary") { return { title: "Glossary", detail: null, url }; } // Fallback: try the h1 const h1 = document.querySelector("h1"); if (h1) { return { title: h1.textContent?.trim() || "Prabhupāda Says", detail: null, url, }; } return null; } /** * Format selected text with source attribution appended. */ export function formatCopyText(selectedText: string): string { const ref = getSourceReference(); if (!ref) return selectedText; const highlightUrl = buildHighlightUrl(selectedText); let source = `\n\nSource:\n${ref.title}`; if (ref.detail) source += `\n${ref.detail}`; source += `\n${highlightUrl}`; return selectedText + source; }