UNPKG

bibcite

Version:
121 lines (108 loc) 4.01 kB
// AVOID DOM RELATED STUFF HERE! -> allow use in build-time mechanism import { Data } from "csl-json"; import { Citation } from "./citation"; import { BibReference } from "./bibReference"; import { CitationKeyUse, BibSortedCitationKeyUse, InsertionSortedCitationKeyUse, } from "./key-use-tracker"; import { BibOrder } from "./order"; export class Bibliography { _bib: Map<string, Data>; // hashed and sorted CSL-json data _reference_lists: BibReference[] = []; // list of <bib-reference> elements _cite_key_use: CitationKeyUse; _bibOrder: BibOrder; constructor(csl_json: Data[], sorting: (c1: Data, c2: Data) => number) { this._bibOrder = { comparison: sorting, inform_citations: false }; this.bib = csl_json; if (this._bibOrder.comparison.name === "insertion") { this._cite_key_use = new InsertionSortedCitationKeyUse(new Map()); } else if (this._bibOrder.inform_citations) { this._cite_key_use = new BibSortedCitationKeyUse( new Map(), new Map(Array.from(this._bib.keys()).map((k, idx) => [k, idx])) ); } else { this._cite_key_use = new CitationKeyUse(new Map()); } } sort_and_hash(csl_json: Data[], comparison: (c1: Data, c2: Data) => number) { return new Map( csl_json // sort function should be argument of this function and be better .sort((a, b) => comparison(a, b)) .map((citation) => [citation.id, citation]) ); } set sorting(new_sorting: BibOrder) { this._bib = this.sort_and_hash(this.bib, new_sorting.comparison); if ( new_sorting.comparison.name === "insertion" && this._bibOrder.comparison.name != "insertion" ) { // we need to track insertion order this._cite_key_use = new InsertionSortedCitationKeyUse( this._cite_key_use.get() ); } else if (new_sorting.inform_citations) { this._cite_key_use = new BibSortedCitationKeyUse( this._cite_key_use.get(), new Map(Array.from(this._bib.keys()).map((k, idx) => [k, idx])) ); } else { // we can stop keeping track this._cite_key_use = new CitationKeyUse(this._cite_key_use.get()); } this._bibOrder = new_sorting; } registerCitation(ci: Citation) { // important side-effect in if clause! if (this._cite_key_use.add(ci).need_ref_update) { for (const bib_ref of this._reference_lists) { bib_ref.usedReferences = this.used_references(); } } ci.bibData = this._bib.get(ci.key); console.log(`[Bibliography] Registered ${ci.key}`); } unregisterCitation(ci: Citation) { // important side-effect in if clause! if (this._cite_key_use.remove(ci).need_ref_update) { for (const bib_ref of this._reference_lists) { bib_ref.usedReferences = this.used_references(); } } } get citations(): Citation[] { return this._cite_key_use.citations; } used_references(): { index: number; csl_data: Data }[] { if (this._bibOrder.comparison.name === "insertion") { return Array.from(this._cite_key_use.get()).map(([key, entry]) => { return { index: entry.index, csl_data: this._bib.get(key) }; }); } else { return Array.from(this._bib) .filter(([key, _]) => this._cite_key_use.has(key)) .map(([_, csl_data], idx) => { return { index: idx, csl_data: csl_data }; }); } } registerReferenceList(bibReference: BibReference) { this._reference_lists.push(bibReference); bibReference.usedReferences = this.used_references(); console.log("[Bibliography] Registered ReferenceList"); } unregisterReferenceList(referenceElement) { this._reference_lists = this._reference_lists.filter( (l) => l != referenceElement ); console.log("[Bibliography] Unregistered ReferenceList"); } set bib(value: Data[]) { this._bib = this.sort_and_hash(value, this._bibOrder.comparison); console.log("[Bibliography] Sorted & Hashed CSL:", this._bib); } }