Adds support for merging adjacent citations (#2875)

This commit is contained in:
Adomas Ven 2022-10-21 10:17:35 +03:00 committed by GitHub
parent a2db01c633
commit 2fa67bae64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 7 deletions

View file

@ -61,6 +61,7 @@ Zotero.HTTPIntegrationClient.Application = function() {
this.supportedNotes = ['footnotes'];
this.supportsImportExport = false;
this.supportsTextInsertion = false;
this.supportsCitationMerging = false;
this.processorName = "HTTP Integration";
};
Zotero.HTTPIntegrationClient.Application.prototype = {
@ -70,6 +71,7 @@ Zotero.HTTPIntegrationClient.Application.prototype = {
this.supportedNotes = result.supportedNotes || this.supportedNotes;
this.supportsImportExport = result.supportsImportExport || this.supportsImportExport;
this.supportsTextInsertion = result.supportsTextInsertion || this.supportsTextInsertion;
this.supportsCitationMerging = result.supportsCitationMerging || this.supportsCitationMerging;
this.processorName = result.processorName || this.processorName;
return new Zotero.HTTPIntegrationClient.Document(result.documentID, this.processorName);
}
@ -168,6 +170,10 @@ Zotero.HTTPIntegrationClient.Field = function(documentID, json) {
this._code = json.code;
this._text = json.text;
this._noteIndex = json.noteIndex;
this._adjacent = json.adjacent;
if (this._adjacent !== 'undefined') {
this.isAdjacentToNextField = this._isAdjacentToNextField;
}
};
Zotero.HTTPIntegrationClient.Field.prototype = {};
@ -202,3 +208,6 @@ Zotero.HTTPIntegrationClient.Field.prototype.getNoteIndex = async function() {
Zotero.HTTPIntegrationClient.Field.prototype.equals = async function(arg) {
return this._id === arg._id;
};
Zotero.HTTPIntegrationClient.Field.prototype._isAdjacentToNextField = async function() {
return this._adjacent;
}

View file

@ -798,7 +798,8 @@ Zotero.Integration.Interface.prototype.addEditBibliography = Zotero.Promise.coro
* @return {Promise}
*/
Zotero.Integration.Interface.prototype.refresh = async function() {
await this._session.init(true, false)
await this._session.init(true, false);
this._session.shouldMerge = true;
this._session.reload = this._session.reload || this._session.data.prefs.delayCitationUpdates;
await this._session.updateFromDocument(FORCE_CITATIONS_REGENERATE);
@ -1067,15 +1068,24 @@ Zotero.Integration.Session.prototype._processFields = async function () {
if (!this._fields) {
throw new Error("_processFields called without fetching fields first");
}
let adjacentCitations = [];
for (var i = 0; i < this._fields.length; i++) {
let field = await Zotero.Integration.Field.loadExisting(this._fields[i]);
if (field.type === INTEGRATION_TYPE_ITEM) {
var noteIndex = await field.getNoteIndex(),
data = await field.unserialize(),
citation = new Zotero.Integration.Citation(field, data, noteIndex);
await this.addCitation(i, noteIndex, citation);
if (this.shouldMerge && typeof field.isAdjacentToNextField === 'function' && await field.isAdjacentToNextField()) {
adjacentCitations.push(citation);
this._deleteFields[i] = true;
continue;
}
await this.addCitation(i, noteIndex, citation, adjacentCitations);
if (adjacentCitations.length) {
adjacentCitations = [];
}
} else if (field.type === INTEGRATION_TYPE_BIBLIOGRAPHY) {
if (this.ignoreEmptyBibliography && (await field.getText()).trim() === "") {
this._removeCodeFields[i] = true;
@ -1957,9 +1967,17 @@ Zotero.Integration.Session.prototype.importDocument = async function() {
/**
* Adds a citation to the arrays representing the document
*/
Zotero.Integration.Session.prototype.addCitation = async function (index, noteIndex, citation) {
Zotero.Integration.Session.prototype.addCitation = async function (index, noteIndex, citation, adjacentCitations=[]) {
index = parseInt(index, 10);
if (adjacentCitations.length) {
Zotero.debug(`Merging adjacent citations ${adjacentCitations.map(c => c.citationID)} to citation ${citation.citationID}`);
for (let adjacentCitation of adjacentCitations) {
citation.mergeCitation(adjacentCitation);
}
this.updateIndices[index] = true;
}
var action = await citation.loadItemData();
if (action == Zotero.Integration.REMOVE_CODE) {
@ -2623,7 +2641,7 @@ Zotero.Integration.Field = class {
throw new Error("Trying to instantiate Integration.Field with Integration.Field, not doc field");
}
for (let func of Zotero.Integration.Field.INTERFACE) {
if (!(func in this)) {
if (!(func in this) && (func in field)) {
this[func] = field[func].bind(field);
}
}
@ -2682,7 +2700,7 @@ Zotero.Integration.Field = class {
}
};
Zotero.Integration.Field.INTERFACE = ['delete', 'removeCode', 'select', 'setText',
'getText', 'setCode', 'getCode', 'equals', 'getNoteIndex'];
'getText', 'setCode', 'getCode', 'equals', 'getNoteIndex', 'isAdjacentToNextField'];
/**
* Load existing field in document and return correct instance of field type
@ -2921,6 +2939,23 @@ Zotero.Integration.Citation = class {
this._field = citationField;
}
/**
* Merge citation items and remove duplicates, unless the items have different
* @param citation {Citation}
*/
mergeCitation(citation) {
let items = this.citationItems.concat(citation.citationItems);
let addedItems = new Set();
this.citationItems = []
for (let item of items) {
if (addedItems.has(item.id)) {
continue;
}
addedItems.add(item.id);
this.citationItems.push(item);
}
}
/**
* Load citation item data
* @param {Boolean} [promptToReselect=true] - will throw a MissingItemException if false