www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 1b353fb2b2b0cf66eba6a1b78c3edda746de0ac4
parent 34800ec81063a87bd68da7f6e6ae213ff1eb6227
Author: Simon Kornblith <simon@simonster.com>
Date:   Tue,  6 Jul 2010 04:29:55 +0000

Update to citeproc-js 1.0.44

From 1.0.39:
 Fix a tiny bug that could cause erroneous position values when
 previewing under some circumstances, resulting in an incorrect
 cite form in preview, and a different (although correct) cite form
 in the document.

From 1.0.40:
 Avoid update to position data of other citations during
 previewing.  On-the-fly updates of related citations upon
 citation edit or insert following preview were broken, but
 should now work correctly.

From 1.0.41:
 Reset processor's internal last_name_rendered variable,
 to prevent previous runs of the processor from affecting
 bibliography output.

From 1.0.42:
 Provisional implementation of ellipsis truncation for
 creator listings as required by APA 6th, in anticipation
 of upcoming point release of CSL schema and specification.

From 1.0.43:
 In test.py, change the -E bundled code dump option to -Z,
 and describe as a Zotero bundle option in script help messages.

 Include an assignment of CSL.error to Zotero.debug in the Zotero
 bundle, so that error messages and warnings from the processor will
 pass through correctly, without crashing the processor.

 Render literal passthrough strings on date objects only when
 the year is included among the requested date elements.

 Add temporary code to normalize the structure of some date
 input objects.

 (... and so we bid a sad farewell to the Meaning of Life
 release.)

From 1.0.44:
 According to the CSL specification, group elements implicitly
 suppress output of term= and value= text elements, if at least
 one element (text, number, names or date) with a variable=
 attribute is in the group, and no such element will produce
 output.  This provides a flexible  and concise syntax for
 attaching customized labels to rendered elements.  An earlier
 version of citeproc-js always rendered empty dates as the short
 form of the "no date" term ("n.d.").  Experience showed this was
 undesirable, and the behavior was withdrawn.  However, the
 code that reported date elements as always producing output
 lingered on, and it was the cause of incorrect output in recent
 testing.  This has been corrected in this release.

 This release also correctly reports dates with only a literal (non-
 parsed) form as non-empty to the same implicit conditional
 code in an enclosing group element.



Diffstat:
Mchrome/content/zotero/xpcom/citeproc.js | 125++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 85 insertions(+), 40 deletions(-)

diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js @@ -62,7 +62,7 @@ var CSL = { print(str); }, PREVIEW: "Just for laughs.", - ASSUME_ALL_ITEMS_REGISTERED: "Assume we have registered all items.", + ASSUME_ALL_ITEMS_REGISTERED: 2, START: 0, END: 1, SINGLETON: 2, @@ -102,12 +102,6 @@ var CSL = { DATE_PARTS_INTERNAL: ["year", "month", "day", "year_end", "month_end", "day_end"], NAME_PARTS: ["family", "given", "dropping-particle", "non-dropping-particle", "suffix"], DECORABLE_NAME_PARTS: ["given", "family", "suffix"], - ET_AL_NAMES: [ - "et-al-min", - "et-al-use-first", - "et-al-subsequent-min", - "et-al-subsequent-use-first" - ], DISAMBIGUATE_OPTIONS: [ "disambiguate-add-names", "disambiguate-add-givenname", @@ -434,6 +428,9 @@ CSL_E4X.prototype.addInstitutionNodes = function(myxml) { } } }; +CSL.error = function(str) { + Zotero.debug("citeproc-js: "+str); +} CSL.Output = {}; CSL.Output.Queue = function (state) { this.levelname = ["top"]; @@ -1487,7 +1484,7 @@ CSL.dateParser = function (txt) { }; CSL.Engine = function (sys, style, lang, xmlmode) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.38"; + this.processor_version = "1.0.44"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -1655,6 +1652,8 @@ CSL.Engine.prototype.setOutputFormat = function (mode) { this.output[mode].tmp = {}; } }; +CSL.Engine.prototype.setLocale = function (locale) { +}; CSL.Engine.prototype.getTerm = function (term, form, plural) { var ret = CSL.Engine.getField(CSL.LOOSE, this.locale[this.opt.lang].terms, term, form, plural); if (typeof ret === "undefined") { @@ -1880,7 +1879,12 @@ CSL.Engine.prototype.dateParseArray = function (date_obj) { } } } else if (date_obj.hasOwnProperty(field)) { - ret[field] = date_obj[field]; + if (field === "literal" && "object" === typeof date_obj.literal && "string" === typeof date_obj.literal.part) { + CSL.error("CSL: fixing up weird literal date value"); + ret.literal = date_obj.literal.part; + } else { + ret[field] = date_obj[field]; + } } } return ret; @@ -1920,6 +1924,7 @@ CSL.Engine.Opt = function () { this.sort_citations = false; this["et-al-min"] = 0; this["et-al-use-first"] = 1; + this["et-al-use-last"] = false; this["et-al-subsequent-min"] = false; this["et-al-subsequent-use-first"] = false; this["demote-non-dropping-particle"] = "display-and-sort"; @@ -2139,6 +2144,7 @@ CSL.getBibliographyEntries = function (bibsection) { var ret, input, include, anymatch, allmatch, bib_entry, res, len, pos, item, llen, ppos, spec, lllen, pppos, bib_layout, topblobs, all_item_ids, entry_item_ids, debug, collapse_parallel, i, siblings, skips, sortedItems, eyetem; ret = []; this.tmp.area = "bibliography"; + this.tmp.last_rendered_name = false; input = this.retrieveItems(this.registry.getSortedIds()); this.tmp.disambig_override = true; function eval_string(a, b) { @@ -2407,19 +2413,30 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, llen = citations.length; for (ppos = 0; ppos < llen; ppos += 1) { onecitation = citations[ppos]; + if (!onecitation.properties.noteIndex) { + onecitation.properties.noteIndex = 0; + } lllen = citations[ppos].sortedItems.length; for (pppos = 0; pppos < lllen; pppos += 1) { item = citations[ppos].sortedItems[pppos]; + if (flag === CSL.PREVIEW) { + if (onecitation.citationID !== citation.citationID) { + if ("undefined" === typeof first_ref[item[1].id]) { + first_ref[item[1].id] = onecitation.properties.noteIndex; + last_ref[item[1].id] = onecitation.properties.noteIndex; + } else { + last_ref[item[1].id] = onecitation.properties.noteIndex; + } + continue; + } + } oldvalue = {}; oldvalue.position = item[1].position; oldvalue["first-reference-note-number"] = item[1]["first-reference-note-number"]; oldvalue["near-note"] = item[1]["near-note"]; item[1]["first-reference-note-number"] = 0; item[1]["near-note"] = false; - if ("number" !== typeof first_ref[item[1].id]) { - if (!onecitation.properties.noteIndex) { - onecitation.properties.noteIndex = 0; - } + if ("undefined" === typeof first_ref[item[1].id]) { first_ref[item[1].id] = onecitation.properties.noteIndex; last_ref[item[1].id] = onecitation.properties.noteIndex; item[1].position = CSL.POSITION_FIRST; @@ -2429,7 +2446,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, if (ppos > 0 && parseInt(pppos, 10) === 0) { items = citations[(ppos - 1)].sortedItems; useme = false; - if ((citations[(ppos - 1)].sortedItems[0][1].id === item[1].id && citations[ppos - 1].properties.noteIndex >= (citations[ppos].properties.noteIndex - 1)) || citations[(ppos - 1)].sortedItems[0][1].id === this.registry.registry[item[1].id].parallel) { + if ((citations[(ppos - 1)].sortedItems[0][1].id == item[1].id && citations[ppos - 1].properties.noteIndex >= (citations[ppos].properties.noteIndex - 1)) || citations[(ppos - 1)].sortedItems[0][1].id == this.registry.registry[item[1].id].parallel) { useme = true; } llllen = items.slice(1).length; @@ -2483,15 +2500,11 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } } if (onecitation.properties.noteIndex) { - cids = this.registry.citationreg.citationsByItemId[item[0].id]; - for (ppppos = (cids.length - 1); ppppos > -1; ppppos += -1) { - if (cids[ppppos].properties.noteIndex < onecitation.properties.noteIndex) { - note_distance = onecitation.properties.noteIndex - cids[ppppos].properties.noteIndex; - if (note_distance <= this.citation.opt["near-note-distance"]) { - item[1]["near-note"] = true; - } - } + note_distance = onecitation.properties.noteIndex - last_ref[item[1].id]; + if (note_distance <= this.citation.opt["near-note-distance"]) { + item[1]["near-note"] = true; } + last_ref[item[1].id] = onecitation.properties.noteIndex; } if (onecitation.citationID !== citation.citationID) { llllen = CSL.POSITION_TEST_VARS.length; @@ -2546,9 +2559,9 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, continue; } obj = []; - citation = this.registry.citationreg.citationById[key]; - obj.push(citation.properties.index); - obj.push(this.process_CitationCluster.call(this, citation.sortedItems)); + var mycitation = this.registry.citationreg.citationById[key]; + obj.push(mycitation.properties.index); + obj.push(this.process_CitationCluster.call(this, mycitation.sortedItems)); ret.push(obj); } } @@ -2802,6 +2815,7 @@ CSL.Node.bibliography = { state.fixOpt(this, "sort-separator", "sort-separator"); state.fixOpt(this, "et-al-min", "et-al-min"); state.fixOpt(this, "et-al-use-first", "et-al-use-first"); + state.fixOpt(this, "et-al-use-last", "et-al-use-last"); state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min"); state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first"); state.build.area_return = state.build.area; @@ -2852,6 +2866,7 @@ CSL.Node.citation = { state.fixOpt(this, "sort-separator", "sort-separator"); state.fixOpt(this, "et-al-min", "et-al-min"); state.fixOpt(this, "et-al-use-first", "et-al-use-first"); + state.fixOpt(this, "et-al-use-last", "et-al-use-last"); state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min"); state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first"); state.build.area_return = state.build.area; @@ -2887,6 +2902,8 @@ CSL.Node.date = { state.tmp.date_object = state.fun.dateparser.parse(date_obj.raw); } else if (date_obj["date-parts"]) { state.tmp.date_object = state.dateParseArray(date_obj); + } else if ("object" === typeof date_obj) { + state.tmp.date_object = state.dateParseArray(date_obj); } len = this.dateparts.length; for (pos = 0; pos < len; pos += 1) { @@ -2934,13 +2951,6 @@ CSL.Node.date = { this.execs.push(func); func = function (state, Item) { state.output.startTag("date", this); - var tok = new CSL.Token("date-part", CSL.SINGLETON); - if (state.tmp.date_object.literal) { - state.parallel.AppendToVariable(state.tmp.date_object.literal); - state.output.append(state.tmp.date_object.literal, tok); - state.tmp.date_object = {}; - } - tok.strings.suffix = " "; }; this.execs.push(func); } @@ -2978,6 +2988,10 @@ CSL.Node["date-part"] = { value = ""; value_end = ""; state.tmp.donesies.push(this.strings.name); + if (state.tmp.date_object.literal && "year" === this.strings.name) { + state.parallel.AppendToVariable(state.tmp.date_object.literal); + state.output.append(state.tmp.date_object.literal, this); + } if (state.tmp.date_object) { value = state.tmp.date_object[this.strings.name]; value_end = state.tmp.date_object[(this.strings.name + "_end")]; @@ -3675,6 +3689,7 @@ CSL.Node.name = { state.fixOpt(this, "sort-separator", "sort-separator"); state.fixOpt(this, "et-al-min", "et-al-min"); state.fixOpt(this, "et-al-use-first", "et-al-use-first"); + state.fixOpt(this, "et-al-use-last", "et-al-use-last"); state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min"); state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first"); state.build.nameattrs = {}; @@ -3712,6 +3727,9 @@ CSL.Node.name = { state.tmp["et-al-use-first"] = this.strings["et-al-use-first"]; } } + if ("undefined" !== this.strings["et-al-use-last"]) { + state.tmp["et-al-use-last"] = this.strings["et-al-use-last"]; + } }; this.execs.push(func); func = function (state, Item) { @@ -3880,7 +3898,7 @@ CSL.Node.names = { } } func = function (state, Item, item) { - var common_term, nameset, name, local_count, withtoken, namesetIndex, lastones, currentones, compset, display_names, suppress_min, suppress_condition, sane, discretionary_names_length, overlength, et_al, and_term, outer_and_term, use_first, append_last, delim, param, paramx, val, s, myform, myinitials, termname, form, namepart, namesets, llen, ppos, label, plural, last_variable, cutinfo, cut_var, obj, et_al_pers, et_al_org, and_pers, and_org, with_term, chk; + var common_term, nameset, name, local_count, withtoken, namesetIndex, lastones, currentones, compset, display_names, suppress_min, suppress_condition, sane, discretionary_names_length, overlength, et_al, and_term, outer_and_term, use_first, append_last, delim, param, paramx, val, s, myform, myinitials, termname, form, namepart, namesets, llen, ppos, label, plural, last_variable, cutinfo, cut_var, obj, et_al_pers, et_al_org, and_pers, and_org, with_term, chk, apply_ellipsis; namesets = []; common_term = CSL.Util.Names.getCommonTerm(state, state.tmp.value); if (common_term) { @@ -4022,6 +4040,11 @@ CSL.Node.names = { state.tmp.names_cut.counts[nameset.variable] = state.tmp["et-al-use-first"]; } sane = state.tmp["et-al-min"] >= state.tmp["et-al-use-first"]; + if (state.tmp["et-al-use-last"] && state.tmp["et-al-min"] >= state.tmp["et-al-use-first"] + 2) { + apply_ellipsis = true; + } else { + apply_ellipsis = false; + } discretionary_names_length = state.tmp["et-al-min"]; suppress_condition = suppress_min && display_names.length >= suppress_min; if (suppress_condition) { @@ -4052,10 +4075,17 @@ CSL.Node.names = { state.output.getToken("et-al-pers").strings.prefix = state.output.getToken("et-al-pers").strings["prefix-single"]; } } - display_names = display_names.slice(0, discretionary_names_length); + if (apply_ellipsis) { + state.tmp.use_ellipsis = true; + display_names = display_names.slice(0, discretionary_names_length).concat(display_names.slice(-1)); + } else { + display_names = display_names.slice(0, discretionary_names_length); + } } else { - if (state.output.getToken("name").strings.and && ! state.tmp.sort_key_flag && display_names.length > 1) { - and_term = state.output.getToken("name").strings.and; + if (!state.tmp.sort_key_flag && display_names.length > 1) { + if (state.output.getToken("name").strings.and) { + and_term = state.output.getToken("name").strings.and; + } } } state.output.formats.value().name.strings.delimiter = and_term; @@ -4174,7 +4204,7 @@ CSL.Node.names = { if (nameset.species === "pers") { state.output.openLevel("etal-join"); // join for etal CSL.Util.Names.outputNames(state, display_names); - if (et_al) { + if (et_al && !state.tmp.use_ellipsis) { state.output.append(et_al, "et-al-pers"); } state.output.closeLevel("etal-join"); // etal @@ -4230,6 +4260,8 @@ CSL.Node.names = { state.tmp["has-first-person"] = false; state.tmp["et-al-min"] = false; state.tmp["et-al-use-first"] = false; + state.tmp["et-al-use-last"] = false; + state.tmp.use_ellipsis = false; state.tmp.can_block_substitute = false; }; this.execs.push(func); @@ -4647,15 +4679,19 @@ CSL.Attributes["@variable"] = function (state, arg) { }; this.execs.push(func); func = function (state, Item, item) { + var mydate; output = false; len = this.variables.length; for (pos = 0; pos < len; pos += 1) { variable = this.variables[pos]; if (CSL.DATE_VARIABLES.indexOf(variable) > -1) { - if (!Item[variable] || !Item[variable]['date-parts'] || !Item[variable]['date-parts'].length) { + if (Item[variable] && Item[variable].raw) { + output = true; + break; + } else if (Item[variable] && Item[variable].literal) { output = true; break; - } else if (this.dateparts && this.dateparts.length) { + } else if (Item[variable] && Item[variable]['date-parts'] && Item[variable]['date-parts'].length && this.dateparts && this.dateparts.length) { varlen = Item[variable]['date-parts'][0].length; needlen = 4; if (this.dateparts.indexOf("year") > -1) { @@ -4908,6 +4944,13 @@ CSL.Attributes["@et-al-min"] = function (state, arg) { CSL.Attributes["@et-al-use-first"] = function (state, arg) { state.setOpt(this, "et-al-use-first", parseInt(arg, 10)); }; +CSL.Attributes["@et-al-use-last"] = function (state, arg) { + if (arg === "true") { + state.setOpt(this, "et-al-use-last", true); + } else { + state.setOpt(this, "et-al-use-last", false); + } +}; CSL.Attributes["@et-al-subsequent-min"] = function (state, arg) { state.setOpt(this, "et-al-subsequent-min", parseInt(arg, 10)); }; @@ -5864,7 +5907,9 @@ CSL.Util.Names.outputNames = function (state, display_names) { var segments, and; segments = new this.StartMiddleEnd(state, display_names); and = state.output.getToken("name").strings.delimiter; - if (state.output.getToken("name").strings["delimiter-precedes-last"] === "always") { + if (state.tmp.use_ellipsis) { + and = state.output.getToken("inner").strings.delimiter + state.getTerm("ellipsis") + " "; + } else if (state.output.getToken("name").strings["delimiter-precedes-last"] === "always") { and = state.output.getToken("inner").strings.delimiter + and; } else if (state.output.getToken("name").strings["delimiter-precedes-last"] === "never") { if (!and) {