72 lines
2.3 KiB
JavaScript
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 };
|