diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js index 03615d1898..e56447c3d3 100644 --- a/chrome/content/zotero/xpcom/citeproc.js +++ b/chrome/content/zotero/xpcom/citeproc.js @@ -57,6 +57,12 @@ if (!Array.indexOf) { }; } var CSL = { + NestedBraces: [ + ["(", "["], + [")", "]"] + ], + checkNestedBraceOpen: new RegExp(".*\\("), + checkNestedBraceClose: new RegExp(".*\\)"), LangPrefsMap: { "title":"titles", "title-short":"titles", @@ -105,9 +111,8 @@ var CSL = { FINISH: 1, POSITION_FIRST: 0, POSITION_SUBSEQUENT: 1, - POSITION_SUBSEQUENT_PARALLEL: 2, - POSITION_IBID: 3, - POSITION_IBID_WITH_LOCATOR: 4, + POSITION_IBID: 2, + POSITION_IBID_WITH_LOCATOR: 3, MARK_TRAILING_NAMES: true, POSITION_TEST_VARS: ["position", "first-reference-note-number", "near-note"], AREAS: ["citation", "citation_sort", "bibliography", "bibliography_sort"], @@ -807,6 +812,12 @@ CSL.Output.Queue.prototype.openLevel = function (token, ephemeral) { } blob = new CSL.Blob(undefined, this.formats.value()[token], token); } + if (this.nestedBraces) { + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + } curr = this.current.value(); curr.push(blob); this.current.push(blob); @@ -865,6 +876,12 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr } } blob = new CSL.Blob(str, token); + if (this.nestedBraces) { + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + } curr = this.current.value(); if ("undefined" === typeof curr && this.current.mystack.length === 0) { this.current.mystack.push([]); @@ -897,7 +914,7 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr }; CSL.Output.Queue.prototype.string = function (state, myblobs, blob) { var i, ilen, j, jlen, b; - var txt_esc = CSL.getSafeEscape(this.state.opt.mode, this.state.tmp.area); + var txt_esc = CSL.getSafeEscape(this.state); var blobs = myblobs.slice(); var ret = []; if (blobs.length === 0) { @@ -936,7 +953,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) { } } if (b && b.length) { - b = txt_esc(blobjr.strings.prefix) + b + txt_esc(blobjr.strings.suffix); + b = txt_esc(blobjr.strings.prefix, state.tmp.nestedBraces) + b + txt_esc(blobjr.strings.suffix, state.tmp.nestedBraces); ret.push(b); if (state.tmp.count_offset_characters) { state.tmp.offset_characters += (blen + blobjr.strings.suffix.length + blobjr.strings.prefix.length); @@ -986,7 +1003,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) { use_suffix = blob.strings.suffix; if (b && b.length) { use_prefix = blob.strings.prefix; - b = txt_esc(use_prefix) + b + txt_esc(use_suffix); + b = txt_esc(use_prefix, state.tmp.nestedBraces) + b + txt_esc(use_suffix, state.tmp.nestedBraces); if (state.tmp.count_offset_characters) { state.tmp.offset_characters += (use_prefix.length + use_suffix.length); } @@ -1039,7 +1056,7 @@ CSL.Output.Queue.prototype.clearlevel = function () { }; CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, has_more) { var state, ret, ret_last_char, use_delim, i, blob, pos, len, ppos, llen, pppos, lllen, res, str, params, txt_esc; - txt_esc = CSL.getSafeEscape(this.state.opt.mode, this.state.tmp.area); + txt_esc = CSL.getSafeEscape(this.state); if (!delim) { delim = ""; } @@ -1963,7 +1980,7 @@ CSL.DateParser = function () { }; CSL.Engine = function (sys, style, lang, forceLang) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.255"; + this.processor_version = "1.0.258"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -2519,6 +2536,7 @@ CSL.Engine.Opt = function () { this.development_extensions.locator_label_parse = true; this.development_extensions.raw_date_parsing = true; this.development_extensions.clean_up_csl_flaws = true; + this.development_extensions.flip_parentheses_to_braces = true; this.gender = {}; this['cite-lang-prefs'] = { persons:['orig'], @@ -3241,6 +3259,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } var citations; if (this.opt.update_mode === CSL.POSITION) { + var citationsInNote = {}; for (i = 0; i < 2; i += 1) { citations = [textCitations, noteCitations][i]; var first_ref = {}; @@ -3250,6 +3269,11 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, if (!onecitation.properties.noteIndex) { onecitation.properties.noteIndex = 0; } + if (!citationsInNote[onecitation.properties.noteIndex]) { + citationsInNote[onecitation.properties.noteIndex] = 1; + } else { + citationsInNote[onecitation.properties.noteIndex] += 1; + } for (k = 0, klen = citations[j].sortedItems.length; k < klen; k += 1) { item = citations[j].sortedItems[k]; if (flag === CSL.PREVIEW) { @@ -3280,7 +3304,9 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, var items = citations[(j - 1)].sortedItems; var useme = false; if ((citations[(j - 1)].sortedItems[0][1].id == item[1].id && citations[j - 1].properties.noteIndex >= (citations[j].properties.noteIndex - 1)) || citations[(j - 1)].sortedItems[0][1].id == this.registry.registry[item[1].id].parallel) { - useme = true; + if (citationsInNote[citations[j - 1].properties.noteIndex] === 1) { + useme = true; + } } for (n = 0, nlen = items.slice(1).length; n < nlen; n += 1) { var itmp = items.slice(1)[n]; @@ -3345,11 +3371,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } } if (suprame) { - if (this.registry.registry[item[1].id].parallel) { - item[1].position = CSL.POSITION_SUBSEQUENT_PARALLEL; - } else { - item[1].position = CSL.POSITION_SUBSEQUENT; - } + item[1].position = CSL.POSITION_SUBSEQUENT; if (first_ref[item[1].id] != onecitation.properties.noteIndex) { item[1]["first-reference-note-number"] = first_ref[item[1].id]; } @@ -3527,7 +3549,8 @@ CSL.getSpliceDelimiter = function (last_collapsed, pos) { CSL.getCitationCluster = function (inputList, citationID) { var result, objects, myparams, len, pos, item, last_collapsed, params, empties, composite, compie, myblobs, Item, llen, ppos, obj, preceding_item, txt_esc, error_object; this.tmp.last_primary_names_string = false; - txt_esc = CSL.Output.Formats[this.opt.mode].text_escape; + this.tmp.nestedBraces = false; + txt_esc = CSL.getSafeEscape(this); this.tmp.area = "citation"; result = ""; objects = []; @@ -3540,6 +3563,50 @@ CSL.getCitationCluster = function (inputList, citationID) { this.registry.citationreg.citationById[citationID].properties.backref_index = false; this.registry.citationreg.citationById[citationID].properties.backref_citation = false; } + if (this.opt.xclass === "note") { + var parasets = []; + var lastTitle = false; + var lastPosition = false; + var lastID = false; + for (var i=0, ilen = inputList.length; i < ilen; i += 1) { + var type = inputList[i][0].type; + var title = inputList[i][0].title; + var position = inputList[i][1].position; + var id = inputList[i][0].id; + if (title && type === "legal_case" && id !== lastID && position) { + if (title !== lastTitle || parasets.length === 0) { + var lst = []; + parasets.push(lst); + } + lst.push(inputList[i][1]); + } + lastTitle = title; + lastPosition = position; + lastID = id; + } + for (var i=0, ilen=parasets.length; i < ilen; i += 1) { + var lst = parasets[i]; + if (lst.length < 2) { + continue; + } + var locatorInLastPosition = lst.slice(-1)[0].locator; + if (locatorInLastPosition) { + for (var j=0, jlen=lst.length - 1; j < jlen; j += 1) { + if (lst[j].locator) { + locatorInLastPosition = false; + } + } + } + if (locatorInLastPosition) { + lst[0].locator = locatorInLastPosition; + delete lst.slice(-1)[0].locator; + lst[0].label = lst.slice(-1)[0].label; + if (lst.slice(-1)[0].label) { + delete lst.slice(-1)[0].label; + } + } + } + } myparams = []; len = inputList.length; for (pos = 0; pos < len; pos += 1) { @@ -3689,6 +3756,7 @@ CSL.getCitationCluster = function (inputList, citationID) { && this.tmp.last_chr === use_layout_suffix.slice(0, 1)) { use_layout_suffix = use_layout_suffix.slice(1); } + this.output.nestedBraces = false; result = txt_esc(this.citation.opt.layout_prefix) + result + txt_esc(use_layout_suffix); if (!this.tmp.suppress_decorations) { len = this.citation.opt.layout_decorations.length; @@ -3764,6 +3832,15 @@ CSL.citeStart = function (Item, item) { } this.tmp.shadow_numbers = {}; this.tmp.first_name_string = false; + if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.prefix) { + var openBrace = CSL.checkNestedBraceOpen.exec(item.prefix); + var closeBrace = CSL.checkNestedBraceClose.exec(item.prefix); + if (openBrace) { + if (!closeBrace || closeBrace[0].length < openBrace[0].length) { + this.output.nestedBraces = CSL.NestedBraces; + } + } + } }; CSL.citeEnd = function (Item, item) { if (this.tmp.disambig_restore) { @@ -3777,6 +3854,15 @@ CSL.citeEnd = function (Item, item) { this.tmp.cut_var = false; this.tmp.disambig_request = false; this.tmp.cite_locales.push(this.tmp.last_cite_locale); + if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.suffix) { + var openBrace = CSL.checkNestedBraceOpen.exec(item.suffix); + var closeBrace = CSL.checkNestedBraceClose.exec(item.suffix); + if (closeBrace) { + if (!openBrace || openBrace[0].length < closeBrace[0].length) { + this.output.nestedBraces = false; + } + } + } }; CSL.Node = {}; CSL.Node.bibliography = { @@ -7841,8 +7927,6 @@ CSL.Attributes["@position"] = function (state, arg) { for (var i = 0, ilen = lst.length; i < ilen; i += 1) { if (lst[i] === "first") { tryposition = CSL.POSITION_FIRST; - } else if (lst[i] === "subsequent-parallel") { - tryposition = CSL.POSITION_SUBSEQUENT_PARALLEL; } else if (lst[i] === "subsequent") { tryposition = CSL.POSITION_SUBSEQUENT; } else if (lst[i] === "ibid") { @@ -8923,7 +9007,7 @@ CSL.Blob = function (str, token, levelname) { var len, pos, key; this.levelname = levelname; if (token) { - this.strings = {}; + this.strings = {"prefix":"","suffix":""}; for (key in token.strings) { if (token.strings.hasOwnProperty(key)) { this.strings[key] = token.strings[key]; @@ -9509,7 +9593,7 @@ CSL.Util.substituteEnd = function (state, target) { author_substitute = new CSL.Token("text", CSL.SINGLETON); func = function (state, Item) { var i, ilen; - var text_esc = CSL.getSafeEscape(state.opt.mode, state.tmp.area); + var text_esc = CSL.getSafeEscape(state); var printing = !state.tmp.suppress_decorations; if (printing && state.tmp.area === "bibliography") { if (!state.tmp.rendered_name) { @@ -10003,7 +10087,7 @@ CSL.Util.FlipFlopper = function (state) { this.okReverseHash = hashes[4]; }; CSL.Util.FlipFlopper.prototype.init = function (str, blob) { - this.txt_esc = CSL.getSafeEscape(this.state.opt.mode, this.state.tmp.area); + this.txt_esc = CSL.getSafeEscape(this.state); str = this._normalizeString(str); if (!blob) { this.strs = this.getSplitStrings(str); @@ -10230,9 +10314,9 @@ CSL.Util.FlipFlopper.prototype.addFlipFlop = function (blob, fun) { return newdecor; }; CSL.Output.Formatters = {}; -CSL.getSafeEscape = function(outputModeOpt, outputArea) { - if (["bibliography", "citation"].indexOf(outputArea) > -1) { - return CSL.Output.Formats[outputModeOpt].text_escape; +CSL.getSafeEscape = function(state) { + if (["bibliography", "citation"].indexOf(state.tmp.area) > -1) { + return CSL.Output.Formats[state.opt.mode].text_escape; } else { return function (txt) { return txt; }; } @@ -10304,7 +10388,7 @@ CSL.Output.Formatters.title = function (state, string) { lowerCaseVariant = words[pos].toLowerCase(); var totallyskip = false; if (!isAllUpperCase || (words.length === 1 && words[pos].length < 4)) { - if (words[pos] === upperCaseVariant) { + if (words[pos] !== lowerCaseVariant) { totallyskip = true; } } @@ -11596,4 +11680,3 @@ CSL.Node.generate = { } } }; -