SPB Git
1.9 KB · 28 lines typescript
1/** Working paper identifiers: permanent, never renumbered, gaps allowed. `WP38` ⇄ slug `wp38`; `FIRC0002` ⇄ slug `firc2`. */2export type ParsedId = { seriesCode: string; number: number; identifier: string; slug: string };3export function makeIdentifier(seriesCode: string, number: number): ParsedId {4  const code = seriesCode.toUpperCase();5  const identifier = code === "WP" ? `WP${String(number).padStart(2, "0")}` : `${code}${String(number).padStart(4, "0")}`;6  return { seriesCode: code, number, identifier, slug: `${code.toLowerCase()}${number}` };7}8/** Accepts `wp38`, `WP38`, `WP038`, `wp-38`, `firc2`, `FIRC0002`, `38` (defaults to WP). */9export function parseIdentifier(input: string): ParsedId | null {10  const s = input.trim().toLowerCase().replace(/[\s_-]+/g, "");11  const m = /^([a-z]*)0*(\d{1,5})$/.exec(s); if (!m) return null;12  const code = m[1] === "" ? "wp" : m[1]; const n = Number(m[2]); if (!Number.isFinite(n) || n <= 0) return null;13  return makeIdentifier(code, n);14}15/** Version labels: `v2`, `v1.1`, `2.0` → version number 2 / label "v2.0". Minor versions are kept in the label only. */16export function parseVersionLabel(v: string): { versionNo: number; label: string } | null {17  const m = /^v?(\d+)(?:\.(\d+))?$/i.exec(v.trim()); if (!m) return null;18  return { versionNo: Number(m[1]), label: `v${m[1]}${m[2] ? "." + m[2] : ""}` };19}20/** Detect a working paper number in text extracted from a title page. */21export function detectWpNumber(text: string): { seriesCode: string; number: number } | null {22  const t = text.replace(/\s+/g, " ");23  const firc = /FIRC[^0-9]{0,40}?(?:No\.?|N[o°]|Paper)\s*0*(\d{1,4})/i.exec(t); if (firc) return { seriesCode: "FIRC", number: Number(firc[1]) };24  const wp = /Working\s+Paper\s+(?:No\.?|N[o°]|Number|#)\s*0*(\d{1,4})/i.exec(t) ?? /\bWP\s*0*(\d{1,4})\b/.exec(t);25  if (wp) return { seriesCode: "WP", number: Number(wp[1]) };26  return null;27}28
Files · main
Menu

Theme