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.
This commit is contained in:
Simon Kornblith 2010-07-06 04:29:55 +00:00
parent 34800ec810
commit 1b353fb2b2

View file

@ -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 (this.dateparts && this.dateparts.length) {
} else if (Item[variable] && Item[variable].literal) {
output = true;
break;
} 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) {