Update citeproc usage logic. See #1638

This commit is contained in:
Adomas Venčkauskas 2019-02-12 10:03:17 +02:00
parent a931c2ba51
commit 9410094ad8

View file

@ -1002,14 +1002,14 @@ Zotero.Integration.Fields.prototype.updateDocument = Zotero.Promise.coroutine(fu
Zotero.Integration.Fields.prototype._updateDocument = async function(forceCitations, forceBibliography,
ignoreCitationChanges) {
if(this.progressCallback) {
var nFieldUpdates = Object.keys(this._session.updateIndices).length;
var nFieldUpdates = Object.keys(this._session.processIndices).length;
if(this._session.bibliographyHasChanged || forceBibliography) {
nFieldUpdates += this._bibliographyFields.length*5;
}
}
var nUpdated=0;
for(var i in this._session.updateIndices) {
for(var i in this._session.processIndices) {
if(this.progressCallback && nUpdated % 10 == 0) {
try {
this.progressCallback(75+(nUpdated/nFieldUpdates)*25);
@ -1257,7 +1257,6 @@ Zotero.Integration.Fields.prototype.addEditCitation = async function (field) {
}
var fieldIndex = await fieldIndexPromise;
this._session.updateIndices[fieldIndex] = true;
// Make sure session is updated
await citationsByItemIDPromise;
return [fieldIndex, field, io.citation];
@ -1371,10 +1370,12 @@ Zotero.Integration.Session.prototype.resetRequest = function(doc) {
// citations that are new to the document will be marked
// as new, so that they are correctly loaded into and processed with citeproc
this.newIndices = {};
// After the processing of new indices with citeproc, some
// citations require additional work (because of disambiguation, numbering changes, etc)
// and will be marked for an additional reprocessing with citeproc to retrieve updated text
// Citations that are not new to the session but where the item metadata
// has changed will be marked in updateIndices
this.updateIndices = {};
// Citations that require updating in the document will be marked in
// processIndices
this.processIndices = {};
// When processing citations this list will be checked for citations that are new to the document
// (i.e. copied from somewhere else) and marked as newIndices to be processed with citeproc if
@ -1616,7 +1617,7 @@ Zotero.Integration.Session.prototype.addCitation = Zotero.Promise.coroutine(func
}
// Deal with citations that are copied into the document from somewhere else
// and have not been added to the processor yet
if (!this.oldCitations.has(citation.citationID) && !this.reload) {
if (!this.oldCitations.has(citation.citationID)) {
this.newIndices[index] = true;
}
if (this.regenAll && !this.newIndices[index]) {
@ -1626,16 +1627,15 @@ Zotero.Integration.Session.prototype.addCitation = Zotero.Promise.coroutine(func
this.documentCitationIDs[citation.citationID] = index;
});
Zotero.Integration.Session.prototype.getCiteprocLists = function(excludeNew) {
Zotero.Integration.Session.prototype.getCiteprocLists = function() {
var citations = [];
var fieldToCitationIdxMapping = {};
var citationToFieldIdxMapping = {};
var i = 0;
// This relies on the order of citationsByIndex keys being stable and sorted in ascending order
// Which it seems to currently be true for every modern JS engine, so we're probably fine
for(let idx in this.citationsByIndex) {
if (excludeNew && this.newIndices[idx]) {
i++;
for (let idx in this.citationsByIndex) {
if (idx in this.newIndices) {
continue;
}
citations.push([this.citationsByIndex[idx].citationID, this.citationsByIndex[idx].properties.noteIndex]);
@ -1654,10 +1654,17 @@ Zotero.Integration.Session.prototype._updateCitations = async function () {
Zotero.debug("Integration: Indices of updated citations");
Zotero.debug(Object.keys(this.updateIndices));
var [citations, fieldToCitationIdxMapping, citationToFieldIdxMapping] = this.getCiteprocLists();
let citations, fieldToCitationIdxMapping, citationToFieldIdxMapping;
for (let indexList of [this.newIndices, this.updateIndices]) {
for (let index in indexList) {
if (indexList == this.newIndices) {
delete this.newIndices[index];
delete this.updateIndices[index];
[citations, fieldToCitationIdxMapping, citationToFieldIdxMapping] =
this.getCiteprocLists()
}
this.processIndices[index] = true;
// Jump to next event loop step for UI updates
await Zotero.Promise.delay();
index = parseInt(index);
@ -1665,17 +1672,9 @@ Zotero.Integration.Session.prototype._updateCitations = async function () {
var citation = this.citationsByIndex[index];
if (!citation) continue;
citation = citation.toJSON();
let citationsPre = citations.slice(0, citationToFieldIdxMapping[index]);
var citationsPost;
if (index in this.newIndices) {
citationsPost = [];
delete this.newIndices[index];
// If this item will need updating later citation processing will reset this index later in the loop
delete this.updateIndices[index];
} else {
citationsPost = citations.slice(citationToFieldIdxMapping[index]+1);
}
var citationsPost = citations.slice(citationToFieldIdxMapping[index]+1);
Zotero.debug("Integration: style.processCitationCluster("+citation.toSource()+", "+citationsPre.toSource()+", "+citationsPost.toSource());
let [info, newCitations] = this.style.processCitationCluster(citation, citationsPre, citationsPost);
@ -1684,11 +1683,11 @@ Zotero.Integration.Session.prototype._updateCitations = async function () {
for (let citationInfo of newCitations) {
let idx = fieldToCitationIdxMapping[citationInfo[0]], text = citationInfo[1];
this.updateIndices[idx] = true;
this.citationsByIndex[idx].text = text;
}
}
[citations, fieldToCitationIdxMapping, citationToFieldIdxMapping] =
this.getCiteprocLists();
}
}