commit 481e00bfc83578bb8e94e54fcc848db68f006dd3
parent 322755e74578b7c63ca86d29bf5dcb33fa5e17c9
Author: Simon Kornblith <simon@simonster.com>
Date: Tue, 19 Nov 2013 02:13:54 -0500
Update citeproc-js
Diffstat:
1 file changed, 103 insertions(+), 27 deletions(-)
diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js
@@ -57,7 +57,7 @@ if (!Array.indexOf) {
};
}
var CSL = {
- PROCESSOR_VERSION: "1.0.502",
+ PROCESSOR_VERSION: "1.0.508",
CONDITION_LEVEL_TOP: 1,
CONDITION_LEVEL_BOTTOM: 2,
PLAIN_HYPHEN_REGEX: /(?:[^\\]-|\u2013)/,
@@ -1597,14 +1597,18 @@ CSL.DateParser = function () {
thedate["date-parts"][0].push(thedate[part]);
delete thedate[part];
}
+ thedate["date-parts"].push([]);
for (i = 0, ilen = slicelen; i < ilen; i += 1) {
part = ["year_end", "month_end", "day_end"][i];
- if (thedate[part] && thedate["date-parts"].length === 1) {
- thedate["date-parts"].push([]);
+ if (!thedate[part]) {
+ break;
}
thedate["date-parts"][1].push(thedate[part]);
delete thedate[part];
}
+ if (thedate["date-parts"][0].length !== thedate["date-parts"][1].length) {
+ thedate["date-parts"].pop();
+ }
};
this.parseNumericDate = function (ret, delim, suff, txt) {
var lst, i, ilen;
@@ -1730,10 +1734,10 @@ CSL.Engine = function (sys, style, lang, forceLang) {
langspec = CSL.localeResolve(lang);
this.opt.lang = langspec.best;
this.opt["default-locale"][0] = langspec.best;
+ this.locale = {};
if (!this.opt["default-locale-sort"]) {
this.opt["default-locale-sort"] = this.opt["default-locale"][0];
}
- this.locale = {};
this.localeConfigure(langspec);
function makeRegExp(lst) {
var lst = lst.slice();
@@ -2714,7 +2718,7 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr
if (notSerious) {
ignorePredecessor = true;
}
- if (this.state.tmp["doing-macro-with-date"]) {
+ if (this.state.tmp["doing-macro-with-date"] && !notSerious) {
if (tokname !== "macro-with-date") {
return false;
}
@@ -3475,7 +3479,6 @@ CSL.Engine.Opt = function () {
this["demote-non-dropping-particle"] = "display-and-sort";
this["parse-names"] = true;
this.citation_number_slug = false;
- this.max_number_of_names = 0;
this.trigraph = "Aaaa00:AaAa00:AaAA00:AAAA00";
this.development_extensions = {};
this.development_extensions.field_hack = true;
@@ -3512,6 +3515,7 @@ CSL.Engine.Opt = function () {
places:['orig'],
number:['translat']
};
+ this.has_layout_locale = false;
};
CSL.Engine.Tmp = function () {
this.names_max = new CSL.Stack();
@@ -3606,6 +3610,9 @@ CSL.Engine.Citation = function (state) {
this.opt.layout_prefix = "";
this.opt.layout_suffix = "";
this.opt.layout_delimiter = "";
+ this.opt.sort_locales = [];
+ this.opt.max_number_of_names = 0;
+ this.root = "citation";
};
CSL.Engine.Bibliography = function () {
this.opt = {};
@@ -3618,6 +3625,9 @@ CSL.Engine.Bibliography = function () {
this.opt.layout_delimiter = "";
this.opt["line-spacing"] = 1;
this.opt["entry-spacing"] = 1;
+ this.opt.sort_locales = [];
+ this.opt.max_number_of_names = 0;
+ this.root = "bibliography";
};
CSL.Engine.BibliographySort = function () {
this.tokens = [];
@@ -3625,6 +3635,7 @@ CSL.Engine.BibliographySort = function () {
this.opt.sort_directions = [];
this.keys = [];
this.opt.topdecor = [];
+ this.root = "bibliography";
};
CSL.Engine.CitationSort = function () {
this.tokens = [];
@@ -3632,6 +3643,7 @@ CSL.Engine.CitationSort = function () {
this.opt.sort_directions = [];
this.keys = [];
this.opt.topdecor = [];
+ this.root = "citation";
};
CSL.Engine.prototype.previewCitationCluster = function (citation, citationsPre, citationsPost, newMode) {
var oldMode = this.opt.mode;
@@ -4962,14 +4974,23 @@ CSL.Engine.prototype.updateUncitedItems = function (idList, nosort) {
this.registry.renumber();
return this.registry.getSortedIds();
};
-CSL.localeResolve = function (langstr) {
+CSL.localeResolve = function (langstr, defaultLocale) {
var ret, langlst;
+ if (!defaultLocale) {
+ defaultLocale = "en-US";
+ }
+ if (!langstr) {
+ langstr = defaultLocale;
+ }
ret = {};
langlst = langstr.split(/[\-_]/);
ret.base = CSL.LANG_BASES[langlst[0]];
if ("undefined" === typeof ret.base) {
- CSL.debug("Warning: unknown locale "+langstr+", setting fallback to en-US");
- return {base:"en-US", best:langstr, bare:langlst[0]};
+ CSL.debug("Warning: unknown locale "+langstr+", setting fallback to "+defaultLocale);
+ return {base:defaultLocale, best:langstr, bare:langlst[0]};
+ }
+ if (langlst.length === 1) {
+ ret.generic = true;
}
if (langlst.length === 1 || langlst[1] === "x") {
ret.best = ret.base.replace("_", "-");
@@ -6718,10 +6739,10 @@ CSL.NameOutput.prototype._truncateNameList = function (container, variable, inde
} else {
lst = container[variable][index];
}
- if (this.state.opt.max_number_of_names
+ if (this.state[this.state[this.state.tmp.area].root].opt.max_number_of_names
&& lst.length > 50
- && lst.length > (this.state.opt.max_number_of_names + 2)) {
- lst = lst.slice(0, this.state.opt.max_number_of_names + 2);
+ && lst.length > (this.state[this.state[this.state.tmp.area].root].opt.max_number_of_names + 2)) {
+ lst = lst.slice(0, this.state[this.state[this.state.tmp.area].root].opt.max_number_of_names + 2);
}
return lst;
};
@@ -7701,14 +7722,22 @@ CSL.NameOutput.prototype._stripPeriods = function (tokname, str) {
return str;
};
CSL.NameOutput.prototype._nonDroppingParticle = function (name) {
- var str = this._stripPeriods("family", name["non-dropping-particle"]);
+ var ndp = name["non-dropping-particle"];
+ if (ndp && this.state.tmp.sort_key_flag) {
+ ndp = ndp.replace(/[\'\u2019]/, "");
+ }
+ var str = this._stripPeriods("family", ndp);
if (this.state.output.append(str, this.family_decor, true)) {
return this.state.output.pop();
}
return false;
};
CSL.NameOutput.prototype._droppingParticle = function (name, pos, j) {
- var str = this._stripPeriods("given", name["dropping-particle"]);
+ var dp = name["dropping-particle"];
+ if (dp && this.state.tmp.sort_key_flag) {
+ dp = dp.replace(/[\'\u2019]/, "");
+ }
+ var str = this._stripPeriods("given", dp);
if (name["dropping-particle"] && name["dropping-particle"].match(/^et.?al[^a-z]$/)) {
if (this.name.strings["et-al-use-last"]) {
if ("undefined" === typeof j) {
@@ -7813,10 +7842,10 @@ CSL.NameOutput.prototype._parseName = function (name) {
noparse = false;
}
if (!name["non-dropping-particle"] && name.family && !noparse && name.given) {
- m = name.family.match(/^((?:[a-z][ \'\u2019a-z]*[-|\s+|\'\u2019]|[ABDVL][^ ][-|\s+][a-z]*\s*|[ABDVL][^ ][^ ][-|\s+][a-z]*\s*))/);
+ m = name.family.match(/^((?:[\'\u2019a-z][ \'\u2019a-z]*[-\s\'\u2019]+|[ABDVL][^ ][-\s]+[a-z]*\s*|[ABDVL][^ ][^ ][-\s]+[a-z]*\s*))/);
if (m) {
name.family = name.family.slice(m[1].length);
- name["non-dropping-particle"] = m[1].replace(/\s+$/, "");
+ name["non-dropping-particle"] = m[1].replace(/\s+$/, "").replace("'", "\u2019");
}
}
if (!name.suffix && name.given) {
@@ -8628,6 +8657,7 @@ CSL.Node.number = {
};
CSL.Node.sort = {
build: function (state, target) {
+ target = state[state.build.root + "_sort"].tokens;
if (this.tokentype === CSL.START) {
if (state.build.area === "citation") {
state.parallel.use_parallels = false;
@@ -8636,12 +8666,38 @@ CSL.Node.sort = {
state.build.area = state.build.root + "_sort";
state.build.extension = "_sort";
var func = function (state, Item) {
+ if (state.opt.has_layout_locale) {
+ var langspec = CSL.localeResolve(Item.language, state.opt["default-locale"][0]);
+ var sort_locales = state[state.tmp.area.slice(0,-5)].opt.sort_locales;
+ var langForItem;
+ for (var i=0,ilen=sort_locales.length;i<ilen;i+=1) {
+ langForItem = sort_locales[i][langspec.bare];
+ if (!langForItem) {
+ langForItem = sort_locales[i][langspec.best];
+ }
+ if (langForItem) {
+ break;
+ }
+ }
+ if (!langForItem) {
+ langForItem = state.opt["default-locale"][0];
+ }
+ state.tmp.lang_sort_hold = state.opt.lang;
+ state.opt.lang = langForItem;
+ }
}
this.execs.push(func);
}
if (this.tokentype === CSL.END) {
state.build.area = state.build.root;
state.build.extension = "";
+ var func = function (state, Item) {
+ if (state.opt.has_layout_locale) {
+ state.opt.lang = state.tmp.lang_sort_hold;
+ delete state.tmp.lang_sort_hold;
+ }
+ }
+ this.execs.push(func);
}
target.push(this);
}
@@ -9430,14 +9486,35 @@ CSL.Attributes["@is-plural"] = function (state, arg) {
};
CSL.Attributes["@locale"] = function (state, arg) {
var func, ret, len, pos, variable, myitem, langspec, lang, lst, i, ilen, fallback;
+ var locale_default = state.opt["default-locale"][0];
if (this.name === "layout") {
this.locale_raw = arg;
+ if (this.tokentype === CSL.START) {
+ var locales = arg.split(/\s+/);
+ var sort_locale = {};
+ var localeMaster = CSL.localeResolve(locales[0], locale_default);
+ if (localeMaster.generic) {
+ sort_locale[localeMaster.generic] = localeMaster.best;
+ } else {
+ sort_locale[localeMaster.best] = localeMaster.best;
+ }
+ for (var i=1,ilen=locales.length;i<ilen;i+=1) {
+ var localeServant = CSL.localeResolve(locales[i], locale_default);
+ if (localeServant.generic) {
+ sort_locale[localeServant.generic] = localeMaster.best;
+ } else {
+ sort_locale[localeServant.best] = localeMaster.best;
+ }
+ }
+ state[state.build.area].opt.sort_locales.push(sort_locale);
+ }
+ state.opt.has_layout_locale = true;
} else {
lst = arg.split(/\s+/);
var locale_bares = [];
for (i = 0, ilen = lst.length; i < ilen; i += 1) {
lang = lst[i];
- langspec = CSL.localeResolve(lang);
+ langspec = CSL.localeResolve(lang, locale_default);
if (lst[i].length === 2) {
locale_bares.push(langspec.bare);
}
@@ -9445,7 +9522,6 @@ CSL.Attributes["@locale"] = function (state, arg) {
lst[i] = langspec;
}
var locale_list = lst.slice();
- var locale_default = state.opt["default-locale"][0];
var maketest = function (locale_list, locale_default,locale_bares) {
return function (Item, item) {
var key, res;
@@ -9458,7 +9534,7 @@ CSL.Attributes["@locale"] = function (state, arg) {
} else {
lang = Item.language;
}
- langspec = CSL.localeResolve(lang);
+ langspec = CSL.localeResolve(lang, locale_default);
for (i = 0, ilen = locale_list.length; i < ilen; i += 1) {
if (langspec.best === locale_list[i].best) {
res = true;
@@ -9480,7 +9556,7 @@ CSL.Attributes["@locale-internal"] = function (state, arg) {
this.locale_bares = [];
for (i = 0, ilen = lst.length; i < ilen; i += 1) {
lang = lst[i];
- langspec = CSL.localeResolve(lang);
+ langspec = CSL.localeResolve(lang, state.opt["default-locale"][0]);
if (lst[i].length === 2) {
this.locale_bares.push(langspec.bare);
}
@@ -9498,7 +9574,7 @@ CSL.Attributes["@locale-internal"] = function (state, arg) {
var langspec = false;
if (Item.language) {
lang = Item.language;
- langspec = CSL.localeResolve(lang);
+ langspec = CSL.localeResolve(lang, state.opt["default-locale"][0]);
if (langspec.best === state.opt["default-locale"][0]) {
langspec = false;
}
@@ -9614,8 +9690,8 @@ CSL.Attributes["@match"] = function (state, arg) {
};
CSL.Attributes["@names-min"] = function (state, arg) {
var val = parseInt(arg, 10);
- if (state.opt.max_number_of_names < val) {
- state.opt.max_number_of_names = val;
+ if (state[state.tmp.area].opt.max_number_of_names < val) {
+ state[state.tmp.area].opt.max_number_of_names = val;
}
this.strings["et-al-min"] = val;
};
@@ -9717,8 +9793,8 @@ CSL.Attributes["@name-delimiter"] = function (state, arg) {
};
CSL.Attributes["@et-al-min"] = function (state, arg) {
var val = parseInt(arg, 10);
- if (state.opt.max_number_of_names < val) {
- state.opt.max_number_of_names = val;
+ if (state[state.tmp.area].opt.max_number_of_names < val) {
+ state[state.tmp.area].opt.max_number_of_names = val;
}
state.setOpt(this, "et-al-min", val);
};
@@ -9734,8 +9810,8 @@ CSL.Attributes["@et-al-use-last"] = function (state, arg) {
};
CSL.Attributes["@et-al-subsequent-min"] = function (state, arg) {
var val = parseInt(arg, 10);
- if (state.opt.max_number_of_names < val) {
- state.opt.max_number_of_names = val;
+ if (state[state.tmp.area].opt.max_number_of_names < val) {
+ state[state.tmp.area].opt.max_number_of_names = val;
}
state.setOpt(this, "et-al-subsequent-min", val);
};