commit 9259bfd49af1c1d776f68a0401884fb7b35903dd
parent 395d596105a55823bf584c08839833f100d5507e
Author: Dan Stillman <dstillman@zotero.org>
Date: Tue, 24 Feb 2015 23:45:42 -0500
Merge pull request #626 from aurimasv/isbn-import
Tweaks to ISBN handling
Diffstat:
7 files changed, 233 insertions(+), 144 deletions(-)
diff --git a/chrome/content/zotero/xpcom/cite.js b/chrome/content/zotero/xpcom/cite.js
@@ -522,100 +522,20 @@ Zotero.Cite.System.prototype = {
throw "Zotero.Cite.System.retrieveItem called on non-item "+item;
}
- // don't return URL or accessed information for journal articles if a
- // pages field exists
- var itemType = Zotero.ItemTypes.getName(zoteroItem.itemTypeID);
- var cslType = CSL_TYPE_MAPPINGS[itemType];
- if(!cslType) cslType = "article";
- var ignoreURL = ((zoteroItem.getField("accessDate", true, true) || zoteroItem.getField("url", true, true)) &&
- ["journalArticle", "newspaperArticle", "magazineArticle"].indexOf(itemType) !== -1
- && zoteroItem.getField("pages")
- && !Zotero.Prefs.get("export.citePaperJournalArticleURL"));
-
- var cslItem = {
- 'id':zoteroItem.id,
- 'type':cslType
- };
+ var cslItem = Zotero.Utilities.itemToCSLJSON(zoteroItem);
- // get all text variables (there must be a better way)
- // TODO: does citeproc-js permit short forms?
- for(var variable in CSL_TEXT_MAPPINGS) {
- var fields = CSL_TEXT_MAPPINGS[variable];
- if(variable == "URL" && ignoreURL) continue;
- for each(var field in fields) {
- var value = zoteroItem.getField(field, false, true).toString();
- if(value != "") {
- // Strip enclosing quotes
- if(value.match(/^".+"$/)) {
- value = value.substr(1, value.length-2);
- }
- cslItem[variable] = value;
- break;
- }
- }
- }
-
- // separate name variables
- var authorID = Zotero.CreatorTypes.getPrimaryIDForType(zoteroItem.itemTypeID);
- var creators = zoteroItem.getCreators();
- for each(var creator in creators) {
- if(creator.creatorTypeID == authorID) {
- var creatorType = "author";
- } else {
- var creatorType = Zotero.CreatorTypes.getName(creator.creatorTypeID);
- }
-
- var creatorType = CSL_NAMES_MAPPINGS[creatorType];
- if(!creatorType) continue;
-
- var nameObj = {'family':creator.ref.lastName, 'given':creator.ref.firstName};
-
- if(cslItem[creatorType]) {
- cslItem[creatorType].push(nameObj);
- } else {
- cslItem[creatorType] = [nameObj];
- }
- }
-
- // get date variables
- for(var variable in CSL_DATE_MAPPINGS) {
- var date = zoteroItem.getField(CSL_DATE_MAPPINGS[variable], false, true);
- if(date) {
- var dateObj = Zotero.Date.strToDate(date);
- // otherwise, use date-parts
- var dateParts = [];
- if(dateObj.year) {
- // add year, month, and day, if they exist
- dateParts.push(dateObj.year);
- if(dateObj.month !== undefined) {
- dateParts.push(dateObj.month+1);
- if(dateObj.day) {
- dateParts.push(dateObj.day);
- }
- }
- cslItem[variable] = {"date-parts":[dateParts]};
-
- // if no month, use season as month
- if(dateObj.part && !dateObj.month) {
- cslItem[variable].season = dateObj.part;
- }
- } else {
- // if no year, pass date literally
- cslItem[variable] = {"literal":date};
- }
+ if (!Zotero.Prefs.get("export.citePaperJournalArticleURL")) {
+ var itemType = Zotero.ItemTypes.getName(zoteroItem.itemTypeID);
+ // don't return URL or accessed information for journal articles if a
+ // pages field exists
+ if (["journalArticle", "newspaperArticle", "magazineArticle"].indexOf(itemType) !== -1
+ && zoteroItem.getField("pages")
+ ) {
+ delete cslItem.URL;
+ delete cslItem.accessed;
}
}
-
- // extract PMID
- var extra = zoteroItem.getField("extra", false, true);
- if(typeof extra === "string") {
- var m = /(?:^|\n)PMID:\s*([0-9]+)/.exec(extra);
- if(m) cslItem.PMID = m[1];
- m = /(?:^|\n)PMCID:\s*((?:PMC)?[0-9]+)/.exec(extra);
- if(m) cslItem.PMCID = m[1];
- }
- //this._cache[zoteroItem.id] = cslItem;
return cslItem;
},
diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js
@@ -821,6 +821,24 @@ Zotero.Item.prototype.setField = function(field, value, loadIn) {
value = value.replace(/[\r\n]+/g, " ");;
}
+ if (fieldID == Zotero.ItemFields.getID('ISBN')) {
+ // Hyphenate ISBNs, but only if everything is in expected format and valid
+ let isbns = ('' + value).trim().split(/\s*[,;]\s*|\s+/),
+ newISBNs = '',
+ failed = false;
+ for (let i=0; i<isbns.length; i++) {
+ let isbn = Zotero.Utilities.Internal.hyphenateISBN(isbns[i]);
+ if (!isbn) {
+ failed = true;
+ break;
+ }
+
+ newISBNs += ' ' + isbn;
+ }
+
+ if (!failed) value = newISBNs.substr(1);
+ }
+
if (!loadIn) {
// Save date field as multipart date
// TEMP - filingDate
diff --git a/chrome/content/zotero/xpcom/isbn.js b/chrome/content/zotero/xpcom/isbn.js
@@ -0,0 +1,11 @@
+/** THIS FILE WAS GENERATED AUTOMATICALLY **/
+
+/**
+ * ISBN Registrant ranges from https://www.isbn-international.org/range_file_generation
+**/
+Zotero.ISBN = {};
+Zotero.ISBN.ranges = (function() {
+ var ranges = {"978":{"0":["00","19","200","699","7000","8499","85000","89999","900000","949999","9500000","9999999"],"1":["00","09","100","329","330","399","4000","5499","55000","86979","869800","998999","9990000","9999999"],"2":["00","19","200","349","400","699","7000","8399","35000","39999","84000","89999","900000","949999","9500000","9999999"],"3":["00","02","04","19","030","033","200","699","0340","0369","7000","8499","03700","03999","85000","89999","95400","96999","99000","99499","99500","99999","900000","949999","9500000","9539999","9700000","9899999"],"5":["01","19","200","420","430","430","440","440","450","699","0050","0099","4210","4299","4310","4399","4410","4499","7000","8499","9200","9299","9501","9799","9910","9999","00000","00499","85000","89999","91000","91999","93000","94999","98000","98999","900000","909999","9500000","9500999","9900000","9909999"],"600":["00","09","100","499","5000","8999","90000","99999"],"601":["00","19","85","99","200","699","7000","7999","80000","84999"],"602":["00","07","200","699","0800","0899","0900","1099","1100","1199","1200","1399","1500","1699","7500","7999","8000","9499","14000","14999","17000","17999","18000","18999","19000","19999","70000","74999","95000","99999"],"603":["00","04","05","49","500","799","8000","8999","90000","99999"],"604":["0","4","50","89","900","979","9800","9999"],"605":["01","02","04","09","030","039","100","399","4000","5999","9000","9999","60000","89999"],"606":["0","0","10","49","500","799","8000","9199","92000","99999"],"607":["00","39","400","749","7500","9499","95000","99999"],"608":["0","0","7","9","10","19","200","449","4500","6499","65000","69999"],"609":["00","39","400","799","8000","9499","95000","99999"],"612":["00","29","50","99","300","399","4000","4499","45000","49999"],"613":["0","9"],"615":["00","09","100","499","5000","7999","80000","89999"],"616":["00","19","200","699","7000","8999","90000","99999"],"617":["00","49","500","699","7000","8999","90000","99999"],"618":["00","19","200","499","5000","7999","80000","99999"],"619":["00","14","150","699","7000","8999","90000","99999"],"621":["00","29","400","599","8000","8999","95000","99999"],"7":["00","09","100","499","5000","7999","80000","89999","900000","999999"],"80":["00","19","200","699","7000","8499","85000","89999","900000","999999"],"82":["00","19","200","689","7000","8999","90000","98999","690000","699999","990000","999999"],"83":["00","19","200","599","7000","8499","60000","69999","85000","89999","900000","999999"],"84":["00","13","140","149","200","699","7000","8499","9000","9199","9700","9999","15000","19999","85000","89999","92400","92999","95000","96999","920000","923999","930000","949999"],"85":["00","19","200","549","5500","5999","7000","8499","60000","69999","85000","89999","98000","99999","900000","979999"],"86":["00","29","300","599","6000","7999","80000","89999","900000","999999"],"87":["00","29","400","649","7000","7999","85000","94999","970000","999999"],"88":["00","19","200","599","910","929","6000","8499","9300","9399","85000","89999","95000","99999","900000","909999","940000","949999"],"89":["00","24","250","549","990","999","5500","8499","85000","94999","97000","98999","950000","969999"],"90":["00","19","90","90","94","94","200","499","5000","6999","8500","8999","70000","79999","800000","849999"],"91":["0","1","20","49","500","649","7000","7999","85000","94999","970000","999999"],"92":["0","5","60","79","800","899","9000","9499","95000","98999","990000","999999"],"93":["00","09","100","499","5000","7999","80000","94999","950000","999999"],"94":["000","599","6000","8999","90000","99999"],"950":["00","49","500","899","9000","9899","99000","99999"],"951":["0","1","20","54","550","889","8900","9499","95000","99999"],"952":["00","19","60","65","80","94","200","499","5000","5999","6600","6699","7000","7999","9500","9899","67000","69999","99000","99999"],"953":["0","0","10","14","51","54","150","509","6000","9499","55000","59999","95000","99999"],"954":["00","28","300","799","2900","2999","8000","8999","9300","9999","90000","92999"],"955":["20","40","550","749","0000","1999","4500","4999","7500","7999","8000","9499","41000","43999","44000","44999","50000","54999","95000","99999"],"956":["00","19","200","699","7000","9999"],"957":["00","02","05","19","21","27","31","43","440","819","0300","0499","2000","2099","8200","9699","28000","30999","97000","99999"],"958":["00","56","600","799","8000","9499","57000","59999","95000","99999"],"959":["00","19","200","699","7000","8499","85000","99999"],"960":["00","19","93","93","200","659","690","699","6600","6899","7000","8499","9400","9799","85000","92999","98000","99999"],"961":["00","19","200","599","6000","8999","90000","94999"],"962":["00","19","200","699","900","999","7000","8499","8700","8999","85000","86999"],"963":["00","19","200","699","7000","8499","9000","9999","85000","89999"],"964":["00","14","150","249","300","549","970","989","2500","2999","5500","8999","9900","9999","90000","96999"],"965":["00","19","200","599","7000","7999","90000","99999"],"966":["00","12","14","14","130","139","170","199","279","289","300","699","910","949","980","999","1500","1699","2000","2789","2900","2999","7000","8999","90000","90999","95000","97999"],"967":["00","00","60","89","300","499","900","989","0100","0999","5000","5999","9900","9989","10000","19999","99900","99999"],"968":["01","39","400","499","800","899","5000","7999","9000","9999"],"969":["0","1","20","22","24","39","400","749","7500","9999","23000","23999"],"970":["01","59","600","899","9000","9099","9700","9999","91000","96999"],"971":["02","02","06","49","97","98","000","015","500","849","0160","0199","0300","0599","8500","9099","9600","9699","9900","9999","91000","95999"],"972":["0","1","20","54","550","799","8000","9499","95000","99999"],"973":["0","0","20","54","100","169","550","759","1700","1999","7600","8499","8900","9499","85000","88999","95000","99999"],"974":["00","19","200","699","7000","8499","9500","9999","85000","89999","90000","94999"],"975":["02","24","250","599","990","999","6000","9199","00000","01999","92000","98999"],"976":["0","3","40","59","600","799","8000","9499","95000","99999"],"977":["00","19","90","99","200","499","700","849","5000","6999","85000","89999"],"978":["000","199","900","999","2000","2999","8000","8999","30000","79999"],"979":["20","29","000","099","400","799","1000","1499","3000","3999","8000","9499","15000","19999","95000","99999"],"980":["00","19","200","599","6000","9999"],"981":["00","11","200","289","290","299","310","399","3000","3099","4000","9999","17000","19999"],"982":["00","09","70","89","100","699","9000","9799","98000","99999"],"983":["00","01","45","49","50","79","020","199","800","899","2000","3999","9000","9899","40000","44999","99000","99999"],"984":["00","39","400","799","8000","8999","90000","99999"],"985":["00","39","400","599","6000","8999","90000","99999"],"986":["00","11","120","559","5600","7999","80000","99999"],"987":["00","09","30","35","40","44","500","899","1000","1999","3600","3999","9000","9499","20000","29999","45000","49999","95000","99999"],"988":["00","11","200","799","8000","9699","12000","14999","15000","16999","17000","19999","97000","99999"],"9925":["0","2","30","54","550","734","7350","9999"],"9926":["0","1","20","39","400","799","8000","9999"],"9927":["00","09","100","399","4000","4999"],"9929":["0","3","40","54","550","799","8000","9999"],"9930":["00","49","500","939","9400","9999"],"9931":["00","29","300","899","9000","9999"],"9932":["00","39","400","849","8500","9999"],"9933":["0","0","10","39","400","899","9000","9999"],"9934":["0","0","10","49","500","799","8000","9999"],"9937":["0","2","30","49","500","799","8000","9999"],"9938":["00","79","800","949","9500","9999"],"9939":["0","4","50","79","800","899","9000","9999"],"9940":["0","1","20","49","500","899","9000","9999"],"9942":["00","84","900","984","8500","8999","9850","9999"],"9943":["00","29","300","399","975","999","4000","9749"],"9944":["60","69","80","89","100","499","700","799","900","999","0000","0999","5000","5999"],"9945":["00","00","08","39","57","57","010","079","400","569","580","849","8500","9999"],"9946":["0","1","20","39","400","899","9000","9999"],"9947":["0","1","20","79","800","999"],"9949":["0","0","10","39","75","89","400","749","9000","9999"],"9950":["00","29","300","849","8500","9999"],"9953":["0","0","10","39","60","89","400","599","9000","9999"],"9955":["00","39","400","929","9300","9999"],"9957":["00","39","70","84","88","99","400","699","8500","8799"],"9958":["00","01","10","18","20","49","020","029","040","089","500","899","0300","0399","0900","0999","1900","1999","9000","9999"],"9959":["0","1","20","79","98","99","800","949","970","979","9500","9699"],"9960":["00","59","600","899","9000","9999"],"9961":["0","2","30","69","700","949","9500","9999"],"9962":["00","54","56","59","600","849","5500","5599","8500","9999"],"9963":["0","1","30","54","250","279","550","734","2000","2499","2800","2999","7350","7499","7500","9999"],"9964":["0","6","70","94","950","999"],"9965":["00","39","400","899","9000","9999"],"9966":["20","69","000","149","750","959","1500","1999","7000","7499","9600","9999"],"9971":["0","5","60","89","900","989","9900","9999"],"9972":["1","1","00","09","30","59","200","249","600","899","2500","2999","9000","9999"],"9973":["00","05","10","69","060","089","700","969","0900","0999","9700","9999"],"9974":["0","2","30","54","95","99","550","749","7500","9499"],"9975":["0","0","45","89","100","299","900","949","3000","3999","4000","4499","9500","9999"],"9977":["00","89","900","989","9900","9999"],"9978":["00","29","40","94","300","399","950","989","9900","9999"],"9979":["0","4","50","64","66","75","650","659","760","899","9000","9999"],"9980":["0","3","40","89","900","989","9900","9999"],"9981":["00","09","20","79","100","159","800","949","1600","1999","9500","9999"],"9982":["00","79","800","989","9900","9999"],"9983":["80","94","950","989","9900","9999"],"9984":["00","49","500","899","9000","9999"],"9986":["00","39","97","99","400","899","940","969","9000","9399"],"9987":["00","39","400","879","8800","9999"],"9988":["0","2","30","54","550","749","7500","9999"],"9989":["0","0","30","59","100","199","600","949","2000","2999","9500","9999"],"99901":["00","49","80","99","500","799"],"99903":["0","1","20","89","900","999"],"99904":["0","5","60","89","900","999"],"99905":["0","3","40","79","800","999"],"99906":["0","2","30","59","70","89","90","94","600","699","950","999"],"99908":["0","0","10","89","900","999"],"99909":["0","3","40","94","950","999"],"99910":["0","2","30","89","900","999"],"99911":["00","59","600","999"],"99912":["0","3","60","89","400","599","900","999"],"99913":["0","2","30","35","600","604"],"99914":["0","4","50","89","900","999"],"99915":["0","4","50","79","800","999"],"99916":["0","2","30","69","700","999"],"99919":["0","2","40","69","70","79","300","399","800","849","850","899","900","999"],"99921":["0","1","8","8","20","69","90","99","700","799"],"99922":["0","3","40","69","700","999"],"99926":["0","0","10","59","87","89","90","99","600","869"],"99927":["0","2","30","59","600","999"],"99928":["0","0","10","79","800","999"],"99932":["0","0","7","7","10","59","80","99","600","699"],"99935":["0","2","7","8","30","59","90","99","600","699"],"99936":["0","0","10","59","600","999"],"99937":["0","1","20","59","600","999"],"99938":["0","1","20","59","90","99","600","899"],"99940":["0","0","10","69","700","999"],"99941":["0","2","30","79","800","999"],"99953":["0","2","30","79","94","99","800","939"],"99954":["0","2","30","69","88","99","700","879"],"99955":["0","1","20","59","80","99","600","799"],"99956":["00","59","86","99","600","859"],"99958":["0","4","50","93","940","949","950","999"],"99960":["0","0","10","94","950","999"],"99961":["0","3","40","89","900","999"],"99963":["00","49","92","99","500","919"],"99966":["0","2","30","69","80","94","700","799"],"99967":["0","1","20","59","600","899"],"99971":["0","5","60","84","850","999"],"99974":["40","79","800","999"],"99976":["0","1","20","59","600","799"]},"979":{"10":["00","19","200","699","7000","8999","90000","97599","976000","999999"],"11":["00","24","250","549","5500","8499","85000","94999","950000","999999"],"12":["200","200"]}};
+ ranges['978']['99968']=ranges['978']['99912'];ranges['978']['9935']=ranges['978']['9941']=ranges['978']['9956']=ranges['978']['9933'];ranges['978']['9976']=ranges['978']['9971'];ranges['978']['99949']=ranges['978']['99903'];ranges['978']['9968']=ranges['978']['9930'];ranges['978']['99929']=ranges['978']['99930']=ranges['978']['99931']=ranges['978']['99942']=ranges['978']['99944']=ranges['978']['99948']=ranges['978']['99950']=ranges['978']['99952']=ranges['978']['99962']=ranges['978']['99969']=ranges['978']['99915'];ranges['978']['99917']=ranges['978']['99910'];ranges['978']['99920']=ranges['978']['99970']=ranges['978']['99972']=ranges['978']['99914'];ranges['978']['99933']=ranges['978']['99943']=ranges['978']['99946']=ranges['978']['99959']=ranges['978']['99927'];ranges['978']['81']=ranges['978']['80'];ranges['978']['9967']=ranges['978']['9970']=ranges['978']['9965'];ranges['978']['9936']=ranges['978']['9952']=ranges['978']['9954']=ranges['978']['9926'];ranges['978']['99965']=ranges['978']['99922'];ranges['978']['9928']=ranges['978']['9927'];ranges['978']['99947']=ranges['978']['99916'];ranges['978']['9985']=ranges['978']['9939'];ranges['978']['99918']=ranges['978']['99925']=ranges['978']['99973']=ranges['978']['99975']=ranges['978']['99905'];ranges['978']['99939']=ranges['978']['99945']=ranges['978']['99904'];ranges['978']['989']=ranges['978']['972'];ranges['978']['620']=ranges['978']['613'];ranges['978']['4']=ranges['978']['0'];ranges['978']['99923']=ranges['978']['99924']=ranges['978']['99934']=ranges['978']['99957']=ranges['978']['99964']=ranges['978']['9947'];ranges['978']['614']=ranges['978']['609'];ranges['978']['9948']=ranges['978']['9951']=ranges['978']['9932'];
+ return ranges;
+})();
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
@@ -616,6 +616,32 @@ Zotero.Translate.Sandbox = {
if(setShortTitle) item.shortTitle = title;
}
+ /* Clean up ISBNs
+ * Allow multiple ISBNs, but...
+ * (1) validate all ISBNs
+ * (2) convert all ISBNs to ISBN-13
+ * (3) remove any duplicates
+ * (4) separate them with space
+ */
+ if (item.ISBN) {
+ // Match ISBNs with groups separated by various dashes or even spaces
+ var isbnRe = /\b(?:97[89][\s\x2D\xAD\u2010-\u2015\u2043\u2212]*)?(?:\d[\s\x2D\xAD\u2010-\u2015\u2043\u2212]*){9}[\dx](?![\x2D\xAD\u2010-\u2015\u2043\u2212])\b/gi,
+ validISBNs = [],
+ isbn;
+ while (isbn = isbnRe.exec(item.ISBN)) {
+ var validISBN = Zotero.Utilities.cleanISBN(isbn[0]);
+ if (!validISBN) {
+ // Back up and move up one character
+ isbnRe.lastIndex = isbn.index + 1;
+ continue;
+ }
+
+ var isbn13 = Zotero.Utilities.toISBN13(validISBN);
+ if (validISBNs.indexOf(isbn13) == -1) validISBNs.push(isbn13);
+ }
+ item.ISBN = validISBNs.join(' ');
+ }
+
// refuse to save very long tags
if(item.tags) {
for(var i=0; i<item.tags.length; i++) {
diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js
@@ -278,13 +278,20 @@ Zotero.Utilities = {
/**
* Clean and validate ISBN.
* Return isbn if valid, otherwise return false
+ * @param {String} isbn
+ * @param {Boolean} [dontValidate=false] Do not validate check digit
+ * @return {String|Boolean} Valid ISBN or false
*/
- "cleanISBN":function(/**String*/ isbn) {
+ "cleanISBN":function(isbn, dontValidate) {
isbn = isbn.replace(/[^0-9a-z]+/ig, '').toUpperCase() //we only want to ignore punctuation, spaces
- .match(/(?:97[89][0-9]{10}|[0-9]{9}[0-9X])/); //13 digit or 10 digit
+ .match(/\b(?:97[89][0-9]{10}|[0-9]{9}[0-9X])\b/); //13 digit or 10 digit
if(!isbn) return false;
isbn = isbn[0];
-
+
+ if (dontValidate && (isbn.length == 10 || isbn.length == 13)) {
+ return isbn;
+ }
+
if(isbn.length == 10) {
// Verify ISBN-10 checksum
var sum = 0;
@@ -310,6 +317,34 @@ Zotero.Utilities = {
return false;
},
+
+ /*
+ * Convert ISBN 10 to ISBN 13
+ * @param {String} isbn ISBN 10 or ISBN 13
+ * cleanISBN
+ * @return {String} ISBN-13
+ */
+ "toISBN13": function(isbn) {
+ if (!/^(?:97[89])?\d{9}[\dxX]$/.test(isbn)
+ && !(isbn = Zotero.Utilities.cleanISBN(isbn))
+ ) {
+ throw new Error('Invalid ISBN: ' + isbn);
+ }
+
+ if (isbn.length == 13) return isbn; // Recalculate check digit?
+
+ isbn = '978' + isbn.substr(0,9);
+
+ var sum = 0;
+ for (var i = 0; i < 12; i++) {
+ sum += isbn[i] * (i%2 ? 3 : 1);
+ }
+
+ var checkDigit = 10 - (sum % 10);
+ if (checkDigit == 10) checkDigit = 0;
+
+ return isbn + checkDigit;
+ },
/**
* Clean and validate ISSN.
@@ -1476,89 +1511,84 @@ Zotero.Utilities = {
/**
* Converts an item from toArray() format to citeproc-js JSON
- * @param {Zotero.Item} item
+ * @param {Zotero.Item} zoteroItem
* @return {Object} The CSL item
*/
- "itemToCSLJSON":function(item) {
- if(item instanceof Zotero.Item) {
- item = item.toArray();
+ "itemToCSLJSON":function(zoteroItem) {
+ if (zoteroItem instanceof Zotero.Item) {
+ zoteroItem = zoteroItem.toArray();
}
- var itemType = item.itemType;
- var cslType = CSL_TYPE_MAPPINGS[itemType];
- if(!cslType) cslType = "article";
+ var cslType = CSL_TYPE_MAPPINGS[zoteroItem.itemType] || "article";
+ var itemTypeID = Zotero.ItemTypes.getID(zoteroItem.itemType);
var cslItem = {
- 'id':item.itemID,
+ 'id':zoteroItem.itemID,
'type':cslType
};
- // Map text fields
- var itemTypeID = Zotero.ItemTypes.getID(itemType);
+ // get all text variables (there must be a better way)
for(var variable in CSL_TEXT_MAPPINGS) {
var fields = CSL_TEXT_MAPPINGS[variable];
for(var i=0, n=fields.length; i<n; i++) {
- var field = fields[i], value = undefined;
+ var field = fields[i],
+ value;
- if(field in item) {
- value = item[field];
+ if(field in zoteroItem) {
+ value = zoteroItem[field];
} else {
var fieldID = Zotero.ItemFields.getID(field),
- baseMapping
+ baseMapping;
if(Zotero.ItemFields.isValidForType(fieldID, itemTypeID)
&& (baseMapping = Zotero.ItemFields.getBaseIDFromTypeAndField(itemTypeID, fieldID))) {
- value = item[Zotero.ItemTypes.getName(baseMapping)];
+ value = zoteroItem[Zotero.ItemTypes.getName(baseMapping)];
}
}
- if(!value) continue;
+ if (!value) continue;
- var valueLength = value.length;
- if(valueLength) {
+ if (typeof value == 'string') {
+ if (field == 'ISBN') {
+ // Only use the first ISBN in CSL JSON
+ var isbn = value.match(/^(?:97[89]-?)?(?:\d-?){9}[\dx](?!-)\b/i);
+ if (isbn) value = isbn[0];
+ }
+
// Strip enclosing quotes
- if(value[0] === '"' && value[valueLength-1] === '"') {
- value = value.substr(1, valueLength-2);
+ if(value.charAt(0) == '"' && value.indexOf('"', 1) == value.length - 1) {
+ value = value.substring(1, value.length-1);
}
+ cslItem[variable] = value;
+ break;
}
-
- cslItem[variable] = value;
- break;
}
}
// separate name variables
- var authorID = Zotero.CreatorTypes.getPrimaryIDForType(itemTypeID);
- var authorFieldName = Zotero.CreatorTypes.getName(authorID);
- var creators = item.creators;
- if(creators) {
- for(var i=0, n=creators.length; i<n; i++) {
- var creator = creators[i];
-
- if(creator.creatorType == authorFieldName) {
- var creatorType = "author";
- } else {
- var creatorType = CSL_NAMES_MAPPINGS[creator.creatorType]
- }
-
- if(!creatorType) continue;
-
- if(creator.fieldMode == 1) {
- var nameObj = {'literal':creator.lastName};
- } else {
- var nameObj = {'family':creator.lastName, 'given':creator.firstName};
- }
-
- if(cslItem[creatorType]) {
- cslItem[creatorType].push(nameObj);
- } else {
- cslItem[creatorType] = [nameObj];
- }
+ var author = Zotero.CreatorTypes.getName(Zotero.CreatorTypes.getPrimaryIDForType(itemTypeID));
+ var creators = zoteroItem.creators;
+ for(var i=0; i<creators.length; i++) {
+ var creator = creators[i];
+ var creatorType = creator.creatorType;
+ if(creatorType == author) {
+ creatorType = "author";
+ }
+
+ creatorType = CSL_NAMES_MAPPINGS[creatorType];
+ if(!creatorType) continue;
+
+ var nameObj = {'family':creator.lastName, 'given':creator.firstName};
+
+ if(cslItem[creatorType]) {
+ cslItem[creatorType].push(nameObj);
+ } else {
+ cslItem[creatorType] = [nameObj];
}
}
// get date variables
for(var variable in CSL_DATE_MAPPINGS) {
- var date = item[CSL_DATE_MAPPINGS[variable]];
+ var date = zoteroItem[CSL_DATE_MAPPINGS[variable]];
if(date) {
var dateObj = Zotero.Date.strToDate(date);
// otherwise, use date-parts
@@ -1584,8 +1614,17 @@ Zotero.Utilities = {
}
}
}
+
+ // extract PMID
+ var extra = zoteroItem.extra;
+ if(typeof extra === "string") {
+ var m = /(?:^|\n)PMID:\s*([0-9]+)/.exec(extra);
+ if(m) cslItem.PMID = m[1];
+ m = /(?:^|\n)PMCID:\s*((?:PMC)?[0-9]+)/.exec(extra);
+ if(m) cslItem.PMCID = m[1];
+ }
- //this._cache[item.id] = cslItem;
+ //this._cache[zoteroItem.id] = cslItem;
return cslItem;
},
diff --git a/chrome/content/zotero/xpcom/utilities_internal.js b/chrome/content/zotero/xpcom/utilities_internal.js
@@ -350,6 +350,80 @@ Zotero.Utilities.Internal = {
childWindow = childWindow.parent;
if(childWindow === parentWindow) return true;
}
+ },
+
+ /**
+ * Hyphenate an ISBN based on the registrant table available from
+ * https://www.isbn-international.org/range_file_generation
+ * See isbn.js
+ *
+ * @param {String} isbn ISBN-10 or ISBN-13
+ * @param {Boolean} dontValidate Do not attempt to validate check digit
+ * @return {String} Hyphenated ISBN or empty string if invalid ISBN is supplied
+ */
+ "hyphenateISBN": function(isbn, dontValidate) {
+ isbn = Zotero.Utilities.cleanISBN(isbn, dontValidate);
+ if (!isbn) return '';
+
+ var ranges = Zotero.ISBN.ranges,
+ parts = [],
+ uccPref,
+ i = 0;
+ if (isbn.length == 10) {
+ uccPref = '978';
+ } else {
+ uccPref = isbn.substr(0,3);
+ if (!ranges[uccPref]) return ''; // Probably invalid ISBN, but the checksum is OK
+ parts.push(uccPref);
+ i = 3; // Skip ahead
+ }
+
+ var group = '',
+ found = false;
+ while (i < isbn.length-3 /* check digit, publication, registrant */) {
+ group += isbn.charAt(i);
+ if (ranges[uccPref][group]) {
+ parts.push(group);
+ found = true;
+ break;
+ }
+ i++;
+ }
+
+ if (!found) return ''; // Did not find a valid group
+
+ // Array of registrant ranges that are valid for a group
+ // Array always contains an even number of values (as string)
+ // From left to right, the values are paired so that the first indicates a
+ // lower bound of the range and the right indicates an upper bound
+ // The ranges are sorted by increasing number of characters
+ var regRanges = ranges[uccPref][group];
+
+ var registrant = '';
+ found = false;
+ i++; // Previous loop 'break'ed early
+ while (!found && i < isbn.length-2 /* check digit, publication */) {
+ registrant += isbn.charAt(i);
+
+ for(let j=0; j < regRanges.length && registrant.length >= regRanges[j].length; j+=2) {
+ if(registrant.length == regRanges[j].length
+ && registrant >= regRanges[j] && registrant <= regRanges[j+1] // Falls within the range
+ ) {
+ parts.push(registrant);
+ found = true;
+ break;
+ }
+ }
+
+ i++;
+ }
+
+ if (!found) return ''; // Outside of valid range, but maybe we need to update our data
+
+ parts.push(isbn.substring(i,isbn.length-1)); // Publication is the remainder up to last digit
+ parts.push(isbn.charAt(isbn.length-1)); // Check digit
+
+ return parts.join('-');
}
}
diff --git a/components/zotero-service.js b/components/zotero-service.js
@@ -46,6 +46,7 @@ const xpcomFilesAll = [
'translation/translate_firefox',
'translation/tlds',
'utilities',
+ 'isbn',
'utilities_internal',
'utilities_translate'
];