update to citeproc-js 1.0.67
From Frank's release notes: Reimplement duplicate terminal punctuation handling in new adjustPunctuation() function. Remove old functions used for this purpose, which were excessively complex and fragile. Some operations in queue.js may now be redundant, since the new code does a much better job of cleaning up the output queue in advance of serialization. Clears some remaining duplicate punctuation issues. Corrects errors in the placement of punctuation where multiple terminal punctuation marks span a formatting boundary (i.e. italics, boldface, etc.).
This commit is contained in:
parent
f10b1dbd94
commit
cd7211da99
1 changed files with 133 additions and 89 deletions
|
@ -627,7 +627,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
|
||||||
}
|
}
|
||||||
if (!blob) {
|
if (!blob) {
|
||||||
blob_delimiter = "";
|
blob_delimiter = "";
|
||||||
CSL.Output.Queue.normalizePunctuation(blobs);
|
CSL.Output.Queue.adjustPunctuation(state, blobs);
|
||||||
} else {
|
} else {
|
||||||
blob_delimiter = blob.strings.delimiter;
|
blob_delimiter = blob.strings.delimiter;
|
||||||
}
|
}
|
||||||
|
@ -640,13 +640,6 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
|
||||||
b = blobjr.blobs;
|
b = blobjr.blobs;
|
||||||
use_suffix = blobjr.strings.suffix;
|
use_suffix = blobjr.strings.suffix;
|
||||||
use_prefix = blobjr.strings.prefix;
|
use_prefix = blobjr.strings.prefix;
|
||||||
for (ppos = blobjr.decorations.length - 1; ppos > -1; ppos += -1) {
|
|
||||||
params = blobjr.decorations[ppos];
|
|
||||||
if (params[0] === "@strip-periods" && params[1] === "true") {
|
|
||||||
b = state.fun.decorate[params[0]][params[1]](state, b);
|
|
||||||
blobjr.decorations = blobjr.decorations.slice(0, ppos).concat(blobjr.decorations.slice(ppos + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CSL.TERMINAL_PUNCTUATION.indexOf(use_suffix.slice(0, 1)) > -1 && use_suffix.slice(0, 1) === b.slice(-1)) {
|
if (CSL.TERMINAL_PUNCTUATION.indexOf(use_suffix.slice(0, 1)) > -1 && use_suffix.slice(0, 1) === b.slice(-1)) {
|
||||||
use_suffix = use_suffix.slice(1);
|
use_suffix = use_suffix.slice(1);
|
||||||
}
|
}
|
||||||
|
@ -858,90 +851,123 @@ CSL.Output.Queue.prototype.swapQuotePunctuation = function (ret, use_delim) {
|
||||||
}
|
}
|
||||||
return [ret, use_delim];
|
return [ret, use_delim];
|
||||||
};
|
};
|
||||||
CSL.Output.Queue.normalizePunctuation = function (blobs, res) {
|
CSL.Output.Queue.adjustPunctuation = function (state, myblobs, stk) {
|
||||||
var pos, len, m, punct, suff, predecessor, rex, params, ppos, llen;
|
var chr, suffix, delimiter, blob;
|
||||||
if ("object" === typeof blobs) {
|
var TERMS = CSL.TERMINAL_PUNCTUATION.slice(0, -1);
|
||||||
for (pos = 0, len = blobs.length; pos < len; pos += 1) {
|
if (!stk) {
|
||||||
if (!blobs[pos].blobs) {
|
stk = [{suffix: "", delimiter: ""}];
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (pos > 0) {
|
delimiter = stk[stk.length - 1].delimiter;
|
||||||
m = blobs[pos].strings.prefix.match(CSL.TERMINAL_PUNCTUATION_REGEXP);
|
suffix = stk[stk.length - 1].suffix;
|
||||||
if (m) {
|
blob = stk[stk.length - 1].blob;
|
||||||
blobs[pos].strings.prefix = m[2];
|
|
||||||
predecessor = blobs[(pos - 1)];
|
|
||||||
CSL.Output.Queue.appendPunctuationToSuffix(predecessor, m[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ("object" === typeof blobs[pos] && blobs[pos].blobs.length) {
|
|
||||||
res = CSL.Output.Queue.normalizePunctuation(blobs[pos].blobs, res);
|
|
||||||
}
|
|
||||||
if (res) {
|
|
||||||
if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(blobs[pos].strings.suffix.slice(0, 1)) > -1) {
|
|
||||||
blobs[pos].strings.suffix = blobs[pos].strings.suffix.slice(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pos === blobs.length -1 && (("string" === typeof blobs[pos].blobs && CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(blobs[pos].blobs.slice(-1)) > -1) || CSL.TERMINAL_PUNCTUATION.slice(0,-1).indexOf(blobs[pos].strings.suffix.slice(0, 1)) > -1)) {
|
|
||||||
res = true;
|
|
||||||
}
|
|
||||||
if (res && blobs[pos].strings.suffix.match(CSL.CLOSURES)) {
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
if (pos !== blobs.length - 1) {
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
CSL.Output.Queue.appendPunctuationToSuffix = function (predecessor, punct) {
|
|
||||||
var suff, newpredecessor;
|
|
||||||
suff = predecessor.strings.suffix;
|
|
||||||
if (suff) {
|
|
||||||
if (CSL.TERMINAL_PUNCTUATION.indexOf(suff.slice(-1)) === -1) {
|
|
||||||
predecessor.strings.suffix += punct;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ("string" === typeof predecessor.blobs) {
|
|
||||||
if (CSL.TERMINAL_PUNCTUATION.indexOf(predecessor.blobs.slice(-1)) === -1) {
|
|
||||||
predecessor.strings.suffix += punct;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newpredecessor = predecessor.blobs.slice(-1)[0];
|
|
||||||
if (newpredecessor) {
|
|
||||||
CSL.Output.Queue.appendPunctuationToSuffix(newpredecessor, punct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CSL.Output.Queue.quashDuplicateFinalPunctuation = function (state, myblobs, chr) {
|
|
||||||
if ("string" === typeof myblobs) {
|
if ("string" === typeof myblobs) {
|
||||||
if (chr === myblobs.slice(-1)) {
|
if (suffix) {
|
||||||
return myblobs.slice(0, -1);
|
if (blob &&
|
||||||
|
TERMS.indexOf(myblobs.slice(-1)) > -1) {
|
||||||
|
blob.strings.suffix = blob.strings.suffix.slice(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return myblobs;
|
for (var i = myblobs.length - 1; i > -1; i += -1) {
|
||||||
|
if (!myblobs[i].blobs.length) {
|
||||||
|
myblobs = myblobs.slice(0, i).concat(myblobs.slice(i + 1));
|
||||||
}
|
}
|
||||||
} else if (myblobs.length) {
|
}
|
||||||
if (state.getOpt('punctuation-in-quote')) {
|
if (delimiter) {
|
||||||
|
for (var j = 0, jlen = myblobs.length - 1; j < jlen; j += 1) {
|
||||||
|
if (TERMS.indexOf(myblobs[j].strings.suffix.slice(-1)) === -1) {
|
||||||
|
myblobs[j].strings.suffix += delimiter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = myblobs.length - 1; i > -1; i += -1) {
|
||||||
|
var doblob = myblobs[i];
|
||||||
|
if (i !== (myblobs.length - 1)) {
|
||||||
|
suffix = "";
|
||||||
|
blob = false;
|
||||||
|
}
|
||||||
|
if (i < (myblobs.length - 1)) {
|
||||||
|
if (blob) {
|
||||||
|
var nextdelimiter = blob.strings.delimiter;
|
||||||
|
} else {
|
||||||
|
var nextdelimiter = "";
|
||||||
|
}
|
||||||
|
var nextprefix = myblobs[i + 1].strings.prefix;
|
||||||
|
if (!nextdelimiter &&
|
||||||
|
nextprefix &&
|
||||||
|
TERMS.indexOf(nextprefix.slice(0, 1)) > -1) {
|
||||||
|
doblob.strings.suffix += nextprefix.slice(0, 1);
|
||||||
|
myblobs[i + 1].strings.prefix = nextprefix.slice(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (suffix) {
|
||||||
|
if (doblob.strings.suffix &&
|
||||||
|
TERMS.indexOf(suffix) > -1 &&
|
||||||
|
TERMS.indexOf(doblob.strings.suffix.slice(-1)) > -1) {
|
||||||
|
blob.strings.suffix = blob.strings.suffix.slice(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("string" === typeof doblob.blobs && doblob.blobs) {
|
||||||
|
for (var ppos = doblob.decorations.length - 1; ppos > -1; ppos += -1) {
|
||||||
|
var params = doblob.decorations[ppos];
|
||||||
|
if (params[0] === "@strip-periods" && params[1] === "true") {
|
||||||
|
doblob.blobs = state.fun.decorate[params[0]][params[1]](state, doblob.blobs);
|
||||||
|
doblob.decorations = doblob.decorations.slice(0, ppos).concat(doblob.decorations.slice(ppos + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i === (myblobs.length - 1) && state.getOpt('punctuation-in-quote')) {
|
||||||
var decorations = myblobs.slice(-1)[0].decorations;
|
var decorations = myblobs.slice(-1)[0].decorations;
|
||||||
for (var i = 0, ilen = decorations.length; i < ilen; i += 1) {
|
for (var j = 0, jlen = decorations.length; j < jlen; j += 1) {
|
||||||
if (decorations[i][0] === '@quotes' && decorations[i][1] === 'true') {
|
if (decorations[j][0] === '@quotes' && decorations[j][1] === 'true') {
|
||||||
myblobs.slice(-1)[0].blobs.slice(-1)[0].blobs += chr;
|
if ("string" === typeof myblobs[j].blobs) {
|
||||||
return true;
|
myblobs[j].blobs += stk[stk.length - 1].suffix;
|
||||||
|
} else {
|
||||||
|
myblobs[j].blobs.slice(-1)[0].strings.suffix += stk[stk.length - 1].suffix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var lastblob = myblobs.slice(-1)[0];
|
|
||||||
if (lastblob.strings.suffix && chr === lastblob.strings.suffix.slice(-1)) {
|
|
||||||
lastblob.strings.suffix = lastblob.strings.suffix.slice(0, -1);
|
|
||||||
} else if ("object" === typeof lastblob.blobs) {
|
|
||||||
return CSL.Output.Queue.quashDuplicateFinalPunctuation(state, lastblob.blobs, chr);
|
|
||||||
} else if ("string" === typeof lastblob.blobs) {
|
|
||||||
lastblob.blobs = CSL.Output.Queue.quashDuplicateFinalPunctuation(state, lastblob.blobs, chr);
|
|
||||||
}
|
}
|
||||||
|
if (i === (myblobs.length - 1)) {
|
||||||
|
if (doblob.strings.suffix) {
|
||||||
|
suffix = doblob.strings.suffix.slice(0, 1);
|
||||||
|
blob = doblob;
|
||||||
|
} else {
|
||||||
|
suffix = stk[stk.length - 1].suffix;
|
||||||
|
blob = stk[stk.length - 1].blob;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (doblob.strings.suffix) {
|
||||||
|
suffix = doblob.strings.suffix.slice(0, 1);
|
||||||
|
blob = doblob;
|
||||||
|
} else {
|
||||||
|
suffix = "";
|
||||||
|
blob = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TERMS.indexOf(suffix) === -1) {
|
||||||
|
suffix = "";
|
||||||
|
blob = false;
|
||||||
|
}
|
||||||
|
if (doblob.strings.delimiter) {
|
||||||
|
delimiter = doblob.strings.delimiter.slice(0, 1);
|
||||||
|
if (TERMS.indexOf(delimiter) > -1) {
|
||||||
|
doblob.strings.delimiter = doblob.strings.delimiter.slice(1);
|
||||||
|
} else {
|
||||||
|
delimiter = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delimiter = "";
|
||||||
|
}
|
||||||
|
stk.push({suffix: suffix, delimiter:delimiter, blob:blob});
|
||||||
|
CSL.Output.Queue.adjustPunctuation(state, doblob.blobs, stk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stk.length > 1) {
|
||||||
|
stk.pop();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
CSL.localeResolve = function (langstr) {
|
CSL.localeResolve = function (langstr) {
|
||||||
var ret, langlst;
|
var ret, langlst;
|
||||||
ret = {};
|
ret = {};
|
||||||
|
@ -1520,7 +1546,7 @@ CSL.dateParser = function (txt) {
|
||||||
};
|
};
|
||||||
CSL.Engine = function (sys, style, lang, xmlmode) {
|
CSL.Engine = function (sys, style, lang, xmlmode) {
|
||||||
var attrs, langspec, localexml, locale;
|
var attrs, langspec, localexml, locale;
|
||||||
this.processor_version = "1.0.66";
|
this.processor_version = "1.0.67";
|
||||||
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();
|
||||||
|
@ -2752,7 +2778,6 @@ CSL.getCitationCluster = function (inputList, citationID) {
|
||||||
var delimiter, result, objects, myparams, len, pos, item, last_collapsed, params, empties, composite, compie, myblobs, Item, llen, ppos, obj, preceding_item, txt_esc, error_object;
|
var delimiter, result, objects, myparams, len, pos, item, last_collapsed, params, empties, composite, compie, myblobs, Item, llen, ppos, obj, preceding_item, txt_esc, error_object;
|
||||||
txt_esc = CSL.Output.Formats[this.opt.mode].text_escape;
|
txt_esc = CSL.Output.Formats[this.opt.mode].text_escape;
|
||||||
this.tmp.area = "citation";
|
this.tmp.area = "citation";
|
||||||
delimiter = "";
|
|
||||||
result = "";
|
result = "";
|
||||||
objects = [];
|
objects = [];
|
||||||
this.tmp.last_suffix_used = "";
|
this.tmp.last_suffix_used = "";
|
||||||
|
@ -2812,13 +2837,33 @@ CSL.getCitationCluster = function (inputList, citationID) {
|
||||||
this.parallel.PruneOutputQueue(this);
|
this.parallel.PruneOutputQueue(this);
|
||||||
empties = 0;
|
empties = 0;
|
||||||
myblobs = this.output.queue.slice();
|
myblobs = this.output.queue.slice();
|
||||||
var use_layout_suffix = this.citation.opt.layout_suffix;
|
var fakeblob = {
|
||||||
if (CSL.TERMINAL_PUNCTUATION.indexOf(use_layout_suffix) > -1) {
|
strings: {
|
||||||
var res = CSL.Output.Queue.quashDuplicateFinalPunctuation(this, myblobs, use_layout_suffix.slice(0, 1));
|
suffix: this.citation.opt.layout_suffix,
|
||||||
if (res === true) {
|
delimiter: this.citation.opt.layout_delimiter
|
||||||
use_layout_suffix = use_layout_suffix.slice(1);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
var suffix = this.citation.opt.layout_suffix;
|
||||||
|
if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(suffix) > -1) {
|
||||||
|
suffix = this.citation.opt.layout_suffix.slice(0, 1);
|
||||||
|
} else {
|
||||||
|
suffix = "";
|
||||||
}
|
}
|
||||||
|
var delimiter = this.citation.opt.layout_delimiter;
|
||||||
|
if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(delimiter) > -1) {
|
||||||
|
delimiter = this.citation.opt.layout_delimiter.slice(0, 1);
|
||||||
|
} else {
|
||||||
|
delimiter = "";
|
||||||
|
}
|
||||||
|
var mystk = [
|
||||||
|
{
|
||||||
|
suffix: suffix,
|
||||||
|
delimiter: delimiter,
|
||||||
|
blob: fakeblob
|
||||||
|
}
|
||||||
|
];
|
||||||
|
CSL.Output.Queue.adjustPunctuation(this, myblobs, mystk);
|
||||||
|
var use_layout_suffix = mystk[0].blob.strings.suffix;
|
||||||
for (pos = 0, len = myblobs.length; pos < len; pos += 1) {
|
for (pos = 0, len = myblobs.length; pos < len; pos += 1) {
|
||||||
this.output.queue = [myblobs[pos]];
|
this.output.queue = [myblobs[pos]];
|
||||||
this.tmp.suppress_decorations = myparams[pos].suppress_decorations;
|
this.tmp.suppress_decorations = myparams[pos].suppress_decorations;
|
||||||
|
@ -2827,7 +2872,6 @@ CSL.getCitationCluster = function (inputList, citationID) {
|
||||||
this.tmp.splice_delimiter = myblobs[pos].parallel_delimiter;
|
this.tmp.splice_delimiter = myblobs[pos].parallel_delimiter;
|
||||||
}
|
}
|
||||||
this.tmp.have_collapsed = myparams[pos].have_collapsed;
|
this.tmp.have_collapsed = myparams[pos].have_collapsed;
|
||||||
CSL.Output.Queue.quashDuplicateFinalPunctuation(this, this.output.queue[this.output.queue.length - 1], "#");
|
|
||||||
composite = this.output.string(this, this.output.queue);
|
composite = this.output.string(this, this.output.queue);
|
||||||
this.tmp.suppress_decorations = false;
|
this.tmp.suppress_decorations = false;
|
||||||
if (item && item["author-only"]) {
|
if (item && item["author-only"]) {
|
||||||
|
|
Loading…
Reference in a new issue