SPB Git
3.9 KB · 59 lines typescript
1export type CitablePaper = {2  identifier: string; slug: string; title: string; subtitle?: string | null; year?: number | null;3  authors: { givenName: string; familyName: string }[];4  seriesName: string; institution: string; url: string; versionLabel?: string | null;5  doi?: string | null; ssrnId?: string | null; keywords?: string[]; abstract?: string[]; releasedOn?: string | null; releasedPrecision?: string | null; pages?: number | null; jel?: string[];6};7const esc = (s: string) => s.replace(/[{}]/g, "").replace(/&/g, "\\&").replace(/%/g, "\\%");8function monthOf(d?: string | null) { if (!d) return null; const m = Number(d.slice(5, 7)); return Number.isFinite(m) && m >= 1 && m <= 12 ? m : null; }9const MONTHS = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];10function fullTitle(p: CitablePaper) { return p.subtitle ? `${p.title}: ${p.subtitle}` : p.title; }11function authorsApa(a: CitablePaper["authors"]) {12  const parts = a.map((x) => `${x.familyName}, ${x.givenName.split(/[\s-]+/).map((g) => g[0] + ".").join("-")}`);13  if (parts.length <= 1) return parts[0] ?? "";14  if (parts.length === 2) return `${parts[0]}, & ${parts[1]}`;15  return parts.slice(0, -1).join(", ") + ", & " + parts[parts.length - 1];16}17function authorsChicago(a: CitablePaper["authors"]) {18  const first = a[0] ? `${a[0].familyName}, ${a[0].givenName}` : ""; const rest = a.slice(1).map((x) => `${x.givenName} ${x.familyName}`);19  if (!rest.length) return first; if (rest.length === 1) return `${first}, and ${rest[0]}`; return `${first}, ${rest.slice(0, -1).join(", ")}, and ${rest[rest.length - 1]}`;20}21export function citationApa(p: CitablePaper) {22  const y = p.year ?? "n.d.";23  return `${authorsApa(p.authors)} (${y}). ${fullTitle(p)} (${p.seriesName} ${p.identifier}${p.versionLabel ? ", " + p.versionLabel : ""}). ${p.institution}. ${p.doi ? `https://doi.org/${p.doi}` : p.url}`;24}25export function citationChicago(p: CitablePaper) {26  const y = p.year ?? "n.d.";27  return `${authorsChicago(p.authors)}. ${y}. “${fullTitle(p)}.” ${p.seriesName} ${p.identifier}. ${p.institution}. ${p.doi ? `https://doi.org/${p.doi}` : p.url}.`;28}29export function citationKey(p: CitablePaper) {30  const fam = (p.authors[0]?.familyName ?? "anon").normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^A-Za-z]/g, "").toLowerCase();31  return `${fam}${p.year ?? ""}${p.slug}`;32}33export function bibtex(p: CitablePaper) {34  const m = monthOf(p.releasedOn); const lines = [35    `@techreport{${citationKey(p)},`,36    `  title = {${esc(fullTitle(p))}},`,37    `  author = {${p.authors.map((a) => `${esc(a.familyName)}, ${esc(a.givenName)}`).join(" and ")}},`,38    p.year ? `  year = {${p.year}},` : null,39    m && p.releasedPrecision !== "year" ? `  month = ${MONTHS[m - 1]},` : null,40    `  institution = {${esc(p.institution)}},`,41    `  type = {${esc(p.seriesName)}},`,42    `  number = {${p.identifier}},`,43    p.versionLabel ? `  note = {Version ${p.versionLabel}},` : null,44    p.doi ? `  doi = {${p.doi}},` : null,45    `  url = {${p.url}},`,46    p.keywords?.length ? `  keywords = {${esc(p.keywords.join(", "))}},` : null,47    p.abstract?.length ? `  abstract = {${esc(p.abstract.join(" "))}},` : null,48    `}`,49  ].filter(Boolean);50  return lines.join("\n");51}52export function ris(p: CitablePaper) {53  const lines = ["TY  - RPRT", `TI  - ${fullTitle(p)}`, ...p.authors.map((a) => `AU  - ${a.familyName}, ${a.givenName}`), p.year ? `PY  - ${p.year}` : null,54    p.releasedOn ? `DA  - ${p.releasedOn.slice(0, 4)}/${p.releasedPrecision === "year" ? "" : p.releasedOn.slice(5, 7)}/${p.releasedPrecision === "day" ? p.releasedOn.slice(8, 10) : ""}/` : null,55    `PB  - ${p.institution}`, `T2  - ${p.seriesName}`, `M1  - ${p.identifier}`, p.versionLabel ? `ET  - ${p.versionLabel}` : null,56    p.doi ? `DO  - ${p.doi}` : null, `UR  - ${p.url}`, ...(p.keywords ?? []).map((k) => `KW  - ${k}`), p.abstract?.length ? `AB  - ${p.abstract.join(" ")}` : null, "ER  - "].filter(Boolean);57  return lines.join("\r\n");58}59
Files · main
Menu

Theme