diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js index a42c1325c..03683f4ae 100644 --- a/chrome/content/zotero/xpcom/citeproc.js +++ b/chrome/content/zotero/xpcom/citeproc.js @@ -620,6 +620,14 @@ CSL_E4X.prototype.addInstitutionNodes = function(myxml) { } } }; +CSL_E4X.prototype.flagDateMacros = function(myxml) { + default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); + for each (node in myxml..macro) { + if (node..date.length()) { + node.@['macro-has-date'] = 'true'; + } + } +}; CSL.getSortCompare = function () { var strcmp; try { @@ -740,11 +748,15 @@ CSL.Output.Queue.prototype.popFormats = function (tokenstore) { }; CSL.Output.Queue.prototype.startTag = function (name, token) { var tokenstore = {}; + if (this.state.tmp["doing-macro-with-date"] && this.state.tmp.area.slice(-5) === "_sort") { + token = this.empty; + name = "empty"; + } tokenstore[name] = token; this.pushFormats(tokenstore); this.openLevel(name); }; -CSL.Output.Queue.prototype.endTag = function () { +CSL.Output.Queue.prototype.endTag = function (name) { this.closeLevel(); this.popFormats(); }; @@ -773,6 +785,14 @@ CSL.Output.Queue.prototype.closeLevel = function (name) { CSL.Output.Queue.prototype.append = function (str, tokname, notSerious) { var token, blob, curr; var useblob = true; + if (this.state.tmp["doing-macro-with-date"]) { + if (tokname !== "macro-with-date") { + return false; + } + if (tokname === "macro-with-date") { + tokname = "empty"; + } + } if ("undefined" === typeof str) { return false; } @@ -1022,7 +1042,7 @@ CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim) { this.append(str, "empty", true); var str_blob = this.pop(); var count_offset_characters = state.tmp.count_offset_characters; - var str = this.string(state, [str_blob], false); + str = this.string(state, [str_blob], false); state.tmp.count_offset_characters = count_offset_characters; if (blob.strings["text-case"]) { str = CSL.Output.Formatters[blob.strings["text-case"]](this.state, str); @@ -1416,19 +1436,13 @@ CSL.cloneAmbigConfig = function (config, oldconfig, tainters) { } ret.givens.push(param); } - if (tainters && tainters.length > 1) { - if (tainters.length == 2 || (oldconfig && oldconfig.year_suffix !== config.year_suffix)) { - for (i = 0, ilen = tainters.length; i < ilen; i += 1) { - var oldYS = this.registry.registry[tainters[i].id].disambig.year_suffix; - if (tainters && (false === oldYS || oldYS != i)) { - this.tmp.taintedItemIDs[tainters[i].id] = true; - } - } - oldconfig = false; - } + if (oldconfig) { + ret.year_suffix = oldconfig.year_suffix; + ret.disambiguate = oldconfig.disambiguate; + } else { + ret.year_suffix = config.year_suffix; + ret.disambiguate = config.disambiguate; } - ret.year_suffix = config.year_suffix; - ret.disambiguate = config.disambiguate; return ret; }; CSL.getAmbigConfig = function () { @@ -1465,16 +1479,25 @@ CSL.tokenExec = function (token, Item, item) { return next; }; CSL.expandMacro = function (macro_key_token) { - var mkey, start_token, key, end_token, navi, macroxml, newoutput, mergeoutput, end_of_macro; + var mkey, start_token, key, end_token, navi, macroxml, newoutput, mergeoutput, end_of_macro, func; mkey = macro_key_token.postponed_macro; if (this.build.macro_stack.indexOf(mkey) > -1) { throw "CSL processor error: call to macro \"" + mkey + "\" would cause an infinite loop"; } else { this.build.macro_stack.push(mkey); } + macroxml = this.sys.xml.getNodesByName(this.cslXml, 'macro', mkey); + var hasDate = this.sys.xml.getAttributeValue(macroxml, "macro-has-date"); + if (hasDate) { + func = function (state, Item) { + if (state.tmp.area.slice(-5) === "_sort") { + state.tmp["doing-macro-with-date"] = true; + } + }; + macro_key_token.execs.push(func); + } macro_key_token.tokentype = CSL.START; CSL.Node.group.build.call(macro_key_token, this, this[this.build.area].tokens, true); - macroxml = this.sys.xml.getNodesByName(this.cslXml, 'macro', mkey); if (!this.sys.xml.getNodeValue(macroxml)) { throw "CSL style error: undefined macro \"" + mkey + "\""; } @@ -1482,6 +1505,12 @@ CSL.expandMacro = function (macro_key_token) { CSL.buildStyle.call(this, navi); end_of_macro = new CSL.Token("group", CSL.END); CSL.Node.group.build.call(end_of_macro, this, this[this.build.area].tokens, true); + func = function (state, Item) { + if (state.tmp.area.slice(-5) === "_sort") { + state.tmp["doing-macro-with-date"] = false; + } + }; + this[this.build.area].tokens[this[this.build.area].tokens.length - 1].execs.push(func); this.build.macro_stack.pop(); }; CSL.XmlToToken = function (state, tokentype) { @@ -1895,7 +1924,7 @@ CSL.DateParser = function () { }; CSL.Engine = function (sys, style, lang, forceLang) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.200"; + this.processor_version = "1.0.202"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -1925,6 +1954,7 @@ CSL.Engine = function (sys, style, lang, forceLang) { this.sys.xml.addMissingNameNodes(this.cslXml); this.sys.xml.addInstitutionNodes(this.cslXml); this.sys.xml.insertPublisherAndPlace(this.cslXml); + this.sys.xml.flagDateMacros(this.cslXml); attrs = this.sys.xml.attributes(this.cslXml); if ("undefined" === typeof attrs["@sort-separator"]) { this.sys.xml.setAttribute(this.cslXml, "sort-separator", ", "); @@ -3705,7 +3735,7 @@ CSL.Engine.prototype.localeConfigure = function (langspec) { this.localeSet(this.cslXml, langspec.best, langspec.best); }; CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) { - var blob, locale, nodes, attributes, pos, ppos, term, form, termname, styleopts, attr, date, attrname, len, genderform, target; + var blob, locale, nodes, attributes, pos, ppos, term, form, termname, styleopts, attr, date, attrname, len, genderform, target, i, ilen; lang_in = lang_in.replace("_", "-"); lang_out = lang_out.replace("_", "-"); if (!this.locale[lang_out]) { @@ -3728,7 +3758,7 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) { } } nodes = this.sys.xml.getNodesByName(locale, 'type'); - for (var i = 0, ilen = this.sys.xml.numberofnodes(nodes); i < ilen; i += 1) { + for (i = 0, ilen = this.sys.xml.numberofnodes(nodes); i < ilen; i += 1) { var typenode = nodes[i]; var type = this.sys.xml.getAttributeValue(typenode, 'name'); var gender = this.sys.xml.getAttributeValue(typenode, 'gender'); @@ -3772,7 +3802,7 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) { } for (termname in this.locale[lang_out].terms) { if (this.locale[lang_out].terms.hasOwnProperty(termname)) { - for (var i = 0, ilen = 2; i < ilen; i += 1) { + for (i = 0, ilen = 2; i < ilen; i += 1) { genderform = CSL.GENDERS[i]; if (this.locale[lang_out].terms[termname][genderform]) { for (form in this.locale[lang_out].terms[termname]) { @@ -3855,79 +3885,77 @@ CSL.Node.date = { if (!state.build.sort_flag) { CSL.Util.substituteStart.call(this, state, target); } - func = function (state, Item) { - var key, dp; - state.tmp.element_rendered_ok = false; - state.tmp.donesies = []; - state.tmp.dateparts = []; - dp = []; - if (this.variables.length - && !(state.tmp.just_looking - && this.variables[0] !== "issued")) { - state.parallel.StartVariable(this.variables[0]); - date_obj = Item[this.variables[0]]; - if ("undefined" === typeof date_obj) { - date_obj = {"date-parts": [[0]] }; - } - if (date_obj.raw) { - date_obj = state.fun.dateparser.parse(date_obj.raw); - } - state.tmp.date_object = state.dateParseArray(date_obj); - len = this.dateparts.length; - for (pos = 0; pos < len; pos += 1) { - part = this.dateparts[pos]; - if ("undefined" !== typeof state.tmp.date_object[(part + "_end")]) { - dp.push(part); - } else if (part === "month" && "undefined" !== typeof state.tmp.date_object.season_end) { - dp.push(part); + if (state.build.area.slice(-5) === "_sort") { + func = CSL.dateMacroAsSortKey; + } else { + func = function (state, Item) { + var key, dp; + state.tmp.element_rendered_ok = false; + state.tmp.donesies = []; + state.tmp.dateparts = []; + dp = []; + if (this.variables.length + && !(state.tmp.just_looking + && this.variables[0] !== "issued")) { + state.parallel.StartVariable(this.variables[0]); + date_obj = Item[this.variables[0]]; + if ("undefined" === typeof date_obj) { + date_obj = {"date-parts": [[0]] }; } - } - dpx = []; - parts = ["year", "month", "day"]; - len = parts.length; - for (pos = 0; pos < len; pos += 1) { - if (dp.indexOf(parts[pos]) > -1) { - dpx.push(parts[pos]); + if (date_obj.raw) { + date_obj = state.fun.dateparser.parse(date_obj.raw); } - } - dp = dpx.slice(); - if (state.tmp.area.slice(-5) !== "_sort" && ("" + Item.volume) === "" + state.tmp.date_object.year && this.dateparts.length === 1 && this.dateparts[0] === "year") { - for (key in state.tmp.date_object) { - if (state.tmp.date_object.hasOwnProperty(key)) { - if (key.slice(0, 4) === "year" && state.tmp.citeblob.can_suppress_identical_year) { - delete state.tmp.date_object[key]; + state.tmp.date_object = state.dateParseArray(date_obj); + len = this.dateparts.length; + for (pos = 0; pos < len; pos += 1) { + part = this.dateparts[pos]; + if ("undefined" !== typeof state.tmp.date_object[(part + "_end")]) { + dp.push(part); + } else if (part === "month" && "undefined" !== typeof state.tmp.date_object.season_end) { + dp.push(part); + } + } + dpx = []; + parts = ["year", "month", "day"]; + len = parts.length; + for (pos = 0; pos < len; pos += 1) { + if (dp.indexOf(parts[pos]) > -1) { + dpx.push(parts[pos]); + } + } + dp = dpx.slice(); + if (state.tmp.area.slice(-5) !== "_sort" && ("" + Item.volume) === "" + state.tmp.date_object.year && this.dateparts.length === 1 && this.dateparts[0] === "year") { + for (key in state.tmp.date_object) { + if (state.tmp.date_object.hasOwnProperty(key)) { + if (key.slice(0, 4) === "year" && state.tmp.citeblob.can_suppress_identical_year) { + delete state.tmp.date_object[key]; + } } } } - } - mypos = 2; - len = dp.length; - for (pos = 0; pos < len; pos += 1) { - part = dp[pos]; - start = state.tmp.date_object[part]; - end = state.tmp.date_object[(part + "_end")]; - if (start !== end) { - mypos = pos; - break; + mypos = 2; + len = dp.length; + for (pos = 0; pos < len; pos += 1) { + part = dp[pos]; + start = state.tmp.date_object[part]; + end = state.tmp.date_object[(part + "_end")]; + if (start !== end) { + mypos = pos; + break; + } } + state.tmp.date_collapse_at = dp.slice(mypos); + } else { + state.tmp.date_object = false; } - state.tmp.date_collapse_at = dp.slice(mypos); - } else { - state.tmp.date_object = false; - } - }; + }; + } this.execs.push(func); func = function (state, Item) { state.output.startTag("date", this); }; this.execs.push(func); } - if (state.build.sort_flag && (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON)) { - tok = new CSL.Token("key", CSL.SINGLETON); - tok.dateparts = state.build.date_parts.slice(); - tok.variables = state.build.date_variables; - CSL.Node.key.build.call(tok, state, target); - } if (!state.build.sort_flag && (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON)) { func = function (state, Item) { state.output.endTag(); @@ -3945,7 +3973,7 @@ CSL.Node.date = { }; CSL.Node["date-part"] = { build: function (state, target) { - var func, pos, len, decor, first_date, value, value_end, real, have_collapsed, invoked, precondition, known_year, bc, ad, bc_end, ad_end, ready, curr, dcurr, number, num, formatter, item; + var func, pos, len, decor, first_date, value, value_end, real, have_collapsed, invoked, precondition, known_year, bc, ad, bc_end, ad_end, ready, curr, dcurr, number, num, formatter, item, i, ilen; if (!this.strings.form) { this.strings.form = "long"; } @@ -4018,10 +4046,10 @@ CSL.Node["date-part"] = { if (state.tmp.strip_periods) { value = value.replace(/\./g, ""); } else { - for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) { + for (i = 0, ilen = this.decorations.length; i < ilen; i += 1) { if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) { value = value.replace(/\./g, ""); - break + break; } } } @@ -4030,10 +4058,10 @@ CSL.Node["date-part"] = { if (state.tmp.strip_periods) { value_end = value_end.replace(/\./g, ""); } else { - for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) { + for (i = 0, ilen = this.decorations.length; i < ilen; i += 1) { if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) { value_end = value_end.replace(/\./g, ""); - break + break; } } } @@ -4210,7 +4238,7 @@ CSL.Node["et-al"] = { }; CSL.Node.group = { build: function (state, target) { - var func, execs; + var func, execs, outer_area; if (this.tokentype === CSL.START) { CSL.Util.substituteStart.call(this, state, target); if (state.build.substitute_level.value()) { @@ -4228,11 +4256,11 @@ CSL.Node.group = { this.execs = execs.concat(this.execs); if (this.strings["has-publisher-and-publisher-place"]) { state.build["publisher-special"] = true; - var outer_area = state.build.area.replace(/_sort$/, ""); + outer_area = state.build.area.replace(/_sort$/, ""); if ("string" === typeof state[outer_area].opt["name-delimiter"]) { func = function (state, Item) { - if (Item["publisher"] && Item["publisher-place"]) { - var publisher_lst = Item["publisher"].split(/;\s*/); + if (Item.publisher && Item["publisher-place"]) { + var publisher_lst = Item.publisher.split(/;\s*/); var publisher_place_lst = Item["publisher-place"].split(/;\s*/); if (publisher_lst.length > 1 && publisher_lst.length === publisher_place_lst.length) { @@ -4242,18 +4270,17 @@ CSL.Node.group = { state.publisherOutput.group_tok = this; } } - } + }; this.execs.push(func); } } } else { if (state.build["publisher-special"]) { state.build["publisher-special"] = false; - var outer_area = state.build.area.replace(/_sort$/, ""); + outer_area = state.build.area.replace(/_sort$/, ""); if ("string" === typeof state[outer_area].opt["name-delimiter"]) { func = function (state, Item) { if (state.publisherOutput) { - var outer_area = state.tmp.area.replace("_sort", ""); state.publisherOutput.name_delimiter = state[outer_area].opt["name-delimiter"]; state.publisherOutput.delimiter_precedes_last = state[outer_area].opt["delimiter-precedes-last"]; state.publisherOutput.and = state[outer_area].opt["and"]; @@ -4422,6 +4449,7 @@ CSL.Node.key = { state.tmp.done_vars = []; }; start_key.execs.push(func); + state.opt.citation_number_sort_direction = this.strings.sort_direction; func = function (state, Item) { state.output.openLevel("empty"); }; @@ -4455,7 +4483,9 @@ CSL.Node.key = { if (state.build.area === "citation_sort") { state.opt.citation_number_sort = true; } - state.opt.citation_number_sort_direction = this.strings.sort_direction; + if (state.build.area === "bibliography_sort") { + state.opt.citation_number_sort_used = true; + } } if (CSL.CREATORS.indexOf(variable) > -1) { var names_start_token = new CSL.Token("names", CSL.START); @@ -4499,57 +4529,8 @@ CSL.Node.key = { state.output.append(trigraph, this); }; } else if (CSL.DATE_VARIABLES.indexOf(variable) > -1) { - func = function (state, Item) { - var dp, elem, value, e, yr, prefix, i, ilen, num; - dp = Item[variable]; - if ("undefined" === typeof dp) { - dp = {"date-parts": [[0]] }; - if (!dp.year) { - state.tmp.empty_date = true; - } - } - if ("undefined" === typeof this.dateparts) { - this.dateparts = ["year", "month", "day"]; - } - if (dp.raw) { - dp = state.fun.dateparser.parse(dp.raw); - } else if (dp["date-parts"]) { - dp = state.dateParseArray(dp); - } - if ("undefined" === typeof dp) { - dp = {}; - } - for (i = 0, ilen = CSL.DATE_PARTS_INTERNAL.length; i < ilen; i += 1) { - elem = CSL.DATE_PARTS_INTERNAL[i]; - value = 0; - e = elem; - if (e.slice(-4) === "_end") { - e = e.slice(0, -4); - } - if (dp[elem] && this.dateparts.indexOf(e) > -1) { - value = dp[elem]; - } - if (elem.slice(0, 4) === "year") { - yr = CSL.Util.Dates[e].numeric(state, value); - prefix = "Y"; - if (yr[0] === "-") { - prefix = "X"; - yr = yr.slice(1); - yr = 9999 - parseInt(yr, 10); - } - state.output.append(CSL.Util.Dates[elem.slice(0, 4)].numeric(state, (prefix + yr))); - } else { - state.output.append(CSL.Util.Dates[e]["numeric-leading-zeros"](state, value)); - } - } - if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix) { - num = state.registry.registry[Item.id].disambig.year_suffix.toString(); - num = CSL.Util.padding(num); - } else { - num = CSL.Util.padding("0"); - } - state.output.append("S"+num); - }; + func = CSL.dateAsSortKey; + single_text.variables = this.variables; } else if ("title" === variable) { state.transform.init("empty", "title"); state.transform.setTransformLocale("locale-sort"); @@ -4567,28 +4548,7 @@ CSL.Node.key = { } else { // macro var token = new CSL.Token("text", CSL.SINGLETON); token.postponed_macro = this.postponed_macro; - var tlen = target.length; - var keypos = false; CSL.expandMacro.call(state, token); - for (i = 0, ilen = target.slice(tlen).length; i < ilen; i += 1) { - var tok = target.slice(tlen)[i]; - if (tok && tok.name === "text" && tok.dateparts) { - keypos = i; - break; - } - if (tok && tok.variables[0] === "citation-number") { - state.opt.citation_number_sort_direction = this.strings.sort_direction; - } - } - if (keypos) { - var saveme = target[(parseInt(keypos, 10) + parseInt(tlen, 10))]; - for (i = (target.length - 1); i > tlen; i += -1) { - target.pop(); - } - target.push(saveme); - var gtok = new CSL.Token("group", CSL.END); - target.push(gtok); - } } var end_key = new CSL.Token("key", CSL.END); func = function (state, Item) { @@ -4832,7 +4792,7 @@ CSL.NameOutput.prototype.outputNames = function () { this.family_decor = CSL.Util.cloneToken(this.family); this.family_decor.strings.prefix = ""; this.family_decor.strings.suffix = ""; - for (var i = 0, ilen = this.family.execs.length; i < ilen; i += 1) { + for (i = 0, ilen = this.family.execs.length; i < ilen; i += 1) { this.family.execs[i].call(this.family_decor, this.state, this.Item); } } else { @@ -4842,7 +4802,7 @@ CSL.NameOutput.prototype.outputNames = function () { this.given_decor = CSL.Util.cloneToken(this.given); this.given_decor.strings.prefix = ""; this.given_decor.strings.suffix = ""; - for (var i = 0, ilen = this.given.execs.length; i < ilen; i += 1) { + for (i = 0, ilen = this.given.execs.length; i < ilen; i += 1) { this.given.execs[i].call(this.given_decor, this.state, this.Item); } } else { @@ -5769,13 +5729,13 @@ CSL.NameOutput.prototype._stripPeriods = function (tokname, str) { for (var i = 0, ilen = decor_tok.decorations.length; i < ilen; i += 1) { if ("@strip-periods" === decor_tok.decorations[i][0] && "true" === decor_tok.decorations[i][1]) { str = str.replace(/\./g, ""); - break + break; } } } } return str; -} +}; CSL.NameOutput.prototype._nonDroppingParticle = function (name) { var str = this._stripPeriods("family", name["non-dropping-particle"]); if (this.state.output.append(str, this.family_decor, true)) { @@ -5806,7 +5766,7 @@ CSL.NameOutput.prototype._familyName = function (name) { }; CSL.NameOutput.prototype._givenName = function (name, pos, i) { if (this.name.strings.initialize === false) { - if (name.family && name.given && this.name.strings["initialize"] === false) { + if (name.family && name.given && this.name.strings.initialize === false) { name.given = CSL.Util.Names.initializeWith(this.state, name.given, this.name.strings["initialize-with"], true); } name.given = CSL.Util.Names.unInitialize(this.state, name.given); @@ -5992,7 +5952,7 @@ CSL.castLabel = function (state, node, term, plural, mode) { for (var i = 0, ilen = node.decorations.length; i < ilen; i += 1) { if ("@strip-periods" === node.decorations[i][0] && "true" === node.decorations[i][1]) { ret = ret.replace(/\./g, ""); - break + break; } } } @@ -6069,6 +6029,65 @@ CSL.PublisherOutput.prototype.clearVars = function () { this.state.tmp["publisher-token"] = false; this.state.tmp["publisher-place-token"] = false; }; +CSL.dateMacroAsSortKey = function (state, Item) { + CSL.dateAsSortKey.call(this, state, Item, true); +}; +CSL.dateAsSortKey = function (state, Item, isMacro) { + var dp, elem, value, e, yr, prefix, i, ilen, num; + var variable = this.variables[0]; + var macroFlag = "empty"; + if (isMacro) { + macroFlag = "macro-with-date"; + } + dp = Item[variable]; + if ("undefined" === typeof dp) { + dp = {"date-parts": [[0]] }; + if (!dp.year) { + state.tmp.empty_date = true; + } + } + if ("undefined" === typeof this.dateparts) { + this.dateparts = ["year", "month", "day"]; + } + if (dp.raw) { + dp = state.fun.dateparser.parse(dp.raw); + } else if (dp["date-parts"]) { + dp = state.dateParseArray(dp); + } + if ("undefined" === typeof dp) { + dp = {}; + } + for (i = 0, ilen = CSL.DATE_PARTS_INTERNAL.length; i < ilen; i += 1) { + elem = CSL.DATE_PARTS_INTERNAL[i]; + value = 0; + e = elem; + if (e.slice(-4) === "_end") { + e = e.slice(0, -4); + } + if (dp[elem] && this.dateparts.indexOf(e) > -1) { + value = dp[elem]; + } + if (elem.slice(0, 4) === "year") { + yr = CSL.Util.Dates[e].numeric(state, value); + prefix = "Y"; + if (yr[0] === "-") { + prefix = "X"; + yr = yr.slice(1); + yr = 9999 - parseInt(yr, 10); + } + state.output.append(CSL.Util.Dates[elem.slice(0, 4)].numeric(state, (prefix + yr)), macroFlag); + } else { + state.output.append(CSL.Util.Dates[e]["numeric-leading-zeros"](state, value), macroFlag); + } + } + if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix) { + num = state.registry.registry[Item.id].disambig.year_suffix.toString(); + num = CSL.Util.padding(num); + } else { + num = CSL.Util.padding("0"); + } + state.output.append("S"+num, macroFlag); +}; CSL.Node.name = { build: function (state, target) { var func, pos, len, attrname; @@ -6482,6 +6501,9 @@ CSL.Node.text = { if (state.build.area === "bibliography") { state.opt.bib_mode = CSL.NUMERIC; } + if (state.build.area === "bibliography_sort") { + state.opt.citation_number_sort_used = true; + } if ("citation-number" === state[state.tmp.area].opt.collapse) { this.range_prefix = state.getTerm("range-delimiter"); } @@ -6584,7 +6606,7 @@ CSL.Node.text = { for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) { if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) { myterm = myterm.replace(/\./g, ""); - break + break; } } } @@ -6915,6 +6937,9 @@ CSL.Attributes["@variable"] = function (state, arg) { }; CSL.Attributes["@lingo"] = function (state, arg) { }; +CSL.Attributes["@macro-has-date"] = function (state, arg) { + this["macro-has-date"] = true; +}; CSL.Attributes["@locale"] = function (state, arg) { var func, ret, len, pos, variable, myitem, langspec, lang, lst, i, ilen, fallback; if (this.name === "layout") { @@ -7013,7 +7038,7 @@ CSL.Attributes["@jurisdiction"] = function (state, arg) { } } return ret; - } + }; this.tests.push(func); }; CSL.Attributes["@is-uncertain-date"] = function (state, arg) { @@ -7346,7 +7371,7 @@ CSL.Attributes["@text-case"] = function (state, arg) { } } } - } + }; this.execs.push(func); }; CSL.Attributes["@page-range-format"] = function (state, arg) { @@ -7658,7 +7683,7 @@ CSL.Transform = function (state) { } } return false; - }; + } function getOutputFunction(variables) { var mytoken, mysubsection, myfieldname, abbreviation_fallback, alternative_varname, transform_locale, transform_fallback, getTextSubfield; mytoken = CSL.Util.cloneToken(token); // the token isn't needed, is it? @@ -8396,7 +8421,7 @@ CSL.Util.Names.initializeWith = function (state, name, terminator, normalizeOnly namelist.push(lst[i]); } } - var lst = namelist; + lst = namelist; for (i = lst.length -1; i > -1; i += -1) { if (lst[i] && lst[i].slice(0, -1).indexOf(".") > -1) { var lstend = lst.slice(i + 1); @@ -8419,6 +8444,7 @@ CSL.Util.Names.initializeWith = function (state, name, terminator, normalizeOnly return ret; }; CSL.Util.Names.doNormalize = function (state, namelist, terminator, mode) { + var i, ilen; var isAbbrev = []; for (i = 0, ilen = namelist.length; i < ilen; i += 1) { if (namelist[i].length > 1 && namelist[i].slice(-1) === ".") { @@ -8448,7 +8474,7 @@ CSL.Util.Names.doNormalize = function (state, namelist, terminator, mode) { return namelist.join("").replace(/\s+$/,""); }; CSL.Util.Names.doInitialize = function (state, namelist, terminator, mode) { - var i, ilen, m, j, jlen, lst; + var i, ilen, m, j, jlen, lst, n; for (i = 0, ilen = namelist.length; i < ilen; i += 2) { n = namelist[i]; if (!n) { @@ -8462,7 +8488,7 @@ CSL.Util.Names.doInitialize = function (state, namelist, terminator, mode) { var extra = ""; if (m[2]) { var s = ""; - var lst = m[2].split(""); + lst = m[2].split(""); for (j = 0, jlen = lst.length; j < jlen; j += 1) { var c = lst[j]; if (c === c.toUpperCase()) { @@ -8640,14 +8666,14 @@ CSL.Util.Sort.strip_prepositions = function (str) { }; CSL.Util.substituteStart = function (state, target) { var element_trace, display, bib_first, func, choose_start, if_start, nodetypes; - var func = function (state, Item) { + func = function (state, Item) { for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) { if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) { state.tmp.strip_periods += 1; break; } } - } + }; this.execs.push(func); nodetypes = ["number", "date", "names"]; if (("text" === this.name && !this.postponed_macro) || nodetypes.indexOf(this.name) > -1) { @@ -8711,14 +8737,14 @@ CSL.Util.substituteStart = function (state, target) { }; CSL.Util.substituteEnd = function (state, target) { var func, bib_first_end, bib_other, if_end, choose_end, toplevel, hasval, author_substitute, str; - var func = function (state, Item) { + func = function (state, Item) { for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) { if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) { state.tmp.strip_periods += -1; break; } } - } + }; this.execs.push(func); state.build.render_nesting_level += -1; if (state.build.render_nesting_level === 0) { @@ -8878,14 +8904,14 @@ CSL.Util.Suffixator = function (slist) { this.slist = slist.split(","); }; CSL.Util.Suffixator.prototype.format = function (N) { - var X, N; + var X; N += 1; var key = ""; do { - X = ((N % 26) == 0) ? 26 : (N % 26); + X = ((N % 26) === 0) ? 26 : (N % 26); key = this.slist[X-1] + key; N = (N - X) / 26; - } while ( N != 0 ); + } while ( N !== 0 ); return key; }; CSL.Util.PageRangeMangler = {}; @@ -9597,7 +9623,7 @@ CSL.Output.Formats.prototype.rtf = { return "\\super " + CSL.SUPERSCRIPTS[aChar] + "\\nosupersub{}"; }) .replace(/[\x7F-\uFFFF]/g, - function(aChar) { return "\\uc0\\u"+aChar.charCodeAt(0).toString()+"{}" }) + function(aChar) { return "\\uc0\\u"+aChar.charCodeAt(0).toString()+"{}"; }) .replace("\t", "\\tab{}", "g"); }, "@passthrough/true": CSL.Output.Formatters.passthrough, @@ -9778,8 +9804,8 @@ CSL.Registry.prototype.douncited = function () { CSL.Registry.prototype.rebuildlist = function () { var count, len, pos, item; this.reflist = []; - if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING) { - this.mylist.reverse(); + if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING + && this.state.opt.citation_number_sort_used) { } len = this.mylist.length; for (pos = 0; pos < len; pos += 1) { @@ -9788,8 +9814,8 @@ CSL.Registry.prototype.rebuildlist = function () { this.oldseq[item] = this.registry[item].seq; this.registry[item].seq = (pos + 1); } - if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING) { - this.mylist.reverse(); + if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING + && this.state.opt.citation_number_sort_used) { } }; CSL.Registry.prototype.dorefreshes = function () { @@ -9829,8 +9855,8 @@ CSL.Registry.prototype.setdisambigs = function () { }; CSL.Registry.prototype.renumber = function () { var len, pos, item; - if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING) { - this.reflist.reverse(); + if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING + && this.state.opt.citation_number_sort_used) { } len = this.reflist.length; for (pos = 0; pos < len; pos += 1) { @@ -9845,7 +9871,8 @@ CSL.Registry.prototype.renumber = function () { } } } - if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING) { + if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING + && this.state.opt.citation_number_sort_used) { this.reflist.reverse(); } }; @@ -9903,7 +9930,7 @@ CSL.Registry.prototype.compareRegistryTokens = function (a, b) { } return 0; }; -CSL.Registry.prototype.registerAmbigToken = function (akey, id, ambig_config, tainters) { +CSL.Registry.prototype.registerAmbigToken = function (akey, id, ambig_config) { if (this.registry[id] && this.registry[id].disambig && this.registry[id].disambig.names) { for (var i = 0, ilen = ambig_config.names.length; i < ilen; i += 1) { var new_names_params = ambig_config.names[i]; @@ -9921,11 +9948,7 @@ CSL.Registry.prototype.registerAmbigToken = function (akey, id, ambig_config, ta } this.registry[id].ambig = akey; var dome = false; - if (tainters) { - this.registry[id].disambig = CSL.cloneAmbigConfig.call(this.state, ambig_config, this.registry[id].disambig, tainters); - } else { - this.registry[id].disambig = CSL.cloneAmbigConfig(ambig_config); - } + this.registry[id].disambig = CSL.cloneAmbigConfig(ambig_config); }; CSL.getSortKeys = function (Item, key_type) { var area, strip_prepositions, use_parallels, len, pos; @@ -10398,11 +10421,16 @@ CSL.Disambiguation.prototype.disYears = function () { tokens.sort(this.state.registry.sorter.compareKeys); for (pos = 0, len = tokens.length; pos < len; pos += 1) { if (pos === 0) { - this.state.registry.registerAmbigToken(this.akey, "" + tokens[pos].id, this.base, this.scanlist); + this.base.year_suffix = ""+pos; + this.state.registry.registerAmbigToken(this.akey, "" + tokens[pos].id, this.base); } else { + this.base.year_suffix = ""+pos; this.state.registry.registerAmbigToken(this.akey, "" + tokens[pos].id, this.base); } - tokens[pos].disambig.year_suffix = ""+pos; + var newys = this.state.registry.registry[tokens[pos].id].disambig.year_suffix; + if (this.old_desc[tokens[pos].id][0] !== newys) { + this.state.tmp.taintedItemIDs[tokens[pos].id] = true; + } } this.lists[this.listpos] = [this.base, []]; }; @@ -10498,11 +10526,14 @@ CSL.Disambiguation.prototype.initVars = function (akey) { this.akey = akey; this.advance_mode = false; myItemBundles = []; + this.old_desc = {}; myIds = this.ambigcites[akey]; if (myIds && myIds.length > 1) { for (i = 0, ilen = myIds.length; i < ilen; i += 1) { var myItem = this.state.retrieveItem("" + myIds[i]); - myItemBundles.push([this.getItemDesc(myItem), myItem]); + var myDesc = this.getItemDesc(myItem); + myItemBundles.push([myDesc, myItem]); + this.old_desc[myIds[i]] = [this.state.registry.registry[myIds[i]].disambig.year_suffix, this.state.registry.registry[myIds[i]].disambig.disambiguate]; } myItemBundles.sort( function (a, b) {