commit 52980133b01efcde6ecbf9273c58e71e9be5bdd6
parent e5103952107a586027ef15b8e49615604bf1163c
Author: Dan Stillman <dstillman@zotero.org>
Date: Mon, 7 Mar 2016 19:40:27 -0500
Update citeproc-js to 1.1.74
Diffstat:
1 file changed, 2110 insertions(+), 1015 deletions(-)
diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js
@@ -1,72 +1,28 @@
/*
- * Copyright (c) 2009-2014 Frank G. Bennett
+ * /**
+ * Copyright (c) 2009-2016 Frank Bennett
*
- * Unless otherwise indicated, the files in this repository are subject
- * to the Common Public Attribution License Version 1.0 (the “License”);
- * you may not use this file except in compliance with the License. You
- * may obtain a copy of the License at:
+ * This program is free software: you can redistribute it and/or
+ * modify it under EITHER
*
- * http://bitbucket.org/fbennett/citeproc-js/src/tip/LICENSE.
+ * * the terms of the Common Public Attribution License (CPAL) as
+ * published by the Open Source Initiative, either version 1 of
+ * the CPAL, or (at your option) any later version; OR
*
- * (See also the note on attribution information below)
+ * * the terms of the GNU Affero General Public License (AGPL)
+ * as published by the Free Software Foundation, either version
+ * 3 of the AGPL, or (at your option) any later version.
*
- * The License is based on the Mozilla Public License Version 1.1 but
- * Sections 1.13, 14 and 15 have been added to cover use of software over a
- * computer network and provide for limited attribution for the
- * Original Developer. In addition, Exhibit A has been modified to be
- * consistent with Exhibit B.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Affero General Public License for more details.
*
- * Software distributed under the License is distributed on an “AS IS”
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is the citation formatting software known as
- * "citeproc-js" (an implementation of the Citation Style Language
- * [CSL]), including the original test fixtures and software located
- * under the ./tests subdirectory of the distribution archive.
- *
- * The Original Developer is not the Initial Developer and is
- * __________. If left blank, the Original Developer is the Initial
- * Developer.
- *
- * The Initial Developer of the Original Code is Frank Bennett. All
- * portions of the code written by Frank Bennett are Copyright (c)
- * 2009-2014 Frank Bennett.
- *
- * ***
- *
- * Alternatively, the files in this repository may be used under the
- * terms of the GNU Affero General Public License (the [AGPLv3] License),
- * in which case the provisions of [AGPLv3] License are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the [AGPLv3] License and not to
- * allow others to use your version of this file under the CPAL, indicate
- * your decision by deleting the provisions above and replace them with
- * the notice and other provisions required by the [AGPLv3] License. If
- * you do not delete the provisions above, a recipient may use your
- * version of this file under either the CPAL or the [AGPLv3] License.
- *
- * ***
- *
- * Attribution Information (CPAL)
- *
- * Attribution Copyright Notice: [no separate attribution copyright notice is required]
- *
- * Attribution Phrase: "Citations by CSL (citeproc-js)"
- *
- * Attribution URL: http://citationstyles.org/
- *
- * Graphic Image: [there is no requirement to display a Graphic Image]
- *
- * Display of Attribution Information is REQUIRED in Larger Works which
- * are defined in the CPAL as a work which combines Covered Code or
- * portions thereof with code not governed by the terms of the CPAL.
- *
- * Display of Attribution Information is also REQUIRED on Associated
- * Websites.
- *
- * [ citeproc-js license :: version 1.1 :: 2012.06.30 ]
+ * You should have received copies of the Common Public Attribution
+ * License and of the GNU Affero General Public License along with
+ * this program. If not, see <https://opensource.org/licenses/> or
+ * <http://www.gnu.org/licenses/> respectively.
+ * */
*/
if (!Array.indexOf) {
Array.prototype.indexOf = function (obj) {
@@ -80,13 +36,13 @@ if (!Array.indexOf) {
};
}
var CSL = {
- PROCESSOR_VERSION: "1.1.60",
+ PROCESSOR_VERSION: "1.1.74",
CONDITION_LEVEL_TOP: 1,
CONDITION_LEVEL_BOTTOM: 2,
PLAIN_HYPHEN_REGEX: /(?:[^\\]-|\u2013)/,
LOCATOR_LABELS_REGEXP: new RegExp("^((art|ch|subch|col|fig|l|n|no|op|p|pp|para|subpara|pt|r|sec|subsec|sv|sch|tit|vrs|vol)\\.)\\s+(.*)"),
- STATUTE_SUBDIV_GROUPED_REGEX: /((?:^| )(?:art|ch|subch|p|pp|para|subpara|pt|r|sec|subsec|sch|tit)\.)/g,
- STATUTE_SUBDIV_PLAIN_REGEX: /(?:(?:^| )(?:art|ch|subch|p|pp|para|subpara|pt|r|sec|subsec|sch|tit)\.)/,
+ STATUTE_SUBDIV_GROUPED_REGEX: /((?:^| )(?:art|bk|ch|subch|col|fig|fol|l|n|no|op|p|pp|para|subpara|pt|r|sec|subsec|sv|sch|tit|vrs|vol)\. *)/g,
+ STATUTE_SUBDIV_PLAIN_REGEX: /(?:(?:^| )(?:art|bk|ch|subch|col|fig|fol|l|n|no|op|p|pp|para|subpara|pt|r|sec|subsec|sv|sch|tit|vrs|vol)\. *)/,
STATUTE_SUBDIV_STRINGS: {
"art.": "article",
"bk.": "book",
@@ -192,9 +148,35 @@ var CSL = {
["(", "["],
[")", "]"]
],
- checkNestedBraceOpen: new RegExp(".*\\("),
- checkNestedBraceClose: new RegExp(".*\\)"),
- MULTI_FIELDS: ["event", "publisher", "publisher-place", "event-place", "title", "container-title", "collection-title", "authority","edition","genre","title-short","medium","jurisdiction","archive","archive-place"],
+ checkNestedBrace: function(state) {
+ if (state.opt.xclass === "note") {
+ this.depth = 0;
+ this.update = function(str) {
+ var str = str ? str : '';
+ var lst = str.split(/([\(\)])/);
+ for (var i=1,ilen=lst.length;i<ilen;i += 2) {
+ if (lst[i] === '(') {
+ if (1 === (this.depth % 2)) {
+ lst[i] = '['
+ }
+ this.depth += 1;
+ } else if (lst[i] === ')') {
+ if (0 === (this.depth % 2)) {
+ lst[i] = ']'
+ }
+ this.depth -= 1;
+ }
+ }
+ var ret = lst.join("");
+ return ret;
+ }
+ } else {
+ this.update = function(str) {
+ return str;
+ }
+ };
+ },
+ MULTI_FIELDS: ["event", "publisher", "publisher-place", "event-place", "title", "container-title", "collection-title", "authority","genre","title-short","medium","jurisdiction","archive","archive-place"],
LangPrefsMap: {
"title":"titles",
"title-short":"titles",
@@ -360,16 +342,61 @@ var CSL = {
"available-date",
"submitted"
],
- TAG_ESCAPE: function (str) {
+ TAG_ESCAPE: function (str, stopWords) {
var mx, lst, len, pos, m, buf1, buf2, idx, ret, myret;
- mx = str.match(/((?:\"|\')|(?:(?:<span\s+class=\"no(?:case|decor)\">).*?(?:<\/span>|<\/?(?:i|sc|b)>)))/g);
- lst = str.split(/(?:(?:\"|\')|(?:(?:<span\s+class=\"no(?:case|decor)\">).*?(?:<\/span>|<\/?(?:i|sc|b)>)))/g);
- myret = [lst[0]];
- for (pos = 1, len = lst.length; pos < len; pos += 1) {
- myret.push(mx[pos - 1]);
- myret.push(lst[pos]);
- }
- lst = myret.slice();
+ if (!stopWords) {
+ stopWords = [];
+ }
+ var pairs = {
+ "<span class=\"nocase\">": "</span>",
+ "<span class=\"nodecor\">": "</span>"
+ };
+ var stack = [];
+ str = str.replace(/(<span)\s+(class=\"no(?:case|decor)\")\s*(>)/g, "$1 $2$3");
+ var m1match = str.match(/((?: \"| \'|\" |\'[-.,;\?:]|\[|\]|\(|\)|<span class=\"no(?:case|decor)\">|<\/span>|<\/?(?:i|sc|b)>))/g);
+ if (!m1match) {
+ return [str];
+ }
+ var m1split = str.split(/(?: \"| \'|\" |\'[-.,;\?:]|\[|\]|\(|\)|<span class=\"no(?:case|decor)\">|<\/span>|<\/?(?:i|sc|b)>)/g);
+ outer: for (var i=0,ilen=m1match.length; i<ilen; i++) {
+ if (pairs[m1match[i]]) {
+ stack.push({
+ tag: m1match[i],
+ pos: i
+ });
+ var mFirstWord = m1split[i].match(/^(\s*([^' ]+[']?))(.*)/);
+ if (mFirstWord) {
+ if (stopWords.indexOf(mFirstWord[2]) > -1) {
+ if (!m1split[i-1].match(/[:\?\!]\s*$/)) {
+ m1match[i-1] = m1match[i-1] + mFirstWord[1];
+ m1split[i] = mFirstWord[3];
+ }
+ }
+ }
+ continue;
+ }
+ if (stack.length) {
+ for (var j=stack.length-1; j>-1; j--) {
+ var stackObj = stack.slice(j)[0];
+ if (m1match[i] === pairs[stackObj.tag]) {
+ stack = stack.slice(0, j+1);
+ var startPos = stack[j].pos;
+ for (var k=stack[j].pos+1; k<i+1; k++) {
+ m1match[k] = m1split[k] + m1match[k];
+ m1split[k] = "";
+ }
+ stack.pop();
+ break;
+ }
+ }
+ }
+ }
+ myret = [m1split[0]];
+ for (pos = 1, len = m1split.length; pos < len; pos += 1) {
+ myret.push(m1match[pos - 1]);
+ myret.push(m1split[pos]);
+ }
+ var lst = myret.slice();
return lst;
},
TAG_USEALL: function (str) {
@@ -659,20 +686,916 @@ if ("object" === typeof console && "function" === typeof console.log) {
throw "CSL error: " + str;
};
}
-var XML_PARSING;
-if ("undefined" !== typeof CSL_IS_NODEJS) {
- XML_PARSING = CSL_NODEJS;
-} else if ("undefined" !== typeof CSL_E4X) {
- XML_PARSING = CSL_E4X;
-} else if ("undefined" !== typeof CSL_JSON) {
- XML_PARSING = CSL_JSON;
-} else {
- XML_PARSING = CSL_CHROME;
+CSL.XmlJSON = function (dataObj) {
+ this.dataObj = dataObj;
+ this.institution = {
+ name:"institution",
+ attrs:{
+ "institution-parts":"long",
+ "delimiter":", ",
+ "substitute-use-first":"1",
+ "use-last":"1"
+ },
+ children:[
+ {
+ name:"institution-part",
+ attrs:{
+ name:"long"
+ },
+ children:[]
+ }
+ ]
+ };
+};
+CSL.XmlJSON.prototype.clean = function (json) {
+ return json;
+};
+CSL.XmlJSON.prototype.getStyleId = function (myjson, styleName) {
+ var tagName = 'id';
+ if (styleName) {
+ tagName = 'title';
+ }
+ return myjson.attrs[tagName];
+};
+CSL.XmlJSON.prototype.children = function (myjson) {
+ if (myjson && myjson.children.length) {
+ return myjson.children.slice();
+ } else {
+ return false;
+ }
+};
+CSL.XmlJSON.prototype.nodename = function (myjson) {
+ return myjson.name;
+};
+CSL.XmlJSON.prototype.attributes = function (myjson) {
+ var ret = {};
+ for (var attrname in myjson.attrs) {
+ ret["@"+attrname] = myjson.attrs[attrname];
+ }
+ return ret;
+};
+CSL.XmlJSON.prototype.content = function (myjson) {
+ var ret = "";
+ if (!myjson || !myjson.children) {
+ return ret;
+ }
+ for (var i=0, ilen=myjson.children.length; i < ilen; i += 1) {
+ if ("string" === typeof myjson.children[i]) {
+ ret += myjson.children[i];
+ }
+ }
+ return ret;
+};
+CSL.XmlJSON.prototype.namespace = {}
+CSL.XmlJSON.prototype.numberofnodes = function (myjson) {
+ if (myjson && "number" == typeof myjson.length) {
+ return myjson.length;
+ } else {
+ return 0;
+ }
+};
+CSL.XmlJSON.prototype.getAttributeValue = function (myjson,name,namespace) {
+ var ret = "";
+ if (namespace) {
+ name = namespace+":"+name;
+ }
+ if (myjson) {
+ if (myjson.attrs) {
+ if (myjson.attrs[name]) {
+ ret = myjson.attrs[name];
+ } else {
+ ret = "";
+ }
+ }
+ }
+ return ret;
+}
+CSL.XmlJSON.prototype.getNodeValue = function (myjson,name) {
+ var ret = "";
+ if (name){
+ for (var i=0, ilen=myjson.children.length; i < ilen; i += 1) {
+ if (myjson.children[i].name === name) {
+ if (myjson.children[i].children.length) {
+ ret = myjson.children[i];
+ } else {
+ ret = "";
+ }
+ }
+ }
+ } else if (myjson) {
+ ret = myjson;
+ }
+ if (ret && ret.children && ret.children.length == 1 && "string" === typeof ret.children[0]) {
+ ret = ret.children[0];
+ }
+ return ret;
+}
+CSL.XmlJSON.prototype.setAttributeOnNodeIdentifiedByNameAttribute = function (myjson,nodename,partname,attrname,val) {
+ var pos, len, xml, nodes, node;
+ if (attrname.slice(0,1) === '@'){
+ attrname = attrname.slice(1);
+ }
+ for (var i=0,ilen=myjson.children.length; i<ilen; i += 1) {
+ if (myjson.children[i].name === nodename && myjson.children[i].attrs.name === partname) {
+ myjson.children[i].attrs[attrname] = val;
+ }
+ }
+}
+CSL.XmlJSON.prototype.deleteNodeByNameAttribute = function (myjson,val) {
+ var i, ilen;
+ for (i = 0, ilen = myjson.children.length; i < ilen; i += 1) {
+ if (!myjson.children[i] || "string" === typeof myjson.children[i]) {
+ continue;
+ }
+ if (myjson.children[i].attrs.name == val) {
+ myjson.children = myjson.children.slice(0,i).concat(myjson.children.slice(i+1));
+ }
+ }
+}
+CSL.XmlJSON.prototype.deleteAttribute = function (myjson,attrname) {
+ var i, ilen;
+ if ("undefined" !== typeof myjson.attrs[attrname]) {
+ myjson.attrs.pop(attrname);
+ }
+}
+CSL.XmlJSON.prototype.setAttribute = function (myjson,attr,val) {
+ myjson.attrs[attr] = val;
+ return false;
+}
+CSL.XmlJSON.prototype.nodeCopy = function (myjson,clone) {
+ if (!clone) {
+ var clone = {};
+ }
+ if ("object" === typeof clone && "undefined" === typeof clone.length) {
+ for (var key in myjson) {
+ if ("string" === typeof myjson[key]) {
+ clone[key] = myjson[key];
+ } else if ("object" === typeof myjson[key]) {
+ if ("undefined" === typeof myjson[key].length) {
+ clone[key] = this.nodeCopy(myjson[key],{});
+ } else {
+ clone[key] = this.nodeCopy(myjson[key],[]);
+ }
+ }
+ }
+ } else {
+ for (var i=0,ilen=myjson.length;i<ilen; i += 1) {
+ if ("string" === typeof myjson[i]) {
+ clone[i] = myjson[i];
+ } else {
+ clone[i] = this.nodeCopy(myjson[i],{});
+ }
+ }
+ }
+ return clone;
+}
+CSL.XmlJSON.prototype.getNodesByName = function (myjson,name,nameattrval,ret) {
+ var nodes, node, pos, len;
+ if (!ret) {
+ var ret = [];
+ }
+ if (!myjson || !myjson.children) {
+ return ret;
+ }
+ if (name === myjson.name) {
+ if (nameattrval) {
+ if (nameattrval === myjson.attrs.name) {
+ ret.push(myjson);
+ }
+ } else {
+ ret.push(myjson);
+ }
+ }
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1){
+ if ("object" !== typeof myjson.children[i]) {
+ continue;
+ }
+ this.getNodesByName(myjson.children[i],name,nameattrval,ret);
+ }
+ return ret;
+}
+CSL.XmlJSON.prototype.nodeNameIs = function (myjson,name) {
+ if (name == myjson.name) {
+ return true;
+ }
+ return false;
+}
+CSL.XmlJSON.prototype.makeXml = function (myjson) {
+ if ("string" === typeof myjson) {
+ if (myjson.slice(0, 1) === "<") {
+ myjson = this.jsonStringWalker.walkToObject(myjson);
+ } else {
+ myjson = JSON.parse(myjson);
+ }
+ }
+ return myjson;
+};
+CSL.XmlJSON.prototype.insertChildNodeAfter = function (parent,node,pos,datejson) {
+ for (var i=0,ilen=parent.children.length;i<ilen;i+=1) {
+ if (node === parent.children[i]) {
+ parent.children = parent.children.slice(0,i).concat([datejson]).concat(parent.children.slice(i+1));
+ break;
+ }
+ }
+ return parent;
+};
+CSL.XmlJSON.prototype.insertPublisherAndPlace = function(myjson) {
+ if (myjson.name === "group") {
+ var useme = true;
+ var mustHaves = ["publisher","publisher-place"];
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1) {
+ var haveVarname = mustHaves.indexOf(myjson.children[i].attrs.variable);
+ var isText = myjson.children[i].name === "text";
+ if (isText && haveVarname > -1 && !myjson.children[i].attrs.prefix && !myjson.children[i].attrs.suffix) {
+ mustHaves = mustHaves.slice(0,haveVarname).concat(mustHaves.slice(haveVarname+1));
+ } else {
+ useme = false;
+ break;
+ }
+ }
+ if (useme && !mustHaves.length) {
+ myjson.attrs["has-publisher-and-publisher-place"] = true;
+ }
+ }
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1) {
+ if ("object" === typeof myjson.children[i]) {
+ this.insertPublisherAndPlace(myjson.children[i]);
+ }
+ }
+}
+CSL.XmlJSON.prototype.isChildOfSubstitute = function(parents) {
+ if (parents.length > 0) {
+ var myparents = parents.slice();
+ var parent = myparents.pop();
+ if (parent === "substitute") {
+ return true;
+ } else {
+ return this.isChildOfSubstitute(myparents);
+ }
+ }
+ return false;
+};
+CSL.XmlJSON.prototype.addMissingNameNodes = function(myjson,parents) {
+ if (!parents) {
+ parents = [];
+ }
+ if (myjson.name === "names") {
+ if (!this.isChildOfSubstitute(parents)) {
+ var addName = true;
+ for (var i=0,ilen=myjson.children.length;i<ilen;i++) {
+ if (myjson.children[i].name === "name") {
+ addName = false;
+ break;
+ }
+ }
+ if (addName) {
+ myjson.children = [{name:"name",attrs:{},children:[]}].concat(myjson.children);
+ }
+ }
+ }
+ parents.push(myjson.name);
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1) {
+ if ("object" === typeof myjson.children[i]) {
+ this.addMissingNameNodes(myjson.children[i],parents);
+ }
+ }
+ parents.pop();
+}
+CSL.XmlJSON.prototype.addInstitutionNodes = function(myjson) {
+ var names, thenames, institution, theinstitution, name, thename, xml, pos, len;
+ if (myjson.name === "names") {
+ var attributes = {};
+ var insertPos = -1;
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1) {
+ if (myjson.children[i].name == "name") {
+ for (var key in myjson.children[i].attrs) {
+ attributes[key] = myjson.children[i].attrs[key];
+ }
+ attributes.delimiter = myjson.children[i].attrs.delimiter;
+ attributes.and = myjson.children[i].attrs.and;
+ insertPos = i;
+ for (var k=0,klen=myjson.children[i].children.length;k<klen;k+=1) {
+ if (myjson.children[i].children[k].attrs.name !== 'family') {
+ continue;
+ }
+ for (var key in myjson.children[i].children[k].attrs) {
+ attributes[key] = myjson.children[i].children[k].attrs[key];
+ }
+ }
+ }
+ if (myjson.children[i].name == "institution") {
+ insertPos = -1;
+ break;
+ }
+ }
+ if (insertPos > -1) {
+ var institution = this.nodeCopy(this.institution);
+ for (var i=0,ilen = CSL.INSTITUTION_KEYS.length;i<ilen;i+=1) {
+ var attrname = CSL.INSTITUTION_KEYS[i];
+ if ("undefined" !== typeof attributes[attrname]) {
+ institution.children[0].attrs[attrname] = attributes[attrname];
+ }
+ if (attributes.delimiter) {
+ institution.attrs.delimiter = attributes.delimiter;
+ }
+ if (attributes.and) {
+ institution.attrs.and = "text";
+ }
+ }
+ myjson.children = myjson.children.slice(0,insertPos+1).concat([institution]).concat(myjson.children.slice(insertPos+1));
+ }
+ }
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1) {
+ if ("string" === typeof myjson.children[i]) {
+ continue;
+ }
+ this.addInstitutionNodes(myjson.children[i]);
+ }
+}
+CSL.XmlJSON.prototype.flagDateMacros = function(myjson) {
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1) {
+ if (myjson.children[i].name === "macro") {
+ if (this.inspectDateMacros(myjson.children[i])) {
+ myjson.children[i].attrs["macro-has-date"] = "true";
+ }
+ }
+ }
+}
+CSL.XmlJSON.prototype.inspectDateMacros = function(myjson) {
+ if (!myjson || !myjson.children) {
+ return false;
+ }
+ if (myjson.name === "date") {
+ return true;
+ } else {
+ for (var i=0,ilen=myjson.children.length;i<ilen;i+=1) {
+ if (this.inspectDateMacros(myjson.children[i])) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+CSL.stripXmlProcessingInstruction = function (xml) {
+ if (!xml) {
+ return xml;
+ }
+ xml = xml.replace(/^<\?[^?]+\?>/, "");
+ xml = xml.replace(/<!--[^>]+-->/g, "");
+ xml = xml.replace(/^\s+/g, "");
+ xml = xml.replace(/\s+$/g, "");
+ return xml;
+};
+CSL.parseXml = function(str) {
+ var _pos = 0;
+ var _obj = {children:[]};
+ var _stack = [_obj.children];
+ function _listifyString(str) {
+ str = str.split("\n").join(" ").replace(/>[ ]+</g, "><").replace(/<\!--.*?-->/g, "");
+ var lst = str.split("><");
+ var stylePos = null;
+ for (var i=0,ilen=lst.length;i<ilen;i++) {
+ if (i > 0) {
+ lst[i] = "<" + lst[i];
+ }
+ if (i < (lst.length-1)) {
+ lst[i] = lst[i] + ">";
+ }
+ if ("number" != typeof stylePos) {
+ if (lst[i].slice(0, 7) === "<style " || lst[i].slice(0, 8) == "<locale ") {
+ stylePos = i;
+ }
+ }
+ }
+ lst = lst.slice(stylePos);
+ for (var i=lst.length-2;i>-1;i--) {
+ if (lst[i].slice(1).indexOf("<") === -1) {
+ var stub = lst[i].slice(0, 5);
+ if (stub === "<term") {
+ if (lst[i+1].slice(0, 6) === "</term") {
+ lst[i] = lst[i] + lst[i+1];
+ lst = lst.slice(0, i+1).concat(lst.slice(i+2));
+ }
+ } else if (["<sing", "<mult"].indexOf(stub) > -1) {
+ if (lst[i].slice(-2) !== "/>" && lst[i+1].slice(0, 1) === "<") {
+ lst[i] = lst[i] + lst[i+1];
+ lst = lst.slice(0, i+1).concat(lst.slice(i+2));
+ }
+ }
+ }
+ }
+ return lst;
+ }
+ function _decodeHtmlEntities(str) {
+ return str
+ .split("&").join("&")
+ .split(""").join("\"")
+ .replace(/&#([0-9]{1,6});/gi, function(match, numStr) {
+ var num = parseInt(numStr, 10); // read num as normal number
+ return String.fromCharCode(num);
+ })
+ .replace(/&#x([a-f0-9]{1,6});/gi, function(match, numStr){
+ var num = parseInt(numStr, 16); // read num as hex
+ return String.fromCharCode(num);
+ });
+ }
+ function _getAttributes(elem) {
+ var m = elem.match(/([^\"= ]+)=\"[^\"]*\"/g);
+ if (m) {
+ for (var i=0,ilen=m.length;i<ilen;i++) {
+ m[i] = m[i].replace(/=.*/, "");
+ }
+ }
+ return m;
+ }
+ function _getAttribute(elem, attr) {
+ var rex = RegExp('^.*[ ]+' + attr + '=\"([^\"]*)\".*$');
+ var m = elem.match(rex);
+ return m ? m[1] : null;
+ }
+ function _getTagName(elem) {
+ var rex = RegExp("^<([^ />]+)");
+ var m = elem.match(rex);
+ return m ? m[1] : null;
+ }
+ function _castObjectFromOpeningTag(elem) {
+ var obj = {};
+ obj.name = _getTagName(elem);
+ obj.attrs = {};
+ var attributes = _getAttributes(elem);
+ if (attributes) {
+ for (var i=0,ilen=attributes.length;i<ilen;i++) {
+ var attr = {
+ name: attributes[i],
+ value: _getAttribute(elem, attributes[i])
+ }
+ obj.attrs[attr.name] = _decodeHtmlEntities(attr.value);
+ }
+ }
+ obj.children = [];
+ return obj;
+ }
+ function _extractTextFromCompositeElement(elem) {
+ var m = elem.match(/^.*>([^<]*)<.*$/);
+ return _decodeHtmlEntities(m[1]);
+ }
+ function _appendToChildren(obj) {
+ _stack.slice(-1)[0].push(obj);
+ }
+ function _extendStackWithNewChildren(obj) {
+ _stack.push(obj.children);
+ }
+ function processElement(elem) {
+ var obj;
+ if (elem.slice(1).indexOf('<') > -1) {
+ var tag = elem.slice(0, elem.indexOf('>')+1);
+ obj = _castObjectFromOpeningTag(tag);
+ obj.children = [_extractTextFromCompositeElement(elem)];
+ _appendToChildren(obj);
+ } else if (elem.slice(-2) === '/>') {
+ obj = _castObjectFromOpeningTag(elem);
+ if (_getTagName(elem) === 'term') {
+ obj.children.push('');
+ }
+ _appendToChildren(obj);
+ } else if (elem.slice(0, 2) === '</') {
+ _stack.pop();
+ } else {
+ obj = _castObjectFromOpeningTag(elem);
+ _appendToChildren(obj)
+ _extendStackWithNewChildren(obj);
+ }
+ }
+ var lst = _listifyString(str);
+ for (var i=0,ilen=lst.length;i<ilen;i++) {
+ var elem = lst[i];
+ processElement(elem);
+ }
+ return _obj.children[0];
+}
+CSL.XmlDOM = function (dataObj) {
+ this.dataObj = dataObj;
+ if ("undefined" == typeof DOMParser) {
+ DOMParser = function() {};
+ DOMParser.prototype.parseFromString = function(str, contentType) {
+ if ("undefined" != typeof ActiveXObject) {
+ var xmldata = new ActiveXObject('MSXML.DomDocument');
+ xmldata.async = false;
+ xmldata.loadXML(str);
+ return xmldata;
+ } else if ("undefined" != typeof XMLHttpRequest) {
+ var xmldata = new XMLHttpRequest;
+ if (!contentType) {
+ contentType = 'text/xml';
+ }
+ xmldata.open('GET', 'data:' + contentType + ';charset=utf-8,' + encodeURIComponent(str), false);
+ if(xmldata.overrideMimeType) {
+ xmldata.overrideMimeType(contentType);
+ }
+ xmldata.send(null);
+ return xmldata.responseXML;
+ } else if ("undefined" != typeof marknote) {
+ var parser = new marknote.Parser();
+ return parser.parse(str);
+ }
+ };
+ this.hasAttributes = function (node) {
+ var ret;
+ if (node.attributes && node.attributes.length) {
+ ret = true;
+ } else {
+ ret = false;
+ }
+ return ret;
+ };
+ } else {
+ this.hasAttributes = function (node) {
+ var ret;
+ if (node.attributes && node.attributes.length) {
+ ret = true;
+ } else {
+ ret = false;
+ }
+ return ret;
+ };
+ }
+ this.importNode = function (doc, srcElement) {
+ if ("undefined" == typeof doc.importNode) {
+ var ret = this._importNode(doc, srcElement, true);
+ } else {
+ var ret = doc.importNode(srcElement, true);
+ }
+ return ret;
+ };
+ this._importNode = function(doc, node, allChildren) {
+ switch (node.nodeType) {
+ case 1:
+ var newNode = doc.createElement(node.nodeName);
+ if (node.attributes && node.attributes.length > 0)
+ for (var i = 0, il = node.attributes.length; i < il;)
+ newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName));
+ if (allChildren && node.childNodes && node.childNodes.length > 0)
+ for (var i = 0, il = node.childNodes.length; i < il;)
+ newNode.appendChild(this._importNode(doc, node.childNodes[i++], allChildren));
+ return newNode;
+ break;
+ case 3:
+ case 4:
+ case 8:
+ }
+ };
+ this.parser = new DOMParser();
+ var str = "<docco><institution institution-parts=\"long\" delimiter=\", \" substitute-use-first=\"1\" use-last=\"1\"><institution-part name=\"long\"/></institution></docco>";
+ var inst_doc = this.parser.parseFromString(str, "text/xml");
+ var inst_node = inst_doc.getElementsByTagName("institution");
+ this.institution = inst_node.item(0);
+ var inst_part_node = inst_doc.getElementsByTagName("institution-part");
+ this.institutionpart = inst_part_node.item(0);
+ this.ns = "http://purl.org/net/xbiblio/csl";
+};
+CSL.XmlDOM.prototype.clean = function (xml) {
+ xml = xml.replace(/<\?[^?]+\?>/g, "");
+ xml = xml.replace(/<![^>]+>/g, "");
+ xml = xml.replace(/^\s+/, "");
+ xml = xml.replace(/\s+$/, "");
+ xml = xml.replace(/^\n*/, "");
+ return xml;
+};
+CSL.XmlDOM.prototype.getStyleId = function (myxml, styleName) {
+ var text = "";
+ var tagName = "id";
+ if (styleName) {
+ tagName = "title";
+ }
+ var node = myxml.getElementsByTagName(tagName);
+ if (node && node.length) {
+ node = node.item(0);
+ }
+ if (node) {
+ text = node.textContent;
+ }
+ if (!text) {
+ text = node.innerText;
+ }
+ if (!text) {
+ text = node.innerHTML;
+ }
+ return text;
+};
+CSL.XmlDOM.prototype.children = function (myxml) {
+ var children, pos, len, ret;
+ if (myxml) {
+ ret = [];
+ children = myxml.childNodes;
+ for (pos = 0, len = children.length; pos < len; pos += 1) {
+ if (children[pos].nodeName != "#text") {
+ ret.push(children[pos]);
+ }
+ }
+ return ret;
+ } else {
+ return [];
+ }
+};
+CSL.XmlDOM.prototype.nodename = function (myxml) {
+ var ret = myxml.nodeName;
+ return ret;
+};
+CSL.XmlDOM.prototype.attributes = function (myxml) {
+ var ret, attrs, attr, key, xml, pos, len;
+ ret = new Object();
+ if (myxml && this.hasAttributes(myxml)) {
+ attrs = myxml.attributes;
+ for (pos = 0, len=attrs.length; pos < len; pos += 1) {
+ attr = attrs[pos];
+ ret["@" + attr.name] = attr.value;
+ }
+ }
+ return ret;
+};
+CSL.XmlDOM.prototype.content = function (myxml) {
+ var ret;
+ if ("undefined" != typeof myxml.textContent) {
+ ret = myxml.textContent;
+ } else if ("undefined" != typeof myxml.innerText) {
+ ret = myxml.innerText;
+ } else {
+ ret = myxml.txt;
+ }
+ return ret;
+};
+CSL.XmlDOM.prototype.namespace = {
+ "xml":"http://www.w3.org/XML/1998/namespace"
+}
+CSL.XmlDOM.prototype.numberofnodes = function (myxml) {
+ if (myxml) {
+ return myxml.length;
+ } else {
+ return 0;
+ }
+};
+CSL.XmlDOM.prototype.getAttributeName = function (attr) {
+ var ret = attr.name;
+ return ret;
+}
+CSL.XmlDOM.prototype.getAttributeValue = function (myxml,name,namespace) {
+ var ret = "";
+ if (namespace) {
+ name = namespace+":"+name;
+ }
+ if (myxml && this.hasAttributes(myxml) && myxml.getAttribute(name)) {
+ ret = myxml.getAttribute(name);
+ }
+ return ret;
+}
+CSL.XmlDOM.prototype.getNodeValue = function (myxml,name) {
+ var ret = null;
+ if (name){
+ var vals = myxml.getElementsByTagName(name);
+ if (vals.length > 0) {
+ if ("undefined" != typeof vals[0].textContent) {
+ ret = vals[0].textContent;
+ } else if ("undefined" != typeof vals[0].innerText) {
+ ret = vals[0].innerText;
+ } else {
+ ret = vals[0].text;
+ }
+ }
+ }
+ if (ret === null && myxml && myxml.childNodes && (myxml.childNodes.length == 0 || (myxml.childNodes.length == 1 && myxml.firstChild.nodeName == "#text"))) {
+ if ("undefined" != typeof myxml.textContent) {
+ ret = myxml.textContent;
+ } else if ("undefined" != typeof myxml.innerText) {
+ ret = myxml.innerText;
+ } else {
+ ret = myxml.text;
+ }
+ }
+ if (ret === null) {
+ ret = myxml;
+ }
+ return ret;
+}
+CSL.XmlDOM.prototype.setAttributeOnNodeIdentifiedByNameAttribute = function (myxml,nodename,partname,attrname,val) {
+ var pos, len, xml, nodes, node;
+ if (attrname.slice(0,1) === '@'){
+ attrname = attrname.slice(1);
+ }
+ nodes = myxml.getElementsByTagName(nodename);
+ for (pos = 0, len = nodes.length; pos < len; pos += 1) {
+ node = nodes[pos];
+ if (node.getAttribute("name") != partname) {
+ continue;
+ }
+ node.setAttribute(attrname, val);
+ }
+}
+CSL.XmlDOM.prototype.deleteNodeByNameAttribute = function (myxml,val) {
+ var pos, len, node, nodes;
+ nodes = myxml.childNodes;
+ for (pos = 0, len = nodes.length; pos < len; pos += 1) {
+ node = nodes[pos];
+ if (!node || node.nodeType == node.TEXT_NODE) {
+ continue;
+ }
+ if (this.hasAttributes(node) && node.getAttribute("name") == val) {
+ myxml.removeChild(nodes[pos]);
+ }
+ }
+}
+CSL.XmlDOM.prototype.deleteAttribute = function (myxml,attr) {
+ myxml.removeAttribute(attr);
+}
+CSL.XmlDOM.prototype.setAttribute = function (myxml,attr,val) {
+ if (!myxml.ownerDocument) {
+ myxml = myxml.firstChild;
+ }
+ if (["function", "unknown"].indexOf(typeof myxml.setAttribute) > -1) {
+ myxml.setAttribute(attr, val);
+ }
+ return false;
+}
+CSL.XmlDOM.prototype.nodeCopy = function (myxml) {
+ var cloned_node = myxml.cloneNode(true);
+ return cloned_node;
+}
+CSL.XmlDOM.prototype.getNodesByName = function (myxml,name,nameattrval) {
+ var ret, nodes, node, pos, len;
+ ret = [];
+ nodes = myxml.getElementsByTagName(name);
+ for (pos = 0, len = nodes.length; pos < len; pos += 1) {
+ node = nodes.item(pos);
+ if (nameattrval && !(this.hasAttributes(node) && node.getAttribute("name") == nameattrval)) {
+ continue;
+ }
+ ret.push(node);
+ }
+ return ret;
+}
+CSL.XmlDOM.prototype.nodeNameIs = function (myxml,name) {
+ if (name == myxml.nodeName) {
+ return true;
+ }
+ return false;
}
-CSL.System = {};
-CSL.System.Xml = {
- "Parsing": XML_PARSING
+CSL.XmlDOM.prototype.makeXml = function (myxml) {
+ var ret, topnode;
+ if (!myxml) {
+ myxml = "<docco><bogus/></docco>";
+ }
+ myxml = myxml.replace(/\s*<\?[^>]*\?>\s*\n*/g, "");
+ var nodetree = this.parser.parseFromString(myxml, "application/xml");
+ return nodetree.firstChild;
+};
+CSL.XmlDOM.prototype.insertChildNodeAfter = function (parent,node,pos,datexml) {
+ var myxml, xml;
+ myxml = this.importNode(node.ownerDocument, datexml);
+ parent.replaceChild(myxml, node);
+ return parent;
+};
+CSL.XmlDOM.prototype.insertPublisherAndPlace = function(myxml) {
+ var group = myxml.getElementsByTagName("group");
+ for (var i = 0, ilen = group.length; i < ilen; i += 1) {
+ var node = group.item(i);
+ var skippers = [];
+ for (var j = 0, jlen = node.childNodes.length; j < jlen; j += 1) {
+ if (node.childNodes.item(j).nodeType !== 1) {
+ skippers.push(j);
+ }
+ }
+ if (node.childNodes.length - skippers.length === 2) {
+ var twovars = [];
+ for (var j = 0, jlen = 2; j < jlen; j += 1) {
+ if (skippers.indexOf(j) > -1) {
+ continue;
+ }
+ var child = node.childNodes.item(j);
+ var subskippers = [];
+ for (var k = 0, klen = child.childNodes.length; k < klen; k += 1) {
+ if (child.childNodes.item(k).nodeType !== 1) {
+ subskippers.push(k);
+ }
+ }
+ if (child.childNodes.length - subskippers.length === 0) {
+ twovars.push(child.getAttribute('variable'));
+ if (child.getAttribute('suffix')
+ || child.getAttribute('prefix')) {
+ twovars = [];
+ break;
+ }
+ }
+ }
+ if (twovars.indexOf("publisher") > -1 && twovars.indexOf("publisher-place") > -1) {
+ node.setAttribute('has-publisher-and-publisher-place', true);
+ }
+ }
+ }
+};
+CSL.XmlDOM.prototype.isChildOfSubstitute = function(node) {
+ if (node.parentNode) {
+ if (node.parentNode.tagName.toLowerCase() === "substitute") {
+ return true;
+ } else {
+ return this.isChildOfSubstitute(node.parentNode);
+ }
+ }
+ return false;
+};
+CSL.XmlDOM.prototype.addMissingNameNodes = function(myxml) {
+ var nameslist = myxml.getElementsByTagName("names");
+ for (var i = 0, ilen = nameslist.length; i < ilen; i += 1) {
+ var names = nameslist.item(i);
+ var namelist = names.getElementsByTagName("name");
+ if ((!namelist || namelist.length === 0)
+ && !this.isChildOfSubstitute(names)) {
+ var doc = names.ownerDocument;
+ var name = doc.createElement("name");
+ names.appendChild(name);
+ }
+ }
+};
+CSL.XmlDOM.prototype.addInstitutionNodes = function(myxml) {
+ var names, thenames, institution, theinstitution, name, thename, xml, pos, len;
+ names = myxml.getElementsByTagName("names");
+ for (pos = 0, len = names.length; pos < len; pos += 1) {
+ thenames = names.item(pos);
+ name = thenames.getElementsByTagName("name");
+ if (name.length == 0) {
+ continue;
+ }
+ institution = thenames.getElementsByTagName("institution");
+ if (institution.length == 0) {
+ theinstitution = this.importNode(myxml.ownerDocument, this.institution);
+ theinstitutionpart = theinstitution.getElementsByTagName("institution-part").item(0);
+ thename = name.item(0);
+ thenames.insertBefore(theinstitution, thename.nextSibling);
+ for (var j = 0, jlen = CSL.INSTITUTION_KEYS.length; j < jlen; j += 1) {
+ var attrname = CSL.INSTITUTION_KEYS[j];
+ var attrval = thename.getAttribute(attrname);
+ if (attrval) {
+ theinstitutionpart.setAttribute(attrname, attrval);
+ }
+ }
+ var nameparts = thename.getElementsByTagName("name-part");
+ for (var j = 0, jlen = nameparts.length; j < jlen; j += 1) {
+ if ('family' === nameparts[j].getAttribute('name')) {
+ for (var k = 0, klen = CSL.INSTITUTION_KEYS.length; k < klen; k += 1) {
+ var attrname = CSL.INSTITUTION_KEYS[k];
+ var attrval = nameparts[j].getAttribute(attrname);
+ if (attrval) {
+ theinstitutionpart.setAttribute(attrname, attrval);
+ }
+ }
+ }
+ }
+ }
+ }
+};
+CSL.XmlDOM.prototype.flagDateMacros = function(myxml) {
+ var pos, len, thenode, thedate;
+ nodes = myxml.getElementsByTagName("macro");
+ for (pos = 0, len = nodes.length; pos < len; pos += 1) {
+ thenode = nodes.item(pos);
+ thedate = thenode.getElementsByTagName("date");
+ if (thedate.length) {
+ thenode.setAttribute('macro-has-date', 'true');
+ }
+ }
};
+if ("undefined" !== typeof XML) {
+ try {
+ } catch (e) {
+ throw "OOPS: "+e;
+ }
+}
+CSL.setupXml = function(xmlObject) {
+ var dataObj = {};
+ var parser = null;
+ if ("undefined" !== typeof xmlObject) {
+ if ("string" === typeof xmlObject) {
+ xmlObject = xmlObject.replace("^\uFEFF", "")
+ .replace(/^\s+/, "");
+ if (xmlObject.slice(0, 1) === "<") {
+ dataObj = CSL.parseXml(xmlObject);
+ } else {
+ dataObj = JSON.parse(xmlObject);
+ }
+ parser = new CSL.XmlJSON(dataObj);
+ } else if ("undefined" !== typeof xmlObject.getAttribute) {
+ parser = new CSL.XmlDOM(xmlObject);
+ } else if ("undefined" !== typeof xmlObject.toXMLString) {
+ parser = new CSL.XmlE4X(xmlObject);
+ } else {
+ parser = new CSL.XmlJSON(xmlObject);
+ }
+ } else {
+ print("OUCH!");
+ }
+ if (!parser) {
+ throw "citeproc-js error: unable to parse style or locale object";
+ }
+ return parser;
+}
CSL.getSortCompare = function (default_locale) {
if (CSL.stringCompare) {
return CSL.stringCompare;
@@ -780,7 +1703,7 @@ CSL.getMinVal = function () {
};
CSL.tokenExec = function (token, Item, item) {
var next, maybenext, exec, debug;
- debug = false;
+ debug = true;
next = token.next;
maybenext = false;
var record = function (result) {
@@ -811,10 +1734,10 @@ CSL.expandMacro = function (macro_key_token, target) {
macro_key_token = new CSL.Token("group", CSL.START);
var hasDate = false;
var macroid = false;
- macro_nodes = this.sys.xml.getNodesByName(this.cslXml, 'macro', mkey);
+ macro_nodes = this.cslXml.getNodesByName(this.cslXml.dataObj, 'macro', mkey);
if (macro_nodes.length) {
- macroid = this.sys.xml.getAttributeValue(macro_nodes[0],'cslid');
- hasDate = this.sys.xml.getAttributeValue(macro_nodes[0], "macro-has-date");
+ macroid = this.cslXml.getAttributeValue(macro_nodes[0],'cslid');
+ hasDate = this.cslXml.getAttributeValue(macro_nodes[0], "macro-has-date");
}
if (hasDate) {
mkey = mkey + "@" + this.build.current_default_locale;
@@ -837,7 +1760,7 @@ CSL.expandMacro = function (macro_key_token, target) {
this.opt.update_mode = CSL.POSITION;
}
CSL.Node.group.build.call(macro_key_token, this, target);
- if (!this.sys.xml.getNodeValue(macro_nodes)) {
+ if (!this.cslXml.getNodeValue(macro_nodes)) {
throw "CSL style error: undefined macro \"" + mkey + "\"";
}
var mytarget = CSL.getMacroTarget.call(this, mkey);
@@ -893,7 +1816,7 @@ CSL.runAltMacro = function (state, alt_macro, Item, item) {
flag[1] = false;
var mytarget = CSL.getMacroTarget.call(state, alt_macro);
if (mytarget) {
- var macro_nodes = state.sys.xml.getNodesByName(state.cslXml, 'macro', alt_macro);
+ var macro_nodes = state.cslXml.getNodesByName(state.cslXml.dataObj, 'macro', alt_macro);
CSL.buildMacro.call(state, mytarget, macro_nodes);
CSL.configureMacro.call(state, mytarget);
}
@@ -920,22 +1843,22 @@ CSL.configureMacro = function (mytarget) {
}
CSL.XmlToToken = function (state, tokentype, explicitTarget) {
var name, txt, attrfuncs, attributes, decorations, token, key, target;
- name = state.sys.xml.nodename(this);
+ name = state.cslXml.nodename(this);
if (state.build.skip && state.build.skip !== name) {
return;
}
if (!name) {
- txt = state.sys.xml.content(this);
+ txt = state.cslXml.content(this);
if (txt) {
state.build.text = txt;
}
return;
}
- if (!CSL.Node[state.sys.xml.nodename(this)]) {
+ if (!CSL.Node[state.cslXml.nodename(this)]) {
throw "Undefined node name \"" + name + "\".";
}
attrfuncs = [];
- attributes = state.sys.xml.attributes(this);
+ attributes = state.cslXml.attributes(this);
decorations = CSL.setDecorations.call(this, state, attributes);
token = new CSL.Token(name, tokentype);
if (tokentype !== CSL.END || name === "if" || name === "else-if" || name === "layout") {
@@ -969,83 +1892,68 @@ CSL.XmlToToken = function (state, tokentype, explicitTarget) {
}
CSL.Node[name].build.call(token, state, target);
};
-CSL.DateParser = function () {
- 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 = [
+CSL.DateParser = new function () {
+ var epochPairs = [
["\u660E\u6CBB", 1867],
["\u5927\u6B63", 1911],
["\u662D\u548C", 1925],
["\u5E73\u6210", 1988]
];
- jiy = {};
- len = jiy_list.length;
- for (pos = 0; pos < len; pos += 1) {
- key = jiy_list[pos][0];
- val = jiy_list[pos][1];
- jiy[key] = val;
- }
- jiymatchstring = [];
- for (pos = 0; pos < len; pos += 1) {
- val = jiy_list[pos][0];
- jiymatchstring.push(val);
- }
- jiymatchstring = jiymatchstring.join("|");
- jiysplitter = "(?:" + jiymatchstring + ")(?:[0-9]+)";
- jiysplitter = new RegExp(jiysplitter);
- jiymatcher = "(?:" + jiymatchstring + ")(?:[0-9]+)";
- jiymatcher = new RegExp(jiymatcher, "g");
- jmd = /(\u6708|\u5E74)/g;
- jy = /\u65E5/g;
- jr = /\u301c/g;
- yearlast = "(?:[?0-9]{1,2}%%NUMD%%){0,2}[?0-9]{4}(?![0-9])";
- yearfirst = "[?0-9]{4}(?:%%NUMD%%[?0-9]{1,2}){0,2}(?![0-9])";
- number = "[?0-9]{1,3}";
- rangesep = "[%%DATED%%]";
- fuzzychar = "[?~]";
- chars = "[a-zA-Z]+";
- rex = "(" + yearfirst + "|" + yearlast + "|" + number + "|" + rangesep + "|" + fuzzychar + "|" + chars + ")";
- rexdash = new RegExp(rex.replace(/%%NUMD%%/g, "-").replace(/%%DATED%%/g, "-"));
- rexdashslash = new RegExp(rex.replace(/%%NUMD%%/g, "-").replace(/%%DATED%%/g, "\/"));
- rexslashdash = new RegExp(rex.replace(/%%NUMD%%/g, "\/").replace(/%%DATED%%/g, "-"));
- seasonstrs = [];
- seasonrexes = [];
- len = seasonstrs.length;
- for (pos = 0; pos < len; pos += 1) {
- seasonrex = new RegExp(seasonstrs[pos] + ".*");
- seasonrexes.push(seasonrex);
- }
- this.mstrings = "january february march april may june july august september october november december spring summer fall winter spring summer";
- this.mstrings = this.mstrings.split(" ");
+ var epochYearByName = {};
+ for (var i=0,ilen=epochPairs.length; i<ilen; i++) {
+ var key = epochPairs[i][0];
+ var val = epochPairs[i][1];
+ epochYearByName[key] = val;
+ }
+ var epochMatchStrings = [];
+ for (var i=0,ilen=epochPairs.length; i<ilen; i++) {
+ var val = epochPairs[i][0];
+ epochMatchStrings.push(val);
+ }
+ var epochMatchString = epochMatchStrings.join("|");
+ var epochSplitter = new RegExp("(?:" + epochMatchString + ")(?:[0-9]+)");
+ var epochMatcher = new RegExp("(?:" + epochMatchString + ")(?:[0-9]+)", "g");
+ var kanjiMonthDay = /(\u6708|\u5E74)/g;
+ var kanjiYear = /\u65E5/g;
+ var kanjiRange = /\u301c/g;
+ var yearLast = "(?:[?0-9]{1,2}%%NUMD%%){0,2}[?0-9]{4}(?![0-9])";
+ var yearFirst = "[?0-9]{4}(?:%%NUMD%%[?0-9]{1,2}){0,2}(?![0-9])";
+ var numberVal = "[?0-9]{1,3}";
+ var rangeSeparator = "[%%DATED%%]";
+ var fuzzyChar = "[?~]";
+ var chars = "[^\-\/\~\?0-9]+";
+ var rexString = "(" + yearFirst + "|" + yearLast + "|" + numberVal + "|" + rangeSeparator + "|" + fuzzyChar + "|" + chars + ")";
+ var rexDash = new RegExp(rexString.replace(/%%NUMD%%/g, "-").replace(/%%DATED%%/g, "-"));
+ var rexDashSlash = new RegExp(rexString.replace(/%%NUMD%%/g, "-").replace(/%%DATED%%/g, "\/"));
+ var rexSlashDash = new RegExp(rexString.replace(/%%NUMD%%/g, "\/").replace(/%%DATED%%/g, "-"));
+ var monthString = "january february march april may june july august september october november december spring summer fall winter spring summer";
+ this.monthStrings = monthString.split(" ");
this.setOrderDayMonth = function() {
- this.monthguess = 1;
- this.dayguess = 0;
+ this.monthGuess = 1;
+ this.dayGuess = 0;
};
this.setOrderMonthDay = function() {
- this.monthguess = 0;
- this.dayguess = 1;
+ this.monthGuess = 0;
+ this.dayGuess = 1;
};
- this.setOrderMonthDay();
- this.resetMonths = function() {
- var i, ilen, j, jlen;
- this.msets = [];
- for (i = 0, ilen = this.mstrings.length; i < ilen; i += 1) {
- this.msets.push([this.mstrings[i]]);
+ this.resetDateParserMonths = function() {
+ this.monthSets = [];
+ for (var i=0,ilen=this.monthStrings.length; i<ilen; i++) {
+ this.monthSets.push([this.monthStrings[i]]);
}
- this.mabbrevs = [];
- for (i = 0, ilen = this.msets.length; i < ilen; i += 1) {
- this.mabbrevs.push([]);
- for (j = 0, jlen = this.msets[i].length; j < jlen; j += 1) {
- this.mabbrevs[i].push(this.msets[i][0].slice(0, 3));
+ this.monthAbbrevs = [];
+ for (var i=0,ilen=this.monthSets.length; i<ilen; i++) {
+ this.monthAbbrevs.push([]);
+ for (var j=0,jlen=this.monthSets[i].length; j<jlen; j++) {
+ this.monthAbbrevs[i].push(this.monthSets[i][0].slice(0, 3));
}
}
- this.mrexes = [];
- for (i = 0, ilen = this.mabbrevs.length; i < ilen; i += 1) {
- this.mrexes.push(new RegExp("(?:" + this.mabbrevs[i].join("|") + ")"));
+ this.monthRexes = [];
+ for (var i=0,ilen=this.monthAbbrevs.length; i<ilen; i++) {
+ this.monthRexes.push(new RegExp("(?:" + this.monthAbbrevs[i].join("|") + ")"));
}
};
- this.resetMonths();
- this.addMonths = function(lst) {
- var i, ilen, j, jlen, k, klen, jkey, kkey;
+ this.addDateParserMonths = function(lst) {
if ("string" === typeof lst) {
lst = lst.split(/\s+/);
}
@@ -1053,198 +1961,259 @@ CSL.DateParser = function () {
CSL.debug("month [+season] list of "+lst.length+", expected 12 or 16. Ignoring.");
return;
}
- var othermatch = [];
- var thismatch = [];
- for (i = 0, ilen = lst.length; i < ilen; i += 1) {
- var abbrevlen = false;
+ var otherMatch = [];
+ var thisMatch = [];
+ for (var i=0,ilen=lst.length; i<ilen; i++) {
+ var abbrevLength = null;
var skip = false;
var insert = 3;
- var extend = {};
- for (j = 0, jlen = this.mabbrevs.length; j < jlen; j += 1) {
- extend[j] = {};
+ var extendedSets = {};
+ for (var j=0,jlen=this.monthAbbrevs.length; j<jlen; j++) {
+ extendedSets[j] = {};
if (j === i) {
- for (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)) {
+ for (var k=0,klen=this.monthAbbrevs[i].length; k<klen; k++) {
+ if (this.monthAbbrevs[i][k] === lst[i].slice(0, this.monthAbbrevs[i][k].length)) {
skip = true;
break;
}
}
} else {
- for (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) {
+ for (var k=0,klen=this.monthAbbrevs[j].length; k<klen; k++) {
+ abbrevLength = this.monthAbbrevs[j][k].length;
+ if (this.monthAbbrevs[j][k] === lst[i].slice(0, abbrevLength)) {
+ while (this.monthSets[j][k].slice(0, abbrevLength) === lst[i].slice(0, abbrevLength)) {
+ if (abbrevLength > lst[i].length || abbrevLength > this.monthSets[j][k].length) {
CSL.debug("unable to disambiguate month string in date parser: "+lst[i]);
break;
} else {
- abbrevlen += 1;
+ abbrevLength += 1;
}
}
- insert = abbrevlen;
- extend[j][k] = abbrevlen;
+ insert = abbrevLength;
+ extendedSets[j][k] = abbrevLength;
}
}
}
- for (jkey in extend) {
- if (extend.hasOwnProperty(jkey)) {
- for (kkey in extend[jkey]) {
- if (extend[jkey].hasOwnProperty(kkey)) {
- abbrevlen = extend[jkey][kkey];
- jkey = parseInt(jkey, 10);
- kkey = parseInt(kkey, 10);
- this.mabbrevs[jkey][kkey] = this.msets[jkey][kkey].slice(0, abbrevlen);
- }
- }
+ for (var jKey in extendedSets) {
+ for (kKey in extendedSets[jKey]) {
+ abbrevLength = extendedSets[jKey][kKey];
+ jKey = parseInt(jKey, 10);
+ kKey = parseInt(kKey, 10);
+ this.monthAbbrevs[jKey][kKey] = this.monthSets[jKey][kKey].slice(0, abbrevLength);
}
}
}
if (!skip) {
- this.msets[i].push(lst[i]);
- this.mabbrevs[i].push(lst[i].slice(0, insert));
+ this.monthSets[i].push(lst[i]);
+ this.monthAbbrevs[i].push(lst[i].slice(0, insert));
}
}
- this.mrexes = [];
- for (i = 0, ilen = this.mabbrevs.length; i < ilen; i += 1) {
- this.mrexes.push(new RegExp("(?:" + this.mabbrevs[i].join("|") + ")"));
+ this.monthRexes = [];
+ this.monthRexStrs = [];
+ for (var i=0,ilen=this.monthAbbrevs.length; i<ilen; i++) {
+ this.monthRexes.push(new RegExp("^(?:" + this.monthAbbrevs[i].join("|") + ")"));
+ this.monthRexStrs.push("^(?:" + this.monthAbbrevs[i].join("|") + ")");
+ }
+ if (this.monthAbbrevs.length === 18) {
+ for (var i=12,ilen=14; i<ilen; i++) {
+ this.monthRexes[i+4] = new RegExp("^(?:" + this.monthAbbrevs[i].join("|") + ")");
+ this.monthRexStrs[i+4] = "^(?:" + this.monthAbbrevs[i].join("|") + ")";
+ }
}
};
- 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, delim, element, mm, slst, mmpos, i, ilen, j, jlen, k, klen;
- if (txt) {
- txt = "" + txt;
- txt = txt.replace(/\s*[0-9]{2}:[0-9]{2}(?::[0-9]+)/,"");
- m = txt.match(jmd);
- if (m) {
- txt = txt.replace(/\s+/, "", "g");
- txt = txt.replace(jy, "");
- txt = txt.replace(jmd, "-");
- txt = txt.replace(jr, "/");
- txt = txt.replace(/\-\//g, "/");
- txt = txt.replace(/-$/g,"");
- slst = txt.split(jiysplitter);
- lst = [];
- mm = txt.match(jiymatcher);
- if (mm) {
- var mmx = [];
- for (pos = 0, len = mm.length; pos < len; pos += 1) {
- mmx = mmx.concat(mm[pos].match(/([^0-9]+)([0-9]+)/).slice(1));
- }
- for (pos = 0, len = slst.length; pos < len; pos += 1) {
- lst.push(slst[pos]);
- if (pos !== (len - 1)) {
- mmpos = (pos * 2);
- lst.push(mmx[mmpos]);
- lst.push(mmx[mmpos + 1]);
- }
+ this.convertDateObjectToArray = function (thedate) {
+ thedate["date-parts"] = [];
+ thedate["date-parts"].push([]);
+ var slicelen = 0;
+ for (var i=0,ilen=3; i<ilen; i++) {
+ var part = ["year", "month", "day"][i];
+ if (!thedate[part]) {
+ break;
+ }
+ slicelen += 1;
+ thedate["date-parts"][0].push(thedate[part]);
+ delete thedate[part];
+ }
+ thedate["date-parts"].push([]);
+ for (var i=0, ilen=slicelen; i<ilen; i++) {
+ part = ["year_end", "month_end", "day_end"][i];
+ 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();
+ }
+ return thedate;
+ };
+ this.convertDateObjectToString = function(thedate) {
+ var ret = [];
+ for (var i = 0, ilen = 3; i < ilen; i += 1) {
+ if (thedate[DATE_PARTS_ALL[i]]) {
+ ret.push(thedate[DATE_PARTS_ALL[i]]);
+ } else {
+ break;
+ }
+ }
+ return ret.join("-");
+ }
+ this._parseNumericDate = function (ret, delim, suff, txt) {
+ if (!suff) suff = "";
+ var lst = txt.split(delim);
+ for (var i=0, ilen=lst.length; i<ilen; i++) {
+ if (lst[i].length === 4) {
+ ret[("year" + suff)] = lst[i].replace(/^0*/, "");
+ if (!i) {
+ lst = lst.slice(1);
+ } else {
+ lst = lst.slice(0, i);
}
+ break;
+ }
+ }
+ for (var i=0,ilen=lst.length; i<ilen; i++) {
+ lst[i] = parseInt(lst[i], 10);
+ }
+ if (lst.length === 1 || (lst.length === 2 && !lst[1])) {
+ ret[("month" + suff)] = "" + lst[0];
+ } else if (lst.length === 2) {
+ if (lst[this.monthGuess] > 12) {
+ ret[("month" + suff)] = "" + lst[this.dayGuess];
+ ret[("day" + suff)] = "" + lst[this.monthGuess];
} else {
- lst = slst;
+ ret[("month" + suff)] = "" + lst[this.monthGuess];
+ ret[("day" + suff)] = "" + lst[this.dayGuess];
}
- l = lst.length;
- for (pos = 1; pos < l; pos += 3) {
- lst[pos + 1] = jiy[lst[pos]] + parseInt(lst[pos + 1], 10);
- lst[pos] = "";
+ }
+ };
+ this.parseDateToObject = function (txt) {
+ var orig = txt;
+ var slashPos = -1;
+ var dashPos = -1;
+ var lst;
+ if (txt) {
+ txt = "" + txt;
+ txt = txt.replace(/\s*[0-9]{2}:[0-9]{2}(?::[0-9]+)/,"");
+ var m = txt.match(kanjiMonthDay);
+ if (m) {
+ txt = txt.replace(/\s+/g, "");
+ txt = txt.replace(kanjiYear, "");
+ txt = txt.replace(kanjiMonthDay, "-");
+ txt = txt.replace(kanjiRange, "/");
+ txt = txt.replace(/\-\//g, "/");
+ txt = txt.replace(/-$/g,"");
+ var slst = txt.split(epochSplitter);
+ lst = [];
+ var mm = txt.match(epochMatcher);
+ if (mm) {
+ var mmx = [];
+ for (var i=0,ilen=mm.length; i<ilen; i++) {
+ mmx = mmx.concat(mm[i].match(/([^0-9]+)([0-9]+)/).slice(1));
+ }
+ for (var i=0,ilen=slst.length; i<ilen; i++) {
+ lst.push(slst[i]);
+ if (i !== (len - 1)) {
+ var mmpos = (pos * 2);
+ lst.push(mmx[mmpos]);
+ lst.push(mmx[mmpos + 1]);
+ }
+ }
+ } else {
+ lst = slst;
+ }
+ for (var i=1,ilen=lst.length; i<ilen; i+=3) {
+ lst[i + 1] = jiy[lst[i]] + parseInt(lst[i + 1], 10);
+ lst[i] = "";
+ }
+ txt = lst.join("");
+ txt = txt.replace(/\s*-\s*$/, "").replace(/\s*-\s*\//, "/");
+ txt = txt.replace(/\.\s*$/, "");
+ txt = txt.replace(/\.(?! )/, "");
+ slashPos = txt.indexOf("/");
+ dashPos = txt.indexOf("-");
}
- txt = lst.join("");
- txt = txt.replace(/\s*-\s*$/, "").replace(/\s*-\s*\//, "/");
- txt = txt.replace(/\.\s*$/, "");
- txt = txt.replace(/\.(?! )/, "");
- slash = txt.indexOf("/");
- dash = txt.indexOf("-");
}
- }
txt = txt.replace(/([A-Za-z])\./g, "$1");
- number = "";
- note = "";
- thedate = {};
+ var number = "";
+ var note = "";
+ var thedate = {};
+ var rangeDelim;
+ var dateDelim;
if (txt.slice(0, 1) === "\"" && txt.slice(-1) === "\"") {
thedate.literal = txt.slice(1, -1);
return thedate;
}
- if (slash > -1 && dash > -1) {
- slashcount = txt.split("/");
- if (slashcount.length > 3) {
- range_delim = "-";
- date_delim = "/";
- lst = txt.split(rexslashdash);
+ if (slashPos > -1 && dashPos > -1) {
+ var slashCount = txt.split("/");
+ if (slashCount.length > 3) {
+ rangeDelim = "-";
+ txt = txt.replace(/\_/g, "-");
+ dateDelim = "/";
+ lst = txt.split(rexSlashDash);
} else {
- range_delim = "/";
- date_delim = "-";
- lst = txt.split(rexdashslash);
+ rangeDelim = "/";
+ txt = txt.replace(/\_/g, "/");
+ dateDelim = "-";
+ lst = txt.split(rexDashSlash);
}
} else {
- txt = txt.replace("/", "-");
- range_delim = "-";
- date_delim = "-";
- lst = txt.split(rexdash);
- }
- ret = [];
- len = lst.length;
- for (pos = 0; pos < len; pos += 1) {
- item = lst[pos];
- m = item.match(/^\s*([\-\/]|[a-zA-Z]+|[\-~?0-9]+)\s*$/);
+ txt = txt.replace(/\//g, "-");
+ txt = txt.replace(/\_/g, "-");
+ rangeDelim = "-";
+ dateDelim = "-";
+ lst = txt.split(rexDash);
+ }
+ var ret = [];
+ for (var i=0,ilen=lst.length; i<ilen; i++) {
+ var m = lst[i].match(/^\s*([\-\/]|[^\-\/\~\?0-9]+|[\-~?0-9]+)\s*$/);
if (m) {
ret.push(m[1]);
}
}
- delim_pos = ret.indexOf(range_delim);
- delims = [];
- isrange = false;
- if (delim_pos > -1) {
- delims.push([0, delim_pos]);
- delims.push([(delim_pos + 1), ret.length]);
- isrange = true;
+ var delimPos = ret.indexOf(rangeDelim);
+ var delims = [];
+ var isRange = false;
+ if (delimPos > -1) {
+ delims.push([0, delimPos]);
+ delims.push([(delimPos + 1), ret.length]);
+ isRange = true;
} else {
delims.push([0, ret.length]);
}
- suff = "";
- for (i = 0, ilen = delims.length; i < ilen; i += 1) {
+ var suff = "";
+ for (var i=0,ilen=delims.length; i<ilen; i++) {
delim = delims[i];
date = ret.slice(delim[0], delim[1]);
- for (j = 0, jlen = date.length; j < jlen; j += 1) {
- element = date[j];
- if (element.indexOf(date_delim) > -1) {
- this.parseNumericDate(thedate, date_delim, suff, element);
+ outer:
+ for (var j=0,jlen=date.length; j<jlen; j++) {
+ var element = date[j];
+ if (element.indexOf(dateDelim) > -1) {
+ this._parseNumericDate(thedate, dateDelim, suff, element);
continue;
}
if (element.match(/[0-9]{4}/)) {
thedate[("year" + suff)] = element.replace(/^0*/, "");
continue;
}
- breakme = false;
- for (k = 0, klen = this.mrexes.length; k < klen; k += 1) {
- if (element.toLocaleLowerCase().match(this.mrexes[k])) {
+ for (var k=0,klen=this.monthRexes.length; k<klen; k++) {
+ if (element.toLocaleLowerCase().match(this.monthRexes[k])) {
thedate[("month" + suff)] = "" + (parseInt(k, 10) + 1);
- breakme = true;
- break;
- }
- if (breakme) {
- continue;
- }
- if (element.match(/^[0-9]+$/)) {
- number = parseInt(element, 10);
- }
- if (element.toLocaleLowerCase().match(/^bc/) && number) {
- thedate[("year" + suff)] = "" + (number * -1);
- number = "";
- continue;
- }
- if (element.toLocaleLowerCase().match(/^ad/) && number) {
- thedate[("year" + suff)] = "" + number;
- number = "";
- continue;
+ continue outer;
}
}
- breakme = false;
- for (k = 0, klen = seasonrexes.length; k < klen; k += 1) {
- if (element.toLocaleLowerCase().match(seasonrexes[k])) {
- thedate[("season" + suff)] = "" + (parseInt(k, 10) + 1);
- breakme = true;
- break;
- }
+ if (element.match(/^[0-9]+$/)) {
+ number = element;
}
- if (breakme) {
+ if (element.toLocaleLowerCase().match(/^bc/) && number) {
+ thedate[("year" + suff)] = "" + (number * -1);
+ number = "";
+ continue;
+ }
+ if (element.toLocaleLowerCase().match(/^ad/) && number) {
+ thedate[("year" + suff)] = "" + number;
+ number = "";
continue;
}
if (element === "~" || element === "?" || element === "c" || element.match(/^cir/)) {
@@ -1266,9 +2235,9 @@ CSL.DateParser = function () {
}
suff = "_end";
}
- if (isrange) {
- for (j = 0, jlen = CSL.DATE_PARTS_ALL.length; j < jlen; j += 1) {
- item = CSL.DATE_PARTS_ALL[j];
+ if (isRange) {
+ for (var j=0,jlen=CSL.DATE_PARTS_ALL.length; j<jlen; j++) {
+ var item = CSL.DATE_PARTS_ALL[j];
if (thedate[item] && !thedate[(item + "_end")]) {
thedate[(item + "_end")] = thedate[item];
} else if (!thedate[item] && thedate[(item + "_end")]) {
@@ -1276,76 +2245,29 @@ CSL.DateParser = function () {
}
}
}
- if (!thedate.year) {
- thedate = { "literal": txt };
+ if (!thedate.year || (thedate.year && thedate.day && !thedate.month)) {
+ thedate = { "literal": orig };
}
- if (this.use_array) {
- this.toArray(thedate);
- }
- return thedate;
- };
- this.returnAsArray = function () {
- this.use_array = true;
- };
- this.returnAsKeys = function () {
- this.use_array = false;
- };
- this.toArray = function (thedate) {
- var i, ilen, part;
- thedate["date-parts"] = [];
- thedate["date-parts"].push([]);
- var slicelen = 0;
- for (i = 0, ilen = 3; i < ilen; i += 1) {
- part = ["year", "month", "day"][i];
- if (!thedate[part]) {
- break;
- }
- slicelen += 1;
- 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]) {
- 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;
- lst = txt.split(delim);
- for (i = 0, ilen = lst.length; i < ilen; i += 1) {
- if (lst[i].length === 4) {
- ret[("year" + suff)] = lst[i].replace(/^0*/, "");
- if (!i) {
- lst = lst.slice(1);
- } else {
- lst = lst.slice(0, i);
- }
- break;
- }
- }
- for (i = 0, ilen = lst.length; i < ilen; i += 1) {
- lst[i] = parseInt(lst[i], 10);
- }
- if (lst.length === 1 || (lst.length === 2 && !lst[1])) {
- ret[("month" + suff)] = "" + lst[0];
- } else if (lst.length === 2) {
- if (lst[this.monthguess] > 12) {
- ret[("month" + suff)] = "" + lst[this.dayguess];
- ret[("day" + suff)] = "" + lst[this.monthguess];
- } else {
- ret[("month" + suff)] = "" + lst[this.monthguess];
- ret[("day" + suff)] = "" + lst[this.dayguess];
+ var parts = ["year", "month", "day", "year_end", "month_end", "day_end"];
+ for (var i=0,ilen=parts.length; i<ilen; i++) {
+ var part = parts[i];
+ if ("string" === typeof thedate[part] && thedate[part].match(/^[0-9]+$/)) {
+ thedate[part] = parseInt(thedate[part], 10);
}
}
+ return thedate;
};
+ this.parseDateToArray = function(txt) {
+ return this.convertDateObjectToArray(this.parseDateToObject(txt));
+ }
+ this.parseDateToString = function(txt) {
+ return this.convertDateObjectToString(this.parseDateToObject(txt));
+ }
+ this.parse = function(txt) {
+ return this.parseDateToObject(txt);
+ }
+ this.setOrderMonthDay();
+ this.resetDateParserMonths();
};
CSL.Engine = function (sys, style, lang, forceLang) {
var attrs, langspec, localexml, locale;
@@ -1355,10 +2277,6 @@ CSL.Engine = function (sys, style, lang, forceLang) {
if (sys.variableWrapper) {
CSL.VARIABLE_WRAPPER_PREPUNCT_REX = new RegExp('^([' + [" "].concat(CSL.SWAPPING_PUNCTUATION).join("") + ']*)(.*)');
}
- this.sys.xml = new CSL.System.Xml.Parsing();
- if ("undefined" === typeof CSL_JSON && "string" !== typeof style) {
- style = "";
- }
if (CSL.retrieveStyleModule) {
this.sys.retrieveStyleModule = CSL.retrieveStyleModule;
}
@@ -1385,45 +2303,44 @@ CSL.Engine = function (sys, style, lang, forceLang) {
this.bibliography = new CSL.Engine.Bibliography();
this.output = new CSL.Output.Queue(this);
this.dateput = new CSL.Output.Queue(this);
- this.cslXml = this.sys.xml.makeXml(style);
+ this.cslXml = CSL.setupXml(style);
if (this.opt.development_extensions.csl_reverse_lookup_support || this.sys.csl_reverse_lookup_support) {
this.build.cslNodeId = 0;
this.setCslNodeIds = function(myxml, nodename) {
- var children = this.sys.xml.children(myxml);
- this.sys.xml.setAttribute(myxml, 'cslid', this.build.cslNodeId);
+ var children = this.cslXml.children(myxml);
+ this.cslXml.setAttribute(myxml, 'cslid', this.build.cslNodeId);
this.opt.nodenames.push(nodename);
this.build.cslNodeId += 1;
- for (var i = 0, ilen = this.sys.xml.numberofnodes(children); i < ilen; i += 1) {
- nodename = this.sys.xml.nodename(children[i]);
+ for (var i = 0, ilen = this.cslXml.numberofnodes(children); i < ilen; i += 1) {
+ nodename = this.cslXml.nodename(children[i]);
if (nodename) {
this.setCslNodeIds(children[i], nodename);
}
}
};
- this.setCslNodeIds(this.cslXml, "style");
+ this.setCslNodeIds(this.cslXml.dataObj, "style");
}
- this.sys.xml.addMissingNameNodes(this.cslXml);
- this.sys.xml.addInstitutionNodes(this.cslXml);
- this.sys.xml.insertPublisherAndPlace(this.cslXml);
- this.sys.xml.flagDateMacros(this.cslXml);
- attrs = this.sys.xml.attributes(this.cslXml);
+ this.cslXml.addMissingNameNodes(this.cslXml.dataObj);
+ this.cslXml.addInstitutionNodes(this.cslXml.dataObj);
+ this.cslXml.insertPublisherAndPlace(this.cslXml.dataObj);
+ this.cslXml.flagDateMacros(this.cslXml.dataObj);
+ attrs = this.cslXml.attributes(this.cslXml.dataObj);
if ("undefined" === typeof attrs["@sort-separator"]) {
- this.sys.xml.setAttribute(this.cslXml, "sort-separator", ", ");
+ this.cslXml.setAttribute(this.cslXml.dataObj, "sort-separator", ", ");
}
this.opt["initialize-with-hyphen"] = true;
this.setStyleAttributes();
- this.opt.xclass = sys.xml.getAttributeValue(this.cslXml, "class");
+ this.opt.xclass = this.cslXml.getAttributeValue(this.cslXml.dataObj, "class");
this.opt.class = this.opt.xclass;
- this.opt.styleID = this.sys.xml.getStyleId(this.cslXml);
+ this.opt.styleID = this.cslXml.getStyleId(this.cslXml.dataObj);
if (CSL.setSuppressedJurisdictions) {
CSL.setSuppressedJurisdictions(this.opt.styleID, this.opt.suppressedJurisdictions);
}
- this.opt.styleName = this.sys.xml.getStyleId(this.cslXml, true);
+ this.opt.styleName = this.cslXml.getStyleId(this.cslXml.dataObj, true);
if (this.opt.version.slice(0,4) === "1.1m") {
this.opt.development_extensions.static_statute_locator = true;
this.opt.development_extensions.handle_parallel_articles = true;
this.opt.development_extensions.main_title_from_short_title = true;
- this.opt.development_extensions.strict_page_numbers = true;
this.opt.development_extensions.rtl_support = true;
this.opt.development_extensions.expect_and_symbol_form = true;
this.opt.development_extensions.require_explicit_legal_case_title_short = true;
@@ -1468,16 +2385,16 @@ CSL.Engine = function (sys, style, lang, forceLang) {
this.registry = new CSL.Registry(this);
this.macros = {};
this.build.area = "citation";
- var area_nodes = this.sys.xml.getNodesByName(this.cslXml, this.build.area);
+ var area_nodes = this.cslXml.getNodesByName(this.cslXml.dataObj, this.build.area);
this.buildTokenLists(area_nodes, this[this.build.area].tokens);
this.build.area = "bibliography";
- var area_nodes = this.sys.xml.getNodesByName(this.cslXml, this.build.area);
+ var area_nodes = this.cslXml.getNodesByName(this.cslXml.dataObj, this.build.area);
this.buildTokenLists(area_nodes, this[this.build.area].tokens);
this.juris = {};
this.configureTokenLists();
this.disambiguate = new CSL.Disambiguation(this);
this.splice_delimiter = false;
- this.fun.dateparser = new CSL.DateParser();
+ this.fun.dateparser = CSL.DateParser;
this.fun.flipflopper = new CSL.Util.FlipFlopper(this);
this.setCloseQuotesArray();
this.fun.ordinalizer.init(this);
@@ -1507,17 +2424,17 @@ CSL.makeBuilder = function (me, target) {
};
function buildStyle (node) {
var starttag, origparent;
- if (me.sys.xml.numberofnodes(me.sys.xml.children(node))) {
+ if (me.cslXml.numberofnodes(me.cslXml.children(node))) {
origparent = node;
enterFunc(origparent);
- for (var i=0;i<me.sys.xml.numberofnodes(me.sys.xml.children(origparent));i+=1) {
- node = me.sys.xml.children(origparent)[i];
- if (me.sys.xml.nodename(node) === null) {
+ for (var i=0;i<me.cslXml.numberofnodes(me.cslXml.children(origparent));i+=1) {
+ node = me.cslXml.children(origparent)[i];
+ if (me.cslXml.nodename(node) === null) {
continue;
}
- if (me.sys.xml.nodename(node) === "date") {
+ if (me.cslXml.nodename(node) === "date") {
CSL.Util.fixDateNode.call(me, origparent, i, node)
- node = me.sys.xml.children(origparent)[i];
+ node = me.cslXml.children(origparent)[i];
}
buildStyle(node, enterFunc, leaveFunc, singletonFunc);
}
@@ -1529,7 +2446,7 @@ CSL.makeBuilder = function (me, target) {
return buildStyle;
};
CSL.Engine.prototype.buildTokenLists = function (area_nodes, target) {
- if (!this.sys.xml.getNodeValue(area_nodes)) return;
+ if (!this.cslXml.getNodeValue(area_nodes)) return;
var builder = CSL.makeBuilder(this, target);
var mynode;
if ("undefined" === typeof area_nodes.length) {
@@ -1541,16 +2458,9 @@ CSL.Engine.prototype.buildTokenLists = function (area_nodes, target) {
};
CSL.Engine.prototype.setStyleAttributes = function () {
var dummy, attr, key, attributes, attrname;
- dummy = {};
- var cslXml = this.cslXml;
- var tagName = this.cslXml.tagName ? ("" + this.cslXml.tagName).toLowerCase() : "";
- if (tagName !== 'style' && tagName !== 'cslstyle') {
- if (this.cslXml.getElementsByTagName) {
- var cslXml = this.cslXml.getElementsByTagName('style')[0];
- }
- }
- dummy.name = this.sys.xml.nodename(cslXml);
- attributes = this.sys.xml.attributes(cslXml);
+ var dummy = {};
+ dummy.name = this.cslXml.nodename(this.cslXml.dataObj);
+ attributes = this.cslXml.attributes(this.cslXml.dataObj);
for (attrname in attributes) {
if (attributes.hasOwnProperty(attrname)) {
CSL.Attributes[attrname].call(dummy, this, attributes[attrname]);
@@ -1798,20 +2708,25 @@ CSL.Engine.prototype.retrieveItem = function (id) {
if (!Item[mm[1]] && CSL.DATE_VARIABLES.indexOf(mm[1]) > -1) {
Item[mm[1]] = {raw:mm[2]};
} else if (!Item[mm[1]] && CSL.NAME_VARIABLES.indexOf(mm[1]) > -1) {
- if (!Item[mm[1]]) {
- Item[mm[1]] = [];
+ if (!names[mm[1]]) {
+ names[mm[1]] = [];
}
var lst = mm[2].split(/\s*\|\|\s*/);
if (lst.length === 1) {
- Item[mm[1]].push({family:lst[0],isInstitution:true});
+ names[mm[1]].push({family:lst[0],isInstitution:true});
} else if (lst.length === 2) {
- Item[mm[1]].push({family:lst[0],given:lst[1]});
+ var name = {family:lst[0],given:lst[1]};
+ CSL.parseParticles(name);
+ names[mm[1]].push(name);
}
} else if (!Item[mm[1]] || mm[1] === "type") {
Item[mm[1]] = mm[2].replace(/^\s+/, "").replace(/\s+$/, "");
}
Item.note.replace(CSL.NOTE_FIELD_REGEXP, "");
}
+ for (var key in names) {
+ Item[key] = names[key];
+ }
}
}
for (var i = 1, ilen = CSL.DATE_VARIABLES.length; i < ilen; i += 1) {
@@ -1819,7 +2734,7 @@ CSL.Engine.prototype.retrieveItem = function (id) {
if (dateobj) {
if (this.opt.development_extensions.raw_date_parsing) {
if (dateobj.raw) {
- dateobj = this.fun.dateparser.parse(dateobj.raw);
+ dateobj = this.fun.dateparser.parseDateToObject(dateobj.raw);
}
}
Item[CSL.DATE_VARIABLES[i]] = this.dateParseArray(dateobj);
@@ -1852,25 +2767,29 @@ CSL.Engine.prototype.retrieveItem = function (id) {
Item["title-short"] = Item.shortTitle;
}
if (this.opt.development_extensions.main_title_from_short_title) {
- Item["title-main"] = Item.title;
- Item["title-sub"] = false;
- if (Item.title && Item['title-short']) {
- var shortTitle = Item['title-short'];
- offset = shortTitle.length;
- if (Item.title.slice(0,offset) === shortTitle && Item.title.slice(offset).match(/^\s*:/)) {
- Item["title-main"] = Item.title.slice(0,offset).replace(/\s+$/,"");
- Item["title-sub"] = Item.title.slice(offset).replace(/^\s*:\s*/,"");
- if (this.opt.development_extensions.uppercase_subtitles && Item["title-sub"]) {
- var subtitle = Item["title-sub"]
- for (var i=0,ilen=subtitle.length;i<ilen;i++) {
- if (subtitle.charAt(i).toLowerCase() !== subtitle.charAt(i).toUpperCase()) {
- Item["title-sub"] = subtitle.slice(0,i) + subtitle.charAt(i).toUpperCase() + subtitle.slice(i+1);
- break
+ var segments = ["", "container-"];
+ for (var i=0,ilen=segments.length;i<ilen;i++) {
+ var seg = segments[i];
+ Item[seg + "title-main"] = Item[seg + "title"];
+ Item[seg + "title-sub"] = false;
+ if (Item[seg + "title"] && Item[seg + "title-short"]) {
+ var shortTitle = Item[seg + "title-short"];
+ offset = shortTitle.length;
+ if (Item[seg + "title"].slice(0,offset) === shortTitle && Item[seg + "title"].slice(offset).match(/^\s*:/)) {
+ Item[seg + "title-main"] = Item[seg + "title"].slice(0,offset).replace(/\s+$/,"");
+ Item[seg + "title-sub"] = Item[seg + "title"].slice(offset).replace(/^\s*:\s*/,"");
+ if (this.opt.development_extensions.uppercase_subtitles && Item[seg + "title-sub"]) {
+ var subtitle = Item[seg + "title-sub"]
+ for (var j=0,jlen=subtitle.length;j<jlen;j++) {
+ if (subtitle.charAt(j).toLowerCase() !== subtitle.charAt(j).toUpperCase()) {
+ Item[seg + "title-sub"] = subtitle.slice(0,j) + subtitle.charAt(j).toUpperCase() + subtitle.slice(j+1);
+ break
+ }
}
}
+ var mainPlusJoinOffset = offset + Item[seg + "title"].length - Item[seg + "title-main"].length - Item[seg + "title-sub"].length;
+ Item[seg + "title"] = Item[seg + "title"].slice(0,mainPlusJoinOffset) + Item[seg + "title-sub"];
}
- var mainPlusJoinOffset = offset + Item.title.length - Item["title-main"].length - Item["title-sub"].length;
- Item.title = Item.title.slice(0,mainPlusJoinOffset) + Item["title-sub"];
}
}
}
@@ -1892,7 +2811,9 @@ CSL.Engine.prototype.retrieveItem = function (id) {
}
}
}
- Item["container-title-short"] = Item.journalAbbreviation;
+ if (!Item["container-title-short"]) {
+ Item["container-title-short"] = Item.journalAbbreviation;
+ }
if (Item["container-title"] && this.sys.getAbbreviation) {
var jurisdiction = this.transform.loadAbbreviation(Item.jurisdiction, "container-title", Item["container-title"]);
if (this.transform.abbrevs[jurisdiction]["container-title"]) {
@@ -1928,89 +2849,54 @@ CSL.Engine.prototype.remapSectionVariable = function (inputList) {
for (var i = 0, ilen = inputList.length; i < ilen; i += 1) {
var Item = inputList[i][0];
var item = inputList[i][1];
- var section_label_count = 0;
- var later_label = false;
- var value = false;
if (["bill","gazette","legislation","regulation","treaty"].indexOf(Item.type) > -1) {
- item.force_pluralism = 0;
- if (!item.label) {
- item.label = "page"
- }
- var loci = ["section","","",""];
- var split;
- if (this.opt.development_extensions.static_statute_locator && Item.section) {
- splt = Item.section.replace(/^\s+/,"").replace(/\s+$/, "").split(/\s+/);
- if (CSL.STATUTE_SUBDIV_STRINGS[splt[0]]) {
- loci[0] = " " + splt[0] + " ";
- loci[1] = splt.slice(1).join(" ");
- } else {
- loci[0] = " sec. ";
- loci[1] = splt.slice(0).join(" ");
- }
- } else {
- if (this.opt.development_extensions.clobber_locator_if_no_statute_section) {
- item.locator = undefined;
- item.label = undefined;
- }
- }
if (item.locator) {
- var splt = item.locator.replace(/^\s+/,"").replace(/\s+$/, "").split(/\s+/);
- if (CSL.STATUTE_SUBDIV_STRINGS[splt[0]]) {
- loci[2] = " " + splt[0] + " ";
- loci[3] = splt.slice(1).join(" ");
- } else if (item.label) {
- loci[2] = " " + CSL.STATUTE_SUBDIV_STRINGS_REVERSE[item.label] + " ";
- loci[3] = splt.slice(0).join(" ");
- } else {
- loci[3] = splt.join(" ")
- }
- if (loci[3] && loci[3].slice(0,1) === "&") {
- loci[3] = " " + loci[3];
- }
- }
- if (!loci[2]) {
- loci[2] = loci[0];
- }
- if (loci[3]) {
- if (loci[3].match(/^[^0-9a-zA-Z]/)) {
- var loclst = loci[3].split(/\s+/);
- if (loci[0] === loci[2] && loclst[1] && !CSL.STATUTE_SUBDIV_STRINGS[loclst[1].replace(/\s+/, "").replace(/\s+/, "")]) {
- item.force_pluralism = 1;
+ item.locator = item.locator.trim();
+ var m = item.locator.match(CSL.STATUTE_SUBDIV_PLAIN_REGEX);
+ if (!m) {
+ if (item.label) {
+ item.locator = CSL.STATUTE_SUBDIV_STRINGS_REVERSE[item.label] + " " + item.locator;
+ } else {
+ item.locator = "p. " + item.locator;
}
- loci[2] = "";
}
- } else {
- loci[2] = "";
}
- if (!loci[1]) {
- loci[0] = "";
+ var sectionMasterLabel = null;
+ if (Item.section) {
+ Item.section = Item.section.trim();
+ var m = Item.section.match(CSL.STATUTE_SUBDIV_PLAIN_REGEX);
+ if (!m) {
+ Item.section = "sec. " + Item.section;
+ sectionMasterLabel = "sec.";
+ } else {
+ sectionMasterLabel = m[0].trim();
+ }
}
- var value = loci.join("");
- value = value.replace(/^\s+/,"").replace(/\s+$/, "");
- if (value) {
- splt = value.split(/\s+/);
- if (CSL.STATUTE_SUBDIV_STRINGS[splt[0]]) {
- var has_other = false;
- for (var j = splt.length - 2; j > 0; j += -2) {
- if (splt[j] === splt[0]) {
- item.force_pluralism = 1;
- splt = splt.slice(0,j).concat(splt.slice(j + 1));
+ if (Item.section) {
+ if (!item.locator) {
+ item.locator = Item.section;
+ } else {
+ var m = item.locator.match(/^([^ ]*)\s*(.*)/);
+ var space = " ";
+ if (m) {
+ if (m[1] === "p." && sectionMasterLabel !== "p.") {
+ item.locator = m[2];
}
+ if (["[", "(", ".", ",", ";", ":", "?"].indexOf(item.locator.slice(0, 1)) > -1) {
+ space = "";
+ }
+ } else {
+ space = "";
}
- item.label = CSL.STATUTE_SUBDIV_STRINGS[splt[0]];
- item.locator = splt.slice(1).join(" ");
- if (item.force_pluralism === 0) {
- delete item.force_pluralism;
- }
- } else {
- item.locator = splt.slice(0).join(" ");
+ item.locator = Item.section + space + item.locator;
}
}
+ item.label = "";
}
}
}
CSL.Engine.prototype.setNumberLabels = function (Item) {
- if (Item.number
+ if (Item.number
&& ["bill", "gazette", "legislation","regulation","treaty"].indexOf(Item.type) > -1
&& this.opt.development_extensions.static_statute_locator
&& !this.tmp.shadow_numbers["number"]) {
@@ -2020,7 +2906,7 @@ CSL.Engine.prototype.setNumberLabels = function (Item) {
this.tmp.shadow_numbers["number"].numeric = false;
this.tmp.shadow_numbers["number"].label = false;
var value = "" + Item.number;
- value = value.replace("\\", "", "g");
+ value = value.split("\\").join("");
var firstword = value.split(/\s+/)[0];
var firstlabel = CSL.STATUTE_SUBDIV_STRINGS[firstword];
if (firstlabel) {
@@ -2472,13 +3358,10 @@ CSL.Output.Queue.prototype.openLevel = function (token, ephemeral) {
}
blob = new CSL.Blob(undefined, this.formats.value()[token], token);
}
- if (this.nestedBraces) {
- blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
- blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
- blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
- blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
- }
curr = this.current.value();
+ if (!this.state.tmp.just_looking && this.checkNestedBrace) {
+ blob.strings.prefix = this.checkNestedBrace.update(blob.strings.prefix);
+ }
curr.push(blob);
this.current.push(blob);
};
@@ -2486,7 +3369,10 @@ CSL.Output.Queue.prototype.closeLevel = function (name) {
if (name && name !== this.current.value().levelname) {
CSL.error("Level mismatch error: wanted " + name + " but found " + this.current.value().levelname);
}
- this.current.pop();
+ var blob = this.current.pop();
+ if (!this.state.tmp.just_looking && this.checkNestedBrace) {
+ blob.strings.suffix = this.checkNestedBrace.update(blob.strings.suffix);
+ }
};
CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePredecessor, noStripPeriods) {
var token, blob, curr;
@@ -2544,12 +3430,6 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr
}
}
blob = new CSL.Blob(str, token);
- if (this.nestedBraces) {
- blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
- blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
- blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
- blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
- }
curr = this.current.value();
if ("undefined" === typeof curr && this.current.mystack.length === 0) {
this.current.mystack.push([]);
@@ -2636,7 +3516,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
}
}
if (b && b.length) {
- b = txt_esc(blobjr.strings.prefix, state.tmp.nestedBraces) + b + txt_esc(blobjr.strings.suffix, state.tmp.nestedBraces);
+ b = txt_esc(blobjr.strings.prefix) + b + txt_esc(blobjr.strings.suffix);
if ((state.opt.development_extensions.csl_reverse_lookup_support || state.sys.csl_reverse_lookup_support) && !state.tmp.suppress_decorations) {
for (j = 0, jlen = blobjr.decorations.length; j < jlen; j += 1) {
params = blobjr.decorations[j];
@@ -2679,10 +3559,20 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
}
}
}
- if (blob && (blob.decorations.length || blob.strings.suffix || blob.strings.prefix)) {
+ if (blob && (blob.decorations.length || blob.strings.suffix)) {
span_split = ret.length;
+ } else if (blob && blob.strings.prefix) {
+ for (var i=0,ilen=ret.length;i<ilen;i++) {
+ if ("undefined" !== typeof ret[i].num) {
+ span_split = i;
+ if (i === 0) {
+ ret[i].strings.prefix = blob.strings.prefix + ret[i].strings.prefix;
+ }
+ break;
+ }
+ }
}
- var blobs_start = state.output.renderBlobs(ret.slice(0, span_split), blob_delimiter, true, blob);
+ var blobs_start = state.output.renderBlobs(ret.slice(0, span_split), blob_delimiter, false, blob);
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) {
@@ -2702,7 +3592,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
use_suffix = blob.strings.suffix;
if (b && b.length) {
use_prefix = blob.strings.prefix;
- b = txt_esc(use_prefix, state.tmp.nestedBraces) + b + txt_esc(use_suffix, state.tmp.nestedBraces);
+ b = txt_esc(use_prefix) + b + txt_esc(use_suffix);
if (state.tmp.count_offset_characters) {
state.tmp.offset_characters += (use_prefix.length + use_suffix.length);
}
@@ -2733,7 +3623,7 @@ 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, undefined, true);
+ ret = state.output.renderBlobs(ret, undefined, false);
}
} else if ("boolean" === typeof blob) {
ret = state.output.renderBlobs(ret, undefined, true);
@@ -2772,7 +3662,9 @@ CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, in_cite, parent
var start = true;
for (pos = 0; pos < len; pos += 1) {
if (blobs[pos].checkNext) {
- blobs[pos].checkNext(blobs[(pos + 1)],start);
+ blobs[pos].checkNext(blobs[pos + 1],start);
+ start = false;
+ } else if (blobs[pos+1] && blobs[pos+1].splice_prefix) {
start = false;
} else {
start = true;
@@ -2781,11 +3673,11 @@ CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, in_cite, parent
var doit = true;
for (pos = blobs.length - 1; pos > 0; pos += -1) {
if (blobs[pos].checkLast) {
- if (doit && blobs[pos].checkLast(blobs[pos - 1])) {
- doit = false;
- }
+ if (doit && blobs[pos].checkLast(blobs[pos - 1])) {
+ doit = false;
+ }
} else {
- doit = true;
+ doit = true;
}
}
len = blobs.length;
@@ -2800,8 +3692,18 @@ CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, in_cite, parent
if (state.tmp.count_offset_characters) {
state.tmp.offset_characters += (use_delim.length);
}
+ } else if (in_cite) {
+ if (ret) {
+ ret = [ret, blob];
+ } else {
+ ret = [blob];
+ }
} else if (blob.status !== CSL.SUPPRESS) {
- str = blob.formatter.format(blob.num, blob.gender);
+ if (blob.particle) {
+ str = blob.particle + blob.num;
+ } else {
+ str = blob.formatter.format(blob.num, blob.gender);
+ }
var strlen = str.replace(/<[^>]*>/g, "").length;
this.append(str, "empty", true);
var str_blob = this.pop();
@@ -2831,7 +3733,11 @@ CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, in_cite, parent
} else if (blob.status === CSL.SUCCESSOR) {
addme = txt_esc(blob.successor_prefix);
} else if (blob.status === CSL.START) {
- addme = "";
+ if (pos > 0) {
+ addme = txt_esc(blob.splice_prefix);
+ } else {
+ addme = "";
+ }
} else if (blob.status === CSL.SEEN) {
addme = txt_esc(blob.splice_prefix);
}
@@ -2980,9 +3886,10 @@ CSL.Output.Queue.adjust = function (punctInQuote) {
}
}
}
- if ("object" !== typeof blob.blobs) return false;
- if (blobHasDescendantQuotes(blob.blobs[blob.blobs.length-1])) return true;
- return false;
+ if ("object" !== typeof blob.blobs) {
+ return false
+ };
+ return blobHasDescendantQuotes(blob.blobs[blob.blobs.length-1]);
}
function blobHasDescendantMergingPunctuation(parentChar,blob) {
var childChar = blob.strings.suffix.slice(-1);
@@ -3166,7 +4073,7 @@ CSL.Output.Queue.adjust = function (punctInQuote) {
break;
}
}
- if (!someChildrenAreNumbers) {
+ if (true || !someChildrenAreNumbers) {
if (parentStrings.delimiter && PUNCT[parentStrings.delimiter.slice(0, 1)]) {
var delimChar = parentStrings.delimiter.slice(0, 1);
for (var i=parent.blobs.length-2;i>-1;i--) {
@@ -3446,7 +4353,6 @@ CSL.Engine.Opt = function () {
this.development_extensions.normalize_lang_keys_to_lowercase = false;
this.development_extensions.strict_text_case_locales = false;
this.development_extensions.rtl_support = false;
- this.development_extensions.strict_page_numbers = false;
this.development_extensions.expect_and_symbol_form = false;
this.development_extensions.require_explicit_legal_case_title_short = false;
this.development_extensions.spoof_institutional_affiliations = false;
@@ -3655,7 +4561,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
raw_locator = raw_locator.slice(idx + 1);
m = raw_locator.match(/^([0-9]{4}-[0-9]{2}-[0-9]{2}).*/);
if (m) {
- item["locator-date"] = this.fun.dateparser.parse(m[1]);
+ item["locator-date"] = this.fun.dateparser.parseDateToObject(m[1]);
raw_locator = raw_locator.slice(m[1].length);
}
item["locator-extra"] = raw_locator.replace(/^\s+/, "").replace(/\s+$/, "");
@@ -3670,8 +4576,11 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
if (item.locator && ["bill","gazette","legislation","regulation","treaty"].indexOf(Item.type) === -1 && (!item.label || item.label === 'page')) {
m = CSL.LOCATOR_LABELS_REGEXP.exec(item.locator);
if (m) {
- item.label = CSL.LOCATOR_LABELS_MAP[m[2]];
- item.locator = m[3];
+ var tryLabel = CSL.LOCATOR_LABELS_MAP[m[2]];
+ if (this.getTerm(tryLabel)) {
+ item.label = tryLabel;
+ item.locator = m[3];
+ }
}
}
}
@@ -4076,8 +4985,11 @@ CSL.Engine.prototype.makeCitationCluster = function (rawList) {
if (item.locator && ["bill","gazette","legislation","regulation","treaty"].indexOf(Item.type) === -1 && (!item.label || item.label === 'page')) {
var m = CSL.LOCATOR_LABELS_REGEXP.exec(item.locator);
if (m) {
- item.label = CSL.LOCATOR_LABELS_MAP[m[2]];
- item.locator = m[3];
+ var tryLabel = CSL.LOCATOR_LABELS_MAP[m[2]];
+ if (this.getTerm(tryLabel)) {
+ item.label = tryLabel;
+ item.locator = m[3];
+ }
}
}
}
@@ -4100,7 +5012,7 @@ CSL.Engine.prototype.makeCitationCluster = function (rawList) {
str = CSL.getCitationCluster.call(this, inputList);
return str;
};
-CSL.getAmbiguousCite = function (Item, disambig, visualForm) {
+CSL.getAmbiguousCite = function (Item, disambig, visualForm, item) {
var use_parallels, ret;
var oldTermSiblingLayer = this.tmp.group_context.value().slice();
if (disambig) {
@@ -4109,8 +5021,13 @@ CSL.getAmbiguousCite = function (Item, disambig, visualForm) {
this.tmp.disambig_request = false;
}
var itemSupp = {
- position: 1
+ position: 1,
+ "near-note": true
};
+ if (item) {
+ itemSupp.locator = item.locator;
+ itemSupp.label = item.label;
+ }
if (this.registry.registry[Item.id]
&& this.registry.citationreg.citationsByItemId
&& this.registry.citationreg.citationsByItemId[Item.id]
@@ -4124,7 +5041,7 @@ CSL.getAmbiguousCite = function (Item, disambig, visualForm) {
this.parallel.use_parallels = (this.parallel.use_parallels === true || this.parallel.use_parallels === null) ? null : false;
this.tmp.suppress_decorations = true;
this.tmp.just_looking = true;
- CSL.getCite.call(this, Item, itemSupp);
+ CSL.getCite.call(this, Item, itemSupp, null, false);
for (var i=0,ilen=this.output.queue.length;i<ilen;i+=1) {
CSL.Output.Queue.purgeEmptyBlobs(this.output.queue[i]);
}
@@ -4146,25 +5063,22 @@ CSL.getAmbiguousCite = function (Item, disambig, visualForm) {
CSL.getSpliceDelimiter = function (last_collapsed, pos) {
if (last_collapsed && ! this.tmp.have_collapsed && "string" === typeof this.citation.opt["after-collapse-delimiter"]) {
this.tmp.splice_delimiter = this.citation.opt["after-collapse-delimiter"];
- } else if (this.tmp.have_collapsed && this.opt.xclass === "in-text" && this.opt.update_mode !== CSL.NUMERIC) {
- this.tmp.splice_delimiter = ", ";
} else if (this.tmp.use_cite_group_delimiter) {
this.tmp.splice_delimiter = this.citation.opt.cite_group_delimiter;
+ } else if (this.tmp.have_collapsed && this.opt.xclass === "in-text" && this.opt.update_mode !== CSL.NUMERIC) {
+ this.tmp.splice_delimiter = ", ";
} else if (this.tmp.cite_locales[pos - 1]) {
var alt_affixes = this.tmp.cite_affixes[this.tmp.area][this.tmp.cite_locales[pos - 1]];
if (alt_affixes && alt_affixes.delimiter) {
this.tmp.splice_delimiter = alt_affixes.delimiter;
}
}
- if (!this.tmp.splice_delimiter) {
- this.tmp.splice_delimiter = "";
- }
return this.tmp.splice_delimiter;
};
CSL.getCitationCluster = function (inputList, citationID) {
var result, objects, myparams, len, pos, item, last_collapsed, params, empties, composite, compie, myblobs, Item, llen, ppos, obj, preceding_item, txt_esc, error_object;
+ inputList = inputList ? inputList : [];
this.tmp.last_primary_names_string = false;
- this.tmp.nestedBraces = false;
txt_esc = CSL.getSafeEscape(this);
this.tmp.area = "citation";
result = "";
@@ -4174,6 +5088,8 @@ CSL.getCitationCluster = function (inputList, citationID) {
this.tmp.last_years_used = [];
this.tmp.backref_index = [];
this.tmp.cite_locales = [];
+ this.output.checkNestedBrace = new CSL.checkNestedBrace(this);
+ var use_layout_prefix = this.output.checkNestedBrace.update(this.citation.opt.layout_prefix);
var suppressTrailingPunctuation = false;
if (this.opt.xclass === "note" && this.citation.opt.suppressTrailingPunctuation) {
suppressTrailingPunctuation = true;
@@ -4235,11 +5151,19 @@ CSL.getCitationCluster = function (inputList, citationID) {
item = inputList[pos][1];
last_collapsed = this.tmp.have_collapsed;
params = {};
+ this.tmp.shadow_numbers = {};
+ if (!this.tmp.just_looking && this.opt.hasPlaceholderTerm) {
+ var output = this.output;
+ this.output = new CSL.Output.Queue(this);
+ this.output.adjust = new CSL.Output.Queue.adjust();
+ CSL.getAmbiguousCite.call(this, Item, null, false, item);
+ this.output = output;
+ }
if (pos > 0) {
- CSL.getCite.call(this, Item, item, "" + inputList[(pos - 1)][0].id);
+ CSL.getCite.call(this, Item, item, "" + inputList[(pos - 1)][0].id, true);
} else {
this.tmp.term_predecessor = false;
- CSL.getCite.call(this, Item, item);
+ CSL.getCite.call(this, Item, item, null, true);
}
if (!this.tmp.cite_renders_content) {
error_object = {
@@ -4261,11 +5185,11 @@ CSL.getCitationCluster = function (inputList, citationID) {
}
if (pos > 0) {
preceding_item = inputList[pos - 1][1];
- var precedingEndsInPeriod = preceding_item.suffix && preceding_item.suffix.slice(-1) === ".";
- var currentStartsWithPeriod = !preceding_item.suffix && item.prefix && item.prefix.slice(0, 1) === ".";
- if (precedingEndsInPeriod || currentStartsWithPeriod) {
+ var precedingEndsInPeriodOrComma = preceding_item.suffix && [".", ","].indexOf(preceding_item.suffix.slice(-1)) > -1;
+ var currentStartsWithPeriodOrComma = !preceding_item.suffix && item.prefix && [".", ","].indexOf(item.prefix.slice(0, 1)) > -1;
+ if (precedingEndsInPeriodOrComma || currentStartsWithPeriodOrComma) {
var spaceidx = params.splice_delimiter.indexOf(" ");
- if (spaceidx > -1 && !currentStartsWithPeriod) {
+ if (spaceidx > -1 && !currentStartsWithPeriodOrComma) {
params.splice_delimiter = params.splice_delimiter.slice(spaceidx);
} else {
params.splice_delimiter = "";
@@ -4301,19 +5225,19 @@ CSL.getCitationCluster = function (inputList, citationID) {
if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(delimiter.slice(0, 1)) > -1) {
delimiter = delimiter.slice(0, 1);
}
- var use_layout_suffix = suffix;
+ suffix = this.output.checkNestedBrace.update(suffix);
for (var i=0,ilen=this.output.queue.length;i<ilen;i+=1) {
CSL.Output.Queue.purgeEmptyBlobs(this.output.queue[i]);
}
if (!this.tmp.suppress_decorations && this.output.queue.length) {
if (!(this.opt.development_extensions.apply_citation_wrapper
&& this.sys.wrapCitationEntry
- && !this.tmp.just_looking
+ && !this.tmp.just_looking
&& this.tmp.area === "citation")) {
if (!suppressTrailingPunctuation) {
- this.output.queue[this.output.queue.length - 1].strings.suffix = use_layout_suffix;
+ this.output.queue[this.output.queue.length - 1].strings.suffix = suffix;
}
- this.output.queue[0].strings.prefix = this.citation.opt.layout_prefix;
+ this.output.queue[0].strings.prefix = use_layout_prefix;
}
}
if (this.opt.development_extensions.clean_up_csl_flaws) {
@@ -4325,6 +5249,7 @@ CSL.getCitationCluster = function (inputList, citationID) {
}
}
for (pos = 0, len = myblobs.length; pos < len; pos += 1) {
+ var buffer = [];
this.output.queue = [myblobs[pos]];
this.tmp.suppress_decorations = myparams[pos].suppress_decorations;
this.tmp.splice_delimiter = myparams[pos].splice_delimiter;
@@ -4348,45 +5273,64 @@ CSL.getCitationCluster = function (inputList, citationID) {
composite.push(preStr + errStr + sufStr);
}
}
- if (objects.length && "string" === typeof composite[0]) {
+ if (buffer.length && "string" === typeof composite[0]) {
composite.reverse();
var tmpstr = composite.pop();
if (tmpstr && tmpstr.slice(0, 1) === ",") {
- objects.push(tmpstr);
- } else if ("string" == typeof objects.slice(-1)[0] && objects.slice(-1)[0].slice(-1) === ",") {
- objects.push(" " + tmpstr);
+ buffer.push(tmpstr);
+ } else if ("string" == typeof buffer.slice(-1)[0] && buffer.slice(-1)[0].slice(-1) === ",") {
+ buffer.push(" " + tmpstr);
} else if (tmpstr) {
- objects.push(txt_esc(this.tmp.splice_delimiter) + tmpstr);
+ buffer.push(txt_esc(this.tmp.splice_delimiter) + tmpstr);
}
} else {
composite.reverse();
compie = composite.pop();
if ("undefined" !== typeof compie) {
- if (objects.length && "string" === typeof objects[objects.length - 1]) {
- objects[objects.length - 1] += compie.successor_prefix;
+ if (buffer.length && "string" === typeof buffer[buffer.length - 1]) {
+ buffer[buffer.length - 1] += compie.successor_prefix;
}
- objects.push(compie);
+ buffer.push(compie);
}
}
llen = composite.length;
for (ppos = 0; ppos < llen; ppos += 1) {
obj = composite[ppos];
if ("string" === typeof obj) {
- objects.push(txt_esc(this.tmp.splice_delimiter) + obj);
+ buffer.push(txt_esc(this.tmp.splice_delimiter) + obj);
continue;
}
compie = composite.pop();
if ("undefined" !== typeof compie) {
- objects.push(compie);
+ buffer.push(compie);
}
}
- if (objects.length === 0 && !inputList[pos][1]["suppress-author"]) {
+ if (buffer.length === 0 && !inputList[pos][1]["suppress-author"]) {
empties += 1;
}
+ if (buffer.length > 1 && typeof buffer[0] !== "string") {
+ buffer = [this.output.renderBlobs(buffer)];
+ }
+ if (buffer.length) {
+ if ("string" === typeof buffer[0]) {
+ if (pos > 0) {
+ if (((myblobs.length-1) > pos && myparams[pos+1].have_collapsed) && !myparams[pos].have_collapsed) {
+ this.tmp.splice_delimiter = myparams[pos-1].splice_delimiter;
+ }
+ buffer[0] = txt_esc(this.tmp.splice_delimiter) + buffer[0];
+ }
+ } else {
+ if (pos > 0) {
+ buffer[0].splice_prefix = this.tmp.splice_delimiter;
+ } else {
+ buffer[0].splice_prefix = "";
+ }
+ }
+ }
+ objects = objects.concat(buffer);
}
result += this.output.renderBlobs(objects);
if (result) {
- this.output.nestedBraces = false;
if (!this.tmp.suppress_decorations) {
len = this.citation.opt.layout_decorations.length;
for (pos = 0; pos < len; pos += 1) {
@@ -4394,18 +5338,20 @@ CSL.getCitationCluster = function (inputList, citationID) {
if (params[1] === "normal") {
continue;
}
- result = this.fun.decorate[params[0]][params[1]](this, result);
+ if (!item || !item["author-only"]) {
+ result = this.fun.decorate[params[0]][params[1]](this, result);
+ }
}
}
}
this.tmp.suppress_decorations = false;
return result;
};
-CSL.getCite = function (Item, item, prevItemID) {
+CSL.getCite = function (Item, item, prevItemID, blockShadowNumberReset) {
var next, error_object;
this.tmp.cite_renders_content = false;
this.parallel.StartCite(Item, item, prevItemID);
- CSL.citeStart.call(this, Item, item);
+ CSL.citeStart.call(this, Item, item, blockShadowNumberReset);
next = 0;
this.nameOutput = new CSL.NameOutput(this, Item, item);
while (next < this[this.tmp.area].tokens.length) {
@@ -4425,7 +5371,10 @@ CSL.getCite = function (Item, item, prevItemID) {
}
return "" + Item.id;
};
-CSL.citeStart = function (Item, item) {
+CSL.citeStart = function (Item, item, blockShadowNumberReset) {
+ if (!blockShadowNumberReset) {
+ this.tmp.shadow_numbers = {};
+ }
this.tmp.disambiguate_count = 0;
this.tmp.disambiguate_maxMax = 0;
this.tmp.same_author_as_previous_cite = false;
@@ -4481,25 +5430,8 @@ CSL.citeStart = function (Item, item) {
if (!this.tmp.just_looking && item && !item.position && this.registry.registry[Item.id]) {
this.tmp.disambig_restore = CSL.cloneAmbigConfig(this.registry.registry[Item.id].disambig);
}
- this.tmp.shadow_numbers = {};
- this.setNumberLabels(Item);
this.tmp.first_name_string = false;
this.tmp.authority_stop_last = 0;
- if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.prefix) {
- var openBrace = CSL.checkNestedBraceOpen.exec(item.prefix);
- var closeBrace = CSL.checkNestedBraceClose.exec(item.prefix);
- if (openBrace) {
- if (!closeBrace) {
- this.output.nestedBraces = CSL.NestedBraces;
- } else if (closeBrace[0].length < openBrace[0].length) {
- this.output.nestedBraces = CSL.NestedBraces;
- } else {
- this.output.nestedBraces = false;
- }
- } else if (closeBrace) {
- this.output.nestedBraces = false;
- }
- }
};
CSL.citeEnd = function (Item, item) {
if (this.tmp.disambig_restore) {
@@ -4535,21 +5467,6 @@ CSL.citeEnd = function (Item, item) {
}
this.tmp.issued_date = false;
this.tmp.renders_collection_number = false;
- if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.suffix) {
- var openBrace = CSL.checkNestedBraceOpen.exec(item.suffix);
- var closeBrace = CSL.checkNestedBraceClose.exec(item.suffix);
- if (closeBrace) {
- if (!openBrace) {
- this.output.nestedBraces = false;
- } else if (openBrace[0].length < closeBrace[0].length) {
- this.output.nestedBraces = false;
- } else {
- this.output.nestedBraces = CSL.NestedBraces;
- }
- } else if (openBrace) {
- this.output.nestedBraces = CSL.NestedBraces;
- }
- }
};
CSL.Engine.prototype.makeBibliography = function (bibsection) {
var debug, ret, params, maxoffset, item, len, pos, tok, tokk, tokkk, entry_ids, entry_strings, bibliography_errors;
@@ -4772,7 +5689,7 @@ CSL.getBibliographyEntries = function (bibsection) {
this.output.adjust.downward(this.output.queue[j],true);
this.output.adjust.fix(this.output.queue[j]);
}
- res = this.output.string(this, this.output.queue)[0];
+ res = this.output.string(this, this.output.queue);
if (!res) {
res = "\n[CSL STYLE ERROR: reference with no printed form.]\n";
}
@@ -5010,14 +5927,14 @@ CSL.Engine.prototype.localeConfigure = function (langspec, beShy) {
if (beShy && this.locale[langspec.best]) {
return;
}
- localexml = this.sys.xml.makeXml(this.sys.retrieveLocale("en-US"));
+ localexml = CSL.setupXml(this.sys.retrieveLocale("en-US"));
this.localeSet(localexml, "en-US", langspec.best);
if (langspec.best !== "en-US") {
if (langspec.base !== langspec.best) {
- localexml = this.sys.xml.makeXml(this.sys.retrieveLocale(langspec.base));
+ localexml = CSL.setupXml(this.sys.retrieveLocale(langspec.base));
this.localeSet(localexml, langspec.base, langspec.best);
}
- localexml = this.sys.xml.makeXml(this.sys.retrieveLocale(langspec.best));
+ localexml = CSL.setupXml(this.sys.retrieveLocale(langspec.best));
this.localeSet(localexml, langspec.best, langspec.best);
}
this.localeSet(this.cslXml, "", langspec.best);
@@ -5069,51 +5986,51 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
this.locale[lang_out].ord = {'1.0.1':false,keys:{}};
this.locale[lang_out]["noun-genders"] = {};
}
- locale = this.sys.xml.makeXml();
- if (this.sys.xml.nodeNameIs(myxml, 'locale')) {
- locale = myxml;
+ locale = myxml.makeXml();
+ if (myxml.nodeNameIs(myxml.dataObj, 'locale')) {
+ locale = myxml.dataObj;
} else {
- nodes = this.sys.xml.getNodesByName(myxml, "locale");
- for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
+ nodes = myxml.getNodesByName(myxml.dataObj, "locale");
+ for (pos = 0, len = myxml.numberofnodes(nodes); pos < len; pos += 1) {
blob = nodes[pos];
- if (this.sys.xml.getAttributeValue(blob, 'lang', 'xml') === lang_in) {
+ if (myxml.getAttributeValue(blob, 'lang', 'xml') === lang_in) {
locale = blob;
break;
}
}
}
- nodes = this.sys.xml.getNodesByName(locale, 'type');
- for (i = 0, ilen = this.sys.xml.numberofnodes(nodes); i < ilen; i += 1) {
+ nodes = myxml.getNodesByName(locale, 'type');
+ for (i = 0, ilen = myxml.numberofnodes(nodes); i < ilen; i += 1) {
var typenode = nodes[i];
- var type = this.sys.xml.getAttributeValue(typenode, 'name');
- var gender = this.sys.xml.getAttributeValue(typenode, 'gender');
+ var type = myxml.getAttributeValue(typenode, 'name');
+ var gender = myxml.getAttributeValue(typenode, 'gender');
this.opt.gender[type] = gender;
}
- var hasCslOrdinals101 = this.sys.xml.getNodesByName(locale, 'term', 'ordinal').length;
+ var hasCslOrdinals101 = myxml.getNodesByName(locale, 'term', 'ordinal').length;
if (hasCslOrdinals101) {
for (var key in this.locale[lang_out].ord.keys) {
delete this.locale[lang_out].terms[key];
}
this.locale[lang_out].ord = {"1.0.1":false,keys:{}};
}
- nodes = this.sys.xml.getNodesByName(locale, 'term');
+ nodes = myxml.getNodesByName(locale, 'term');
var ordinals101 = {"last-digit":{},"last-two-digits":{},"whole-number":{}};
var ordinals101_toggle = false;
var genderized_terms = {};
- for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
+ for (pos = 0, len = myxml.numberofnodes(nodes); pos < len; pos += 1) {
term = nodes[pos];
- termname = this.sys.xml.getAttributeValue(term, 'name');
+ termname = myxml.getAttributeValue(term, 'name');
if (termname === "sub verbo") {
termname = "sub-verbo";
}
if (termname.slice(0,7) === "ordinal") {
- var termstring = this.sys.xml.getNodeValue(term);
+ var termstring = myxml.getNodeValue(term);
if (termname === "ordinal") {
ordinals101_toggle = true;
} else {
- var match = this.sys.xml.getAttributeValue(term, 'match');
+ var match = myxml.getAttributeValue(term, 'match');
var termstub = termname.slice(8);
- var genderform = this.sys.xml.getAttributeValue(term, 'gender-form');
+ var genderform = myxml.getAttributeValue(term, 'gender-form');
if (!genderform) {
genderform = "neuter";
}
@@ -5138,14 +6055,14 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
}
form = "long";
genderform = false;
- if (this.sys.xml.getAttributeValue(term, 'form')) {
- form = this.sys.xml.getAttributeValue(term, 'form');
+ if (myxml.getAttributeValue(term, 'form')) {
+ form = myxml.getAttributeValue(term, 'form');
}
- if (this.sys.xml.getAttributeValue(term, 'gender-form')) {
- genderform = this.sys.xml.getAttributeValue(term, 'gender-form');
+ if (myxml.getAttributeValue(term, 'gender-form')) {
+ genderform = myxml.getAttributeValue(term, 'gender-form');
}
- if (this.sys.xml.getAttributeValue(term, 'gender')) {
- this.locale[lang_out]["noun-genders"][termname] = this.sys.xml.getAttributeValue(term, 'gender');
+ if (myxml.getAttributeValue(term, 'gender')) {
+ this.locale[lang_out]["noun-genders"][termname] = myxml.getAttributeValue(term, 'gender');
}
if (genderform) {
this.locale[lang_out].terms[termname][genderform] = {};
@@ -5156,11 +6073,20 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
this.locale[lang_out].terms[termname][form] = [];
target = this.locale[lang_out].terms[termname];
}
- if (this.sys.xml.numberofnodes(this.sys.xml.getNodesByName(term, 'multiple'))) {
- target[form][0] = this.sys.xml.getNodeValue(term, 'single');
- target[form][1] = this.sys.xml.getNodeValue(term, 'multiple');
+ if (myxml.numberofnodes(myxml.getNodesByName(term, 'multiple'))) {
+ target[form][0] = myxml.getNodeValue(term, 'single');
+ if (target[form][0].indexOf("%s") > -1) {
+ this.opt.hasPlaceholderTerm = true;
+ }
+ target[form][1] = myxml.getNodeValue(term, 'multiple');
+ if (target[form][1].indexOf("%s") > -1) {
+ this.opt.hasPlaceholderTerm = true;
+ }
} else {
- target[form] = this.sys.xml.getNodeValue(term);
+ target[form] = myxml.getNodeValue(term);
+ if (target[form].indexOf("%s") > -1) {
+ this.opt.hasPlaceholderTerm = true;
+ }
}
}
if (ordinals101_toggle) {
@@ -5200,11 +6126,11 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
}
}
}
- nodes = this.sys.xml.getNodesByName(locale, 'style-options');
- for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
+ nodes = myxml.getNodesByName(locale, 'style-options');
+ for (pos = 0, len = myxml.numberofnodes(nodes); pos < len; pos += 1) {
if (true) {
styleopts = nodes[pos];
- attributes = this.sys.xml.attributes(styleopts);
+ attributes = myxml.attributes(styleopts);
for (attrname in attributes) {
if (attributes.hasOwnProperty(attrname)) {
if (attrname === "@punctuation-in-quote" || attrname === "@limit-day-ordinals-to-day-1") {
@@ -5219,7 +6145,7 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
} else if (attrname === "@skip-words") {
var skip_words = attributes[attrname].split(/\s*,\s*/);
this.locale[lang_out].opts[attrname.slice(1)] = skip_words;
- } else if (attrname === "@leading-noise-words" && lang_in === lang_out) {
+ } else if (attrname === "@leading-noise-words") {
var val = attributes[attrname].split(/\s*,\s*/);
this.locale[lang_out].opts["leading-noise-words"] = val;
} else if (attrname === "@name-as-sort-order") {
@@ -5245,11 +6171,11 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
}
}
}
- nodes = this.sys.xml.getNodesByName(locale, 'date');
- for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
+ nodes = myxml.getNodesByName(locale, 'date');
+ for (pos = 0, len = myxml.numberofnodes(nodes); pos < len; pos += 1) {
if (true) {
date = nodes[pos];
- this.locale[lang_out].dates[this.sys.xml.getAttributeValue(date, "form")] = date;
+ this.locale[lang_out].dates[myxml.getAttributeValue(date, "form")] = date;
}
}
};
@@ -5646,7 +6572,7 @@ CSL.Node["date-part"] = {
if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false && !state.tmp.has_done_year_suffix) {
state.tmp.has_done_year_suffix = true;
num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10);
- number = new CSL.NumericBlob(num, this, Item.id);
+ number = new CSL.NumericBlob(false, num, this, Item.id);
this.successor_prefix = state[state.build.area].opt.layout_delimiter;
this.splice_prefix = state[state.build.area].opt.layout_delimiter;
formatter = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS);
@@ -5764,10 +6690,10 @@ CSL.Node.group = {
for (var jurisdiction in res) {
var macroCount = 0;
state.juris[jurisdiction] = {};
- var myXml = state.sys.xml.makeXml(res[jurisdiction]);
- var myNodes = state.sys.xml.getNodesByName(myXml, "law-module");
+ var myXml = CSL.setupXml(res[jurisdiction]);
+ var myNodes = myXml.getNodesByName(myXml.dataObj, "law-module");
for (var i=0,ilen=myNodes.length;i<ilen;i++) {
- var myTypes = state.sys.xml.getAttributeValue(myNodes[i],"types");
+ var myTypes = myXml.getAttributeValue(myNodes[i],"types");
if (myTypes) {
state.juris[jurisdiction].types = {};
myTypes = myTypes.split(/\s+/);
@@ -5779,9 +6705,9 @@ CSL.Node.group = {
if (!state.juris[jurisdiction].types) {
state.juris[jurisdiction].types = CSL.MODULE_TYPES;
}
- var myNodes = state.sys.xml.getNodesByName(myXml, "macro");
+ var myNodes = myXml.getNodesByName(myXml.dataObj, "macro");
for (var i=0,ilen=myNodes.length;i<ilen;i++) {
- var myName = state.sys.xml.getAttributeValue(myNodes[i], "name");
+ var myName = myXml.getAttributeValue(myNodes[i], "name");
if (!CSL.MODULE_MACROS[myName]) {
CSL.debug("CSL: skipping non-modular macro name \"" + myName + "\" in module context");
continue;
@@ -6201,6 +7127,7 @@ CSL.Node.key = {
if (state.sys.normalizeUnicode) {
keystring = state.sys.normalizeUnicode(keystring);
}
+ keystring = keystring.split(" ").join("");
if ("" === keystring) {
keystring = undefined;
}
@@ -6243,7 +7170,6 @@ CSL.Node.label = {
if (this.strings.term) {
var plural = false;
if (!this.strings.form) {
- this.strings.form = "long";
}
var func = function (state, Item, item) {
var termtxt = CSL.evaluateLabel(this, state, Item, item);
@@ -6257,7 +7183,9 @@ CSL.Node.label = {
flag[0] = true;
state.tmp.group_context.replace(flag);
}
- state.output.append(termtxt, this);
+ if (termtxt.indexOf("%s") === -1) {
+ state.output.append(termtxt, this);
+ }
if (item && this.strings.term === "locator") {
state.parallel.CloseVariable();
}
@@ -6396,6 +7324,9 @@ CSL.Node.layout = {
ignorePredecessor = true;
}
prefix = (item.prefix + sp).replace(/\s+/g, " ");
+ if (!state.tmp.just_looking) {
+ prefix = state.output.checkNestedBrace.update(prefix);
+ }
state.output.append(prefix, this, false, ignorePredecessor);
}
};
@@ -6481,7 +7412,11 @@ CSL.Node.layout = {
|| ['[','('].indexOf(item.suffix.slice(0,1)) > -1) {
sp = " ";
}
- state.output.append((sp + item.suffix), this);
+ var suffix = item.suffix;
+ if (!state.tmp.just_looking) {
+ suffix = state.output.checkNestedBrace.update(suffix);
+ }
+ state.output.append((sp + suffix), this);
}
};
suffix_token.execs.push(func);
@@ -7810,11 +8745,11 @@ CSL.NameOutput.prototype._renderOnePersonalName = function (value, pos, i, j) {
} else if (this.state.tmp.sort_key_flag) {
if (this.state.opt["demote-non-dropping-particle"] === "never") {
first = this._join([non_dropping_particle, family, dropping_particle], " ");
- merged = this._join([first, given], " ");
+ merged = this._join([first, given], "0");
blob = this._join([merged, suffix], " ");
} else {
second = this._join([given, dropping_particle, non_dropping_particle], " ");
- merged = this._join([family, second], " ");
+ merged = this._join([family, second], "0");
blob = this._join([merged, suffix], " ");
}
} else if (this.name.strings["name-as-sort-order"] === "all" || (this.name.strings["name-as-sort-order"] === "first" && i === 0 && (j === 0 || "undefined" === typeof j))) {
@@ -8424,29 +9359,17 @@ CSL.evaluateLabel = function (node, state, Item, item) {
myterm = node.strings.term;
}
var plural = node.strings.plural;
- if (item && "locator" === node.strings.term && "number" === typeof item.force_pluralism) {
- plural = item.force_pluralism;
- } else if ("number" !== typeof plural) {
- if ("locator" === node.strings.term) {
- if (item && item.locator) {
- if (state.opt.development_extensions.locator_parsing_for_plurals) {
- if (!state.tmp.shadow_numbers.locator) {
- state.processNumber(false, item, "locator", Item.type);
- }
- plural = state.tmp.shadow_numbers.locator.plural;
- } else {
- plural = CSL.evaluateStringPluralism(item.locator);
- }
- }
- } else if (["page", "page-first", "number"].indexOf(node.variables[0]) > -1) {
- state.processNumber(false, Item, myterm, Item.type);
- plural = state.tmp.shadow_numbers[myterm].plural;
- myterm = state.tmp.shadow_numbers[myterm].label;
- } else {
- if (!state.tmp.shadow_numbers[myterm]) {
- state.processNumber(false, Item, myterm, Item.type);
- }
- plural = state.tmp.shadow_numbers[myterm].plural;
+ if ("number" !== typeof plural) {
+ var theItem = node.strings.term === "locator" ? item : Item;
+ state.processNumber(false, theItem, node.strings.term, Item.type);
+ plural = state.tmp.shadow_numbers[node.strings.term].plural;
+ if (!state.tmp.shadow_numbers[node.strings.term].labelForm
+ && !state.tmp.shadow_numbers[node.strings.term].labelDecorations) {
+ state.tmp.shadow_numbers[node.strings.term].labelForm = node.strings.form;
+ state.tmp.shadow_numbers[node.strings.term].labelDecorations = node.decorations.slice();
+ }
+ if (["locator", "number", "page"].indexOf(node.strings.term) > -1 && state.tmp.shadow_numbers[node.strings.term].label) {
+ myterm = state.tmp.shadow_numbers[node.strings.term].label;
}
if (node.decorations && (state.opt.development_extensions.csl_reverse_lookup_support || state.sys.csl_reverse_lookup_support)) {
node.decorations.reverse();
@@ -8456,15 +9379,6 @@ CSL.evaluateLabel = function (node, state, Item, item) {
}
return CSL.castLabel(state, node, myterm, plural, CSL.TOLERANT);
};
-CSL.evaluateStringPluralism = function (str) {
- if (str) {
- var m = str.match(/(?:[0-9],\s*[0-9]|\s+and\s+|&|([0-9]+)\s*[\-\u2013]\s*([0-9]+))/);
- if (m && (!m[1] || parseInt(m[1], 10) < parseInt(m[2], 10))) {
- return 1;
- }
- }
- return 0;
-};
CSL.castLabel = function (state, node, term, plural, mode) {
var label_form = node.strings.form;
if (state.tmp.group_context.value()[5]) {
@@ -8789,110 +9703,18 @@ CSL.Node.number = {
if (this.strings.label_form_override) {
form = this.strings.label_form_override;
}
- if (varname === "locator"
- && item.locator) {
- item.locator = item.locator.replace(/([^\\])\s*-\s*/, "$1" + state.getTerm("page-range-delimiter"));
- m = item.locator.match(CSL.STATUTE_SUBDIV_GROUPED_REGEX);
- if (m) {
- lst = item.locator.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX);
- for (i = 0, ilen = lst.length; i < ilen; i += 1) {
- lst[i] = state.fun.page_mangler(lst[i]);
- }
- newlst = [lst[0]];
- if (!this.strings.label_form_override && state.tmp.group_context.value()[5]) {
- form = state.tmp.group_context.value()[5];
- }
- for (i = 1, ilen = lst.length; i < ilen; i += 1) {
- var subplural = 0;
- if (lst[i].match(rex)) {
- subplural = 1;
- }
- var term = CSL.STATUTE_SUBDIV_STRINGS[m[i - 1].replace(/^\s*/,"")];
- var myform = form;
- if (item.section_label_count > i && item.section_form_override) {
- myform = item.section_form_override;
- }
- newlst.push(state.getTerm(term, myform, subplural));
- newlst.push(lst[i].replace(/^\s*/,""));
- }
- value = newlst.join(" ");
- value = value.replace(/\\/, "", "g");
- state.output.append(value, this);
- } else {
- value = state.fun.page_mangler(item.locator);
- value = value.replace(/\\/, "", "g");
- state.output.append(value, this);
- }
- } else {
- var node = this;
- if (!state.tmp.shadow_numbers[varname]
- || (state.tmp.shadow_numbers[varname].values.length
- && state.tmp.shadow_numbers[varname].values[0][2] === false)) {
- if (varname === "locator") {
- state.processNumber(node, item, varname, Item.type);
- } else {
- state.processNumber(node, Item, varname, Item.type);
- }
- }
- var values = state.tmp.shadow_numbers[varname].values;
- var blob;
- var newstr = "";
- var rangeType = "page";
- if (["bill","gazette","legal_case","legislation","regulation","treaty"].indexOf(Item.type) > -1
- && varname === "collection-number") {
- rangeType = "year";
- }
- if (((varname === "number"
- && ["bill","gazette","legislation","regulation","treaty"].indexOf(Item.type) > -1)
- || state.opt[rangeType + "-range-format"])
- && !this.strings.prefix && !this.strings.suffix
- && !this.strings.form) {
- for (i = 0, ilen = values.length; i < ilen; i += 1) {
- newstr += values[i][1];
- }
- }
- if (newstr && !newstr.match(/^[\-.\u20130-9]+$/)) {
- if (varname === "number"
- && ["bill","gazette","legislation","regulation","treaty"].indexOf(Item.type) > -1) {
- var firstword = newstr.split(/\s/)[0];
- if (firstword) {
- newlst = [];
- m = newstr.match(CSL.STATUTE_SUBDIV_GROUPED_REGEX);
- if (m) {
- lst = newstr.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX);
- for (i = 1, ilen = lst.length; i < ilen; i += 1) {
- newlst.push(state.getTerm(CSL.STATUTE_SUBDIV_STRINGS[m[i - 1].replace(/^\s+/, "")], this.strings.label_form_override));
- newlst.push(lst[i].replace(/^\s+/, ""));
- }
- newstr = newlst.join(" ");
- }
- }
- }
- state.output.append(newstr, this);
- } else {
- if (values.length) {
- state.output.openLevel("empty");
- for (i = 0, ilen = values.length; i < ilen; i += 1) {
- blob = new CSL[values[i][0]](values[i][1], values[i][2], Item.id);
- if (i > 0) {
- blob.strings.prefix = blob.strings.prefix.replace(/^\s*/, "");
- }
- if (i < values.length - 1) {
- blob.strings.suffix = blob.strings.suffix.replace(/\s*$/, "");
- }
- if ("undefined" === typeof blob.gender) {
- blob.gender = state.locale[state.opt.lang]["noun-genders"][varname];
- }
- state.output.append(blob, "literal", false, false, true);
- }
- state.output.closeLevel("empty");
- }
- }
- }
+ var node = this;
if (varname === "locator") {
- state.tmp.done_vars.push("locator");
+ state.processNumber(node, item, varname, Item.type);
+ } else {
+ state.processNumber(node, Item, varname, Item.type);
}
+ CSL.Util.outputNumericField(state, varname, Item.id);
state.parallel.CloseVariable("number");
+ if (["locator", "locator-extra"].indexOf(this.variables_real[0]) > -1
+ && !state.tmp.just_looking) {
+ state.tmp.done_vars.push(this.variables_real[0]);
+ }
};
this.execs.push(func);
target.push(this);
@@ -9032,7 +9854,7 @@ CSL.Node.text = {
if (state.opt.citation_number_slug) {
state.output.append(state.opt.citation_number_slug, this);
} else {
- number = new CSL.NumericBlob(num, this, Item.id);
+ number = new CSL.NumericBlob(false, num, this, Item.id);
state.output.append(number, "literal");
}
}
@@ -9050,7 +9872,7 @@ CSL.Node.text = {
func = function (state, Item) {
if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false && !state.tmp.just_looking) {
num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10);
- number = new CSL.NumericBlob(num, this, Item.id);
+ number = new CSL.NumericBlob(false, num, this, Item.id);
formatter = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS);
number.setFormatter(formatter);
state.output.append(number, "literal");
@@ -9159,44 +9981,20 @@ CSL.Node.text = {
if (CSL.CITE_FIELDS.indexOf(this.variables_real[0]) > -1) {
func = function (state, Item, item) {
if (item && item[this.variables[0]]) {
- var value = "" + item[this.variables[0]];
- value = value.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter"));
- value = value.replace(/\\-/g,"-");
- state.output.append(value, this, false, false, true);
- if (this.variables[0] === "locator-extra") {
- state.tmp.done_vars.push("locator-extra");
- }
- }
- };
- } else if (this.variables_real[0] === "page-first") {
- func = function (state, Item) {
- var idx, value;
- value = state.getVariable(Item, "page-first", form);
- if (value) {
- value = value.replace("\\", "");
- state.output.append(value, this, false, false, true);
- }
- };
- } else if (this.variables_real[0] === "page") {
- func = function (state, Item) {
- var value = state.getVariable(Item, "page", form);
- if (value) {
- value = ""+value;
- value = value.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter"));
- value = value.replace(/\\-/g,"-");
- value = state.fun.page_mangler(value);
+ state.processNumber(this, item, this.variables[0], Item.type);
+ CSL.Util.outputNumericField(state, this.variables[0], Item.id);
state.output.append(value, this, false, false, true);
- }
- };
- } else if (this.variables_real[0] === "volume") {
- func = function (state, Item) {
- if (this.variables[0]) {
- var value = state.getVariable(Item, this.variables[0], form);
- if (value) {
- state.output.append(value, this);
+ if (["locator", "locator-extra"].indexOf(this.variables_real[0]) > -1
+ && !state.tmp.just_looking) {
+ state.tmp.done_vars.push(this.variables_real[0]);
}
}
};
+ } else if (["page", "page-first", "chapter-number", "collection-number", "edition", "issue", "number", "number-of-pages", "number-of-volumes", "volume"].indexOf(this.variables_real[0]) > -1) {
+ func = function(state, Item) {
+ state.processNumber(this, Item, this.variables[0], Item.type);
+ CSL.Util.outputNumericField(state, this.variables[0], Item.id);
+ }
} else if (["URL", "DOI"].indexOf(this.variables_real[0]) > -1) {
func = function (state, Item) {
var value;
@@ -9239,7 +10037,7 @@ CSL.Node.text = {
value = state.getVariable(Item, this.variables[0], form);
if (value) {
value = "" + value;
- value = value.replace("\\", "", "g");
+ value = value.split("\\").join("");
state.output.append(value, this);
}
}
@@ -9355,13 +10153,8 @@ CSL.Attributes["@locator"] = function (state, arg) {
var maketest = function (trylabel) {
return function(Item, item) {
var label;
- if ("undefined" === typeof item || !item.label) {
- label = "page";
- } else if (item.label === "sub verbo") {
- label = "sub-verbo";
- } else {
- label = item.label;
- }
+ state.processNumber(false, item, "locator");
+ label = state.tmp.shadow_numbers.locator.label;
if (trylabel === label) {
return true;
} else {
@@ -11310,10 +12103,11 @@ CSL.Blob.prototype.push = function (blob) {
this.blobs.push(blob);
}
};
-CSL.NumericBlob = function (num, mother_token, id) {
+CSL.NumericBlob = function (particle, num, mother_token, id) {
this.id = id;
this.alldecor = [];
this.num = num;
+ this.particle = particle;
this.blobs = num.toString();
this.status = CSL.START;
this.strings = {};
@@ -11365,8 +12159,8 @@ CSL.NumericBlob.prototype.checkNext = function (next,start) {
if (this.status === CSL.SUCCESSOR_OF_SUCCESSOR) {
this.status = CSL.END;
}
- if ("object" === typeof next) {
- next.status = CSL.SEEN;
+ if ("object" === typeof next) {
+ next.status = CSL.SEEN;
}
} else { // next number is in the sequence
if (this.status === CSL.START || this.status === CSL.SEEN) {
@@ -11392,43 +12186,43 @@ CSL.NumericBlob.prototype.checkLast = function (last) {
CSL.Util.fixDateNode = function (parent, pos, node) {
var form, variable, datexml, subnode, partname, attr, val, prefix, suffix, children, key, subchildren, kkey, display, cslid;
this.build.date_key = true;
- form = this.sys.xml.getAttributeValue(node, "form");
+ form = this.cslXml.getAttributeValue(node, "form");
var lingo;
- if ("accessed" === this.sys.xml.getAttributeValue(node, "variable")) {
+ if ("accessed" === this.cslXml.getAttributeValue(node, "variable")) {
lingo = this.opt["default-locale"][0];
} else {
- lingo = this.sys.xml.getAttributeValue(node, "lingo");
+ lingo = this.cslXml.getAttributeValue(node, "lingo");
}
if (!this.getDate(form)) {
return parent;
}
- var dateparts = this.sys.xml.getAttributeValue(node, "date-parts");
- variable = this.sys.xml.getAttributeValue(node, "variable");
- prefix = this.sys.xml.getAttributeValue(node, "prefix");
- suffix = this.sys.xml.getAttributeValue(node, "suffix");
- display = this.sys.xml.getAttributeValue(node, "display");
- cslid = this.sys.xml.getAttributeValue(node, "cslid");
- datexml = this.sys.xml.nodeCopy(this.getDate(form, ("accessed" === variable)));
- this.sys.xml.setAttribute(datexml, 'lingo', this.opt.lang);
- this.sys.xml.setAttribute(datexml, 'form', form);
- this.sys.xml.setAttribute(datexml, 'date-parts', dateparts);
- this.sys.xml.setAttribute(datexml, "cslid", cslid);
- this.sys.xml.setAttribute(datexml, 'variable', variable);
+ var dateparts = this.cslXml.getAttributeValue(node, "date-parts");
+ variable = this.cslXml.getAttributeValue(node, "variable");
+ prefix = this.cslXml.getAttributeValue(node, "prefix");
+ suffix = this.cslXml.getAttributeValue(node, "suffix");
+ display = this.cslXml.getAttributeValue(node, "display");
+ cslid = this.cslXml.getAttributeValue(node, "cslid");
+ datexml = this.cslXml.nodeCopy(this.getDate(form, ("accessed" === variable)));
+ this.cslXml.setAttribute(datexml, 'lingo', this.opt.lang);
+ this.cslXml.setAttribute(datexml, 'form', form);
+ this.cslXml.setAttribute(datexml, 'date-parts', dateparts);
+ this.cslXml.setAttribute(datexml, "cslid", cslid);
+ this.cslXml.setAttribute(datexml, 'variable', variable);
if (prefix) {
- this.sys.xml.setAttribute(datexml, "prefix", prefix);
+ this.cslXml.setAttribute(datexml, "prefix", prefix);
}
if (suffix) {
- this.sys.xml.setAttribute(datexml, "suffix", suffix);
+ this.cslXml.setAttribute(datexml, "suffix", suffix);
}
if (display) {
- this.sys.xml.setAttribute(datexml, "display", display);
+ this.cslXml.setAttribute(datexml, "display", display);
}
- children = this.sys.xml.children(node);
+ children = this.cslXml.children(node);
for (key in children) {
subnode = children[key];
- if ("date-part" === this.sys.xml.nodename(subnode)) {
- partname = this.sys.xml.getAttributeValue(subnode, "name");
- subchildren = this.sys.xml.attributes(subnode);
+ if ("date-part" === this.cslXml.nodename(subnode)) {
+ partname = this.cslXml.getAttributeValue(subnode, "name");
+ subchildren = this.cslXml.attributes(subnode);
for (attr in subchildren) {
if (subchildren.hasOwnProperty(attr)) {
if ("@name" === attr) {
@@ -11440,18 +12234,18 @@ CSL.Util.fixDateNode = function (parent, pos, node) {
}
}
val = subchildren[attr];
- this.sys.xml.setAttributeOnNodeIdentifiedByNameAttribute(datexml, "date-part", partname, attr, val);
+ this.cslXml.setAttributeOnNodeIdentifiedByNameAttribute(datexml, "date-part", partname, attr, val);
}
}
}
}
- if ("year" === this.sys.xml.getAttributeValue(node, "date-parts")) {
- this.sys.xml.deleteNodeByNameAttribute(datexml, 'month');
- this.sys.xml.deleteNodeByNameAttribute(datexml, 'day');
- } else if ("year-month" === this.sys.xml.getAttributeValue(node, "date-parts")) {
- this.sys.xml.deleteNodeByNameAttribute(datexml, 'day');
+ if ("year" === this.cslXml.getAttributeValue(node, "date-parts")) {
+ this.cslXml.deleteNodeByNameAttribute(datexml, 'month');
+ this.cslXml.deleteNodeByNameAttribute(datexml, 'day');
+ } else if ("year-month" === this.cslXml.getAttributeValue(node, "date-parts")) {
+ this.cslXml.deleteNodeByNameAttribute(datexml, 'day');
}
- return this.sys.xml.insertChildNodeAfter(parent, node, pos, datexml);
+ return this.cslXml.insertChildNodeAfter(parent, node, pos, datexml);
};
CSL.dateMacroAsSortKey = function (state, Item) {
CSL.dateAsSortKey.call(this, state, Item, true);
@@ -11474,7 +12268,7 @@ CSL.dateAsSortKey = function (state, Item, isMacro) {
this.dateparts = ["year", "month", "day"];
}
if (dp.raw) {
- dp = state.fun.dateparser.parse(dp.raw);
+ dp = state.fun.dateparser.parseDateToArray(dp.raw);
} else if (dp["date-parts"]) {
dp = state.dateParseArray(dp);
}
@@ -12290,176 +13084,477 @@ CSL.Util.Suffixator.prototype.format = function (N) {
return key;
};
CSL.Engine.prototype.processNumber = function (node, ItemObject, variable, type) {
- var num, m, i, ilen, j, jlen;
+ var val, m, i, ilen, j, jlen;
var debug = false;
- if (this.tmp.shadow_numbers[variable]) {
- if (this.tmp.shadow_numbers[variable].numeric) {
- for (var i = 0, ilen = this.tmp.shadow_numbers[variable].values.length; i < ilen; i += 2) {
- this.tmp.shadow_numbers[variable].values[i][2] = node;
+ var me = this;
+ function normalizeFieldValue(str, defaultLabel) {
+ var m = str.match(/^([^ ]+)/);
+ if (m && !CSL.STATUTE_SUBDIV_STRINGS[m[1]]) {
+ var embeddedLabel = null;
+ if (variable === "locator" ) {
+ if (ItemObject.label) {
+ embeddedLabel = CSL.STATUTE_SUBDIV_STRINGS_REVERSE[ItemObject.label];
+ } else {
+ embeddedLabel = "p.";
+ }
+ } else {
+ embeddedLabel = CSL.STATUTE_SUBDIV_STRINGS_REVERSE[variable];
+ }
+ if (embeddedLabel) {
+ str = embeddedLabel + " " + str;
}
}
- return;
- }
- this.tmp.shadow_numbers[variable] = {};
- this.tmp.shadow_numbers[variable].values = [];
- this.tmp.shadow_numbers[variable].plural = 0;
- this.tmp.shadow_numbers[variable].numeric = false;
- this.tmp.shadow_numbers[variable].label = false;
- if (!ItemObject) {
- return;
- }
- var languageRole = CSL.LangPrefsMap[variable];
- if (languageRole) {
- var localeType = this.opt["cite-lang-prefs"][languageRole][0];
- num = this.transform.getTextSubField(ItemObject, variable, "locale-"+localeType, true);
- num = num.name;
- } else {
- num = ItemObject[variable];
+ return str;
}
- if (num && this.sys.getAbbreviation) {
- num = ("" + num).replace(/^\"/, "").replace(/\"$/, "");
- var jurisdiction = this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", num);
- if (this.transform.abbrevs[jurisdiction].number[num]) {
- num = this.transform.abbrevs[jurisdiction].number[num];
+ function composeNumberInfo(origLabel, label, val, joiningSuffix) {
+ joiningSuffix = joiningSuffix ? joiningSuffix : "";
+ var info = {};
+ if (!label && !CSL.STATUTE_SUBDIV_STRINGS_REVERSE[variable]) {
+ label = "var:"+variable;
+ }
+ if (label) {
+ var m = label.match(/(\s*)([^\s]*)(\s*)/);
+ info.label = m[2];
+ info.origLabel = origLabel;
+ info.labelSuffix = m[3] ? m[3] : "";
+ info.plural = 0;
+ info.labelVisibility = false;
+ }
+ var m = val.match(/^([a-zA-Z]0*)([0-9]+(?:[a-zA-Z]*|[-,a-zA-Z]+))$/);
+ if (m) {
+ info.particle = m[1];
+ info.value = m[2];
+ } else {
+ info.particle = "";
+ info.value = val;
+ }
+ info.joiningSuffix = joiningSuffix.replace(/\s*-\s*/, "-");
+ return info;
+ };
+ function fixupSubsections(elems) {
+ for (var i=elems.length-2;i>-1;i-=2) {
+ if (elems[i] === "-"
+ && elems[i-1].match(/^(?:(?:[a-z]|[a-z][a-z]|[a-z][a-z][a-z]|[a-z][a-z][a-z][a-z])\. *)*[0-9]+[,a-zA-Z]+$/)
+ && elems[i+1].match(/^[,a-zA-Z]+$/)) {
+ elems[i-1] = elems.slice(i-1,i+2).join("");
+ elems = elems.slice(0,i).concat(elems.slice(i+2));
+ }
+ }
+ return elems;
+ }
+ function parseString(str, defaultLabel) {
+ defaultLabel = defaultLabel ? defaultLabel : "";
+ str = normalizeFieldValue(str, defaultLabel);
+ var elems = [];
+ var m = str.match(/(,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/g);
+ if (m) {
+ var lst = str.split(/(?:,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/);
+ for (var i=0,ilen=lst.length-1; i<ilen; i++) {
+ elems.push(lst[i]);
+ elems.push(m[i]);
+ }
+ elems.push(lst[lst.length-1]);
+ elems = fixupSubsections(elems);
} else {
- if ("undefined" !== typeof this.transform.abbrevs[jurisdiction].number[num]) {
- delete this.transform.abbrevs[jurisdiction].number[num];
+ var elems = [str];
+ }
+ var values = [];
+ var label = defaultLabel;
+ var origLabel = "";
+ for (var i=0,ilen=elems.length;i<ilen;i += 2) {
+ var m = elems[i].match(/((?:^| )(?:[a-z]|[a-z][a-z]|[a-z][a-z][a-z]|[a-z][a-z][a-z][a-z])\. *)/g);
+ if (m) {
+ var lst = elems[i].split(/(?:(?:^| )(?:[a-z]|[a-z][a-z]|[a-z][a-z][a-z]|[a-z][a-z][a-z][a-z])\. *)/);
+ if (i === 0) {
+ var slug = m[0].trim();
+ if (!CSL.STATUTE_SUBDIV_STRINGS[slug]
+ || !me.getTerm(CSL.STATUTE_SUBDIV_STRINGS[slug])
+ || (["locator", "number"].indexOf(variable) === -1 && CSL.STATUTE_SUBDIV_STRINGS[slug] !== variable)) {
+ m = m.slice(1);
+ lst[0] = lst[0] + " " + slug + " " + lst[1];
+ lst = lst.slice(0,1).concat(lst.slice(2))
+ }
+ }
+ for (var j=0,jlen=lst.length; j<jlen; j++) {
+ if (lst[j] || j === (lst.length-1)) {
+ label = m[j-1] ? m[j-1] : label;
+ var origLabel = j > 1 ? m[j-1] : "";
+ var str = lst[j] ? lst[j].trim() : "";
+ if (j === (lst.length-1)) {
+ values.push(composeNumberInfo(origLabel, label, str, elems[i+1]));
+ } else {
+ values.push(composeNumberInfo(origLabel, label, str));
+ }
+ }
+ }
+ } else {
+ values.push(composeNumberInfo(origLabel, label, elems[i], elems[i+1]));
}
}
+ return values;
}
- if ("undefined" !== typeof num) {
- if ("number" === typeof num) {
- num = "" + num;
+ function setSpaces(values) {
+ for (var i=0,ilen=values.length-1;i<ilen;i++) {
+ if (!values[i].joiningSuffix && values[i+1].label) {
+ values[i].joiningSuffix = " ";
+ }
}
- this.tmp.shadow_numbers[variable].label = variable;
- if (num.slice(0, 1) === '"' && num.slice(-1) === '"') {
- num = num.slice(1, -1);
+ }
+ function fixNumericAndCount(values, i, currentLabelInfo) {
+ var master = values[currentLabelInfo.pos];
+ var val = values[i].value;
+ var isEscapedHyphen = master.joiningSuffix === "\\-";
+ if (val.particle && val.particle !== master.particle) {
+ currentLabelInfo.collapsible = false;
}
- if (num && ["number-of-volumes","number-of-pages"].indexOf(variable) > -1) {
- var m = num.match(/[^0-9]*([0-9]+).*/);
- if (m) {
- this.tmp.shadow_numbers[variable].numeric = true;
- if (m[1] !== "1") {
- this.tmp.shadow_numbers[variable].plural = 1;
- }
+ var mVal = val.match(/^[0-9]+([-,:a-zA-Z]*)$/);
+ var mCurrentLabel = master.value.match(/^[0-9]+([-,:a-zA-Z]*)$/);
+ if (!val || !mVal || !mCurrentLabel || isEscapedHyphen) {
+ currentLabelInfo.collapsible = false;
+ if (!val || !mCurrentLabel) {
+ currentLabelInfo.numeric = false;
+ }
+ if (isEscapedHyphen) {
+ currentLabelInfo.count--;
}
}
- if ("locator" === variable
- && ["bill","gazette","legislation","regulation","treaty"].indexOf(type) > -1) {
- num = num.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX)[0];
+ if ((mVal && mVal[1]) || (mCurrentLabel && mCurrentLabel[1])) {
+ currentLabelInfo.collapsible = false;
}
- var rangeType = "page";
- if (["bill","gazette","legislation","legal_case","regulation","treaty"].indexOf(type) > -1
- && variable === "collection-number") {
- rangeType = "year";
+ var isCollapsible = currentLabelInfo.collapsible;
+ if (!isCollapsible && i>0 && val.match(/^[ivxlcmIVXLCM]+$/) && values[i-1].value.match(/^[ivxlcmIVXLCM]+$/)) {
+ isCollapsible = true;
}
- if (["page", "page-first", "number"].indexOf(variable) > -1) {
- var m = num.split(" ")[0].match(CSL.STATUTE_SUBDIV_GROUPED_REGEX);
- if (m){
- if (this.opt.development_extensions.static_statute_locator) {
- this.tmp.shadow_numbers[variable].label = CSL.STATUTE_SUBDIV_STRINGS[m[0]];
- }
- var mm = num.match(/[^ ]+\s+(.*)/);
- if (mm) {
- num = mm[1];
- }
+ for (var j=currentLabelInfo.pos,jlen=values.length; j<jlen; j++) {
+ if (currentLabelInfo.count > 1 && isCollapsible) {
+ values[j].plural = 1;
}
+ values[j].numeric = currentLabelInfo.numeric;
+ values[j].collapsible = currentLabelInfo.collapsible;
}
- var lst = num.split(/(?:,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/);
- var m = num.match(/(,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/g);
- var elements = [];
- for (var i = 0, ilen = lst.length - 1; i < ilen; i += 1) {
- elements.push(lst[i]);
- elements.push(m[i]);
+ currentLabelInfo.label = values[i].label;
+ currentLabelInfo.count = 1;
+ currentLabelInfo.pos = i;
+ currentLabelInfo.numeric = true;
+ currentLabelInfo.collapsible = true;
+ }
+ function setPluralsAndNumerics(values) {
+ var currentLabelInfo = {
+ label: null,
+ count: 1,
+ numeric: true,
+ collapsible: true,
+ pos: 0
}
- elements.push(lst[lst.length - 1]);
- var count = 0;
- var numeric = true;
- for (var i = 0, ilen = elements.length; i < ilen; i += 1) {
- var odd = ((i%2) === 0);
- if (odd) {
- if (elements[i]) {
- if (elements[i].match(/(?:[0-9]|[xivcmlXIVCML])/)) {
- if (elements[i - 1] && elements[i - 1].match(/^\s*\\*[\-\u2013]+\s*$/)) {
- var middle = this.tmp.shadow_numbers[variable].values.slice(-1);
- if (middle[0][1].indexOf("\\") == -1) {
- if (elements[i - 2] && ("" + elements[i - 2]).match(/(:?[a-zA-Z]*[0-9]+$|^[ivxlcmIVXLCM]+$)/)
- && elements[i].match(/(?:^[a-zA-Z]*[0-9]+|^[ivxlcmIVXLCM]+$)/)) {
- var start = this.tmp.shadow_numbers[variable].values.slice(-2);
- middle[0][1] = this.getTerm(rangeType + "-range-delimiter");
- if (this.opt[rangeType + "-range-format"] ) {
- var newstr = this.fun[rangeType + "_mangler"](start[0][1] +"-"+elements[i]);
- newstr = newstr.split(this.getTerm(rangeType + "-range-delimiter"));
- elements[i] = newstr[1];
- }
- count = count + 1;
- }
- if (middle[0][1].indexOf("--") > -1) {
- middle[0][1] = middle[0][1].replace(/--*/, "\u2013");
- }
- } else {
- middle[0][1] = middle[0][1].replace(/\\/, "", "g");
+ var masterLabel = values.length ? values[0].label : null;
+ for (var i=0,ilen=values.length;i<ilen;i++) {
+ if (values[i].label) {
+ if (values[i].label === currentLabelInfo.label) {
+ currentLabelInfo.count++;
+ } else {
+ fixNumericAndCount(values, i, currentLabelInfo);
+ if (currentLabelInfo.pos === 0) {
+ if (variable === "locator" || variable === "number") {
+ if (!me.getTerm(CSL.STATUTE_SUBDIV_STRINGS[currentLabelInfo.label]) && currentLabelInfo.label.slice(0, 4) !== "var:") {
+ values[currentLabelInfo.pos].labelVisibility = true;
}
- } else if (elements[i].indexOf(" ") === -1) {
- count = count + 1;
}
- }
- var subelements = elements[i].split(/\s+/);
- for (var j = 0, jlen = subelements.length; j < jlen; j += 1) {
- if (this.opt.development_extensions.strict_page_numbers
- && variable === "page"
- && !subelements[j].match(/^-*[0-9]/)) {
- numeric = false;
- } else if (!subelements[j].match(/[-0-9]/)) {
- numeric = false;
- }
- }
- if (elements[i].match(/^[1-9][0-9]*$/)) {
- elements[i] = parseInt(elements[i], 10);
- if (node && "undefined" === typeof node.gender) {
- node.gender = this.locale[this.opt.lang]["noun-genders"][variable];
- if (!node.gender) {
- node.gender = "";
+ if (["locator", "number"].indexOf(variable) === -1) {
+ if (CSL.STATUTE_SUBDIV_STRINGS[currentLabelInfo.label] !== variable && currentLabelInfo.label.slice(0, 4) !== "var:") {
+ values[0].labelVisibility = true;
}
}
- this.tmp.shadow_numbers[variable].values.push(["NumericBlob", elements[i], node]);
} else {
- var str = elements[i];
- this.tmp.shadow_numbers[variable].values.push(["Blob", str, node]);
+ if (values[i-1].label !== values[i].label && currentLabelInfo.label.slice(0, 4) !== "var:") {
+ values[currentLabelInfo.pos].labelVisibility = true;
+ }
}
}
- } else {
- if (elements[i]) {
- this.tmp.shadow_numbers[variable].values.push(["Blob", elements[i], undefined]);
+ }
+ }
+ fixNumericAndCount(values, values.length-1, currentLabelInfo);
+ if (values.length && values[0].numeric && variable.slice(0, 10) === "number-of-") {
+ if (parseInt(ItemObject[variable], 10) > 1) {
+ values[0].plural = 1;
+ }
+ }
+ for (var i=0,ilen=values.length;i<ilen;i++) {
+ if (!values[i].numeric) {
+ var origLabel = values[i].origLabel ? values[i].origLabel : "";
+ values[i].value = (origLabel + values[i].value).trim();
+ if (values[i].label !== values[0].label) {
+ values[i].label = "";
}
}
- };
- if (this.opt.development_extensions.strict_page_numbers && variable === "page") {
- if (num.indexOf(" ") === -1 && num.match(/^-*[0-9]/)) {
- this.tmp.shadow_numbers[variable].numeric = true;
- } else {
- this.tmp.shadow_numbers[variable].numeric = numeric;
+ }
+ }
+ function setStyling(values) {
+ var masterNode = CSL.Util.cloneToken(node);
+ var masterStyling = new CSL.Token();
+ if (!me.tmp.just_looking) {
+ for (var j=masterNode.decorations.length-1;j>-1;j--) {
+ if (masterNode.decorations[j][0] === "@quotes") {
+ masterStyling.decorations = masterStyling.decorations.concat(masterNode.decorations.slice(j, j+1));
+ masterNode.decorations = masterNode.decorations.slice(0, j).concat(masterNode.decorations.slice(j+1))
+ }
+ }
+ masterStyling.strings.prefix = masterNode.strings.prefix;
+ masterNode.strings.prefix = "";
+ masterStyling.strings.suffix = masterNode.strings.suffix;
+ masterNode.strings.suffix = "";
+ }
+ var masterLabel = values.length ? values[0].label : null;
+ if (values.length) {
+ for (var i=0,ilen=values.length; i<ilen; i++) {
+ var val = values[i];
+ var newnode = CSL.Util.cloneToken(masterNode);
+ newnode.gender = node.gender;
+ if (masterLabel === val.label) {
+ newnode.formatter = node.formatter;
+ }
+ if (val.numeric) {
+ newnode.successor_prefix = val.successor_prefix;
+ }
+ newnode.strings.suffix = newnode.strings.suffix + stripHyphenBackslash(val.joiningSuffix);
+ val.styling = newnode;
+ }
+ if (!me.tmp.just_looking) {
+ if (values[0].value.slice(0,1) === "\"" && values[values.length-1].value.slice(-1) === "\"") {
+ values[0].value = values[0].value.slice(1);
+ values[values.length-1].value = values[values.length-1].value.slice(0,-1);
+ masterStyling.decorations.push(["@quotes", true]);
+ }
+ }
+ }
+ return masterStyling;
+ }
+ function stripHyphenBackslash(joiningSuffix) {
+ return joiningSuffix.replace("\\-", "-");
+ }
+ function fixupRangeDelimiter(variable, val, rangeDelimiter, isNumeric) {
+ var isPage = checkPage(variable, val);
+ if (rangeDelimiter === "-") {
+ if (isNumeric) {
+ if (isPage || (variable === "locator" && val.label === "art.") || ["issue", "volume", "edition", "number"].indexOf(variable) > -1) {
+ rangeDelimiter = me.getTerm("page-range-delimiter")
+ if (!rangeDelimiter) {
+ rangeDelimiter = "\u2013";
+ }
+ }
+ if (variable === "collection-number") {
+ rangeDelimiter = me.getTerm("year-range-delimiter");
+ if (!rangeDelimiter) {
+ rangeDelimiter = "\u2013";
+ }
+ }
}
+ }
+ return rangeDelimiter;
+ }
+ function checkPage(variable, val) {
+ return variable === "page"
+ || (variable === "locator" && (["p.", "para.", "ch."].indexOf(val.label) > -1));
+ }
+ function manglePageNumbers(values, i, currentInfo) {
+ if (i<1) return;
+ if (currentInfo.count !== 2) {
+ return;
+ }
+ if (values[i-1].particle !== values[i].particle) {
+ return;
+ }
+ if (values[i-1].joiningSuffix !== "-") {
+ currentInfo.count = 1;
+ return;
+ }
+ if (!me.opt["page-range-format"] && parseInt(values[i-1].value, 10) > parseInt(values[i].value, 10)) {
+ values[i-1].joiningSuffix = fixupRangeDelimiter(variable, values[i], values[i-1].joiningSuffix, true);
+ return;
+ }
+ var val = values[i];
+ var isPage = checkPage(variable, val);
+ if (isPage) {
+ var str = values[i-1].particle + values[i-1].value + " - " + values[i].particle + values[i].value;
+ str = me.fun.page_mangler(str);
} else {
- if (num.indexOf(" ") === -1 && num.match(/[0-9]/)) {
- this.tmp.shadow_numbers[variable].numeric = true;
+ str = values[i-1].value + stripHyphenBackslash(values[i-1].joiningSuffix) + values[i].value;
+ }
+ var m = str.match(/^([a-zA-Z]?0*)([0-9]+)(\s*[^0-9]+\s*)([-,a-zA-Z]?0*)([0-9]+)$/);
+ if (m) {
+ var rangeDelimiter = m[3];
+ rangeDelimiter = fixupRangeDelimiter(variable, val, rangeDelimiter, values[i].numeric);
+ values[i-1].particle = m[1];
+ values[i-1].value = m[2];
+ values[i-1].joiningSuffix = rangeDelimiter;
+ values[i].particle = m[4];
+ values[i].value = m[5];
+ }
+ currentInfo.count = 0;
+ }
+ function fixRanges(values) {
+ if (!node) return;
+ if (["page", "page-first", "chapter-number", "collection-number", "edition", "issue", "number", "number-of-pages", "number-of-volumes", "volume", "locator"].indexOf(variable) === -1) return;
+ var currentInfo = {
+ count: 0,
+ label: null,
+ lastHadRangeDelimiter: false
+ }
+ for (var i=0,ilen=values.length; i<ilen; i++) {
+ var val = values[i];
+ if (!val.collapsible) {
+ currentInfo.count = 0;
+ currentInfo.label = null;
+ var isNumeric = val.numeric;
+ if (i<(values.length-1) && !isNumeric && val.value.match(/^[ivxlcmIVXLCM]+$/) && values[i+1].value.match(/^[ivxlcmIVXLCM]+$/)) {
+ isNumeric = true;
+ }
+ val.joiningSuffix = fixupRangeDelimiter(variable, val, val.joiningSuffix, isNumeric);
+ } else if (currentInfo.label === val.label && val.joiningSuffix === "-") {
+ currentInfo.count = 1;
+ } else if (currentInfo.label === val.label && val.joiningSuffix !== "-") {
+ currentInfo.count++;
+ if (currentInfo.count === 2) {
+ manglePageNumbers(values, i, currentInfo);
+ }
+ } else if (currentInfo.label !== val.label) {
+ currentInfo.label = val.label;
+ currentInfo.count = 1;
} else {
- this.tmp.shadow_numbers[variable].numeric = numeric;
+ currentInfo.count = 1;
+ currentInfo.label = val.label;
}
}
- if (!this.tmp.shadow_numbers[variable].numeric) {
- this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", num);
+ if (currentInfo.count === 2) {
+ manglePageNumbers(values, values.length-1, currentInfo);
}
- if (count > 1) {
- this.tmp.shadow_numbers[variable].plural = 1;
+ }
+ function setVariableParams(obj, values) {
+ if (values.length) {
+ obj.numeric = values[0].numeric;
+ obj.collapsible = values[0].collapsible;
+ obj.plural = values[0].plural;
+ obj.label = CSL.STATUTE_SUBDIV_STRINGS[values[0].label];
+ }
+ }
+ if (node && this.tmp.shadow_numbers[variable] && this.tmp.shadow_numbers[variable].values.length) {
+ var values = this.tmp.shadow_numbers[variable].values;
+ fixRanges(values);
+ this.tmp.shadow_numbers[variable].masterStyling = setStyling(values);
+ return;
+ }
+ if (!this.tmp.shadow_numbers[variable]) {
+ this.tmp.shadow_numbers[variable] = {
+ values:[]
+ };
+ }
+ if (!ItemObject) {
+ return;
+ }
+ var languageRole = CSL.LangPrefsMap[variable];
+ if (languageRole) {
+ var localeType = this.opt["cite-lang-prefs"][languageRole][0];
+ val = this.transform.getTextSubField(ItemObject, variable, "locale-"+localeType, true);
+ val = val.name;
+ } else {
+ val = ItemObject[variable];
+ }
+ if (val && this.sys.getAbbreviation) {
+ var jurisdiction = this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", val);
+ if (this.transform.abbrevs[jurisdiction].number[val]) {
+ val = this.transform.abbrevs[jurisdiction].number[val];
+ } else {
+ if ("undefined" !== typeof this.transform.abbrevs[jurisdiction].number[val]) {
+ delete this.transform.abbrevs[jurisdiction].number[val];
+ }
+ }
+ }
+ if ("undefined" !== typeof val && ("string" === typeof val || "number" === typeof val)) {
+ if ("number" === typeof val) {
+ val = "" + val;
+ }
+ var defaultLabel = CSL.STATUTE_SUBDIV_STRINGS_REVERSE[variable];
+ if (!this.tmp.shadow_numbers.values) {
+ var values = parseString(val, defaultLabel);
+ setSpaces(values);
+ setPluralsAndNumerics(values);
+ this.tmp.shadow_numbers[variable].values = values;
}
- if (ItemObject.force_pluralism === 1) {
- this.tmp.shadow_numbers[variable].plural = 1;
- } else if (ItemObject.force_pluralism === 0) {
- this.tmp.shadow_numbers[variable].plural = 0;
+ if (node) {
+ fixRanges(values);
+ this.tmp.shadow_numbers[variable].masterStyling = setStyling(values)
}
+ setVariableParams(this.tmp.shadow_numbers[variable], values);
}
};
+CSL.Util.outputNumericField = function(state, varname, itemID) {
+ state.output.openLevel(state.tmp.shadow_numbers[varname].masterStyling);
+ var nums = state.tmp.shadow_numbers[varname].values;
+ var masterLabel = nums.length ? nums[0].label : null;
+ var labelForm = state.tmp.shadow_numbers[varname].labelForm;
+ var embeddedLabelForm;
+ if (labelForm) {
+ embeddedLabelForm = labelForm
+ } else {
+ embeddedLabelForm = "short";
+ }
+ var labelDecorations = state.tmp.shadow_numbers[varname].labelDecorations;
+ var lastLabelName = null;
+ for (var i=0,ilen=nums.length;i<ilen;i++) {
+ var num = nums[i];
+ var labelName = CSL.STATUTE_SUBDIV_STRINGS[num.label];
+ if (num.label === masterLabel) {
+ label = state.getTerm(labelName, labelForm, num.plural);
+ } else {
+ label = state.getTerm(labelName, embeddedLabelForm, num.plural);
+ }
+ var labelPlaceholderPos = -1;
+ if (label) {
+ labelPlaceholderPos = label.indexOf("%s");
+ }
+ var numStyling = CSL.Util.cloneToken(num.styling);
+ numStyling.formatter = num.styling.formatter;
+ numStyling.type = num.styling.type;
+ numStyling.num = num.styling.num;
+ numStyling.gender = num.styling.gender;
+ if (labelPlaceholderPos > 0 && labelPlaceholderPos < (label.length-2)) {
+ numStyling.strings.prefix += label.slice(0,labelPlaceholderPos);
+ numStyling.strings.suffix = label.slice(labelPlaceholderPos+2) + numStyling.strings.suffix;
+ } else if (num.labelVisibility) {
+ if (!label) {
+ label = num.label;
+ labelName = num.label;
+ }
+ if (labelPlaceholderPos > 0) {
+ var prefixLabelStyling = new CSL.Token();
+ prefixLabelStyling.decorations = labelDecorations;
+ state.output.append(label.slice(0,labelPlaceholderPos), prefixLabelStyling);
+ } else if (labelPlaceholderPos === (label.length-2) || labelPlaceholderPos === -1) {
+ state.output.append(label+num.labelSuffix, "empty");
+ }
+ }
+ if (num.collapsible) {
+ var blob = new CSL.NumericBlob(num.particle, parseInt(num.value, 10), numStyling, itemID);
+ if ("undefined" === typeof blob.gender) {
+ blob.gender = state.locale[state.opt.lang]["noun-genders"][varname];
+ }
+ state.output.append(blob, "literal");
+ } else {
+ state.output.append(num.particle + num.value, numStyling)
+ }
+ if (labelPlaceholderPos === 0 && labelPlaceholderPos < (label.length-2)) {
+ if (lastLabelName === null) {
+ lastLabelName = labelName;
+ }
+ if (labelName !== lastLabelName || i === (nums.length-1)) {
+ var suffixLabelStyling = new CSL.Token();
+ suffixLabelStyling.decorations = labelDecorations;
+ state.output.append(label.slice(labelPlaceholderPos+2), suffixLabelStyling);
+ }
+ }
+ lastLabelName === labelName;
+ }
+ state.output.closeLevel();
+}
CSL.Util.PageRangeMangler = {};
CSL.Util.PageRangeMangler.getFunction = function (state, rangeType) {
var rangerex, pos, len, stringify, listify, expand, minimize, minimize_internal, chicago, lst, m, b, e, ret, begin, end, ret_func, ppos, llen;
@@ -12583,7 +13678,7 @@ CSL.Util.PageRangeMangler.getFunction = function (state, rangeType) {
}
if (!state.opt[rangeType + "-range-format"]) {
ret_func = function (str) {
- return str;
+ return sniff(str, stringify);
};
} else if (state.opt[rangeType + "-range-format"] === "expanded") {
ret_func = function (str) {
@@ -12721,7 +13816,7 @@ CSL.Util.FlipFlopper.prototype._normalizeString = function (str) {
oldStr = str;
for (i = 0, ilen = 2; i < ilen; i += 1) {
if (this.quotechars[i + 2]) {
- str = str.replace(this.quotechars[i + 2], this.quotechars[0]);
+ str = str.split(this.quotechars[i + 2]).join(this.quotechars[0]);
}
}
}
@@ -12733,9 +13828,9 @@ CSL.Util.FlipFlopper.prototype._normalizeString = function (str) {
for (i = 0, ilen = 2; i < ilen; i += 1) {
if (this.quotechars[i + 4]) {
if (i === 0) {
- str = str.replace(this.quotechars[i + 4], " " + this.quotechars[1]);
+ str = str.split(this.quotechars[i + 4]).join(" " + this.quotechars[1]);
} else {
- str = str.replace(this.quotechars[i + 4], this.quotechars[1]);
+ str = str.split(this.quotechars[i + 4]).join(this.quotechars[1]);
}
}
}
@@ -12839,8 +13934,8 @@ CSL.Util.FlipFlopper.prototype.getSplitStrings = function (str) {
}
len = strs.length;
for (pos = 0; pos < len; pos += 2) {
- strs[pos] = strs[pos].replace("'", "\u2019", "g");
- strs[pos] = strs[pos].replace(" \u2019", " \u2019", "g");
+ strs[pos] = strs[pos].split("'").join("\u2019");
+ strs[pos] = strs[pos].split(" \u2019").join(" \u2019");
}
return strs;
};
@@ -13024,10 +14119,10 @@ CSL.Output.Formatters.title = function (state, string) {
if (!string) {
return "";
}
- var doppel = CSL.Output.Formatters.doppelString(string, CSL.TAG_ESCAPE);
- function capitalise (word) {
- var m = word.match(/([:?!]+\s+|-|^)([a-zA-Z])(.*)/);
- if (m) {
+ var doppel = CSL.Output.Formatters.doppelString(string, CSL.TAG_ESCAPE, SKIP_WORDS);
+ function capitalise (word, force) {
+ var m = word.match(/([:?!]+\s+|-|^)((?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))(.*)/);
+ if (m && !(m[2].match(/^[\u0370-\u03FF]$/) && !m[3])) {
return m[1] + m[2].toUpperCase() + m[3];
}
return word;
@@ -13079,10 +14174,10 @@ CSL.Output.Formatters.title = function (state, string) {
var ret = CSL.Output.Formatters.undoppelString(doppel);
return ret;
};
-CSL.Output.Formatters.doppelString = function (string, rex) {
+CSL.Output.Formatters.doppelString = function (string, rex, stopWords) {
var ret, pos, len;
ret = {};
- ret.array = rex(string);
+ ret.array = rex(string, stopWords);
ret.string = "";
for (var i=0,ilen=ret.array.length; i<ilen; i += 2) {
if (ret.array[i-1] === "-" && false) {
@@ -13213,7 +14308,7 @@ CSL.Output.Formats.prototype.html = {
if (!state.tmp.just_looking && ! state.tmp.suppress_decorations) {
if (cslid) {
return "<span class=\"" + state.opt.nodenames[cslid] + "\" cslid=\"" + cslid + "\">" + str + "</span>";
- } else if ("string" === typeof str) {
+ } else if (this.params && "string" === typeof str) {
var prePunct = "";
if (str) {
var m = str.match(CSL.VARIABLE_WRAPPER_PREPUNCT_REX);
@@ -13312,14 +14407,14 @@ CSL.Output.Formats.prototype.rtf = {
text = "";
}
return text
- .replace(/([\\{}])/g, "\\$1", "g")
+ .replace(/([\\{}])/g, "\\$1")
.replace(CSL.SUPERSCRIPTS_REGEXP,
function(aChar) {
return "\\super " + CSL.SUPERSCRIPTS[aChar] + "\\nosupersub{}";
})
.replace(/[\u007F-\uFFFF]/g,
function(aChar) { return "\\uc0\\u"+aChar.charCodeAt(0).toString()+"{}"; })
- .replace("\t", "\\tab{}", "g");
+ .split("\t").join("\\tab{}");
},
"@passthrough/true": CSL.Output.Formatters.passthrough,
"@font-style/italic":"{\\i{}%%STRING%%}",
@@ -14037,7 +15132,7 @@ CSL.Disambiguation.prototype.scanItems = function (list) {
this.partners.push(this.Item);
this.nonpartners = [];
var clashes = 0;
- for (pos = 1, len = list[1].length; pos < len; pos += 1) {
+ for (var pos = 1, len = list[1].length; pos < len; pos += 1) {
otherItem = list[1][pos];
var otherItemCite = CSL.getAmbiguousCite.call(this.state, otherItem, this.base, true);
if (this.ItemCite === otherItemCite) {
@@ -14087,7 +15182,7 @@ CSL.Disambiguation.prototype.disNames = function (ismax) {
this.lists[this.listpos] = [this.betterbase, this.nonpartners];
this.lists.push([this.betterbase, this.partners]);
if (this.modeindex === this.modes.length - 1) {
- for (i = 0, ilen = this.partners.length; i < ilen; i += 1) {
+ for (var i = 0, ilen = this.partners.length; i < ilen; i += 1) {
this.state.registry.registerAmbigToken(this.akey, "" + this.partners[i].id, this.betterbase);
}
this.lists[this.listpos] = [this.betterbase, []];
@@ -14150,7 +15245,7 @@ CSL.Disambiguation.prototype.disYears = function () {
}
}
tokens.sort(this.state.registry.sorter.compareKeys);
- for (pos = 0, len = tokens.length; pos < len; pos += 1) {
+ for (var pos = 0, len = tokens.length; pos < len; pos += 1) {
base.year_suffix = ""+pos;
var oldBase = this.state.registry.registry[tokens[pos].id].disambig;
this.state.registry.registerAmbigToken(this.akey, "" + tokens[pos].id, base);
@@ -14237,7 +15332,7 @@ CSL.Disambiguation.prototype.initVars = function (akey) {
this.base = CSL.getAmbigConfig.call(this.state);
if (myIds && myIds.length > 1) {
myItemBundles.push([this.maxNamesByItemId[myItem.id], myItem]);
- for (i = 1, ilen = myIds.length; i < ilen; i += 1) {
+ for (var i = 1, ilen = myIds.length; i < ilen; i += 1) {
myItem = this.state.retrieveItem("" + myIds[i]);
this.getCiteData(myItem, this.base);
myItemBundles.push([this.maxNamesByItemId[myItem.id], myItem]);
@@ -14260,7 +15355,7 @@ CSL.Disambiguation.prototype.initVars = function (akey) {
}
);
myItems = [];
- for (i = 0, ilen = myItemBundles.length; i < ilen; i += 1) {
+ for (var i = 0, ilen = myItemBundles.length; i < ilen; i += 1) {
myItems.push(myItemBundles[i][1]);
}
this.lists.push([this.base, myItems]);