commit ff5353fec1025157769d54817985f8da96ac5aaf
parent 9b1b4803dc675b8d01d0953389dd51fe1c5e9547
Author: Simon Kornblith <simon@simonster.com>
Date: Tue, 16 Apr 2013 00:11:19 -0400
Update to citeproc-js 1.0.450
Diffstat:
1 file changed, 594 insertions(+), 527 deletions(-)
diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js
@@ -57,7 +57,9 @@ if (!Array.indexOf) {
};
}
var CSL = {
- PROCESSOR_VERSION: "1.0.446",
+ PROCESSOR_VERSION: "1.0.450",
+ CONDITION_LEVEL_TOP: 1,
+ CONDITION_LEVEL_BOTTOM: 2,
PLAIN_HYPHEN_REGEX: /(?:[^\\]-|\u2013)/,
LOCATOR_LABELS_REGEXP: new RegExp("^((art|ch|Ch|subch|col|fig|l|n|no|op|p|pp|para|subpara|pt|r|sec|subsec|Sec|sv|sch|tit|vrs|vol)\\.)\\s+(.*)"),
STATUTE_SUBDIV_GROUPED_REGEX: /((?:^| )(?:art|ch|Ch|subch|p|pp|para|subpara|pt|r|sec|subsec|Sec|sch|tit)\.)/g,
@@ -348,7 +350,7 @@ var CSL = {
ret[ret.length - 1] += str;
return ret;
},
- SKIP_WORDS: ["but", "or", "yet", "so", "for", "and", "nor", "a", "an", "the", "at", "by", "from", "in", "into", "of", "on", "to", "with", "up", "down", "as", "via", "onto", "over", "till"],
+ SKIP_WORDS: ["but", "or", "yet", "so", "for", "and", "nor", "a", "an", "the", "at", "by", "from", "in", "into", "of", "on", "to", "with", "up", "down", "as", "via", "onto", "over", "till", "de", "d'", "von", "van"],
FORMAT_KEY_SEQUENCE: [
"@strip-periods",
"@font-style",
@@ -1273,6 +1275,13 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
state.tmp.count_offset_characters = false;
}
}
+ for (i=0,ilen=ret.length - 1;i<ilen;i+=1) {
+ if ("number" === typeof ret[i].num && "number" === typeof ret[i+1].num && !ret[i+1].UGLY_DELIMITER_SUPPRESS_HACK) {
+ ret[i].strings.suffix = txt_esc(blob_delimiter);
+ ret[i+1].successor_prefix = "";
+ ret[i+1].UGLY_DELIMITER_SUPPRESS_HACK = true;
+ }
+ }
var span_split = 0;
for (i = 0, ilen = ret.length; i < ilen; i += 1) {
if ("string" === typeof ret[i]) {
@@ -1280,7 +1289,6 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
if (i < ret.length - 1 && "object" === typeof ret[i + 1]) {
if (blob_delimiter && !ret[i + 1].UGLY_DELIMITER_SUPPRESS_HACK) {
ret[i] += txt_esc(blob_delimiter);
- } else {
}
ret[i + 1].UGLY_DELIMITER_SUPPRESS_HACK = true;
}
@@ -1289,7 +1297,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
if (blob && (blob.decorations.length || blob.strings.suffix || blob.strings.prefix)) {
span_split = ret.length;
}
- var blobs_start = state.output.renderBlobs(ret.slice(0, span_split), blob_delimiter);
+ var blobs_start = state.output.renderBlobs(ret.slice(0, span_split), blob_delimiter, true);
if (blobs_start && blob && (blob.decorations.length || blob.strings.suffix || blob.strings.prefix)) {
if (!state.tmp.suppress_decorations) {
for (i = 0, ilen = blob.decorations.length; i < ilen; i += 1) {
@@ -1336,19 +1344,15 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
this.current.mystack = [];
this.current.mystack.push(this.queue);
if (state.tmp.suppress_decorations) {
- ret = state.output.renderBlobs(ret);
+ ret = state.output.renderBlobs(ret, undefined, true);
}
} else if ("boolean" === typeof blob) {
- ret = state.output.renderBlobs(ret);
+ ret = state.output.renderBlobs(ret, undefined, true);
}
if (blob && blob.new_locale) {
state.opt.lang = blob.old_locale;
}
- if (blob) {
- return ret;
- } else {
- return ret;
- }
+ return ret;
};
CSL.Output.Queue.prototype.clearlevel = function () {
var blob, pos, len;
@@ -1358,7 +1362,7 @@ CSL.Output.Queue.prototype.clearlevel = function () {
blob.blobs.pop();
}
};
-CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, has_more) {
+CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, in_cite) {
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);
if (!delim) {
@@ -3365,7 +3369,7 @@ CSL.Engine.Citation = function (state) {
this.opt["disambiguate-add-names"] = false;
this.opt["disambiguate-add-givenname"] = false;
this.opt["disambiguate-add-year-suffix"] = false;
- this.opt["givenname-disambiguation-rule"] = "none";
+ this.opt["givenname-disambiguation-rule"] = "by-cite";
this.opt["near-note-distance"] = 5;
this.opt.topdecor = [];
this.opt.layout_decorations = [];
@@ -3440,7 +3444,6 @@ CSL.Engine.prototype.rebuildProcessorState = function (citations, mode, uncitedI
}
}
this.updateItems(itemIDs);
- this.updateUncitedItems(uncitedItemIDs);
var pre = [];
var post = [];
var ret = [];
@@ -3458,6 +3461,7 @@ CSL.Engine.prototype.rebuildProcessorState = function (citations, mode, uncitedI
];
}
}
+ this.updateUncitedItems(uncitedItemIDs);
this.setOutputFormat(oldMode);
return ret;
}
@@ -5438,8 +5442,19 @@ CSL.Node["else-if"] = {
if (this.locale) {
state.opt.lang = this.locale;
}
- if (! this.evaluator) {
- this.evaluator = state.fun.match.any;
+ if (!this.evaluator) {
+ this.evaluator = function (token, state, Item, item) {
+ var record = function (result) {
+ if (result) {
+ state.tmp.jump.replace("succeed");
+ return token.succeed;
+ } else {
+ state.tmp.jump.replace("fail");
+ return token.fail;
+ }
+ }
+ return record(state.fun.match.any(token, state, token.tests, CSL.CONDITION_LEVEL_TOP)(Item, item));
+ };
}
}
if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) {
@@ -5601,7 +5616,18 @@ CSL.Node["if"] = {
state.opt.lang = this.locale;
}
if (!this.evaluator) {
- this.evaluator = state.fun.match.any;
+ this.evaluator = function (token, state, Item, item) {
+ var record = function (result) {
+ if (result) {
+ state.tmp.jump.replace("succeed");
+ return token.succeed;
+ } else {
+ state.tmp.jump.replace("fail");
+ return token.fail;
+ }
+ }
+ return record(state.fun.match.any(token, state, token.tests, CSL.CONDITION_LEVEL_TOP)(Item, item));
+ };
}
}
if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) {
@@ -8622,7 +8648,7 @@ CSL.Node.text = {
flag[0] = true;
state.tmp.group_context.replace(flag);
}
- if (!state.tmp.term_predecessor) {
+ if (!state.tmp.term_predecessor && !(state.opt["class"] === "in-text" && state.tmp.area === "citation")) {
myterm = CSL.Output.Formatters["capitalize-first"](state, term);
} else {
myterm = term;
@@ -8788,192 +8814,198 @@ CSL.Node.text = {
}
};
CSL.Attributes = {};
-CSL.Attributes["@gender"] = function (state, arg) {
- this.gender = arg;
-}
-CSL.Attributes["@cslid"] = function (state, arg) {
- this.cslid = parseInt(arg, 10);
-};
-CSL.Attributes["@is-parallel"] = function (state, arg) {
- var values = arg.split(" ");
- for (var i = 0, ilen = values.length; i < ilen; i += 1) {
- if (values[i] === "true") {
- values[i] = true;
- } else if (values[i] === "false") {
- values[i] = false;
- }
+CSL.Attributes["@disambiguate"] = function (state, arg) {
+ if (arg === "true") {
+ state.opt.has_disambiguate = true;
+ var func = function (Item, item) {
+ var ret;
+ if (state.tmp.disambig_settings.disambiguate) {
+ return true;
+ }
+ return false;
+ };
+ this.tests.push(func);
}
- this.strings.set_parallel_condition = values;
};
-CSL.Attributes["@is-plural"] = function (state, arg) {
- var func = function (state, Item, item) {
- var nameList = Item[arg];
- var ret = false;
- if (nameList && nameList.length) {
- var persons = 0;
- var institutions = 0;
- var last_is_person = false;
- for (var i = 0, ilen = nameList.length; i < ilen; i += 1) {
- if (nameList[i].isInstitution && (nameList[i].literal || (nameList[i].family && !nameList[i].given))) {
- institutions += 1;
- last_is_person = false;
- } else {
- persons += 1;
- last_is_person = true;
- }
+CSL.Attributes["@is-numeric"] = function (state, arg) {
+ var variables = arg.split(/\s+/);
+ var reverses = CSL.Util.setReverseConditions.call(this, variables);
+ var maketest = function(variable, reverse) {
+ return function (Item, item) {
+ var myitem = Item;
+ var mytests = [];
+ if (["locator","locator-revision"].indexOf(variable) > -1) {
+ myitem = item;
}
- if (persons > 1) {
- ret = true;
- } else if (institutions > 1) {
- ret = true;
- } else if (institutions && last_is_person) {
- ret = true;
+ if (CSL.NUMERIC_VARIABLES.indexOf(variable) > -1) {
+ if (!state.tmp.shadow_numbers[variable]) {
+ state.processNumber(false, myitem, variable, Item.type);
+ }
+ if (myitem[variable] && state.tmp.shadow_numbers[variable].numeric) {
+ return reverse ? false : true;
+ }
+ } else if (["title", "locator-revision","version"].indexOf(variable) > -1) {
+ if (myitem[variable]) {
+ if (myitem[variable].slice(-1) === "" + parseInt(myitem[variable].slice(-1), 10)) {
+ return reverse ? false : true;
+ }
+ }
}
+ return reverse ? true : false;
}
- return ret;
- };
+ }
+ var mytests = [];
+ for (var i=0; i<variables.length; i+=1) {
+ mytests.push(maketest(variables[i], reverses[i]));
+ }
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
this.tests.push(func);
};
-CSL.Attributes["@subjurisdictions"] = function (state, arg) {
- var trysubjurisdictions = parseInt(arg, 10);
- var func = function (state, Item, item) {
- var subjurisdictions = 0;
- if (Item.jurisdiction) {
- subjurisdictions = Item.jurisdiction.split(";").length;
- }
- if (subjurisdictions) {
- subjurisdictions += -1;
- }
- var ret = false;
- if (subjurisdictions >= trysubjurisdictions) {
- ret = true;
- }
- return [ret];
- };
- this.tests.push(func);
+CSL.Attributes["@is-numeric-any"] = function (state, arg) {
+ CSL.Attributes["@is-numeric"].call(this, state, arg, "any");
};
-CSL.Attributes["@label-form"] = function (state, arg) {
- this.strings.label_form_override = arg;
+CSL.Attributes["@is-numeric-all"] = function (state, arg) {
+ CSL.Attributes["@is-numeric"].call(this, state, arg, "all");
};
-CSL.Attributes["@has-year-only"] = function (state, arg) {
- var trydates = arg.split(/\s+/);
- var func = function (state, Item, item) {
- var ret = [];
- for (var i = 0, ilen = trydates.length; i < ilen; i += 1) {
- var trydate = Item[trydates[i]];
- if (!trydate || trydate.month || trydate.season) {
- ret.push(false);
+CSL.Attributes["@is-uncertain-date"] = function (state, arg) {
+ var variables = arg.split(/\s+/);
+ var reverses = CSL.Util.setReverseConditions.call(this, variables);
+ var maketest = function (myvariable, reverse) {
+ return function(Item, item) {
+ if (Item[myvariable] && Item[myvariable].circa) {
+ return reverse ? false : true;
} else {
- ret.push(true);
+ return reverse ? true : false;
}
}
- return ret;
+ }
+ var mytests = [];
+ for (var i=0,ilen=variables.length;i<ilen;i+=1) {
+ mytests.push(maketest(variables[i], reverses[i]));
};
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
this.tests.push(func);
};
-CSL.Attributes["@has-month-or-season-only"] = function (state, arg) {
- var trydates = arg.split(/\s+/);
- var func = function (state, Item, item) {
- var ret = [];
- for (var i = 0, ilen = trydates.length; i < ilen; i += 1) {
- var trydate = Item[trydates[i]];
- if (!trydate || (!trydate.month && !trydate.season) || trydate.day) {
- ret.push(false);
+CSL.Attributes["@is-uncertain-date-any"] = function (state, arg) {
+ CSL.Attributes["@is-uncertain-date"].call(this, state, arg, "any");
+};
+CSL.Attributes["@is-uncertain-date-all"] = function (state, arg) {
+ CSL.Attributes["@is-uncertain-date"].call(this, state, arg, "all");
+};
+CSL.Attributes["@locator"] = function (state, arg) {
+ var trylabels = arg.replace("sub verbo", "sub-verbo");
+ trylabels = trylabels.split(/\s+/);
+ var reverses = CSL.Util.setReverseConditions.call(this, trylabels);
+ var maketest = function (trylabel, reverse) {
+ return function(Item, item) {
+ var label;
+ if ("undefined" === typeof item || !item.label) {
+ label = "page";
+ } else if (item.label === "sub verbo") {
+ label = "sub-verbo";
} else {
- ret.push(true);
+ label = item.label;
}
- }
- return ret;
- };
- this.tests.push(func);
-};
-CSL.Attributes["@has-day-only"] = function (state, arg) {
- var trydates = arg.split(/\s+/);
- var func = function (state, Item, item) {
- var ret = [];
- for (var i = 0, ilen = trydates.length; i < ilen; i += 1) {
- var trydate = Item[trydates[i]];
- if (!trydate || !trydate.day) {
- ret.push(false);
+ if (trylabel === label) {
+ return reverse ? false : true;
} else {
- ret.push(true);
+ return reverse ? true : false;
}
}
- return ret;
- };
- this.tests.push(func);
-};
-CSL.Attributes["@part-separator"] = function (state, arg) {
- this.strings["part-separator"] = arg;
-};
-CSL.Attributes["@context"] = function (state, arg) {
- var func = function (state, Item) {
- var area = state.tmp.area.slice(0, arg.length);
- var result = false;
- if (area === arg) {
- result = true;
- }
- return result;
- };
+ }
+ var mytests = [];
+ for (var i=0,ilen=trylabels.length;i<ilen;i+=1) {
+ mytests.push(maketest(trylabels[i], reverses[i]));
+ }
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
this.tests.push(func);
};
-CSL.Attributes["@leading-noise-words"] = function (state, arg) {
- this["leading-noise-words"] = arg;
-};
-CSL.Attributes["@class"] = function (state, arg) {
- state.opt["class"] = arg;
-};
-CSL.Attributes["@version"] = function (state, arg) {
- state.opt.version = arg;
-};
-CSL.Attributes["@value"] = function (state, arg) {
- this.strings.value = arg;
-};
-CSL.Attributes["@name"] = function (state, arg) {
- this.strings.name = arg;
-};
-CSL.Attributes["@form"] = function (state, arg) {
- this.strings.form = arg;
-};
-CSL.Attributes["@date-parts"] = function (state, arg) {
- this.strings["date-parts"] = arg;
-};
-CSL.Attributes["@range-delimiter"] = function (state, arg) {
- this.strings["range-delimiter"] = arg;
+CSL.Attributes["@locator-any"] = function (state, arg) {
+ CSL.Attributes["@locator"].call(this, state, arg, "any");
};
-CSL.Attributes["@macro"] = function (state, arg) {
- this.postponed_macro = arg;
+CSL.Attributes["@locator-all"] = function (state, arg) {
+ CSL.Attributes["@locator"].call(this, state, arg, "all");
};
-CSL.Attributes["@term"] = function (state, arg) {
- if (arg === "sub verbo") {
- this.strings.term = "sub-verbo";
- } else {
- this.strings.term = arg;
+CSL.Attributes["@position"] = function (state, arg) {
+ var tryposition;
+ state.opt.update_mode = CSL.POSITION;
+ state.parallel.use_parallels = true;
+ var trypositions = arg.split(/\s+/);
+ var maketest = function(tryposition) {
+ return function (Item, item) {
+ if (state.tmp.area === "bibliography") {
+ return false;
+ }
+ if (item && "undefined" === typeof item.position) {
+ item.position = 0;
+ }
+ if (item && typeof item.position === "number") {
+ if (item.position === 0 && tryposition === 0) {
+ return true;
+ } else if (tryposition > 0 && item.position >= tryposition) {
+ return true;
+ }
+ } else if (tryposition === 0) {
+ return true;
+ }
+ return false;
+ }
}
-};
-CSL.Attributes["@xmlns"] = function (state, arg) {};
-CSL.Attributes["@lang"] = function (state, arg) {
- if (arg) {
- state.build.lang = arg;
+ var mytests = [];
+ for (var i=0,ilen=trypositions.length;i<ilen;i+=1) {
+ var tryposition = trypositions[i];
+ if (tryposition === "first") {
+ tryposition = CSL.POSITION_FIRST;
+ } else if (tryposition === "subsequent") {
+ tryposition = CSL.POSITION_SUBSEQUENT;
+ } else if (tryposition === "ibid") {
+ tryposition = CSL.POSITION_IBID;
+ } else if (tryposition === "ibid-with-locator") {
+ tryposition = CSL.POSITION_IBID_WITH_LOCATOR;
+ }
+ if ("near-note" === tryposition) {
+ mytests.push(function (Item, item) {
+ if (item && item.position === CSL.POSITION_SUBSEQUENT && item["near-note"]) {
+ return true;
+ }
+ return false;
+ });
+ } else {
+ mytests.push(maketest(tryposition));
+ }
}
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
+ this.tests.push(func);
};
CSL.Attributes["@type"] = function (state, arg) {
- var types, ret, func, len, pos;
- func = function (state, Item) {
- types = arg.split(/\s+/);
- ret = [];
- len = types.length;
- for (pos = 0; pos < len; pos += 1) {
- ret.push(Item.type === types[pos]);
+ var types = arg.split(/\s+/);
+ var reverses = CSL.Util.setReverseConditions.call(this, types);
+ var maketest = function (mytype, reverse) {
+ return function(Item,item) {
+ var ret = (Item.type === mytype);
+ if (ret) {
+ return reverse ? false : true;
+ } else {
+ return reverse ? true : false;
+ }
}
- return ret;
- };
+ }
+ var mytests = [];
+ for (var i=0,ilen=types.length;i<ilen;i+=1) {
+ mytests.push(maketest(types[i], reverses[i]));
+ }
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
this.tests.push(func);
};
+CSL.Attributes["@type-any"] = function (state, arg) {
+ CSL.Attributes["@type"].call(this, state, arg, "any");
+};
+CSL.Attributes["@type-all"] = function (state, arg) {
+ CSL.Attributes["@type"].call(this, state, arg, "all");
+};
CSL.Attributes["@variable"] = function (state, arg) {
- var variables, pos, len, func, output, variable, varlen, needlen, ret, myitem, key, flag;
this.variables = arg.split(/\s+/);
- this.variables_real = arg.split(/\s+/);
+ this.variables_real = this.variables.slice();
if ("label" === this.name && this.variables[0]) {
this.strings.term = this.variables[0];
} else if (["names", "date", "text", "number"].indexOf(this.name) > -1) {
@@ -9092,218 +9124,388 @@ CSL.Attributes["@variable"] = function (state, arg) {
};
this.execs.push(func);
} else if (["if", "else-if"].indexOf(this.name) > -1) {
- func = function (state, Item, item) {
- var key, x;
- ret = [];
- len = this.variables.length;
- for (pos = 0; pos < len; pos += 1) {
- variable = this.variables[pos];
- x = false;
- myitem = Item;
+ var reverses = CSL.Util.setReverseConditions.call(this, this.variables);
+ var maketest = function (variable, reverse) {
+ return function(Item,item){
+ var myitem = Item;
if (item && ["locator", "locator-revision", "first-reference-note-number", "locator-date"].indexOf(variable) > -1) {
myitem = item;
}
if (variable === "hereinafter" && state.sys.getAbbreviation && myitem.id) {
if (state.transform.abbrevs["default"].hereinafter[myitem.id]) {
- x = true;
+ return reverse ? false : true;
}
} else if (myitem[variable]) {
if ("number" === typeof myitem[variable] || "string" === typeof myitem[variable]) {
- x = true;
+ return reverse ? false : true;
} else if ("object" === typeof myitem[variable]) {
for (key in myitem[variable]) {
if (myitem[variable][key]) {
- x = true;
- break;
- } else {
- x = false;
+ return reverse ? false : true;
}
}
}
}
- ret.push(x);
+ return reverse ? true : false;
}
- return ret;
- };
+ }
+ var mytests = [];
+ for (var i=0,ilen=this.variables.length;i<ilen;i+=1) {
+ mytests.push(maketest(this.variables[i], reverses[i]));
+ }
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
this.tests.push(func);
}
};
-CSL.Attributes["@lingo"] = function (state, arg) {
+CSL.Attributes["@variable-any"] = function (state, arg) {
+ CSL.Attributes["@variable"].call(this, state, arg, "any");
};
-CSL.Attributes["@macro-has-date"] = function (state, arg) {
- this["macro-has-date"] = true;
+CSL.Attributes["@variable-all"] = function (state, arg) {
+ CSL.Attributes["@variable"].call(this, state, arg, "all");
};
-CSL.Attributes["@locale"] = function (state, arg) {
- var func, ret, len, pos, variable, myitem, langspec, lang, lst, i, ilen, fallback;
- if (this.name === "layout") {
- this.locale_raw = arg;
- } else {
- lst = arg.split(/\s+/);
- this.locale_bares = [];
- for (i = 0, ilen = lst.length; i < ilen; i += 1) {
- lang = lst[i];
- langspec = CSL.localeResolve(lang);
- if (lst[i].length === 2) {
- this.locale_bares.push(langspec.bare);
+CSL.Attributes["@page"] = function (state, arg) {
+ var trylabels = arg.replace("sub verbo", "sub-verbo");
+ trylabels = trylabels.split(/\s+/);
+ var reverses = CSL.Util.setReverseConditions.call(this, trylabels);
+ var maketest = function (trylabel, reverse) {
+ return function(Item, item) {
+ var label;
+ state.processNumber(false, Item, "page", Item.type);
+ if (!state.tmp.shadow_numbers.page.label) {
+ label = "page";
+ } else if (state.tmp.shadow_numbers.page.label === "sub verbo") {
+ label = "sub-verbo";
+ } else {
+ label = state.tmp.shadow_numbers.page.label;
}
- state.localeConfigure(langspec);
- lst[i] = langspec;
- }
- this.locale_default = state.opt["default-locale"][0];
- this.locale = lst[0].best;
- this.locale_list = lst.slice();
- func = function (state, Item, item) {
- var key, res;
- ret = [];
- res = false;
- var langspec = false;
- if (Item.language) {
- lang = Item.language;
- langspec = CSL.localeResolve(lang);
- if (langspec.best === state.opt["default-locale"][0]) {
- langspec = false;
- }
- }
- if (langspec) {
- for (i = 0, ilen = this.locale_list.length; i < ilen; i += 1) {
- if (langspec.best === this.locale_list[i].best) {
- state.opt.lang = this.locale;
- state.tmp.last_cite_locale = this.locale;
- state.output.openLevel("empty");
- state.output.current.value().new_locale = this.locale;
- res = true;
- break;
- }
- }
- if (!res && this.locale_bares.indexOf(langspec.bare) > -1) {
- state.opt.lang = this.locale;
- state.tmp.last_cite_locale = this.locale;
- state.output.openLevel("empty");
- state.output.current.value().new_locale = this.locale;
- res = true;
- }
+ if (trylabel === label) {
+ return reverse ? false : true;
+ } else {
+ return reverse ? true : false;
}
- ret.push(res);
- return ret;
- };
- this.tests.push(func);
+ }
+ }
+ var mytests = [];
+ for (var i=0,ilen=trylabels.length;i<ilen;i+=1) {
+ mytests.push(maketest(trylabels[i], reverses[i]));
}
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
+ this.tests.push(func);
};
-CSL.Attributes["@suffix"] = function (state, arg) {
- this.strings.suffix = arg;
+CSL.Attributes["@page-any"] = function (state, arg) {
+ CSL.Attributes["@page"].call(this, state, arg, "any");
};
-CSL.Attributes["@prefix"] = function (state, arg) {
- this.strings.prefix = arg;
+CSL.Attributes["@page-all"] = function (state, arg) {
+ CSL.Attributes["@page"].call(this, state, arg, "all");
};
-CSL.Attributes["@delimiter"] = function (state, arg) {
- if ("name" == this.name) {
- this.strings.name_delimiter = arg;
- } else {
- this.strings.delimiter = arg;
+CSL.Attributes["@jurisdiction"] = function (state, arg) {
+ var tryjurisdictions = arg.split(/\s+/);
+ var reverses = CSL.Util.setReverseConditions.call(this, tryjurisdictions);
+ for (var i=0,ilen=tryjurisdictions.length;i<ilen;i+=1) {
+ tryjurisdictions[i] = tryjurisdictions[i].split(";");
}
+ var maketests = function (tryjurisdiction, reverse) {
+ return function(Item,item){
+ if (!Item.jurisdiction) {
+ return reverse ? true : false;
+ }
+ var jurisdictions = Item.jurisdiction.split(";");
+ for (var i=0,ilen=jurisdictions.length;i<ilen;i+=1) {
+ jurisdictions[i] = jurisdictions[i].split(";");
+ }
+ for (i=tryjurisdiction.length;i>0;i+=-1) {
+ var tryjurisdictionStr = tryjurisdiction.slice(0,i).join(";");
+ var jurisdiction = jurisdictions.slice(0,i).join(";");
+ if (tryjurisdictionStr === jurisdiction) {
+ return reverse ? false : true;
+ }
+ }
+ return reverse ? true : false;
+ }
+ }
+ var mytests = [];
+ for (var i=0,ilen=tryjurisdictions.length;i<ilen;i+=1) {
+ var tryjurisdictionSlice = tryjurisdictions[i].slice();
+ mytests.push(maketests(tryjurisdictionSlice, reverses[i]));
+ }
+ var func = state.fun.match[this.match](this, state, mytests, CSL.CONDITION_LEVEL_BOTTOM);
+ this.tests.push(func);
};
-CSL.Attributes["@match"] = function (state, arg) {
- var evaluator;
- if (this.tokentype === CSL.START || CSL.SINGLETON) {
- if ("none" === arg) {
- evaluator = state.fun.match.none;
- } else if ("any" === arg) {
- evaluator = state.fun.match.any;
- } else if ("all" === arg) {
- evaluator = state.fun.match.all;
- } else {
- throw "Unknown match condition \"" + arg + "\" in @match";
+CSL.Attributes["@jurisdiction-any"] = function (state, arg) {
+ CSL.Attributes["@jurisdiction"].call(this, state, arg, "any");
+};
+CSL.Attributes["@jurisdiction-all"] = function (state, arg) {
+ CSL.Attributes["@jurisdiction"].call(this, state, arg, "all");
+};
+CSL.Attributes["@context"] = function (state, arg) {
+ var func = function (Item, item) {
+ var area = state.tmp.area.slice(0, arg.length);
+ if (area === arg) {
+ return true;
+ }
+ return false;
+ };
+ this.tests.push(func);
+};
+CSL.Attributes["@has-year-only"] = function (state, arg) {
+ var trydates = arg.split(/\s+/);
+ var maketest = function (trydate) {
+ return function(Item,item){
+ var date = Item[trydate];
+ if (!date || date.month || date.season) {
+ return false;
+ } else {
+ return true;
+ }
}
- this.evaluator = evaluator;
}
+ var mytests = [];
+ for (var i=0,ilen=trydates.length;i<ilen;i+=1) {
+ mytests.push(maketest(trydates[i]));
+ }
+ var func = state.fun.match[this.match](this, state, mytests);
+ this.tests.push(func);
};
-CSL.Attributes["@jurisdiction"] = function (state, arg) {
- var style_lexlst = arg.split(/\s+/);
- var func = function (state, Item) {
- var input_lex = false;
- var ret = false;
- if (Item.jurisdiction) {
- input_lex = Item.jurisdiction;
- } else if (Item.language) {
- var m = Item.language.match(/^.*-x-lex-([.;a-zA-Z]+).*$/);
- if (m) {
- input_lex = m[1];
- }
- }
- if (input_lex) {
- var input_lexlst = input_lex.split(";");
- outerLoop: for (var i = 0, ilen = style_lexlst.length; i < ilen; i += 1) {
- var style_lexlst_subjur = style_lexlst[i].split(";");
- middleLoop: for (var j = 0, jlen = style_lexlst_subjur.length; j < jlen; j += 1) {
- var style_lex_elem = style_lexlst_subjur[j];
- innerLoop: for (var k = 0, klen = input_lexlst.length; k < klen; k += 1) {
- var input_lex_elem = input_lexlst[k];
- if (style_lex_elem === input_lex_elem && j === style_lexlst_subjur.length - 1) {
- ret = true;
- break outerLoop;
- }
- }
- }
+CSL.Attributes["@has-month-or-season-only"] = function (state, arg) {
+ var trydates = arg.split(/\s+/);
+ var maketest = function (trydate) {
+ return function(Item,item){
+ var date = Item[trydate];
+ if (!date || (!date.month && !date.season) || date.day) {
+ return false;
+ } else {
+ return true;
}
}
- return ret;
- };
+ }
+ var mytests = [];
+ for (var i=0,ilen=trydates.length;i<ilen;i+=1) {
+ mytests.push(maketest(trydates[i]));
+ }
+ var func = state.fun.match[this.match](this, state, mytests);
this.tests.push(func);
};
-CSL.Attributes["@is-uncertain-date"] = function (state, arg) {
- var variables, len, pos, func, variable, ret;
- variables = arg.split(/\s+/);
- len = variables.length;
- func = function (state, Item) {
- ret = [];
- for (pos = 0; pos < len; pos += 1) {
- variable = variables[pos];
- if (Item[variable] && Item[variable].circa) {
- ret.push(true);
+CSL.Attributes["@has-day-only"] = function (state, arg) {
+ var trydates = arg.split(/\s+/);
+ var maketest = function (trydate) {
+ return function(Item,item){
+ var date = Item[trydate];
+ if (!date || !date.day) {
+ return false;
} else {
- ret.push(false);
+ return true;
}
}
- return ret;
+ }
+ var mytests = [];
+ for (var i=0,ilen=trydates.length;i<ilen;i+=1) {
+ mytests.push(maketest(trydates[i]));
};
+ var func = state.fun.match[this.match](this, state, mytests);
this.tests.push(func);
};
-CSL.Attributes["@is-numeric"] = function (state, arg) {
- var variables, func, len, ret;
- variables = arg.split(/\s+/);
- len = variables.length;
- func = function (state, Item, item) {
- ret = [];
- for (var i = 0; i < len; i += 1) {
- var myitem = Item;
- if (["locator","locator-revision"].indexOf(variables[i]) > -1) {
- myitem = item;
- }
- if (CSL.NUMERIC_VARIABLES.indexOf(variables[i]) > -1) {
- if (!state.tmp.shadow_numbers[variables[i]]) {
- state.processNumber(false, myitem, variables[i], Item.type);
- }
- if (myitem[variables[i]] && state.tmp.shadow_numbers[variables[i]].numeric) {
- ret.push(true);
- } else {
- ret.push(false);
- }
- } else if (["title", "locator-revision","version"].indexOf(variables[i]) > -1) {
- if (myitem[variables[i]]) {
- if (myitem[variables[i]].slice(-1) === "" + parseInt(myitem[variables[i]].slice(-1), 10)) {
- ret.push(true);
- } else {
- ret.push(false);
- }
+CSL.Attributes["@subjurisdictions"] = function (state, arg) {
+ var trysubjurisdictions = parseInt(arg, 10);
+ var func = function (Item, item) {
+ var subjurisdictions = 0;
+ if (Item.jurisdiction) {
+ subjurisdictions = Item.jurisdiction.split(";").length;
+ }
+ if (subjurisdictions) {
+ subjurisdictions += -1;
+ }
+ if (subjurisdictions >= trysubjurisdictions) {
+ return true;
+ }
+ return false;
+ };
+ this.tests.push(func);
+};
+CSL.Attributes["@is-plural"] = function (state, arg) {
+ var func = function (Item, item) {
+ var nameList = Item[arg];
+ if (nameList && nameList.length) {
+ var persons = 0;
+ var institutions = 0;
+ var last_is_person = false;
+ for (var i = 0, ilen = nameList.length; i < ilen; i += 1) {
+ if (nameList[i].isInstitution && (nameList[i].literal || (nameList[i].family && !nameList[i].given))) {
+ institutions += 1;
+ last_is_person = false;
} else {
- ret.push(false);
+ persons += 1;
+ last_is_person = true;
}
}
+ if (persons > 1) {
+ return true;
+ } else if (institutions > 1) {
+ return true;
+ } else if (institutions && last_is_person) {
+ return true;
+ }
}
- return ret;
+ return false;
};
this.tests.push(func);
};
+CSL.Attributes["@locale"] = function (state, arg) {
+ var func, ret, len, pos, variable, myitem, langspec, lang, lst, i, ilen, fallback;
+ if (this.name === "layout") {
+ this.locale_raw = arg;
+ } else {
+ lst = arg.split(/\s+/);
+ this.locale_bares = [];
+ for (i = 0, ilen = lst.length; i < ilen; i += 1) {
+ lang = lst[i];
+ langspec = CSL.localeResolve(lang);
+ if (lst[i].length === 2) {
+ this.locale_bares.push(langspec.bare);
+ }
+ state.localeConfigure(langspec);
+ lst[i] = langspec;
+ }
+ this.locale_default = state.opt["default-locale"][0];
+ this.locale = lst[0].best;
+ this.locale_list = lst.slice();
+ var maketest = function (me) {
+ return function (Item, item) {
+ var key, res;
+ ret = [];
+ res = false;
+ var langspec = false;
+ if (Item.language) {
+ lang = Item.language;
+ langspec = CSL.localeResolve(lang);
+ if (langspec.best === state.opt["default-locale"][0]) {
+ langspec = false;
+ }
+ }
+ if (langspec) {
+ for (i = 0, ilen = me.locale_list.length; i < ilen; i += 1) {
+ if (langspec.best === me.locale_list[i].best) {
+ state.opt.lang = me.locale;
+ state.tmp.last_cite_locale = me.locale;
+ state.output.openLevel("empty");
+ state.output.current.value().new_locale = me.locale;
+ res = true;
+ break;
+ }
+ }
+ if (!res && me.locale_bares.indexOf(langspec.bare) > -1) {
+ state.opt.lang = me.locale;
+ state.tmp.last_cite_locale = me.locale;
+ state.output.openLevel("empty");
+ state.output.current.value().new_locale = me.locale;
+ res = true;
+ }
+ }
+ return res;
+ }
+ }
+ var me = this;
+ this.tests.push(maketest(me));
+ }
+};
+CSL.Attributes["@is-parallel"] = function (state, arg) {
+ var values = arg.split(" ");
+ for (var i = 0, ilen = values.length; i < ilen; i += 1) {
+ if (values[i] === "true") {
+ values[i] = true;
+ } else if (values[i] === "false") {
+ values[i] = false;
+ }
+ }
+ this.strings.set_parallel_condition = values;
+};
+CSL.Attributes["@gender"] = function (state, arg) {
+ this.gender = arg;
+}
+CSL.Attributes["@cslid"] = function (state, arg) {
+ this.cslid = parseInt(arg, 10);
+};
+CSL.Attributes["@label-form"] = function (state, arg) {
+ this.strings.label_form_override = arg;
+};
+CSL.Attributes["@part-separator"] = function (state, arg) {
+ this.strings["part-separator"] = arg;
+};
+CSL.Attributes["@leading-noise-words"] = function (state, arg) {
+ this["leading-noise-words"] = arg;
+};
+CSL.Attributes["@class"] = function (state, arg) {
+ state.opt["class"] = arg;
+};
+CSL.Attributes["@version"] = function (state, arg) {
+ state.opt.version = arg;
+};
+CSL.Attributes["@value"] = function (state, arg) {
+ this.strings.value = arg;
+};
+CSL.Attributes["@name"] = function (state, arg) {
+ this.strings.name = arg;
+};
+CSL.Attributes["@form"] = function (state, arg) {
+ this.strings.form = arg;
+};
+CSL.Attributes["@date-parts"] = function (state, arg) {
+ this.strings["date-parts"] = arg;
+};
+CSL.Attributes["@range-delimiter"] = function (state, arg) {
+ this.strings["range-delimiter"] = arg;
+};
+CSL.Attributes["@macro"] = function (state, arg) {
+ this.postponed_macro = arg;
+};
+CSL.Attributes["@term"] = function (state, arg) {
+ if (arg === "sub verbo") {
+ this.strings.term = "sub-verbo";
+ } else {
+ this.strings.term = arg;
+ }
+};
+CSL.Attributes["@xmlns"] = function (state, arg) {};
+CSL.Attributes["@lang"] = function (state, arg) {
+ if (arg) {
+ state.build.lang = arg;
+ }
+};
+CSL.Attributes["@lingo"] = function (state, arg) {
+};
+CSL.Attributes["@macro-has-date"] = function (state, arg) {
+ this["macro-has-date"] = true;
+};
+CSL.Attributes["@suffix"] = function (state, arg) {
+ this.strings.suffix = arg;
+};
+CSL.Attributes["@prefix"] = function (state, arg) {
+ this.strings.prefix = arg;
+};
+CSL.Attributes["@delimiter"] = function (state, arg) {
+ if ("name" == this.name) {
+ this.strings.name_delimiter = arg;
+ } else {
+ this.strings.delimiter = arg;
+ }
+};
+CSL.Attributes["@match"] = function (state, arg) {
+ var match;
+ if (this.tokentype === CSL.START || CSL.SINGLETON) {
+ this.match = arg;
+ this.evaluator = function (token, state, Item, item) {
+ var record = function (result) {
+ if (result) {
+ state.tmp.jump.replace("succeed");
+ return token.succeed;
+ } else {
+ state.tmp.jump.replace("fail");
+ return token.fail;
+ }
+ }
+ return record(state.fun.match[arg](token, state, token.tests, CSL.CONDITION_LEVEL_TOP)(Item, item));
+ };
+ }
+};
CSL.Attributes["@names-min"] = function (state, arg) {
var val = parseInt(arg, 10);
if (state.opt.max_number_of_names < val) {
@@ -9335,61 +9537,6 @@ CSL.Attributes["@plural"] = function (state, arg) {
this.strings.plural = false;
}
};
-CSL.Attributes["@locator"] = function (state, arg) {
- var func;
- var trylabels = arg.replace("sub verbo", "sub-verbo");
- trylabels = trylabels.split(/\s+/);
- if (["if", "else-if"].indexOf(this.name) > -1) {
- func = function (state, Item, item) {
- var ret = [];
- var label;
- if ("undefined" === typeof item || !item.label) {
- label = "page";
- } else if (item.label === "sub verbo") {
- label = "sub-verbo";
- } else {
- label = item.label;
- }
- for (var i = 0, ilen = trylabels.length; i < ilen; i += 1) {
- if (trylabels[i] === label) {
- ret.push(true);
- } else {
- ret.push(false);
- }
- }
- return ret;
- };
- this.tests.push(func);
- }
-};
-CSL.Attributes["@page"] = function (state, arg) {
- var func;
- var trylabels = arg.replace("sub verbo", "sub-verbo");
- trylabels = trylabels.split(/\s+/);
- if (["if", "else-if"].indexOf(this.name) > -1) {
- func = function (state, Item, item) {
- var ret = [];
- var label;
- state.processNumber(false, Item, "page", Item.type);
- if (!state.tmp.shadow_numbers.page.label) {
- label = "page";
- } else if (state.tmp.shadow_numbers.page.label === "sub verbo") {
- label = "sub-verbo";
- } else {
- label = state.tmp.shadow_numbers.page.label;
- }
- for (var i = 0, ilen = trylabels.length; i < ilen; i += 1) {
- if (trylabels[i] === label) {
- ret.push(true);
- } else {
- ret.push(false);
- }
- }
- return ret;
- };
- this.tests.push(func);
- }
-};
CSL.Attributes["@number"] = function (state, arg) {
var func;
var trylabels = arg.replace("sub verbo", "sub-verbo");
@@ -9432,69 +9579,6 @@ CSL.Attributes["@publisher-and"] = function (state, arg) {
};
CSL.Attributes["@newdate"] = function (state, arg) {
};
-CSL.Attributes["@position"] = function (state, arg) {
- var tryposition;
- state.opt.update_mode = CSL.POSITION;
- state.parallel.use_parallels = true;
- if ("near-note" === arg) {
- var near_note_func = function (state, Item, item) {
- if (item && item.position === CSL.POSITION_SUBSEQUENT && item["near-note"]) {
- return true;
- }
- return false;
- };
- this.tests.push(near_note_func);
- } else {
- var factory = function (tryposition) {
- return function (state, Item, item) {
- if (state.tmp.area === "bibliography") {
- return false;
- }
- if (item && "undefined" === typeof item.position) {
- item.position = 0;
- }
- if (item && typeof item.position === "number") {
- if (item.position === 0 && tryposition === 0) {
- return true;
- } else if (tryposition > 0 && item.position >= tryposition) {
- return true;
- }
- } else if (tryposition === 0) {
- return true;
- }
- return false;
- };
- };
- var lst = arg.split(/\s+/);
- for (var i = 0, ilen = lst.length; i < ilen; i += 1) {
- if (lst[i] === "first") {
- tryposition = CSL.POSITION_FIRST;
- } else if (lst[i] === "subsequent") {
- tryposition = CSL.POSITION_SUBSEQUENT;
- } else if (lst[i] === "ibid") {
- tryposition = CSL.POSITION_IBID;
- } else if (lst[i] === "ibid-with-locator") {
- tryposition = CSL.POSITION_IBID_WITH_LOCATOR;
- }
- var func = factory(tryposition);
- this.tests.push(func);
- }
- }
-};
-CSL.Attributes["@disambiguate"] = function (state, arg) {
- if (this.tokentype === CSL.START && ["if", "else-if"].indexOf(this.name) > -1) {
- if (arg === "true") {
- state.opt.has_disambiguate = true;
- var func = function (state, Item) {
- if (state.tmp.disambig_settings.disambiguate) {
- return true;
- }
- return false;
- };
- this.tests.push(func);
- }
- }
-};
CSL.Attributes["@givenname-disambiguation-rule"] = function (state, arg) {
if (CSL.GIVENNAME_DISAMBIGUATION_RULES.indexOf(arg) > -1) {
state.opt["givenname-disambiguation-rule"] = arg;
@@ -9767,88 +9851,57 @@ CSL.Stack.prototype.value = function () {
CSL.Stack.prototype.length = function () {
return this.mystack.length;
};
-CSL.Util = {};
+CSL.Util = {
+ setReverseConditions: function (lst) {
+ reverses = [];
+ for (var i=0,ilen=lst.length;i<ilen;i+=1) {
+ if (lst[i].slice(0,4) === "not:") {
+ lst[i] = lst[i].slice(4);
+ reverses.push(true);
+ } else {
+ reverses.push(false);
+ }
+ }
+ return reverses;
+ }
+};
CSL.Util.Match = function () {
- this.any = function (token, state, Item, item) {
- var ret = false;
- for (var i = 0, ilen = token.tests.length; i < ilen; i += 1) {
- var func = token.tests[i];
- var reslist = func.call(token, state, Item, item);
- if ("object" !== typeof reslist) {
- reslist = [reslist];
- }
- for (var j = 0, jlen = reslist.length; j < jlen; j += 1) {
- if (reslist[j]) {
- ret = true;
- break;
+ this.any = function (token, state, tests, level) {
+ return function (Item, item) {
+ for (var i=0, ilen=tests.length; i < ilen; i += 1) {
+ result = tests[i](Item, item);
+ if (result) {
+ return true;
}
}
- if (ret) {
- break;
- }
- }
- if (ret) {
- ret = token.succeed;
- state.tmp.jump.replace("succeed");
- } else {
- ret = token.fail;
- state.tmp.jump.replace("fail");
- }
- return ret;
+ return false;
+ };
};
- this.none = function (token, state, Item, item) {
- var ret = true;
- for (var i = 0, ilen = this.tests.length; i < ilen; i += 1) {
- var func = this.tests[i];
- var reslist = func.call(token, state, Item, item);
- if ("object" !== typeof reslist) {
- reslist = [reslist];
- }
- for (var j = 0, jlen = reslist.length; j < jlen; j += 1) {
- if (reslist[j]) {
- ret = false;
- break;
+ this[undefined] = this.any;
+ this.none = function (token, state, tests, level) {
+ if (CSL.CONDITION_LEVEL_TOP !== level) {
+ return this.any(token, state, tests, level);
+ }
+ return function (Item, item) {
+ for (var i=0,ilen=tests.length;i<ilen;i+=1) {
+ result = tests[i](Item,item);
+ if (result) {
+ return false;
}
}
- if (!ret) {
- break;
- }
- }
- if (ret) {
- ret = token.succeed;
- state.tmp.jump.replace("succeed");
- } else {
- ret = token.fail;
- state.tmp.jump.replace("fail");
- }
- return ret;
+ return true;
+ };
};
- this.all = function (token, state, Item, item) {
- var ret = true;
- for (var i = 0, ilen = this.tests.length; i < ilen; i += 1) {
- var func = this.tests[i];
- var reslist = func.call(token, state, Item, item);
- if ("object" !== typeof reslist) {
- reslist = [reslist];
- }
- for (var j = 0, jlen = reslist.length; j < jlen; j += 1) {
- if (!reslist[j]) {
- ret = false;
- break;
+ this.all = function (token, state, tests, level) {
+ return function (Item, item) {
+ for (var i=0,ilen=tests.length;i<ilen;i+=1) {
+ result = tests[i](Item,item);
+ if (!result) {
+ return false;
}
}
- if (!ret) {
- break;
- }
- }
- if (ret) {
- ret = token.succeed;
- state.tmp.jump.replace("succeed");
- } else {
- ret = token.fail;
- state.tmp.jump.replace("fail");
- }
- return ret;
+ return true;
+ };
};
};
CSL.Transform = function (state) {
@@ -11255,14 +11308,25 @@ CSL.Util.substituteStart = function (state, target) {
choose_start = new CSL.Token("choose", CSL.START);
CSL.Node.choose.build.call(choose_start, state, target);
if_start = new CSL.Token("if", CSL.START);
- func = function (state, Item) {
+ func = function (Item,item) {
if (state.tmp.can_substitute.value()) {
return true;
}
return false;
};
if_start.tests.push(func);
- if_start.evaluator = state.fun.match.any;
+ if_start.evaluator = function (token, state, Item, item) {
+ var record = function (result) {
+ if (result) {
+ state.tmp.jump.replace("succeed");
+ return token.succeed;
+ } else {
+ state.tmp.jump.replace("fail");
+ return token.fail;
+ }
+ }
+ return record(state.fun.match.any(token, state, token.tests, CSL.CONDITION_LEVEL_BOTTOM)(Item, item));
+ };
target.push(if_start);
}
};
@@ -11464,6 +11528,9 @@ CSL.Util.Ordinalizer.prototype.format = function (num, gender) {
}
}
} else {
+ if (!gender) {
+ gender = undefined;
+ }
this.state.fun.ordinalizer.init();
if ((num / 10) % 10 === 1 || (num > 10 && num < 20)) {
suffix = this.suffixes[this.state.opt.lang][gender][3];