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:
parent
34800ec810
commit
1b353fb2b2
1 changed files with 85 additions and 40 deletions
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue