Cache CiteProc Engine instances, pre-cache for Quick Copy (#5399)
This commit is contained in:
parent
b95f9eea89
commit
7b56a3eefe
4 changed files with 76 additions and 18 deletions
|
@ -831,7 +831,7 @@ var Zotero_File_Interface = new function() {
|
|||
|
||||
clipboardService.setData(transferable, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
|
||||
Zotero.debug(`Copied bibliography to clipboard in ${new Date() - d} ms}`);
|
||||
Zotero.debug(`Copied bibliography to clipboard in ${new Date() - d} ms`);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2231,10 +2231,13 @@ Zotero.Integration.Session.prototype.restoreProcessorState = function() {
|
|||
}
|
||||
}
|
||||
if (!Zotero.Prefs.get('cite.useCiteprocRs')) {
|
||||
// Due to a bug in citeproc-js there are disambiguation issues after changing items in Zotero library
|
||||
// and rebuilding the processor state, so we reinitialize the processor altogether
|
||||
let style = Zotero.Styles.get(this.data.style.styleID);
|
||||
this.style = style.getCiteProc(this.data.style.locale, this.outputFormat, this.data.prefs.automaticJournalAbbreviations);
|
||||
// Due to a bug in citeproc-js there are disambiguation issues after
|
||||
// modifying items in Zotero, even after calling rebuildProcessorState(),
|
||||
// because rebuildProcessorState() doesn't reset three properties of the
|
||||
// processor (registry, tmp, and disambiguate) used for disambiguation.
|
||||
// Call the deprecated restoreProcessorState(), which resets everything.
|
||||
// Revisit if restoreProcessorState() is removed.
|
||||
this.style.restoreProcessorState();
|
||||
}
|
||||
this.style.rebuildProcessorState(citations, this.outputFormat, uncited);
|
||||
}
|
||||
|
|
|
@ -279,8 +279,7 @@ Zotero.QuickCopy = new function() {
|
|||
else if (format.mode == 'bibliography') {
|
||||
items = items.filter(item => !item.isNote());
|
||||
|
||||
// determine locale preference
|
||||
var locale = format.locale ? format.locale : Zotero.Prefs.get('export.quickCopy.locale');
|
||||
var locale = _getLocale(format);
|
||||
|
||||
// Copy citations if shift key pressed
|
||||
if (modified) {
|
||||
|
@ -354,9 +353,21 @@ Zotero.QuickCopy = new function() {
|
|||
translator.cacheCode = true;
|
||||
await Zotero.Translators.getCodeForTranslator(translator);
|
||||
}
|
||||
else if (format.mode === 'bibliography') {
|
||||
let style = Zotero.Styles.get(format.id);
|
||||
let locale = _getLocale(format);
|
||||
// Cache CiteProc instances for HTML and text
|
||||
style.getCiteProc(locale, 'html');
|
||||
style.getCiteProc(locale, 'text');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function _getLocale(format) {
|
||||
return format.locale || Zotero.Prefs.get('export.quickCopy.locale');
|
||||
}
|
||||
|
||||
|
||||
var _loadFormattedNames = Zotero.Promise.coroutine(function* () {
|
||||
var t = new Date;
|
||||
Zotero.debug("Loading formatted names for Quick Copy");
|
||||
|
|
|
@ -39,6 +39,19 @@ Zotero.Styles = new function() {
|
|||
};
|
||||
|
||||
this.CSL_VALIDATOR_URL = "resource://zotero/csl-validator.js";
|
||||
|
||||
this._memoryPressureObserver = {
|
||||
observe: (subject, topic) => {
|
||||
if (topic !== 'memory-pressure') {
|
||||
return;
|
||||
}
|
||||
for (let style of Object.values(this.getAll())) {
|
||||
style.clearEngineCache();
|
||||
}
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(['nsISupportsWeakReference']),
|
||||
};
|
||||
Services.obs.addObserver(this._memoryPressureObserver, 'memory-pressure', /* ownsWeak */ true);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -201,7 +214,7 @@ Zotero.Styles = new function() {
|
|||
/**
|
||||
* Gets a style with a given ID
|
||||
* @param {String} id
|
||||
* @param {Boolean} skipMappings Don't automatically return renamed style
|
||||
* @param {Boolean} [skipMappings] Don't automatically return renamed style
|
||||
*/
|
||||
this.get = function (id, skipMappings) {
|
||||
if (!_initialized) {
|
||||
|
@ -681,22 +694,39 @@ Zotero.Style = function (style, path) {
|
|||
if(this.source === this.styleID) {
|
||||
throw new Error("Style with ID "+this.styleID+" references itself as source");
|
||||
}
|
||||
|
||||
this._cachedEngines = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a citeproc-js CSL.Engine instance
|
||||
* @param {String} locale Locale code
|
||||
* @param {String} format Output format one of [rtf, html, text]
|
||||
* @param {Boolean} automaticJournalAbbreviations Whether to automatically abbreviate titles
|
||||
* @param {String} [format] Output format one of [rtf, html, text]
|
||||
* @param {Boolean} [automaticJournalAbbreviations] Whether to automatically abbreviate titles
|
||||
*/
|
||||
Zotero.Style.prototype.getCiteProc = function(locale, format, automaticJournalAbbreviations) {
|
||||
if(!locale) {
|
||||
var locale = Zotero.locale;
|
||||
if(!locale) {
|
||||
var locale = 'en-US';
|
||||
}
|
||||
}
|
||||
locale = locale || Zotero.locale || 'en-US';
|
||||
format = format || 'text';
|
||||
automaticJournalAbbreviations = !!automaticJournalAbbreviations;
|
||||
|
||||
let useCiteprocRs = Zotero.Prefs.get('cite.useCiteprocRs');
|
||||
|
||||
// We can cache the Engine instance if we aren't using citeproc-rs
|
||||
// and this is an installed style
|
||||
let cacheKey = !useCiteprocRs && this.path
|
||||
? JSON.stringify({ locale, format, automaticJournalAbbreviations })
|
||||
: null;
|
||||
if (cacheKey && this._cachedEngines.has(cacheKey)) {
|
||||
let engine = this._cachedEngines.get(cacheKey);
|
||||
// Due to a bug in citeproc-js there are disambiguation issues after
|
||||
// modifying items in Zotero. The lighter-weight rerebuildProcessorState()
|
||||
// doesn't reset three properties of the processor (registry, tmp, and
|
||||
// disambiguate) used for disambiguation, so we need to call the
|
||||
// deprecated restoreProcessorState(), which resets everything.
|
||||
// Revisit if restoreProcessorState() is removed.
|
||||
engine.restoreProcessorState();
|
||||
return engine;
|
||||
}
|
||||
|
||||
// APA and some similar styles capitalize the first word of subtitles
|
||||
var uppercaseSubtitlesRE = /^apa($|-)|^academy-of-management($|-)|^(freshwater-science)/;
|
||||
|
@ -763,7 +793,8 @@ Zotero.Style.prototype.getCiteProc = function(locale, format, automaticJournalAb
|
|||
|
||||
try {
|
||||
var citeproc;
|
||||
if (Zotero.Prefs.get('cite.useCiteprocRs')) {
|
||||
var engineDesc;
|
||||
if (useCiteprocRs) {
|
||||
citeproc = new Zotero.CiteprocRs.Engine(
|
||||
new Zotero.Cite.System({
|
||||
automaticJournalAbbreviations,
|
||||
|
@ -775,6 +806,7 @@ Zotero.Style.prototype.getCiteProc = function(locale, format, automaticJournalAb
|
|||
format == 'text' ? 'plain' : format,
|
||||
overrideLocale
|
||||
);
|
||||
engineDesc = 'CiteprocRs';
|
||||
}
|
||||
else {
|
||||
citeproc = new Zotero.CiteProc.CSL.Engine(
|
||||
|
@ -791,15 +823,27 @@ Zotero.Style.prototype.getCiteProc = function(locale, format, automaticJournalAb
|
|||
citeproc.opt.development_extensions.wrap_url_and_doi = true;
|
||||
// Don't try to parse author names. We parse them in itemToCSLJSON
|
||||
citeproc.opt.development_extensions.parse_names = false;
|
||||
engineDesc = 'CSL';
|
||||
}
|
||||
|
||||
// Cache the Engine instance if allowed
|
||||
if (cacheKey) {
|
||||
this._cachedEngines.set(cacheKey, citeproc);
|
||||
Zotero.debug(`Caching ${engineDesc}.Engine instance with ${cacheKey} for ${this.styleID}`);
|
||||
}
|
||||
|
||||
return citeproc;
|
||||
} catch(e) {
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
Zotero.Style.prototype.clearEngineCache = function () {
|
||||
this._cachedEngines.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* Temporarily substitute `event-title` for `event`
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue