{ "translatorID": "6614a99-479a-4524-8e30-686e4d66663e", "label": "Nature Publishing Group", "creator": "Aurimas Vinckevicius", "target": "^https?://(?:[^/]+\\.)?(?:nature\\.com|palgrave-journals\\.com)(?::[\\d]+)?(?=/)[^?]*(?:/(?:journal|archive|research|topten|search|full|abs)/|/current_issue\\.htm|/most\\.htm)", "minVersion": "3.0", "maxVersion": "", "priority": 200, "inRepository": true, "translatorType": 4, "browserSupport": "gcsibv", "lastUpdated": "2014-01-11 14:00:00" } /** Copyright (c) 2012 Aurimas Vinckevicius This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ //mimetype map for supplementary attachments var suppTypeMap = { 'pdf': 'application/pdf', // 'zip': 'application/zip', 'doc': 'application/msword', 'xls': 'application/vnd.ms-excel', 'excel': 'application/vnd.ms-excel' }; function attachSupplementary(doc, item, next) { //nature's new website var attachAsLink = Z.getHiddenPref("supplementaryAsLink"); var suppDiv = doc.getElementById("supplementary-information"); if(suppDiv) { var fileClasses = ZU.xpath(suppDiv, './/div[contains(@class, "supp-info")]/h2'); for(var i=0, n=fileClasses.length; i abstract.length)) { item.abstractNote = abstract; } item.tags = getKeywords(doc) || []; if (item.notes) item.notes = []; if(item.ISSN && ZU.cleanISSN) { //introduced in 3.0.12 var issn = ZU.cleanISSN(item.ISSN); if(!issn) delete item.ISSN; else item.ISSN = issn; } else if(item.ISSN === "ERROR! NO ISSN") { delete item.ISSN; } next(item); }); translator.translate(); } function scrapeRIS(doc, url, next) { var navBar = doc.getElementById('articlenav') || doc.getElementById('extranav'); var risURL if(navBar) { risURL = doc.evaluate('//li[@class="export"]/a', navBar, null, XPathResult.ANY_TYPE, null).iterateNext(); if(!risURL) risURL = doc.evaluate('//a[normalize-space(text())="Export citation" and not(@href="#")]', navBar, null, XPathResult.ANY_TYPE, null).iterateNext(); } if(!risURL) risURL = doc.evaluate('//a[normalize-space(text())="RIS" and not(@href="#")]', doc, null, XPathResult.ANY_TYPE, null).iterateNext(); if(!risURL) risURL = doc.evaluate('//li[@class="download-citation"]/a', doc, null, XPathResult.ANY_TYPE, null).iterateNext(); if(!risURL) risURL = doc.evaluate('//a[normalize-space(text())="Export citation" and not(@href="#")]', doc, null, XPathResult.ANY_TYPE, null).iterateNext(); if(risURL) { risURL = risURL.href; ZU.doGet(risURL, function(text) { if(text.search(/^TY /m) != -1) { var translator = Zotero.loadTranslator('import'); translator.setTranslator('32d59d2d-b65a-4da4-b0a3-bdd3cfb979e7'); translator.setString(text); translator.setHandler('itemDone', function(obj, newItem) { newItem.notes = []; next(newItem); }) translator.setHandler('error', function() { next() }); translator.translate(); } else { next(); } }); } else { Z.debug('Could not find RIS export'); next(); } } function getMultipleNodes(doc, url) { var allHNodes = '*[self::h1 or self::h2 or self::h3 or self::h4 or self::h5]'; var nodex, titlex, linkx; var nodes = []; if (url.indexOf('/search/') != -1 || url.indexOf('/most.htm') != -1) { //search, "top" lists nodex = '//ol[@class="results-list" or @id="content-list"]/li'; titlex = './' + allHNodes + '/node()[not(self::span)]'; linkx = './' + allHNodes + '/a'; nodes = Zotero.Utilities.xpath(doc, nodex); } else { //Maybe there's a nice way to figure out which journal uses what style, but for now we'll just try one until it matches //these seem to be listed in order of frequency var styles = [ //ToC { 'nodex': '//tr[./td/span[@class="articletitle"]]', 'titlex': './td/span[@class="articletitle"]', 'linkx': './td/a[@class="contentslink" and substring(@href, string-length(@href)-3) != "pdf"][1]' //abstract or full text }, //oncogene { 'nodex': '//div[child::*[@class="atl"]]', 'titlex': './' + allHNodes + '[last()]/node()[not(self::span)]', //ignore "subheading" 'linkx': './p[@class="links" or @class="articlelinks"]/a[contains(text(),"Full Text") or contains(text(),"Full text")]' }, //embo journal { 'nodex': '//ul[@class="articles"]/li', 'titlex': './' + allHNodes + '[@class="article-title"]/node()[not(self::span)]', 'linkx': './ul[@class="article-links"]/li/a[contains(text(),"Full Text") or contains(text(),"Full text")]' }, //nature { 'nodex': '//ul[contains(@class,"article-list") or contains(@class,"collapsed-list")]/li', 'titlex': './/' + allHNodes + '/a', 'linkx': './/' + allHNodes + '/a' }, //archive (e.g. http://www.nature.com/bonekey/archive/type.html) { 'nodex': '//table[@class="archive"]/tbody/tr', 'titlex': './td/' + allHNodes + '[last()]/a', 'linkx': './td/' + allHNodes + '[last()]/a', }, //some more ToC (e.g. http://www.nature.com/nrcardio/journal/v5/n1s/index.html) { 'nodex': '//div[@class="container"]/div[./h4[@class="norm"] and ./p[@class="journal"]/a[@title]]', 'titlex': './h4[@class="norm"]', 'linkx': './p[@class="journal"]/a[@title][1]' } ]; for (var i = 0; i < styles.length && !nodes.length; i++) { nodex = styles[i].nodex; titlex = styles[i].titlex; linkx = styles[i].linkx; nodes = Zotero.Utilities.xpath(doc, nodex); } } if(nodes.length) Z.debug("multiples found using: " + nodex); return [nodes, titlex, linkx]; } function isNature(url) { return url.search(/^https?:\/\/(?:[^\/]+\.)?nature.com/) != -1; } function detectWeb(doc, url) { if (url.search(/\/(full|abs)\/[^\/]+($|\?|#)|\/fp\/.+?[?&]lang=ja(?:&|$)/) != -1) { return 'journalArticle'; } else if (doc.title.toLowerCase().indexOf('table of contents') != -1 //single issue ToC. e.g. http://www.nature.com/emboj/journal/v30/n1/index.html or http://www.nature.com/nature/journal/v481/n7381/index.html || doc.title.toLowerCase().indexOf('current issue') != -1 || url.indexOf('/research/') != -1 || url.indexOf('/topten/') != -1 || url.indexOf('/most.htm') != -1 || (url.indexOf('/vaop/') != -1 && url.indexOf('index.html') != -1) //advanced online publication || url.indexOf('sp-q=') != -1 //search query || url.search(/journal\/v\d+\/n\d+\/index\.html/i) != -1) { //more ToC return getMultipleNodes(doc, url)[0].length ? 'multiple' : null; } else if (url.indexOf('/archive/') != -1) { if (url.indexOf('index.htm') != -1) return false; //list of issues if (url.indexOf('subject.htm') != -1) return false; //list of subjects if (url.indexOf('category.htm') != -1 && url.indexOf('code=') == -1) return false; //list of categories return getMultipleNodes(doc, url)[0].length ? 'multiple' : null; //all else should be ok } } function supplementItem(item, supp, prefer) { for(var i in supp) { if(!supp.hasOwnProperty(i) || (item.hasOwnProperty(i) && prefer.indexOf(i) == -1)) { continue; //this also skips creators, tags, notes, and related } Z.debug('Supplementing item.' + i); item[i] = supp[i]; } return item; } function runScrapers(scrapers, done) { var items = []; var args = Array.prototype.splice.call(arguments, 2); //remove scrapers and done handler var run = function(item) { items.push(item); if(scrapers.length) { (scrapers.shift()).apply(null, args); } }; args.push(run); args.push(items); scrapers.push(function() { done(items); }); (scrapers.shift()).apply(null, args); } function scrape(doc, url) { runScrapers([scrapeEM, scrapeRIS], function(items) { var item = items[0]; if(!item) { //EM failed (unlikely) item = items[1]; } else if(items[1]) { var preferredRisFields = ['journalAbbreviation', 'date']; //palgrave-macmillan journals if(!isNature(url)) { preferredRisFields.push('publisher'); //all others are going to be dropped since we only handle journalArticle if(item.rights.indexOf('Nature Publishing Group') != -1) { delete item.rights; } } item = supplementItem(item, items[1], preferredRisFields); if(items[1].tags.length) item.tags = items[1].tags; //RIS doesn't seem to have tags, but we check just in case //RIS can properly split first and last name //but it does not (sometimes?) include accented letters //We try to get best of both worlds by trying to re-split EM authors correctly //hopefully the authors match up for(var i=0, j=0, n=item.creators.length, m=items[1].creators.length; i