- update to latest update.xsl

- update to citeproc-js 1.0.93

From 1.0.93:

Cast human-readable dates parser as a separate JS module, and provide
documentation in the processor manual.

Small change to multiple value handling in cs:number.

From 1.0.92:

Fix wrong ordinal suffix assignment for values 11 - 13 (for English,
at least).

From 1.0.91:

Set circa rather than fuzzy on uncertain dates in the internal human-
readable dates parser.

From 1.0.90:

Reimplement language conditions through cs:layout rather than
cs:choose.

From 1.0.89:

In language condition statements, allow multiple locales to be
specified in a condition; restrict fallback behavior to base (single
two-character) locale specifiers; and use the first locale listed in
the attribute as the locale to be assigned to children of the
condition when the test is successful.

Properly honor locale for quotes and punctuation in language condition
statements.

Implement dynamic locale-sensitive layout delimiter and affixes with
language condition statements.

Fix minor bug in xmle4x.js XML parser that affected some locale load
operations that can arise when executing language condition
statements.
This commit is contained in:
Simon Kornblith 2010-12-21 18:37:06 +00:00
parent b43c6da675
commit 8c80d6acb6
2 changed files with 329 additions and 126 deletions

View file

@ -20,6 +20,7 @@
</xsl:when> </xsl:when>
</xsl:choose> </xsl:choose>
<xsl:attribute name="version">1.0</xsl:attribute> <xsl:attribute name="version">1.0</xsl:attribute>
<xsl:attribute name="demote-non-dropping-particle">sort-only</xsl:attribute>
<xsl:apply-templates/> <xsl:apply-templates/>
</xsl:copy> </xsl:copy>
</xsl:template> </xsl:template>
@ -444,4 +445,4 @@
</xsl:choose> </xsl:choose>
</xsl:template> </xsl:template>
</xsl:stylesheet> </xsl:stylesheet>

View file

@ -91,6 +91,7 @@ var CSL = {
MINIMAL_NAME_FIELDS: ["literal", "family"], MINIMAL_NAME_FIELDS: ["literal", "family"],
SWAPPING_PUNCTUATION: [".", "!", "?", ":",",",";"], SWAPPING_PUNCTUATION: [".", "!", "?", ":",",",";"],
TERMINAL_PUNCTUATION: [".", "!", "?", ":", " "], TERMINAL_PUNCTUATION: [".", "!", "?", ":", " "],
SPLICE_PUNCTUATION: [".", "!", "?", ":", ";", ","],
NONE: 0, NONE: 0,
NUMERIC: 1, NUMERIC: 1,
POSITION: 2, POSITION: 2,
@ -397,7 +398,7 @@ CSL_E4X.prototype.getNodesByName = function (myxml,name,nameattrval) {
CSL_E4X.prototype.nodeNameIs = function (myxml,name) { CSL_E4X.prototype.nodeNameIs = function (myxml,name) {
var xml; var xml;
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
if (myxml.localName().toString() == name){ if (myxml.localName() && myxml.localName().toString() == name){
return true; return true;
} }
return false; return false;
@ -644,6 +645,9 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
} else { } else {
blob_delimiter = blob.strings.delimiter; blob_delimiter = blob.strings.delimiter;
} }
if (blob && blob.new_locale) {
state.opt.lang = blob.new_locale;
}
for (pos = 0, len = blobs.length; pos < len; pos += 1) { for (pos = 0, len = blobs.length; pos < len; pos += 1) {
blobjr = blobs[pos]; blobjr = blobs[pos];
if ("string" === typeof blobjr.blobs) { if ("string" === typeof blobjr.blobs) {
@ -738,6 +742,9 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
} else if ("boolean" === typeof blob) { } else if ("boolean" === typeof blob) {
ret = state.output.renderBlobs(ret); ret = state.output.renderBlobs(ret);
} }
if (blob && blob.new_locale) {
state.opt.lang = blob.old_locale;
}
if (blob) { if (blob) {
return ret; return ret;
} else { } else {
@ -1335,9 +1342,9 @@ CSL.XmlToToken = function (state, tokentype) {
attributes = state.sys.xml.attributes(this); attributes = state.sys.xml.attributes(this);
decorations = CSL.setDecorations.call(this, state, attributes); decorations = CSL.setDecorations.call(this, state, attributes);
token = new CSL.Token(name, tokentype); token = new CSL.Token(name, tokentype);
if (tokentype !== CSL.END || name === "if" || name === "else-if") { if (tokentype !== CSL.END || name === "if" || name === "else-if" || name === "layout") {
for (key in attributes) { for (key in attributes) {
if (tokentype === CSL.END && key !== "@language") { if (tokentype === CSL.END && key !== "@language" && key !== "@locale") {
continue; continue;
} }
if (attributes.hasOwnProperty(key)) { if (attributes.hasOwnProperty(key)) {
@ -1357,8 +1364,8 @@ CSL.XmlToToken = function (state, tokentype) {
target = state[state.build.area].tokens; target = state[state.build.area].tokens;
CSL.Node[name].build.call(token, state, target); CSL.Node[name].build.call(token, state, target);
}; };
CSL.dateParser = function (txt) { CSL.DateParser = function (txt) {
var jiy_list, jiy, jiysplitter, jy, jmd, jr, pos, key, val, yearlast, yearfirst, number, rangesep, fuzzychar, chars, rex, rexdash, rexdashslash, rexslashdash, seasonstrs, seasonrexes, seasonstr, monthstrs, monthstr, monthrexes, seasonrex, len, jiymatchstring, jiymatcher; var jiy_list, jiy, jiysplitter, jy, jmd, jr, pos, key, val, yearlast, yearfirst, number, rangesep, fuzzychar, chars, rex, rexdash, rexdashslash, rexslashdash, seasonstrs, seasonrexes, seasonstr, monthstrs, monthstr, mrexes, seasonrex, len, jiymatchstring, jiymatcher;
jiy_list = [ jiy_list = [
["\u660E\u6CBB", 1867], ["\u660E\u6CBB", 1867],
["\u5927\u6B63", 1911], ["\u5927\u6B63", 1911],
@ -1402,17 +1409,97 @@ CSL.dateParser = function (txt) {
seasonrex = new RegExp(seasonstrs[pos] + ".*"); seasonrex = new RegExp(seasonstrs[pos] + ".*");
seasonrexes.push(seasonrex); seasonrexes.push(seasonrex);
} }
monthstrs = "jan feb mar apr may jun jul aug sep oct nov dec spr sum fal win spr sum"; this.mstrings = "january february march april may june july august september october november december spring summer fall winter spring summer";
monthstrs = monthstrs.split(" "); this.mstrings = this.mstrings.split(" ");
monthrexes = []; this.setOrderDayMonth = function() {
len = monthstrs.length; this.monthguess = 1;
for (pos = 0; pos < len; pos += 1) { this.dayguess = 0;
monthstr = monthstrs[pos]; }
rex = new RegExp(monthstr); this.setOrderMonthDay = function() {
monthrexes.push(rex); this.monthguess = 0;
this.dayguess = 1;
}
this.setOrderMonthDay();
this.resetMonths = function() {
this.msets = [];
for (var i = 0, ilen = this.mstrings.length; i < ilen; i += 1) {
this.msets.push([this.mstrings[i]]);
}
this.mabbrevs = [];
for (var i = 0, ilen = this.msets.length; i < ilen; i += 1) {
this.mabbrevs.push([]);
for (var j = 0, jlen = this.msets[i].length; j < jlen; j += 1) {
this.mabbrevs[i].push(this.msets[i][0].slice(0, 3));
}
}
this.mrexes = [];
for (var i = 0, ilen = this.mabbrevs.length; i < ilen; i += 1) {
this.mrexes.push(new RegExp("(?:" + this.mabbrevs[i].join("|") + ")"));
}
}
this.resetMonths();
this.addMonths = function(lst) {
if ("string" === typeof lst) {
lst = lst.split(/\s+/);
}
if (lst.length !== 12 && lst.length !== 16) {
CSL.debug("month [+season] list of "+lst.length+", expected 12 or 16. Ignoring.");
return;
}
var othermatch = [];
var thismatch = [];
for (var i = 0, ilen = lst.length; i < ilen; i += 1) {
var abbrevlen = false;
var skip = false;
var insert = 3;
var extend = {};
for (var j = 0, jlen = this.mabbrevs.length; j < jlen; j += 1) {
extend[j] = {};
if (j === i) {
for (var k = 0, klen = this.mabbrevs[i].length; k < klen; k += 1) {
if (this.mabbrevs[i][k] === lst[i].slice(0, this.mabbrevs[i][k].length)) {
skip = true;
break;
}
}
} else {
for (var k = 0, klen = this.mabbrevs[j].length; k < klen; k += 1) {
abbrevlen = this.mabbrevs[j][k].length;
if (this.mabbrevs[j][k] === lst[i].slice(0, abbrevlen)) {
while (this.msets[j][k].slice(0, abbrevlen) === lst[i].slice(0, abbrevlen)) {
if (abbrevlen > lst[i].length || abbrevlen > this.msets[j][k].length) {
CSL.debug("unable to disambiguate month string in date parser: "+lst[i]);
break;
} else {
abbrevlen += 1;
}
}
insert = abbrevlen;
extend[j][k] = abbrevlen;
}
}
}
for (var j in extend) {
j = parseInt(j, 10);
for (var k in extend[j]) {
k = parseInt(k, 10);
abbrevlen = extend[j][k];
this.mabbrevs[j][k] = this.msets[j][k].slice(0, abbrevlen);
}
}
}
if (!skip) {
this.msets[i].push(lst[i]);
this.mabbrevs[i].push(lst[i].slice(0, insert));
}
}
this.mrexes = [];
for (var i = 0, ilen = this.mabbrevs.length; i < ilen; i += 1) {
this.mrexes.push(new RegExp("(?:" + this.mabbrevs[i].join("|") + ")"));
}
} }
this.parse = function (txt) { this.parse = function (txt) {
var slash, dash, lst, l, m, number, note, thedate, slashcount, range_delim, date_delim, ret, delim_pos, delims, isrange, suff, date, breakme, item, pos, delim, ppos, element, pppos, len, llen, lllen, mm, slst, mmpos; var slash, dash, lst, l, m, number, note, thedate, slashcount, range_delim, date_delim, ret, delim_pos, delims, isrange, suff, date, breakme, item, delim, element, mm, slst, mmpos, i, ilen, j, jlen, k, klen;
m = txt.match(jmd); m = txt.match(jmd);
if (m) { if (m) {
txt = txt.replace(jy, ""); txt = txt.replace(jy, "");
@ -1492,13 +1579,11 @@ CSL.dateParser = function (txt) {
delims.push([0, ret.length]); delims.push([0, ret.length]);
} }
suff = ""; suff = "";
len = delims.length; for (i = 0, ilen = delims.length; i < ilen; i += 1) {
for (pos = 0; pos < len; pos += 1) { delim = delims[i];
delim = delims[pos];
date = ret.slice(delim[0], delim[1]); date = ret.slice(delim[0], delim[1]);
llen = date.length; for (j = 0, jlen = date.length; j < jlen; j += 1) {
for (ppos = 0; ppos < llen; ppos += 1) { element = date[j];
element = date[ppos];
if (element.indexOf(date_delim) > -1) { if (element.indexOf(date_delim) > -1) {
this.parseNumericDate(thedate, date_delim, suff, element); this.parseNumericDate(thedate, date_delim, suff, element);
continue; continue;
@ -1508,10 +1593,9 @@ CSL.dateParser = function (txt) {
continue; continue;
} }
breakme = false; breakme = false;
lllen = monthrexes.length; for (k = 0, klen = this.mrexes.length; k < klen; k += 1) {
for (pppos = 0; pppos < lllen; pppos += 1) { if (element.toLocaleLowerCase().match(this.mrexes[k])) {
if (element.toLocaleLowerCase().match(monthrexes[pppos])) { thedate[("month" + suff)] = "" + (parseInt(k, 10) + 1);
thedate[("month" + suff)] = "" + (parseInt(pppos, 10) + 1);
breakme = true; breakme = true;
break; break;
} }
@ -1534,9 +1618,9 @@ CSL.dateParser = function (txt) {
} }
breakme = false; breakme = false;
lllen = seasonrexes.length; lllen = seasonrexes.length;
for (pppos = 0; pppos < lllen; pppos += 1) { for (k = 0, klen = seasonrexes.length; k < klen; k += 1) {
if (element.toLocaleLowerCase().match(seasonrexes[pppos])) { if (element.toLocaleLowerCase().match(seasonrexes[k])) {
thedate[("season" + suff)] = "" + (parseInt(pppos, 10) + 1); thedate[("season" + suff)] = "" + (parseInt(k, 10) + 1);
breakme = true; breakme = true;
break; break;
} }
@ -1545,7 +1629,7 @@ CSL.dateParser = function (txt) {
continue; continue;
} }
if (element === "~" || element === "?" || element === "c" || element.match(/^cir/)) { if (element === "~" || element === "?" || element === "c" || element.match(/^cir/)) {
thedate.fuzzy = "" + 1; thedate.circa = "" + 1;
continue; continue;
} }
if (element.toLocaleLowerCase().match(/(?:mic|tri|hil|eas)/) && !thedate[("season" + suff)]) { if (element.toLocaleLowerCase().match(/(?:mic|tri|hil|eas)/) && !thedate[("season" + suff)]) {
@ -1564,9 +1648,8 @@ CSL.dateParser = function (txt) {
suff = "_end"; suff = "_end";
} }
if (isrange) { if (isrange) {
len = CSL.DATE_PARTS_ALL.length; for (j = 0, jlen = CSL.DATE_PARTS_ALL.length; j < jlen; j += 1) {
for (pos = 0; pos < len; pos += 1) { item = CSL.DATE_PARTS_ALL[j];
item = CSL.DATE_PARTS_ALL[pos];
if (thedate[item] && !thedate[(item + "_end")]) { if (thedate[item] && !thedate[(item + "_end")]) {
thedate[(item + "_end")] = thedate[item]; thedate[(item + "_end")] = thedate[item];
} else if (!thedate[item] && thedate[(item + "_end")]) { } else if (!thedate[item] && thedate[(item + "_end")]) {
@ -1577,43 +1660,72 @@ CSL.dateParser = function (txt) {
if (!thedate.year) { if (!thedate.year) {
thedate = { "literal": txt }; thedate = { "literal": txt };
} }
if (this.use_array) {
this.toArray(thedate);
}
return thedate; return thedate;
}; };
this.returnAsArray = function () {
this.use_array = true;
}
this.returnAsKeys = function () {
this.use_array = false;
}
this.toArray = function (thedate) {
thedate["date-parts"] = [];
thedate["date-parts"].push([]);
var slicelen = 0;
for (var i = 0, ilen = 3; i < ilen; i += 1) {
var part = ["year", "month", "day"][i];
if (!thedate[part]) {
break;
}
slicelen += 1;
thedate["date-parts"][0].push(thedate[part]);
delete thedate[part];
}
for (var i = 0, ilen = slicelen; i < ilen; i += 1) {
var part = ["year_end", "month_end", "day_end"][i];
if (thedate[part] && thedate["date-parts"].length === 1) {
thedate["date-parts"].push([]);
}
thedate["date-parts"][1].push(thedate[part]);
delete thedate[part];
}
}
this.parseNumericDate = function (ret, delim, suff, txt) { this.parseNumericDate = function (ret, delim, suff, txt) {
var lst, pos, len; var lst, pos, len;
lst = txt.split(delim); lst = txt.split(delim);
len = lst.length; for (i = 0, ilen = lst.length; i < ilen; i += 1) {
for (pos = 0; pos < len; pos += 1) { if (lst[i].length === 4) {
if (lst[pos].length === 4) { ret[("year" + suff)] = lst[i].replace(/^0*/, "");
ret[("year" + suff)] = lst[pos].replace(/^0*/, ""); if (!i) {
if (!pos) {
lst = lst.slice(1); lst = lst.slice(1);
} else { } else {
lst = lst.slice(0, pos); lst = lst.slice(0, i);
} }
break; break;
} }
} }
len = lst.length; for (i = 0, ilen = lst.length; i < ilen; i += 1) {
for (pos = 0; pos < len; pos += 1) { lst[i] = parseInt(lst[i], 10);
lst[pos] = parseInt(lst[pos], 10);
} }
if (lst.length === 1) { if (lst.length === 1) {
ret[("month" + suff)] = "" + lst[0]; ret[("month" + suff)] = "" + lst[0];
} else if (lst.length === 2) { } else if (lst.length === 2) {
if (lst[0] > 12) { if (lst[this.monthguess] > 12) {
ret[("month" + suff)] = "" + lst[1]; ret[("month" + suff)] = "" + lst[this.dayguess];
ret[("day" + suff)] = "" + lst[0]; ret[("day" + suff)] = "" + lst[this.monthguess];
} else { } else {
ret[("month" + suff)] = "" + lst[0]; ret[("month" + suff)] = "" + lst[this.monthguess];
ret[("day" + suff)] = "" + lst[1]; ret[("day" + suff)] = "" + lst[this.dayguess];
} }
} }
}; };
}; };
CSL.Engine = function (sys, style, lang, forceLang) { CSL.Engine = function (sys, style, lang, forceLang) {
var attrs, langspec, localexml, locale; var attrs, langspec, localexml, locale;
this.processor_version = "1.0.88"; this.processor_version = "1.0.93";
this.csl_version = "1.0"; this.csl_version = "1.0";
this.sys = sys; this.sys = sys;
this.sys.xml = new CSL.System.Xml.Parsing(); this.sys.xml = new CSL.System.Xml.Parsing();
@ -1684,7 +1796,7 @@ CSL.Engine = function (sys, style, lang, forceLang) {
this.registry = new CSL.Registry(this); this.registry = new CSL.Registry(this);
this.disambiguate = new CSL.Disambiguation(this); this.disambiguate = new CSL.Disambiguation(this);
this.splice_delimiter = false; this.splice_delimiter = false;
this.fun.dateparser = new CSL.dateParser(); this.fun.dateparser = new CSL.DateParser();
this.fun.flipflopper = new CSL.Util.FlipFlopper(this); this.fun.flipflopper = new CSL.Util.FlipFlopper(this);
this.setCloseQuotesArray(); this.setCloseQuotesArray();
this.fun.ordinalizer.init(this); this.fun.ordinalizer.init(this);
@ -2147,6 +2259,8 @@ CSL.Engine.Tmp = function () {
this.suffix = new CSL.Stack("", CSL.LITERAL); this.suffix = new CSL.Stack("", CSL.LITERAL);
this.delimiter = new CSL.Stack("", CSL.LITERAL); this.delimiter = new CSL.Stack("", CSL.LITERAL);
this.names_cut = {}; this.names_cut = {};
this.cite_locales = [];
this.cite_affixes = false;
}; };
CSL.Engine.Fun = function () { CSL.Engine.Fun = function () {
this.match = new CSL.Util.Match(); this.match = new CSL.Util.Match();
@ -2855,9 +2969,14 @@ CSL.getAmbiguousCite = function (Item, disambig) {
this.parallel.use_parallels = use_parallels; this.parallel.use_parallels = use_parallels;
return ret; return ret;
}; };
CSL.getSpliceDelimiter = function (last_collapsed) { CSL.getSpliceDelimiter = function (last_collapsed, pos) {
if (last_collapsed && ! this.tmp.have_collapsed && this.citation.opt["after-collapse-delimiter"]) { if (last_collapsed && ! this.tmp.have_collapsed && this.citation.opt["after-collapse-delimiter"]) {
this.tmp.splice_delimiter = this.citation.opt["after-collapse-delimiter"]; this.tmp.splice_delimiter = this.citation.opt["after-collapse-delimiter"];
} else if (this.tmp.cite_locales[pos - 1]) {
var alt_affixes = this.tmp.cite_affixes[this.tmp.cite_locales[pos - 1]];
if (alt_affixes && alt_affixes.delimiter) {
this.tmp.splice_delimiter = alt_affixes.delimiter;
}
} }
return this.tmp.splice_delimiter; return this.tmp.splice_delimiter;
}; };
@ -2871,6 +2990,7 @@ CSL.getCitationCluster = function (inputList, citationID) {
this.tmp.last_names_used = []; this.tmp.last_names_used = [];
this.tmp.last_years_used = []; this.tmp.last_years_used = [];
this.tmp.backref_index = []; this.tmp.backref_index = [];
this.tmp.cite_locales = [];
if (citationID) { if (citationID) {
this.registry.citationreg.citationById[citationID].properties.backref_index = false; this.registry.citationreg.citationById[citationID].properties.backref_index = false;
this.registry.citationreg.citationById[citationID].properties.backref_citation = false; this.registry.citationreg.citationById[citationID].properties.backref_citation = false;
@ -2902,7 +3022,7 @@ CSL.getCitationCluster = function (inputList, citationID) {
if (pos === (inputList.length - 1)) { if (pos === (inputList.length - 1)) {
this.parallel.ComposeSet(); this.parallel.ComposeSet();
} }
params.splice_delimiter = CSL.getSpliceDelimiter.call(this, last_collapsed); params.splice_delimiter = CSL.getSpliceDelimiter.call(this, last_collapsed, pos);
if (item && item["author-only"]) { if (item && item["author-only"]) {
this.tmp.suppress_decorations = true; this.tmp.suppress_decorations = true;
} }
@ -2931,16 +3051,18 @@ CSL.getCitationCluster = function (inputList, citationID) {
} }
}; };
var suffix = this.citation.opt.layout_suffix; var suffix = this.citation.opt.layout_suffix;
if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(suffix) > -1) { var last_locale = this.tmp.cite_locales[this.tmp.cite_locales.length - 1];
suffix = this.citation.opt.layout_suffix.slice(0, 1); if (last_locale
} else { && this.tmp.cite_affixes[last_locale]
suffix = ""; && this.tmp.cite_affixes[last_locale].suffix) {
suffix = this.tmp.cite_affixes[last_locale].suffix;
}
if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(suffix.slice(0, 1)) > -1) {
suffix = suffix.slice(0, 1);
} }
var delimiter = this.citation.opt.layout_delimiter; var delimiter = this.citation.opt.layout_delimiter;
if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(delimiter) > -1) { if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(delimiter.slice(0, 1)) > -1) {
delimiter = this.citation.opt.layout_delimiter.slice(0, 1); delimiter = delimiter.slice(0, 1);
} else {
delimiter = "";
} }
var mystk = [ var mystk = [
{ {
@ -2949,7 +3071,7 @@ CSL.getCitationCluster = function (inputList, citationID) {
blob: fakeblob blob: fakeblob
} }
]; ];
var use_layout_suffix = this.citation.opt.layout_suffix; var use_layout_suffix = suffix;
for (pos = 0, len = myblobs.length; pos < len; pos += 1) { for (pos = 0, len = myblobs.length; pos < len; pos += 1) {
CSL.Output.Queue.purgeEmptyBlobs(this.output.queue, true); CSL.Output.Queue.purgeEmptyBlobs(this.output.queue, true);
} }
@ -3051,13 +3173,14 @@ CSL.citeStart = function (Item) {
this.tmp.nameset_counter = 0; this.tmp.nameset_counter = 0;
this.tmp.years_used = []; this.tmp.years_used = [];
this.tmp.names_max.clear(); this.tmp.names_max.clear();
this.tmp.splice_delimiter = this[this.tmp.area].opt.delimiter; this.tmp.splice_delimiter = this[this.tmp.area].opt.layout_delimiter;
this.bibliography_sort.keys = []; this.bibliography_sort.keys = [];
this.citation_sort.keys = []; this.citation_sort.keys = [];
this.tmp.count_offset_characters = false; this.tmp.count_offset_characters = false;
this.tmp.offset_characters = 0; this.tmp.offset_characters = 0;
this.tmp.has_done_year_suffix = false; this.tmp.has_done_year_suffix = false;
CSL.Util.Names.initNameSlices(this); CSL.Util.Names.initNameSlices(this);
this.tmp.last_cite_locale = false;
}; };
CSL.citeEnd = function (Item) { CSL.citeEnd = function (Item) {
if (this.tmp.last_suffix_used && this.tmp.last_suffix_used.match(/[\-.,;:]$/)) { if (this.tmp.last_suffix_used && this.tmp.last_suffix_used.match(/[\-.,;:]$/)) {
@ -3076,6 +3199,7 @@ CSL.citeEnd = function (Item) {
if (!this.tmp.suppress_decorations && this.tmp.offset_characters) { if (!this.tmp.suppress_decorations && this.tmp.offset_characters) {
this.registry.registry[Item.id].offset = this.tmp.offset_characters; this.registry.registry[Item.id].offset = this.tmp.offset_characters;
} }
this.tmp.cite_locales.push(this.tmp.last_cite_locale);
}; };
CSL.Node = {}; CSL.Node = {};
CSL.Node.bibliography = { CSL.Node.bibliography = {
@ -3309,15 +3433,10 @@ CSL.Node.date = {
date_obj = {"date-parts": [[0]] }; date_obj = {"date-parts": [[0]] };
} }
if (date_obj.raw) { if (date_obj.raw) {
state.tmp.date_object = state.fun.dateparser.parse(date_obj.raw); date_obj = 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);
} }
state.tmp.date_object = state.dateParseArray(date_obj);
len = this.dateparts.length; len = this.dateparts.length;
for (pos = 0; pos < len; pos += 1) {
}
for (pos = 0; pos < len; pos += 1) { for (pos = 0; pos < len; pos += 1) {
part = this.dateparts[pos]; part = this.dateparts[pos];
if ("undefined" !== typeof state.tmp.date_object[(part + "_end")]) { if ("undefined" !== typeof state.tmp.date_object[(part + "_end")]) {
@ -3565,6 +3684,8 @@ CSL.Node["else-if"] = {
if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) { if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) {
func = function (state, Item) { func = function (state, Item) {
if (this.locale_default) { if (this.locale_default) {
state.output.current.value().old_locale = this.locale_default;
state.output.closeLevel("empty");
state.opt.lang = this.locale_default; state.opt.lang = this.locale_default;
} }
var next = this[state.tmp.jump.value()]; var next = this[state.tmp.jump.value()];
@ -3687,6 +3808,8 @@ CSL.Node["if"] = {
if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) { if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) {
func = function (state, Item) { func = function (state, Item) {
if (this.locale_default) { if (this.locale_default) {
state.output.current.value().old_locale = this.locale_default;
state.output.closeLevel("empty");
state.opt.lang = this.locale_default; state.opt.lang = this.locale_default;
} }
var next = this[state.tmp.jump.value()]; var next = this[state.tmp.jump.value()];
@ -4038,10 +4161,7 @@ CSL.evaluateStringPluralism = function (str) {
CSL.Node.layout = { CSL.Node.layout = {
build: function (state, target) { build: function (state, target) {
var func, prefix_token, suffix_token; var func, prefix_token, suffix_token;
if (this.tokentype === CSL.START) { if (this.tokentype === CSL.START && !state.tmp.cite_affixes) {
state.build.layout_flag = true;
state[state.tmp.area].opt.topdecor = [this.decorations];
state[(state.tmp.area + "_sort")].opt.topdecor = [this.decorations];
func = function (state, Item) { func = function (state, Item) {
state.tmp.done_vars = []; state.tmp.done_vars = [];
state.tmp.rendered_name = false; state.tmp.rendered_name = false;
@ -4059,10 +4179,6 @@ CSL.Node.layout = {
state.tmp.nameset_counter = 0; state.tmp.nameset_counter = 0;
}; };
this.execs.push(func); this.execs.push(func);
state[state.build.area].opt.layout_prefix = this.strings.prefix;
state[state.build.area].opt.layout_suffix = this.strings.suffix;
state[state.build.area].opt.layout_delimiter = this.strings.delimiter;
state[state.build.area].opt.layout_decorations = this.decorations;
func = function (state, Item) { func = function (state, Item) {
state.output.openLevel("empty"); state.output.openLevel("empty");
state.tmp.citeblob = state.output.queue[state.output.queue.length - 1]; state.tmp.citeblob = state.output.queue[state.output.queue.length - 1];
@ -4085,33 +4201,96 @@ CSL.Node.layout = {
target.push(prefix_token); target.push(prefix_token);
} }
} }
if (this.tokentype === CSL.END) { if (this.locale_raw) {
state.build.layout_flag = false; var my_tok = new CSL.Token("dummy", CSL.START);
if (state.build.area === "citation") { my_tok.locale = this.locale_raw;
suffix_token = new CSL.Token("text", CSL.SINGLETON); my_tok.strings.delimiter = this.strings.delimiter;
func = function (state, Item, item) { my_tok.strings.suffix = this.strings.suffix;
var sp; if (!state.tmp.cite_affixes) {
if (item && item.suffix) { state.tmp.cite_affixes = {};
sp = "";
if (item.suffix.match(CSL.ROMANESQUE_REGEXP)) {
sp = " ";
}
state.output.append((sp + item.suffix), this);
}
};
suffix_token.execs.push(func);
target.push(suffix_token);
} }
func = function (state, Item) { }
if (state.tmp.area === "bibliography") { if (this.tokentype === CSL.START) {
if (state.bibliography.opt["second-field-align"]) { state.build.layout_flag = true;
state.output.endTag(); if (!this.locale_raw) {
} state[state.tmp.area].opt.topdecor = [this.decorations];
state[(state.tmp.area + "_sort")].opt.topdecor = [this.decorations];
state[state.build.area].opt.layout_prefix = this.strings.prefix;
state[state.build.area].opt.layout_suffix = this.strings.suffix;
state[state.build.area].opt.layout_delimiter = this.strings.delimiter;
state[state.build.area].opt.layout_decorations = this.decorations;
if (state.tmp.cite_affixes) {
tok = new CSL.Token("else", CSL.START);
CSL.Node["else"].build.call(tok, state, target);
} }
state.output.closeLevel(); } // !this.locale_raw
}; if (this.locale_raw) {
this.execs.push(func); if (!state.build.layout_locale_flag) {
target.push(this); var choose_tok = new CSL.Token("choose", CSL.START);
CSL.Node.choose.build.call(choose_tok, state, target);
my_tok.name = "if";
CSL.Attributes["@locale"].call(my_tok, state, this.locale_raw);
CSL.Node["if"].build.call(my_tok, state, target);
} else {
my_tok.name = "else-if";
CSL.Attributes["@locale"].call(my_tok, state, this.locale_raw);
CSL.Node["else-if"].build.call(my_tok, state, target);
}
state.tmp.cite_affixes[my_tok.locale] = {};
state.tmp.cite_affixes[my_tok.locale].delimiter = this.strings.delimiter;
state.tmp.cite_affixes[my_tok.locale].suffix = this.strings.suffix;
}
}
if (this.tokentype === CSL.END) {
if (this.locale_raw) {
if (!state.build.layout_locale_flag) {
my_tok.name = "if";
my_tok.tokentype = CSL.END;
CSL.Attributes["@locale"].call(my_tok, state, this.locale_raw);
CSL.Node["if"].build.call(my_tok, state, target);
state.build.layout_locale_flag = true;
} else {
my_tok.name = "else-if";
my_tok.tokentype = CSL.END;
CSL.Attributes["@locale"].call(my_tok, state, this.locale_raw);
CSL.Node["else-if"].build.call(my_tok, state, target);
}
}
if (!this.locale_raw) {
if (state.tmp.cite_affixes) {
tok = new CSL.Token("else", CSL.END);
CSL.Node["else"].build.call(tok, state, target);
tok = new CSL.Token("choose", CSL.END);
CSL.Node.choose.build.call(tok, state, target);
}
state.build_layout_locale_flag = true;
if (state.build.area === "citation") {
suffix_token = new CSL.Token("text", CSL.SINGLETON);
func = function (state, Item, item) {
var sp;
if (item && item.suffix) {
sp = "";
if (item.suffix.match(CSL.ROMANESQUE_REGEXP)) {
sp = " ";
}
state.output.append((sp + item.suffix), this);
}
};
suffix_token.execs.push(func);
target.push(suffix_token);
}
func = function (state, Item) {
if (state.tmp.area === "bibliography") {
if (state.bibliography.opt["second-field-align"]) {
state.output.endTag();
}
}
state.output.closeLevel();
};
this.execs.push(func);
target.push(this);
state.build.layout_flag = false;
} // !this.layout_raw
} }
} }
}; };
@ -4802,8 +4981,8 @@ CSL.Node.number = {
var all_with_spaces = true; var all_with_spaces = true;
for (var i = 1, ilen = prefixes.length - 1; i < ilen; i += 1) { for (var i = 1, ilen = prefixes.length - 1; i < ilen; i += 1) {
if (prefixes[i].indexOf(" ") === -1) { if (prefixes[i].indexOf(" ") === -1) {
all_with_spaces = false; all_with_spaces = false;
break; break;
} }
} }
if (state.tmp.area !== "citation_sort" if (state.tmp.area !== "citation_sort"
@ -4863,7 +5042,7 @@ CSL.Node.number = {
} else if (!all_with_spaces || prefixes.length > 2) { } else if (!all_with_spaces || prefixes.length > 2) {
state.output.append(num, this); state.output.append(num, this);
} else { } else {
m = num.match(/\s*([0-9]+)/); m = num.match(/\s*([0-9]+)(?:[^-]* |[^-]*$)/);
if (m) { if (m) {
num = parseInt(m[1], 10); num = parseInt(m[1], 10);
number = new CSL.NumericBlob(num, this); number = new CSL.NumericBlob(num, this);
@ -5368,30 +5547,55 @@ CSL.Attributes["@variable"] = function (state, arg) {
}; };
CSL.Attributes["@lingo"] = function (state, arg) { CSL.Attributes["@lingo"] = function (state, arg) {
} }
CSL.Attributes["@language"] = function (state, arg) { CSL.Attributes["@locale"] = function (state, arg) {
var func, ret, len, pos, variable, myitem, x, langspec, lang; var func, ret, len, pos, variable, myitem, langspec, lang, lst, i, ilen, fallback;
lang = CSL.localeParse(arg); if (this.name === "layout") {
langspec = CSL.localeResolve(lang); this.locale_raw = arg;
state.localeConfigure(langspec); } else {
this.locale_default = state.opt["default-locale"][0]; lst = arg.split(/\s+/);
this.locale_base = langspec.base; this.locale_bases = [];
this.locale = langspec.best; for (i = 0, ilen = lst.length; i < ilen; i += 1) {
func = function (state, Item, item) { lang = CSL.localeParse(lst[i]);
var key;
ret = [];
x = false;
if (Item.language) {
lang = CSL.localeParse(Item.language);
langspec = CSL.localeResolve(lang); langspec = CSL.localeResolve(lang);
if (langspec.base === this.locale_base) { if (lst[i].length === 2) {
state.opt.lang = this.locale; this.locale_bases.push(langspec.base);
x = true;
ret.push(x);
} }
state.localeConfigure(langspec);
lst[i] = langspec;
} }
return ret; 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 = [];
if (Item.language) {
lang = CSL.localeParse(Item.language);
langspec = CSL.localeResolve(lang);
res = false;
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_bases.indexOf(langspec.base) > -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;
}
}
ret.push(res);
return ret;
};
this.tests.push(func);
}; };
this.tests.push(func);
}; };
CSL.Attributes["@suffix"] = function (state, arg) { CSL.Attributes["@suffix"] = function (state, arg) {
this.strings.suffix = arg; this.strings.suffix = arg;
@ -6813,9 +7017,7 @@ CSL.Util.Names.getCommonTerm = function (state, namesets) {
} }
base_nameset = namesets[0]; base_nameset = namesets[0];
varnames = []; varnames = [];
if (varnames.indexOf(base_nameset.variable) === -1) {
varnames.push(base_nameset.variable); varnames.push(base_nameset.variable);
}
short_namesets = namesets.slice(1); short_namesets = namesets.slice(1);
len = short_namesets.length; len = short_namesets.length;
for (pos = 0; pos < len; pos += 1) { for (pos = 0; pos < len; pos += 1) {
@ -7285,7 +7487,7 @@ CSL.Util.Ordinalizer.prototype.format = function (num, gender) {
var str; var str;
num = parseInt(num, 10); num = parseInt(num, 10);
str = num.toString(); str = num.toString();
if ((num / 10) % 10 === 1) { if ((num / 10) % 10 === 1 || (num > 10 && num < 20)) {
str += this.suffixes[gender][3]; str += this.suffixes[gender][3];
} else if (num % 10 === 1) { } else if (num % 10 === 1) {
str += this.suffixes[gender][0]; str += this.suffixes[gender][0];