site/node_modules/@citation-js/plugin-csl/lib-mjs/engines.js
2024-10-14 08:09:33 +02:00

72 lines
2.3 KiB
JavaScript

import CSL from 'citeproc';
import { templates } from './styles.js';
import { locales } from './locales.js';
const proxied = Symbol.for('proxied');
const getWrapperProxy = function (original) {
const proxy = function (state, entry) {
if (state.sys.wrapBibliographyEntry) {
const [prefix, postfix] = state.sys.wrapBibliographyEntry(this.system_id);
entry = [prefix, entry, postfix].join('');
}
return original.call(this, state, entry);
};
proxy[proxied] = true;
return proxy;
};
for (const format in CSL.Output.Formats) {
const original = CSL.Output.Formats[format]['@bibliography/entry'];
if (!original || original[proxied]) {
continue;
}
CSL.Output.Formats[format]['@bibliography/entry'] = getWrapperProxy(original);
}
function retrieveLocale(locale) {
if (locales.has(locale)) {
return locales.get(locale);
}
const unnormalised = locale.replace('-', '_');
if (locales.has(unnormalised)) {
return locales.get(unnormalised);
}
return {};
}
const engines = {};
const fetchEngine = function (style, locale, styleXml, retrieveItem, retrieveLocale) {
const engineHash = `${style}|${locale}`;
let engine;
if (engines[engineHash] instanceof CSL.Engine) {
engine = engines[engineHash];
engine.sys.retrieveItem = retrieveItem;
engine.sys.wrapBibliographyEntry = undefined;
engine.updateItems([]);
} else {
engine = engines[engineHash] = new CSL.Engine({
retrieveLocale,
retrieveItem
}, styleXml, locale, true);
}
return engine;
};
const prepareEngine = function (data, style, locale, format) {
if (!CSL.Output.Formats[format] || !CSL.Output.Formats[format]['@bibliography/entry']) {
throw new TypeError(`Cannot find format '${format}'`);
}
const items = data.reduce((store, entry) => {
store[entry.id] = entry;
return store;
}, {});
const template = templates.get(templates.has(style) ? style : 'apa');
locale = locales.has(locale) ? locale : undefined;
const callback = function (key) {
if (Object.prototype.hasOwnProperty.call(items, key)) {
return items[key];
} else {
throw new Error(`Cannot find entry with id '${key}'`);
}
};
const engine = fetchEngine(style, locale, template, callback, retrieveLocale);
engine.setOutputFormat(format);
return engine;
};
export default prepareEngine;
export { fetchEngine };