SPB Git

spb/autoscholar

Public
1.4 KB · 40 lines typescript
1export interface BibEntry {2  type: string;3  key: string;4  fields: Record<string, string>;5}67/** Minimal BibTeX parser (enough for key extraction and field checks). */8export function parseBib(text: string): BibEntry[] {9  const entries: BibEntry[] = [];10  const re = /@(\w+)\s*\{\s*([^,\s]+)\s*,/g;11  for (const m of text.matchAll(re)) {12    const type = (m[1] ?? "").toLowerCase();13    if (type === "comment" || type === "preamble" || type === "string") continue;14    const start = (m.index ?? 0) + m[0].length;15    let depth = 1;16    let i = start;17    while (i < text.length && depth > 0) {18      if (text[i] === "{") depth++;19      else if (text[i] === "}") depth--;20      i++;21    }22    const body = text.slice(start, i - 1);23    const fields: Record<string, string> = {};24    const fre = /(\w+)\s*=\s*(\{((?:[^{}]|\{[^{}]*\})*)\}|"([^"]*)"|([^,\n]+))/g;25    for (const f of body.matchAll(fre))26      fields[(f[1] ?? "").toLowerCase()] = (f[3] ?? f[4] ?? f[5] ?? "").trim();27    entries.push({ type, key: m[2] ?? "", fields });28  }29  return entries;30}3132export function citeKeysInTex(tex: string): string[] {33  const keys = new Set<string>();34  const re =35    /\\(?:cite|citep|citet|citeauthor|citeyear|parencite|textcite|autocite|citealp|citealt|nocite)\*?(?:\[[^\]]*\]){0,2}\{([^}]+)\}/g;36  for (const m of tex.matchAll(re))37    for (const k of (m[1] ?? "").split(",")) if (k.trim() && k.trim() !== "*") keys.add(k.trim());38  return [...keys];39}40
Files · main
Menu

Theme