From 1da48cf8d2e53b3a4638dc4aeb63dad8380d80eb Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sun, 13 Jun 2010 22:53:57 +0000 Subject: [PATCH] - implement previewCitationCluster(), restoreProcessorState(), new "bibchange" flag in processCitationCluster() output, and new opt.sort_citations flag in word processor integration - upgrade to citeproc-js 1.0.29 From Frank's 1.0.25 announcement: Provide new command, previewCitationCluster(), that returns string for hypothetical citation at specified position, without affecting processor state. Fix bug that would have cause appendCitationCluster() to run updateItems() unnecessarily. Provide for forced generation of citationID, for internal use in previewing. From Frank's 1.0.26 announcement: Implement new command restoreProcessorState(), for use in, er, restoring the processor state, when position variables and citation sort keys are already known. From Frank's 1.0.27 announcement: This fixes a couple of obvious problems in the code of the new restoreProcessorState() command. From Frank's 1.0.28 announcement: This version introduces a significant change to the return value of processCitationCluster(). It is now an array with two elements, the first being a JS object that serves as a data segment, and the second the list of two-element arrays representing insertion indexes and strings for insertion (as previously documented). An API change of this scale probably calls for some more visible sign in the version numbering, but the original statement on versioning says that the major and minor numbers will align with the CSL schema, so we stay at level 1.0. The data segment referred to above contains just one element currently, "bibchange", which is true if processing the citation results in any change affecting the bibliography. This release also introduces one change and one addition to style configuration flags. The flag at citation.opt["citation-number-sort"] has been moved to opt.citation_number_sort, for clarity and consistency. A new flag, opt.sort_citations, is true if citations are sorted by the style in any way. From Frank's 1.0.29 announcement: Complete reimplementation of cite-level disambiguation. The new code is more compact and maintainable, and avoids thrashing behavior that afflicted the previous code when a large number of cites required both add-names and year-suffix disambiguation. Suppress year suffix when fresh ambig keys are generated. Inserts by a plugin affecting year suffixes should now be correctly handled. --- .../zotero/integration/addCitationDialog.js | 30 +- chrome/content/zotero/xpcom/citeproc.js | 833 +++++++++--------- chrome/content/zotero/xpcom/integration.js | 79 +- 3 files changed, 502 insertions(+), 440 deletions(-) diff --git a/chrome/content/zotero/integration/addCitationDialog.js b/chrome/content/zotero/integration/addCitationDialog.js index 11dc408e1..5014501af 100644 --- a/chrome/content/zotero/integration/addCitationDialog.js +++ b/chrome/content/zotero/integration/addCitationDialog.js @@ -547,21 +547,25 @@ var Zotero_Citation_Dialog = new function () { } else { var items = itemsView.getSelectedItems(true); // treeview from selectItemsDialog.js - var citationItem = {}; - citationItem.id = items[0]; - for(var property in _preserveData) { - if(property == "label") { - citationItem[property] = _locatorNameArray[document.getElementById(property).selectedIndex]; - } else { - citationItem[property] = document.getElementById(property)[_preserveData[property]]; + if(items.length) { + var citationItem = {}; + citationItem.id = items[0]; + for(var property in _preserveData) { + if(property == "label") { + citationItem[property] = _locatorNameArray[document.getElementById(property).selectedIndex]; + } else { + citationItem[property] = document.getElementById(property)[_preserveData[property]]; + } } + + if(citationItem["locator"] == "") { + citationItem["locator"] = citationItem["label"] = undefined; + } + + io.citation.citationItems = [citationItem]; + } else { + io.citation.citationItems = []; } - - if(citationItem["locator"] == "") { - citationItem["locator"] = citationItem["label"] = undefined; - } - - io.citation.citationItems = [citationItem]; } } diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js index 4da5d7606..fe377de7a 100644 --- a/chrome/content/zotero/xpcom/citeproc.js +++ b/chrome/content/zotero/xpcom/citeproc.js @@ -61,6 +61,8 @@ var CSL = { error: function (str) { print(str); }, + PREVIEW: "Just for laughs.", + ASSUME_ALL_ITEMS_REGISTERED: "Assume we have registered all items.", START: 0, END: 1, SINGLETON: 2, @@ -1055,11 +1057,31 @@ CSL.setDecorations = function (state, attributes) { } return ret; }; +CSL.compareAmbigConfig = function(a, b) { + var ret, pos, len, ppos, llen; + if (a.names.length !== b.names.length) { + return 1; + } else { + for (pos = 0, len = a.names.length; pos < len; pos += 1) { + if (a.names[pos] !== b.names[pos]) { + return 1; + } else { + for (ppos = 0, llen = a.names[pos]; ppos < llen; ppos += 1) { + if (a.givens[pos][ppos] !== b.givens[pos][ppos]) { + return 1; + } + } + } + } + } + return 0; +}; CSL.cloneAmbigConfig = function (config, oldconfig, itemID) { var ret, param, pos, ppos, len, llen; ret = {}; ret.names = []; ret.givens = []; + ret.year_suffix_citeform = false; ret.year_suffix = false; ret.disambiguate = false; len = config.names.length; @@ -1088,14 +1110,24 @@ CSL.cloneAmbigConfig = function (config, oldconfig, itemID) { this.tmp.taintedItemIDs[itemID] = true; oldconfig = false; } - ret.year_suffix = config.year_suffix; - if (oldconfig && oldconfig.year_suffix !== config.year_suffix) { - this.tmp.taintedItemIDs[itemID] = true; - oldconfig = false; - } ret.disambiguate = config.disambiguate; return ret; }; +CSL.getAmbigConfig = function () { + var config, ret; + config = this.tmp.disambig_request; + if (!config) { + config = this.tmp.disambig_settings; + } + ret = CSL.cloneAmbigConfig(config); + return ret; +}; +CSL.getMaxVals = function () { + return this.tmp.names_max.mystack.slice(); +}; +CSL.getMinVal = function () { + return this.tmp["et-al-min"]; +}; CSL.tokenExec = function (token, Item, item) { var next, maybenext, exec, pos, len, debug; debug = false; @@ -1432,7 +1464,7 @@ CSL.dateParser = function (txt) { }; CSL.Engine = function (sys, style, lang, xmlmode) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.24"; + this.processor_version = "1.0.29"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -1486,6 +1518,7 @@ CSL.Engine = function (sys, style, lang, xmlmode) { this.buildTokenLists("bibliography"); this.configureTokenLists(); this.registry = new CSL.Registry(this); + this.disambiguate = new CSL.Disambiguation(this); this.splice_delimiter = false; this.fun.dateparser = new CSL.dateParser(); this.fun.flipflopper = new CSL.Util.FlipFlopper(this); @@ -1860,6 +1893,8 @@ CSL.Engine.Opt = function () { this["locale-name"] = []; this["default-locale"] = ["en"]; this.update_mode = CSL.NONE; + this.bib_mode = CSL.NONE; + this.sort_citations = false; this["et-al-min"] = 0; this["et-al-use-first"] = 1; this["et-al-subsequent-min"] = false; @@ -1938,6 +1973,8 @@ CSL.Engine.Citation = function (state) { this.opt.collapse = []; this.opt["disambiguate-add-names"] = false; this.opt["disambiguate-add-givenname"] = false; + this.opt["disambiguate-add-year-suffix"] = false; + this.opt["givenname-disambiguation-rule"] = "none"; this.opt["near-note-distance"] = 5; this.opt.topdecor = []; }; @@ -1945,8 +1982,6 @@ CSL.Engine.Bibliography = function () { this.opt = {}; this.tokens = []; this.opt.collapse = []; - this.opt["disambiguate-add-names"] = false; - this.opt["disambiguate-add-givenname"] = false; this.opt.topdecor = []; this.opt.layout_decorations = []; this.opt.layout_prefix = ""; @@ -1969,11 +2004,10 @@ CSL.Engine.CitationSort = function () { this.keys = []; this.opt.topdecor = []; }; -CSL.Engine.prototype.setCitationId = function (citation) { +CSL.Engine.prototype.setCitationId = function (citation, force) { var ret, id, direction; ret = false; - if (!citation.citationID) { - ret = true; + if (!citation.citationID || force) { id = Math.floor(Math.random() * 100000000000000); while (true) { direction = 0; @@ -1991,10 +2025,37 @@ CSL.Engine.prototype.setCitationId = function (citation) { id += -1; } } + ret = id; } this.registry.citationreg.citationById[citation.citationID] = citation; return ret; }; +CSL.Engine.prototype.restoreProcessorState = function (citations) { + var pos, len, ppos, llen, item, Item, newitem, citationList, itemList, sortedItems; + citationList = []; + itemList = []; + for (pos = 0, len = citations.length; pos < len; pos += 1) { + sortedItems = []; + for (ppos = 0, len = citations[pos].citationItems.length; ppos < llen; ppos += 1) { + item = citations[pos].citationItems[ppos]; + Item = this.sys.retrieveItem(item.id); + newitem = [Item, item]; + sortedItems.push(newitem); + citations[pos].citationItems[ppos].item = Item; + itemList.push(item.id); + } + if (!citations[pos].properties.unsorted) { + sortedItems.sort(this.citation.srt.compareCompositeKeys); + } + citations[pos].sortedItems = sortedItems; + this.registry.citationreg.citationById[citations[pos].citationID] = citations[pos]; + citationList.push([citations[pos].citationID, citations[pos].properties.noteIndex]); + } + this.updateItems(itemList); + if (citations && citations.length) { + this.processCitationCluster(citations[0], [], citationList.slice(1)); + } +}; CSL.Engine.prototype.updateItems = function (idList) { var debug = false; this.registry.init(idList); @@ -2002,11 +2063,10 @@ CSL.Engine.prototype.updateItems = function (idList) { this.registry.doinserts(this.registry.mylist); this.registry.dorefreshes(); this.registry.rebuildlist(); - this.registry.setdisambigs(); this.registry.setsortkeys(); + this.registry.setdisambigs(); this.registry.sorttokens(); this.registry.renumber(); - this.registry.yearsuffix(); return this.registry.getSortedIds(); }; CSL.Engine.prototype.updateUncitedItems = function (idList) { @@ -2015,11 +2075,10 @@ CSL.Engine.prototype.updateUncitedItems = function (idList) { this.registry.doinserts(this.registry.mylist); this.registry.douncited(); this.registry.rebuildlist(); - this.registry.setdisambigs(); this.registry.setsortkeys(); + this.registry.setdisambigs(); this.registry.sorttokens(); this.registry.renumber(); - this.registry.yearsuffix(); return this.registry.getSortedIds(); }; CSL.Engine.prototype.makeBibliography = function (bibsection) { @@ -2200,7 +2259,19 @@ CSL.getBibliographyEntries = function (bibsection) { this.tmp.disambig_override = false; return [all_item_ids, ret]; }; -CSL.Engine.prototype.appendCitationCluster = function (citation, has_bibliography) { +CSL.Engine.prototype.previewCitationCluster = function (citation, citationsPre, citationsPost, newMode) { + var oldMode, oldCitationID, newCitationID, ret, data; + oldMode = this.opt.mode; + this.setOutputFormat(newMode); + oldCitationID = citation.citationID; + newCitationID = this.setCitationId(citation, true); + [data, ret] = this.processCitationCluster(citation, citationsPre, citationsPost, CSL.PREVIEW); + delete this.registry.citationreg.citationById[newCitationID]; + citation.citationID = oldCitationID; + this.setOutputFormat(oldMode); + return ret; +}; +CSL.Engine.prototype.appendCitationCluster = function (citation) { var pos, len, c, citationsPre; citationsPre = []; len = this.registry.citationreg.citationByIndex.length; @@ -2208,10 +2279,37 @@ CSL.Engine.prototype.appendCitationCluster = function (citation, has_bibliograph c = this.registry.citationreg.citationByIndex[pos]; citationsPre.push([c.citationID, c.properties.noteIndex]); } - return this.processCitationCluster(citation, citationsPre, []); + return this.processCitationCluster(citation, citationsPre, [], CSL.ASSUME_ALL_ITEMS_REGISTERED); }; -CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, citationsPost, has_bibliography) { - var sortedItems, new_citation, pos, len, item, citationByIndex, c, Item, newitem, k, textCitations, noteCitations, update_items, citations, first_ref, last_ref, ipos, ilen, cpos, onecitation, oldvalue, ibidme, suprame, useme, items, i, key, prev_locator, curr_locator, param, ret, obj, ppos, llen, lllen, pppos, ppppos, llllen, cids, note_distance; +CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, citationsPost, flag) { + var sortedItems, new_citation, pos, len, item, citationByIndex, c, Item, newitem, k, textCitations, noteCitations, update_items, citations, first_ref, last_ref, ipos, ilen, cpos, onecitation, oldvalue, ibidme, suprame, useme, items, i, key, prev_locator, curr_locator, param, ret, obj, ppos, llen, lllen, pppos, ppppos, llllen, cids, note_distance, return_data; + return_data = {"bibchange": false}; + this.registry.return_data = return_data; + if (flag === CSL.PREVIEW) { + var tmpItems = []; + for (pos = 0, len = citation.citationItems.length; pos < len; pos += 1) { + if (!this.registry.registry[citation.citationItems[pos].id]) { + tmpItems.push(citation.citationItems[pos].id); + } + } + var oldAmbigs = {}; + var oldAmbigData = []; + for (pos = 0, len = tmpItems.length; pos < len; pos += 1) { + for (key in oldAmbigs) { + oldAmbigs[CSL.getAmbiguousCite.call(this, tmpItems[pos])] = []; + if (oldAmbigs.hasOwnProperty) { + var ids = this.registry.ambigcites[oldAmbigs[ppos]]; + if (ids) { + for (ppos = 0, llen = ids.length; ppos < llen; ppos += 1) { + var disambig = CSL.cloneAmbigConfig(this.registry[ids[ppos]].disambig); + oldAmbigData.push([ids[ppos], disambig]); + } + } + } + } + } + this.updateItems(this.registry.mylist.concat(tmpItems)); + } this.tmp.taintedItemIDs = {}; this.tmp.taintedCitationIDs = {}; sortedItems = []; @@ -2224,7 +2322,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, sortedItems.push(newitem); citation.citationItems[pos].item = Item; } - if (!this.citation.opt["citation-number-sort"] && sortedItems && sortedItems.length > 1 && this.citation_sort.tokens.length > 0) { + if (!this.opt.citation_number_sort && sortedItems && sortedItems.length > 1 && this.citation_sort.tokens.length > 0) { len = sortedItems.length; for (pos = 0; pos < len; pos += 1) { sortedItems[pos][1].sortkeys = CSL.getSortKeys.call(this, sortedItems[pos][0], "citation_sort"); @@ -2277,7 +2375,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } } } - if (!has_bibliography) { + if (flag !== CSL.PREVIEW && flag !== CSL.ASSUME_ALL_ITEMS_REGISTERED) { this.updateItems(update_items); } if (this.opt.update_mode === CSL.POSITION) { @@ -2387,7 +2485,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } } } - if (this.citation.opt["citation-number-sort"] && sortedItems && sortedItems.length > 1 && this.citation_sort.tokens.length > 0) { + if (this.opt.citation_number_sort && sortedItems && sortedItems.length > 1 && this.citation_sort.tokens.length > 0) { len = sortedItems.length; for (pos = 0; pos < len; pos += 1) { sortedItems[pos][1].sortkeys = CSL.getSortKeys.call(this, sortedItems[pos][0], "citation_sort"); @@ -2405,31 +2503,52 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } } ret = []; - for (key in this.tmp.taintedCitationIDs) { - if (this.tmp.taintedCitationIDs.hasOwnProperty(key)) { - obj = []; - citation = this.registry.citationreg.citationById[key]; - obj.push(citation.properties.index); - obj.push(this.process_CitationCluster.call(this, citation.sortedItems)); - ret.push(obj); + if (flag === CSL.PREVIEW) { + ret = this.process_CitationCluster.call(this, citation.sortedItems); + this.registry.namereg.delitems(tmpItems); + for (pos = 0, len = oldAmbigData.length; pos < len; pos += 1) { + this.registry[oldAmbigData[pos][0]].disambig = oldAmbigData[pos][1]; } + for (key in oldAmbigs) { + if (oldAmbigs.hasOwnProperty(key)) { + var lst = this.registry.ambigcites[oldAmbigs[key]]; + for (pos = lst.length - 1; pos > -1; pos += 1) { + if (tmpItems.indexOf(lst[pos]) > -1) { + this.registry.registry[oldAmbigs[key]] = lst.slice(0, pos).concat(lst.slice(pos + 1)); + } + } + } + } + for (pos = 0, len = tmpItems.length; pos < len; pos += 1) { + delete this.registry.registry[tmpItems[pos]]; + } + } else { + for (key in this.tmp.taintedCitationIDs) { + if (this.tmp.taintedCitationIDs.hasOwnProperty(key)) { + obj = []; + citation = this.registry.citationreg.citationById[key]; + obj.push(citation.properties.index); + obj.push(this.process_CitationCluster.call(this, citation.sortedItems)); + ret.push(obj); + } + } + this.tmp.taintedItemIDs = false; + this.tmp.taintedCitationIDs = false; + obj = []; + obj.push(citationsPre.length); + obj.push(this.process_CitationCluster.call(this, sortedItems)); + ret.push(obj); + ret.sort(function (a, b) { + if (a[0] > b[0]) { + return 1; + } else if (a[0] < b[0]) { + return -1; + } else { + return 0; + } + }); } - this.tmp.taintedItemIDs = false; - this.tmp.taintedCitationIDs = false; - obj = []; - obj.push(citationsPre.length); - obj.push(this.process_CitationCluster.call(this, sortedItems)); - ret.push(obj); - ret.sort(function (a, b) { - if (a[0] > b[0]) { - return 1; - } else if (a[0] < b[0]) { - return -1; - } else { - return 0; - } - }); - return ret; + return [return_data, ret]; }; CSL.Engine.prototype.process_CitationCluster = function (sortedItems) { var str; @@ -2836,7 +2955,7 @@ CSL.Node["date-part"] = { real = !state.tmp.suppress_decorations; have_collapsed = state.tmp.have_collapsed; invoked = state[state.tmp.area].opt.collapse === "year-suffix" || state[state.tmp.area].opt.collapse === "year-suffix-ranged"; - precondition = state[state.tmp.area].opt["disambiguate-add-year-suffix"]; + precondition = state.opt["disambiguate-add-year-suffix"]; if (real && precondition && invoked) { state.tmp.years_used.push(value); known_year = state.tmp.last_years_used.length >= state.tmp.years_used.length; @@ -2949,10 +3068,10 @@ CSL.Node["date-part"] = { } } state.tmp.value = []; - if (!state.opt.has_year_suffix && "year" === this.strings.name) { - if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig[2] && !state.tmp.has_done_year_suffix) { + if (!state.opt.has_year_suffix && "year" === this.strings.name && !state.tmp.just_looking) { + if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false && !state.tmp.has_done_year_suffix) { state.tmp.has_done_year_suffix = true; - num = parseInt(state.registry.registry[Item.id].disambig[2], 10); + num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10); number = new CSL.NumericBlob(num, this); formatter = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS); number.setFormatter(formatter); @@ -3235,7 +3354,7 @@ CSL.Node.key = { if (this.variables.length) { variable = this.variables[0]; if (variable === "citation-number" && state.build.area === "citation_sort") { - state.citation.opt["citation-number-sort"] = true; + state.opt.citation_number_sort = true; } if (CSL.CREATORS.indexOf(variable) > -1) { names_start_token = new CSL.Token("names", CSL.START); @@ -3962,7 +4081,7 @@ CSL.Node.names = { val = 2; } param = val; - if (state[state.tmp.area].opt["disambiguate-add-givenname"]) { + if (state.opt["disambiguate-add-givenname"]) { param = state.registry.namereg.evalname(Item.id, nameset.names[ppos], ppos, param, state.output.getToken("name").strings.form, this.strings["initialize-with"]); } } else { @@ -4148,6 +4267,7 @@ CSL.Node.sort = { if (this.tokentype === CSL.START) { if (state.build.area === "citation") { state.parallel.use_parallels = false; + state.opt.sort_citations = true; } state.build.sort_flag = true; state.build.area_return = state.build.area; @@ -4195,6 +4315,9 @@ CSL.Node.text = { if (state.build.area === "citation") { state.opt.update_mode = CSL.NUMERIC; } + if (state.build.area === "bibliography") { + state.opt.bib_mode = CSL.NUMERIC; + } if ("citation-number" === state[state.tmp.area].opt.collapse) { this.range_prefix = "-"; } @@ -4229,8 +4352,8 @@ CSL.Node.text = { this.successor_prefix = state[state.build.area].opt["year-suffix-delimiter"]; } func = function (state, Item) { - if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig[2]) { - num = parseInt(state.registry.registry[Item.id].disambig[2], 10); + if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false && !state.tmp.just_looking) { + num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10); number = new CSL.NumericBlob(num, this); formatter = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS); number.setFormatter(formatter); @@ -4286,8 +4409,8 @@ CSL.Node.text = { label = myname + year; } suffix = ""; - if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig[2]) { - num = parseInt(state.registry.registry[Item.id].disambig[2], 10); + if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false) { + num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10); suffix = state.fun.suffixator.format(num); } label += suffix; @@ -4729,7 +4852,7 @@ CSL.Attributes["@disambiguate"] = function (state, arg) { }; CSL.Attributes["@givenname-disambiguation-rule"] = function (state, arg) { if (CSL.GIVENNAME_DISAMBIGUATION_RULES.indexOf(arg) > -1) { - state[this.name].opt["givenname-disambiguation-rule"] = arg; + state.opt["givenname-disambiguation-rule"] = arg; } }; CSL.Attributes["@collapse"] = function (state, arg) { @@ -4796,17 +4919,17 @@ CSL.Attributes["@subsequent-author-substitute"] = function (state, arg) { }; CSL.Attributes["@disambiguate-add-names"] = function (state, arg) { if (arg === "true") { - state[this.name].opt["disambiguate-add-names"] = true; + state.opt["disambiguate-add-names"] = true; } }; CSL.Attributes["@disambiguate-add-givenname"] = function (state, arg) { if (arg === "true") { - state[this.name].opt["disambiguate-add-givenname"] = true; + state.opt["disambiguate-add-givenname"] = true; } }; CSL.Attributes["@disambiguate-add-year-suffix"] = function (state, arg) { if (arg === "true") { - state[this.name].opt["disambiguate-add-year-suffix"] = true; + state.opt["disambiguate-add-year-suffix"] = true; } }; CSL.Attributes["@second-field-align"] = function (state, arg) { @@ -5517,7 +5640,7 @@ CSL.AmbigConfig = function () { this.minval = 1; this.names = []; this.givens = []; - this.year_suffix = 0; + this.year_suffix = false; this.disambiguate = 0; }; CSL.Blob = function (token, str, levelname) { @@ -7013,7 +7136,7 @@ CSL.Output.Formats.prototype.rtf = { return str+spacing.join(""); }, "@display/left-margin": function(state,str){ - return str+"\\tab"; + return str+"\\tab "; }, "@display/right-inline": function (state, str) { return str+"\n"; @@ -7039,10 +7162,9 @@ CSL.Registry = function (state) { this.refreshes = {}; this.akeys = {}; this.oldseq = {}; + this.return_data = {}; this.ambigcites = {}; this.sorter = new CSL.Registry.Comparifier(state, "bibliography_sort"); - this.modes = CSL.getModes.call(this.state); - this.checkerator = new CSL.Checkerator(); this.getSortedIds = function () { ret = []; len = this.reflist.length; @@ -7101,6 +7223,7 @@ CSL.Registry.prototype.dodeletes = function (myhash) { this.refreshes[id] = true; } delete this.registry[key]; + this.return_data.bibchange = true; } } }; @@ -7128,6 +7251,7 @@ CSL.Registry.prototype.doinserts = function (mylist) { abase = CSL.getAmbigConfig.call(this.state); this.registerAmbigToken(akey, item, abase); this.touched[item] = true; + this.return_data.bibchange = true; } } }; @@ -7182,24 +7306,7 @@ CSL.Registry.prototype.setdisambigs = function () { this.leftovers = []; for (akey in this.akeys) { if (this.akeys.hasOwnProperty(akey)) { - if (this.ambigcites[akey].length > 1) { - if (this.modes.length) { - leftovers = this.disambiguateCites(this.state, akey, this.modes); - } else { - leftovers = []; - len = this.ambigcites[akey].length; - for (pos = 0; pos < len; pos += 1) { - key = this.ambigcites[akey][pos]; - leftovers.push(this.registry[key]); - } - } - if (leftovers && leftovers.length && this.state.opt.has_disambiguate) { - leftovers = this.disambiguateCites(this.state, akey, this.modes, leftovers); - } - if (leftovers.length > 1) { - this.leftovers.push(leftovers); - } - } + this.state.disambiguate.run(akey); } } this.akeys = {}; @@ -7210,21 +7317,12 @@ CSL.Registry.prototype.renumber = function () { for (pos = 0; pos < len; pos += 1) { item = this.reflist[pos]; item.seq = (pos + 1); - if (this.state.opt.update_mode === CSL.NUMERIC && this.state.tmp.taintedItemIDs && item.seq !== this.oldseq[item.id]) { - this.state.tmp.taintedItemIDs[item.id] = true; - } - } -}; -CSL.Registry.prototype.yearsuffix = function () { - var leftovers, pos, len, ppos, llen; - len = this.leftovers.length; - for (pos = 0; pos < len; pos += 1) { - leftovers = this.leftovers[pos]; - if (leftovers && leftovers.length && this.state[this.state.tmp.area].opt["disambiguate-add-year-suffix"]) { - leftovers.sort(this.compareRegistryTokens); - llen = leftovers.length; - for (ppos = 0; ppos < llen; ppos += 1) { - this.registry[leftovers[("" + ppos)].id].disambig[2] = "" + ppos; + if (this.state.tmp.taintedItemIDs && item.seq !== this.oldseq[item.id]) { + if (this.state.opt.update_mode === CSL.NUMERIC) { + this.state.tmp.taintedItemIDs[item.id] = true; + } + if (this.state.opt.bib_mode === CSL.NUMERIC) { + this.return_data.bibchange = true; } } } @@ -7334,7 +7432,7 @@ CSL.Registry.NameReg = function (state) { pkey = strip_periods(nameobj.family); skey = strip_periods(nameobj.given); ikey = CSL.Util.Names.initializeWith(state, skey, ""); - if (state[state.tmp.area].opt["givenname-disambiguation-rule"] === "by-cite") { + if (state.opt["givenname-disambiguation-rule"] === "by-cite") { pkey = itemid + pkey; } }; @@ -7345,8 +7443,8 @@ CSL.Registry.NameReg = function (state) { return 2; } param = 2; - dagopt = state[state.tmp.area].opt["disambiguate-add-givenname"]; - gdropt = state[state.tmp.area].opt["givenname-disambiguation-rule"]; + dagopt = state.opt["disambiguate-add-givenname"]; + gdropt = state.opt["givenname-disambiguation-rule"]; if (gdropt === "by-cite") { gdropt = "all-names"; } @@ -7551,317 +7649,294 @@ CSL.Registry.NameReg = function (state) { this.delitems = delitems; this.evalname = evalname; }; -var debug = false; -CSL.Registry.prototype.disambiguateCites = function (state, akey, modes, candidate_list) { - var ambigs, reg_token, keypos, id_vals, a, base, token, pos, len, tokens, str, maxvals, minval, testpartner, otherstr, base_return, ret, id, key, origbase, remainder, last_remainder; - if (!candidate_list) { - ambigs = this.ambigcites[akey].slice(); - this.ambigcites[akey] = []; - } else { - ambigs = []; - len = candidate_list.length; - for (pos = 0; pos < len; pos += 1) { - reg_token = candidate_list[pos]; - ambigs.push(reg_token.id); - keypos = this.ambigcites[akey].indexOf(reg_token.id); - if (keypos > -1) { - this.ambigcites[akey] = this.ambigcites[akey].slice(0, keypos).concat(this.ambigcites[akey].slice((keypos + 1))); - } - } +CSL.Disambiguation = function (state) { + this.state = state; + this.sys = this.state.sys; + this.registry = state.registry.registry; + this.ambigcites = state.registry.ambigcites; + this.configModes(); + this.clashes = [1, 0]; +}; +CSL.Disambiguation.prototype.run = function(akey) { + if (!this.modes.length) { + return; } - id_vals = []; - len = ambigs.length; - for (pos = 0; pos < len; pos += 1) { - id_vals.push(ambigs[pos]); - } - tokens = state.retrieveItems(id_vals); - if (candidate_list && candidate_list.length) { - modes = ["disambiguate_true"].concat(modes); - } - CSL.initCheckerator.call(this.checkerator, tokens, modes); - this.checkerator.lastclashes = (ambigs.length - 1); - base = false; - this.checkerator.pos = 0; - str = CSL.getAmbiguousCite.call(state, tokens[0], base); - maxvals = CSL.getMaxVals.call(state); - minval = CSL.getMinVal.call(state); - base = CSL.getAmbigConfig.call(state); - origbase = CSL.cloneAmbigConfig(base); - remainder = tokens.length; - last_remainder = this.checkerator.seen.length; - while (CSL.runCheckerator.call(this.checkerator)) { - token = this.checkerator.tokens[this.checkerator.pos]; - if (this.ambigcites[akey].indexOf(token.id) > -1) { - this.checkerator.pos += 1; - continue; - } - this.checkerator.candidate = token.id; - if (base === false) { - this.checkerator.mode = modes[0]; - } - str = CSL.getAmbiguousCite.call(state, token, base); - maxvals = CSL.getMaxVals.call(state); - minval = CSL.getMinVal.call(state); - base = CSL.getAmbigConfig.call(state); - if (candidate_list && candidate_list.length) { - base.disambiguate = true; - } - CSL.setCheckeratorBase.call(this.checkerator, base); - CSL.setMaxVals.call(this.checkerator, maxvals); - CSL.setMinVal.call(this.checkerator, minval); - len = tokens.length; - for (pos = 0; pos < len; pos += 1) { - testpartner = tokens[pos]; - if (token.id === testpartner.id) { - continue; + this.initVars(akey); + this.runDisambig(); +}; +CSL.Disambiguation.prototype.runDisambig = function () { + var pos, len, ppos, llen, pppos, lllen, ismax; + for (pos = 0; pos < this.lists.length; pos += 1) { + this.nnameset = 0; + this.gnameset = 0; + this.gname = 0; + while(this.lists[pos][1].length) { + this.listpos = pos; + if (!this.base) { + this.base = this.lists[pos][0]; } - otherstr = CSL.getAmbiguousCite.call(state, testpartner, base); - if (CSL.checkCheckeratorForClash.call(this.checkerator, str, otherstr)) { - break; - } - } - if (CSL.evaluateCheckeratorClashes.call(this.checkerator)) { - remainder = tokens.length - this.checkerator.seen.length; - if (remainder === 1 && last_remainder === 0) { - base_return = CSL.decrementCheckeratorGivenNames.call(this, state, base, origbase, token.id); + if (this.rerun) { + this.rerun = false; } else { - base_return = CSL.decrementCheckeratorNames.call(this, state, base, origbase, token.id); + this.scanItems(this.lists[pos], 0); } - last_remainder = remainder; - this.registerAmbigToken(akey, token.id, base_return); - this.checkerator.seen.push(token.id); - continue; - } - if (CSL.maxCheckeratorAmbigLevel.call(this.checkerator)) { - this.checkerator.mode1_counts = false; - this.checkerator.maxed_out_bases[token.id] = CSL.cloneAmbigConfig(base); - this.checkerator.seen.push(token.id); - base = false; - continue; - } - CSL.incrementCheckeratorAmbigLevel.call(this.checkerator); - } - ret = []; - len = this.checkerator.ids.length; - for (pos = 0; pos < len; pos += 1) { - id = this.checkerator.ids[pos]; - if (id) { - ret.push(this.registry[id]); + ismax = this.incrementDisambig(); + this.scanItems(this.lists[pos], 1); + this.evalScan(ismax); } } - len = this.checkerator.maxed_out_bases.length; - for (key in this.checkerator.maxed_out_bases) { - if (this.checkerator.maxed_out_bases.hasOwnProperty(key)) { - this.registry[key].disambig = this.checkerator.maxed_out_bases[key]; +}; +CSL.Disambiguation.prototype.scanItems = function (list, phase) { + var pos, len, Item, otherItem, ItemCite, otherItemCite, ignore, base; + Item = list[1][0]; + this.partners = []; + [this.base, this.maxvals, this.minval, ItemCite] = this.getItem(Item); + this.partners.push(Item); + this.clashes[phase] = 0; + this.nonpartners = []; + for (pos = 1, len = list[1].length; pos < len; pos += 1) { + otherItem = list[1][pos]; + [ignore, ignore, ignore, otherItemCite] = this.getItem(otherItem); + if (ItemCite === otherItemCite) { + this.clashes[phase] += 1; + this.partners.push(otherItem); + } else { + this.nonpartners.push(otherItem); } } - return ret; }; -CSL.Checkerator = function () {}; -CSL.initCheckerator = function (tokens, modes) { - var len, pos; - this.tokens = tokens; - this.seen = []; - this.modes = modes; - this.mode = this.modes[0]; - this.tokens_length = tokens.length; - this.pos = 0; - this.clashes = 0; - this.maxvals = false; - this.base = false; - this.ids = []; - this.maxed_out_bases = {}; - len = tokens.length; - for (pos = 0; pos < len; pos += 1) { - this.ids.push(tokens[pos].id); - } - this.lastclashes = -1; - this.namepos = 0; - this.modepos = 0; - this.mode1_counts = false; +CSL.Disambiguation.prototype.evalScan = function (ismax) { + this[this.modes[this.modeindex]](ismax); }; -CSL.runCheckerator = function () { - var len, pos; - if (this.seen.length < this.tokens_length) { - return true; - } - return false; -}; -CSL.setMaxVals = function (maxvals) { - this.maxvals = maxvals; -}; -CSL.setMinVal = function (minval) { - this.minval = minval; -}; -CSL.setCheckeratorBase = function (base) { +CSL.Disambiguation.prototype.disNames = function (ismax) { var pos, len; - this.base = base; - if (! this.mode1_counts) { - this.mode1_counts = []; - len = this.base.givens.length; - for (pos = 0; pos < len; pos += 1) { - this.mode1_counts.push(0); - } - } -}; -CSL.setCheckeratorMode = function (mode) { - this.mode = mode; -}; -CSL.checkCheckeratorForClash = function (str, otherstr) { - if (str === otherstr) { - if (this.mode === "names" || this.mode === "disambiguate_true") { - this.clashes += 1; - return true; - } - if (this.mode === "givens") { - this.clashes += 1; - } - return false; - } -}; -CSL.evaluateCheckeratorClashes = function () { - var namepos, ret, old; - if (!this.maxvals.length) { - return false; - } - if (this.mode === "names" || this.mode === "disambiguate_true") { - if (this.clashes) { - this.lastclashes = this.clashes; - this.clashes = 0; - return false; + if (this.clashes[1] === 0) { + this.registry[this.partners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + if (this.nonpartners.length === 1) { + this.registry[this.nonpartners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + this.lists[this.listpos] = [this.base,[]]; } else { - this.ids[this.pos] = false; - this.pos += 1; - this.lastclashes = this.clashes; - return true; + this.lists[this.listpos] = [this.base, this.nonpartners]; } - } - if (this.mode === "givens") { - ret = true; - namepos = this.mode1_counts[this.modepos]; - if (this.clashes && this.clashes === this.lastclashes) { - if (this.mode1_defaults && namepos > 0) { - old = this.mode1_defaults[(namepos - 1)]; - this.base.givens[this.modepos][(namepos - 1)] = old; + } else if (this.clashes[1] < this.clashes[0]) { + this.lists[this.listpos] = [this.base, this.partners]; + if (this.nonpartners.length === 1) { + this.registry[this.nonpartners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + } else { + this.lists.push([this.base, this.nonpartners]); + } + } else { + if (ismax || this.advance_mode) { + for (pos = 0, len = this.partners.length; pos < len; pos += 1) { + this.registry[this.partners[pos].id].disambig = CSL.cloneAmbigConfig(this.base); } - ret = false; - } else if (this.clashes) { - ret = false; - } else { // only non-clash should be possible - this.mode1_counts = false; - this.pos += 1; - ret = true; + if (ismax) { + this.lists[this.listpos] = [this.base, this.nonpartners]; + } + } else { + this.rerun = true; } - this.lastclashes = this.clashes; - this.clashes = 0; - if (ret) { - this.ids[this.pos] = false; - } - return ret; } }; -CSL.maxCheckeratorAmbigLevel = function () { - if (!this.maxvals.length) { - return true; - } - if (this.mode === "disambiguate_true") { - if (this.modes.indexOf("disambiguate_true") < (this.modes.length - 1)) { - this.mode = this.modes[(this.modes.indexOf("disambiguate_true") + 1)]; - this.modepos = 0; +CSL.Disambiguation.prototype.disGivens = function (ismax) { + var pos, len; + if (this.clashes[1] === 0) { + this.base = this.decrementNames(); + this.registry[this.partners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + if (this.nonpartners.length === 1) { + this.registry[this.nonpartners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + this.lists[this.listpos] = [this.base,[]]; } else { - this.pos += 1; - return true; + this.lists[this.listpos] = [this.base, this.nonpartners]; + } + } else if (this.clashes[1] < this.clashes[0]) { + this.lists[this.listpos] = [this.base, this.partners]; + if (this.nonpartners.length === 1) { + this.registry[this.nonpartners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + } else { + this.lists.push([this.base, this.nonpartners]); + } + } else { + this.base = CSL.cloneAmbigConfig(this.oldbase); + if (ismax || this.advance_mode) { + for (pos = 0, len = this.partners.length; pos < len; pos += 1) { + this.registry[this.partners[pos].id].disambig = CSL.cloneAmbigConfig(this.base); + } + if (ismax) { + this.lists[this.listpos] = [this.base, this.nonpartners]; + } + } else { + this.rerun = true; } } - if (this.mode === "names") { - if (this.modepos === (this.base.names.length - 1) && this.base.names[this.modepos] === this.maxvals[this.modepos]) { - if (this.modes.length === 2) { - this.mode = "givens"; - this.mode1_counts[this.modepos] = 0; - this.modepos = 0; - } else { - this.pos += 1; +}; +CSL.Disambiguation.prototype.disExtraText = function () { + var pos, len; + if (this.clashes[1] === 0) { + this.registry[this.partners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + if (this.nonpartners.length === 1) { + this.registry[this.nonpartners[0].id].disambig = CSL.cloneAmbigConfig(this.base); + this.lists[this.listpos] = [this.base,[]]; + } else { + this.lists[this.listpos] = [this.base, this.nonpartners]; + } + } else { + this.base.disambiguate = false; + this.lists[this.listpos] = [this.base, this.lists[this.listpos][1].slice(1)]; + } +}; +CSL.Disambiguation.prototype.disYears = function () { + var pos, len, tokens, token, item; + tokens = []; + for (pos = 0, len = this.lists[this.listpos][1].length; pos < len; pos += 1) { + token = this.registry[this.lists[this.listpos][1][pos].id]; + tokens.push(token); + } + tokens.sort(this.state.registry.sorter.compareKeys); + for (pos = 0, len = tokens.length; pos < len; pos += 1) { + tokens[pos].disambig = CSL.cloneAmbigConfig(this.base); + tokens[pos].disambig.year_suffix = ""+pos; + } + this.lists[this.listpos] = [this.base, []]; +}; +CSL.Disambiguation.prototype.incrementDisambig = function () { + var val, maxed; + maxed = false; + this.oldbase = CSL.cloneAmbigConfig(this.base); + if (this.advance_mode) { + this.modeindex += 1; + this.advance_mode = false; + } + if (!maxed && "disNames" === this.modes[this.modeindex]) { + if (this.base.names[this.nnameset] < this.maxvals[this.nnameset]) { + this.base.names[this.nnameset] += 1; + } else { + if (this.nnameset < (this.base.names.length - 1)) { + this.nnameset += 1; + } + if (this.base.names[this.nnameset] < this.maxvals[this.nnameset]) { + this.base.names[this.nnameset] += 1; + } + } + if (this.nnameset === (this.base.names.length - 1) && this.base.names[this.nnameset] === this.maxvals[this.nnameset]) { + if (this.modeindex === (this.modes.length - 1)) { return true; - } - } - } else if (this.mode === "givens") { - if (this.modepos === (this.mode1_counts.length - 1) && this.mode1_counts[this.modepos] === (this.maxvals[this.modepos])) { - if (this.modes.length === 2) { - this.mode = "givens"; - this.pos += 1; } else { - this.pos += 1; + maxed = false; } - return true; } } - return false; -}; -CSL.incrementCheckeratorAmbigLevel = function () { - var val; - if (this.mode === "names") { - val = this.base.names[this.modepos]; - if (val < this.maxvals[this.modepos]) { - this.base.names[this.modepos] += 1; - } else if (this.modepos < (this.base.names.length - 1)) { - this.modepos += 1; - this.base.names[this.modepos] = 0; - } - } - if (this.mode === "givens") { - val = (this.mode1_counts[this.modepos]); - if (val < this.maxvals[this.modepos]) { - if (this.given_name_second_pass) { - this.given_name_second_pass = false; - this.mode1_counts[this.modepos] += 1; - this.base.givens[this.modepos][val] += 1; - } else { - this.mode1_defaults = this.base.givens[this.modepos].slice(); - this.given_name_second_pass = true; + if (!maxed && "disGivens" === this.modes[this.modeindex]) { + if (this.gname < this.maxvals[this.gnameset]) { + if (this.base.givens[this.gnameset][this.gname] === this.minval) { + this.base.givens[this.gnameset][this.gname] += 1; } - } else if (this.modepos < (this.base.givens.length - 1)) { - this.modepos += 1; - this.base.givens[this.modepos][0] += 1; - this.mode1_defaults = this.base.givens[this.modepos].slice(); + this.base.givens[this.gnameset][this.gname] += 1; + this.gname += 1; } else { - this.mode = "names"; - this.pos += 1; + if (this.gnameset < (this.base.givens.length - 1)) { + this.gnameset += 1; + this.gname = 0; + } + if (this.gname < this.maxvals[this.gnameset]) { + this.base.givens[this.gnameset][this.gname] += 1; + this.gname += 1; + } } } -}; -CSL.decrementCheckeratorGivenNames = function (state, base, origbase, id) { - var base_return, ids, pos, len; - ids = this.checkerator.ids; - this.checkerator.ids = ids.slice(0,ids.indexOf(id)).concat(ids.slice(ids.indexOf(id) + 1)); - base_return = CSL.cloneAmbigConfig(base); - for (pos = 0, len = base_return.givens.length; pos < len; pos += 1) { - base_return.givens[pos] = origbase.givens[pos].slice(); + if (!maxed && "disExtraText" === this.modes[this.modeindex]) { + maxed = false; + this.base.disambiguate = true; + if (this.modeindex === (this.modes.length - 1)) { + return true; + } else { + maxed = false; + } } - return base_return; + if (!maxed && "disYears" === this.modes[this.modeindex]) { + maxed = false; + } + if (this.modes[this.modeindex] === "disGivens") { + if ((this.gnameset === (this.base.names.length - 1) && this.gname === this.maxvals[this.gnameset]) || this.base.names.length === 0) { + if (this.modeindex === (this.modes.length - 1)) { + maxed = true; + } else { + this.advance_mode = true; + } + } + } + if (this.modes[this.modeindex] === "disNames") { + if ((this.nnameset === (this.base.names.length - 1) && this.base.names[this.nnameset] === this.maxvals[this.nnameset]) || this.base.names.length === 0) { + if (this.modeindex === (this.modes.length - 1)) { + maxed = true; + } else { + this.advance_mode = true; + } + } + } + return maxed; }; -CSL.decrementCheckeratorNames = function (state, base, origbase, id) { +CSL.Disambiguation.prototype.getItem = function (Item) { + var str, maxvals, minval, base; + str = CSL.getAmbiguousCite.call(this.state, Item, this.base); + maxvals = CSL.getMaxVals.call(this.state); + minval = CSL.getMinVal.call(this.state); + base = CSL.getAmbigConfig.call(this.state); + return [base, maxvals, minval, str]; +}; +CSL.Disambiguation.prototype.initVars = function (akey) { + var pos, len; + var myIds, myItems; + this.lists = []; + this.base = false; + myItems = []; + myIds = this.ambigcites[akey]; + for (pos = 0, len = myIds.length; pos < len; pos += 1) { + this.state.tmp.taintedItemIDs[myIds[pos]] = true; + } + if (myIds.length > 1) { + myItems = [this.sys.retrieveItem(myIds[p]) for (p in myIds)]; + this.lists.push([this.base, myItems]); + } + this.modeindex = 0; +}; +CSL.Disambiguation.prototype.configModes = function () { + var dagopt, gdropt; + this.modes = []; + if (this.state.opt["disambiguate-add-names"]) { + this.modes.push("disNames"); + } + dagopt = this.state.opt["disambiguate-add-givenname"]; + gdropt = this.state.opt["givenname-disambiguation-rule"]; + if (dagopt && gdropt === "by-cite") { + this.modes.push("disGivens"); + } + if (this.state.opt.has_disambiguate) { + this.modes.push("disExtraText"); + } + if (this.state.opt["disambiguate-add-year-suffix"]) { + this.modes.push("disYears"); + } +}; +CSL.Disambiguation.prototype.decrementNames = function () { var base_return, do_me, i, j, pos, len, ppos, llen, ids; - base_return = CSL.cloneAmbigConfig(base); + base_return = CSL.cloneAmbigConfig(this.base); do_me = false; len = base_return.givens.length - 1; for (pos = len; pos > -1; pos += -1) { llen = base_return.givens[pos].length - 1; for (ppos = llen; ppos > -1; ppos += -1) { - if (base_return.givens[pos][ppos] > origbase.givens[pos][ppos]) { + if (base_return.givens[pos][ppos] > this.oldbase.givens[pos][ppos]) { do_me = true; } } } if (do_me) { - ids = this.checkerator.ids; len = base_return.givens.length - 1; for (pos = len; pos > -1; pos += -1) { llen = base_return.givens[pos].length - 1; for (ppos = llen; ppos > -1; ppos += -1) { - if (base_return.givens[pos][ppos] > origbase.givens[pos][ppos]) { - if (ids.indexOf(id) > -1) { - this.checkerator.ids = ids.slice(0,ids.indexOf(id)).concat(ids.slice(ids.indexOf(id) + 1)); - } + if (base_return.givens[pos][ppos] > this.oldbase.givens[pos][ppos]) { break; } if (ppos < base_return.names[pos]) { @@ -7872,36 +7947,6 @@ CSL.decrementCheckeratorNames = function (state, base, origbase, id) { } return base_return; }; -CSL.getAmbigConfig = function () { - var config, ret; - config = this.tmp.disambig_request; - if (!config) { - config = this.tmp.disambig_settings; - } - ret = CSL.cloneAmbigConfig(config); - return ret; -}; -CSL.getMaxVals = function () { - return this.tmp.names_max.mystack.slice(); -}; -CSL.getMinVal = function () { - return this.tmp["et-al-min"]; -}; -CSL.getModes = function () { - var ret, dagopt, gdropt; - ret = []; - if (this[this.tmp.area].opt["disambiguate-add-names"]) { - ret.push("names"); - } - dagopt = this[this.tmp.area].opt["disambiguate-add-givenname"]; - gdropt = this[this.tmp.area].opt["givenname-disambiguation-rule"]; - if (dagopt) { - if (!gdropt || ("string" === typeof gdropt && "primary-name" !== gdropt.slice(0, 12))) { - ret.push("givens"); - } - } - return ret; -}; CSL.Registry.CitationReg = function (state) { this.citationById = {}; this.citationByIndex = []; diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js index 6e7373176..afdc73a45 100644 --- a/chrome/content/zotero/xpcom/integration.js +++ b/chrome/content/zotero/xpcom/integration.js @@ -584,7 +584,7 @@ Zotero.Integration.Document.prototype._updateSession = function(newField, editFi // if we are reloading this session, assume no item IDs to be updated except for edited items if(this._reloadSession) { - this._session.updateCitations(); + this._session.restoreProcessorState(); this._session.updateIndices = {}; this._session.updateItemIDs = {}; this._session.bibliographyHasChanged = false; @@ -1300,37 +1300,43 @@ Zotero.Integration.Session.prototype.updateUpdateIndices = function(regenerateAl } } +/** + * Returns citations before and after a given index + */ +Zotero.Integration.Session.prototype._getPrePost = function(index) { + var citationIndices = []; + var citationsPre = []; + for(var i=0; i 1); + return newCitations.bibchange; } } @@ -1395,6 +1401,20 @@ Zotero.Integration.Session.prototype.updateCitations = function() { return deleteCitations; } +/** + * Updates the list of citations to be serialized to the document + */ +Zotero.Integration.Session.prototype.restoreProcessorState = function() { + var citations = []; + for(var i in this.citationsByIndex.length) { + if(this.citationsByIndex[i] && !this.newIndices[i] && !this.citationsByIndex[i].properties.delete) { + citations.push(this.citationsByIndex[i]); + } + } + + this.style.restoreProcessorState(citations); +} + /** * Loads document data from a JSON object */ @@ -1494,21 +1514,14 @@ Zotero.Integration.Session.prototype.getBibliographyData = function() { * and position) */ Zotero.Integration.Session.prototype.previewCitation = function(citation) { - // remove cached citation text - this.citationText = {}; - this.addCitation(citation.properties.index, citation.properties.noteIndex, citation); - - // add citation items + var citationsPre, citationsPost, citationIndices; + [citationsPre, citationsPost, citationIndices] = this._getPrePost(citation.properties.index); try { - this.formatCitation(citation.properties.index, citation); + return this.style.previewCitationCluster(citation, citationsPre, citationsPost, "rtf"); } catch(e) { Zotero.debug(e); - this.deleteCitation(citation.properties.index); throw e; } - this.deleteCitation(citation.properties.index); - - return this.citationText[citation.properties.index]; } /** @@ -1544,7 +1557,7 @@ Zotero.Integration.Session.prototype.editCitation = function(index, noteIndex, c return me.previewCitation(io.citation); } // determine whether citation is sortable in current style - io.sortable = !this.style.citation.opt["citation-number-sort"] && this.style.citation_sort.tokens.length > 0; + io.sortable = this.style.opt.sort_citations; var window = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] .getService(Components.interfaces.nsIWindowWatcher)