{ "translatorID": "1300cd65-d23a-4bbf-93e5-a3c9e00d1066", "label": "Primo", "creator": "Matt Burton, Avram Lyon, Etienne Cavalié, Rintze Zelle, Philipp Zumstein, Sebastian Karcher, Aurimas Vinckevicius", "target": "/primo_library/|/nebis/|^https?://www\\.recherche-portal\\.ch/zbz/", "minVersion": "2.1.9", "maxVersion": "", "priority": 100, "inRepository": true, "translatorType": 4, "browserSupport": "gcsb", "lastUpdated": "2014-09-23 21:03:41" } /* Supports Primo 2: Université de Nice, France (http://catalogue.unice.fr/) (looks like this is Primo3 now, too) Supports Primo 3 Boston College (http://www.bc.edu/libraries/), Oxford Libraries (http://solo.ouls.ox.ac.uk/) Primos with showPNX.jsp installed: (1) http://purdue-primo-prod.hosted.exlibrisgroup.com/primo_library/libweb/action/search.do?vid=PURDUE (2) http://primo.bib.uni-mannheim.de/primo_library/libweb/action/search.do?vid=MAN_UB (3) http://limo.libis.be/primo_library/libweb/action/search.do?vid=LIBISnet&fromLogin=true (4.a) http://virtuose.uqam.ca/primo_library/libweb/action/search.do?vid=UQAM (5) http://searchit.princeton.edu/primo_library/libweb/action/dlDisplay.do?docId=PRN_VOYAGER2778598&vid=PRINCETON&institution=PRN */ function getSearchResults(doc) { var linkXPaths = [ //order dictates preference './/li[starts-with(@id,"exlidResult") and substring(@id,string-length(@id)-10)="-DetailsTab"]/a[@href]', //details link './/h2[@class="EXLResultTitle"]/a[@href]' //title link ]; var resultsXPath = '//*[self::tr or self::div][starts-with(@id, "exlidResult") and ' + 'number(substring(@id,12))=substring(@id,12)][' + linkXPaths.join(' or ') + ']'; //Z.debug(resultsXPath); var results = ZU.xpath(doc, resultsXPath); results.titleXPath = './/h2[@class="EXLResultTitle"]'; results.linkXPaths = linkXPaths; return results; } function detectWeb(doc, url) { if(getSearchResults(doc).length) { return 'multiple'; } var contentDiv = doc.getElementsByClassName('EXLFullResultsHeader'); if(!contentDiv.length) contentDiv = doc.getElementsByClassName('EXLFullDisplay'); if(!contentDiv.length) contentDiv = doc.getElementsByClassName('EXLFullView'); if(contentDiv.length) return 'book'; } function doWeb(doc, url) { var searchResults = getSearchResults(doc); if(searchResults.length) { var items = {}, itemIDs = {}, title, link, linkXPaths = searchResults.linkXPaths; for(var i=0, n=searchResults.length; i]*\>/g, "") .replace(/(<\/?)\w+:([^\>]*)/g, "$1$2") //remove namespaces //remove ns declarations - we don't need them and they break this .replace(/<[^>]+/g, function(m) { return m.replace(/\s+xmlns(?::\w+)?\s*=\s*(['"]).*?\1/ig, ''); }); //Z.debug(text); var parser = new DOMParser(); var doc = parser.parseFromString(text, "text/xml"); var item = new Zotero.Item(); var itemType = ZU.xpathText(doc, '//display/type'); if(!itemType) { throw new Error('Could not locate item type'); } switch(itemType.toLowerCase()) { case 'book': case 'books': item.itemType = "book"; break; case 'audio': item.itemType = "audioRecording"; break; case 'video': item.itemType = "videoRecording"; break; case 'report': item.itemType = "report"; break; case 'webpage': item.itemType = "webpage"; break; case 'article': item.itemType = "journalArticle"; break; case 'thesis': item.itemType = "thesis"; break; case 'map': item.itemType = "map"; break; case 'newspaper_article': item.itemType="newspaperArticle"; break; default: item.itemType = "document"; } item.title = ZU.xpathText(doc, '//display/title'); if(item.title) item.title = ZU.unescapeHTML(item.title); var creators; var contributors; if(ZU.xpathText(doc, '//display/creator')) { creators = ZU.xpath(doc, '//display/creator'); } if(ZU.xpathText(doc, '//display/contributor')) { contributors = ZU.xpath(doc, '//display/contributor'); } if(!creators && contributors) { // not available using as author instead creators = contributors; contributors = null; } if(!creators && ! contributors){ creators = ZU.xpath(doc, '//addata/addau') } for(i in creators) { if(creators[i]) { var creator = ZU.unescapeHTML(creators[i].textContent).split(/\s*;\s*/); for(j in creator){ creator[j] = creator[j].replace(/\d{4}-(\d{4})?/g, ''); item.creators.push(Zotero.Utilities.cleanAuthor(creator[j], "author", true)); } } } for(i in contributors) { if(contributors[i]) { var contributor = ZU.unescapeHTML(contributors[i].textContent).split(/\s*;\s*/); for(j in contributor){ contributor[j] = contributor[j].replace(/\d{4}-(\d{4})?/g, ''); item.creators.push(Zotero.Utilities.cleanAuthor(contributor[j], "contributor", true)); } } } //PNX doesn't do well with institutional authors; This isn't perfect, but it helps: for(i in item.creators){ if(!item.creators[i].firstName){ item.creators[i].fieldMode=1; } } var publisher = ZU.xpathText(doc, '//display/publisher'); if(publisher) var pubplace = ZU.unescapeHTML(publisher).split(" : "); if(pubplace && pubplace[1]) { item.place = pubplace[0].replace(/,\s*c?\d+|[\(\)\[\]]|(\.\s*)?/g, ""); item.publisher = pubplace[1].replace(/,\s*c?\d+|[\(\)\[\]]|(\.\s*)?/g, "") .replace(/^\s*"|,?"\s*$/g, ''); } else if(pubplace) { item.publisher = pubplace[0].replace(/,\s*c?\d+|[\(\)\[\]]|(\.\s*)?/g, "") .replace(/^\s*"|,?"\s*$/g, ''); } var date = ZU.xpathText(doc, '//display/creationdate|//search/creationdate'); var m; if(date && (m = date.match(/\d+/))) { item.date = m[0]; } // the three letter ISO codes that should be in the language field work well: item.language = ZU.xpathText(doc, '//display/language'); var pages = ZU.xpathText(doc, '//display/format'); if(pages && pages.search(/[0-9]+/) != -1) { pages = pages.replace(/[\(\)\[\]]/g, "").match(/[0-9]+/); item.pages = item.numPages = pages[0]; } // The identifier field is supposed to have standardized format, but // the super-tolerant idCheck should be better than a regex. // (although note that it will reject invalid ISBNs) var locators = ZU.xpathText(doc, '//display/identifier'); if(locators) { item.ISBN = ZU.cleanISBN(locators); item.ISSN = ZU.cleanISSN(locators); } item.edition = ZU.xpathText(doc, '//display/edition'); var subjects = ZU.xpath(doc, '//search/subject'); for(var i=0, n=subjects.length; i