{ "translatorID": "fcf41bed-0cbc-3704-85c7-8062a0068a7a", "label": "NCBI PubMed", "creator": "Simon Kornblith, Michael Berkowitz, Avram Lyon, and Rintze Zelle", "target": "https?://[^/]*(www|preview)[\\.\\-]ncbi[\\.\\-]nlm[\\.\\-]nih[\\.\\-]gov[^/]*/(?:m/)?(books|pubmed|sites/pubmed|sites/entrez|entrez/query\\.fcgi\\?.*db=PubMed|myncbi/browse/collection/|myncbi/collections/)", "minVersion": "2.1.9", "maxVersion": "", "priority": 100, "configOptions": { "dataMode": "block" }, "inRepository": true, "translatorType": 13, "browserSupport": "gcsbv", "lastUpdated": "2014-06-20 04:23:04" } /***************************** * General utility functions * *****************************/ function lookupPMIDs(ids, next) { var newUri = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?" + "db=PubMed&tool=Zotero&retmode=xml&rettype=citation&id="+ids.join(","); Zotero.debug(newUri); Zotero.Utilities.HTTP.doGet(newUri, function(text) { //Z.debug(text); doImportFromText(text, next); }); //call the import translator } /**************************** * Web translator functions * ****************************/ //retrieves the UID from an item page. Returns false if there is more than one. function getUID(doc) { var uid = ZU.xpath(doc, 'html/head/meta[@name="ncbi_uidlist"]/@content'); if(!uid.length) { uid = ZU.xpath(doc, '//input[@id="absid"]/@value'); } if(uid.length == 1 && uid[0].textContent.search(/^\d+$/) != -1) { return uid[0].textContent; } uid = ZU.xpath(doc, 'html/head/link[@media="handheld"]/@href'); if(!uid.length) uid = ZU.xpath(doc, 'html/head/link[@rel="canonical"]/@href'); //mobile site if(uid.length == 1) { uid = uid[0].textContent.match(/\/(\d+)(?:\/|$)/); if(uid) return uid[1]; } //PMID from a bookshelf entry var maincontent = doc.getElementById('maincontent'); if(maincontent) { uid = ZU.xpath(maincontent, './/a[@title="PubMed record of this title" or @title="PubMed record of this page"]'); if(uid.length == 1 && uid[0].textContent.search(/^\d+$/) != -1) return uid; } return false; } // retrieve itemprop elements for scraping books directly from page where UID is not available function getBookProps(doc) { var main = doc.getElementById('maincontent'); if(!main) return; var itemprops = ZU.xpath(main, './/div[@itemtype="http://schema.org/Book"]//*[@itemprop]'); return itemprops.length ? itemprops : null; } // itemprop to Zotero field map var bookRDFaMap = { name: 'title', bookEdition: 'edition', author: 'creator/author', publisher: 'publisher', datePublished: 'date', isbn: 'ISBN', description: 'abstractNote' }; function scrapeItemProps(itemprops) { var item = new Zotero.Item('book'); for(var i=0; i 0 && url.indexOf("/books/") == -1) { return "multiple"; } if(!getUID(doc)) { if(getBookProps(doc)) return 'book'; return; } //try to determine if this is a book //"Sections" heading only seems to show up for books var maincontent = doc.getElementById('maincontent'); if(maincontent && ZU.xpath(maincontent, './/div[@class="sections"]').length) { var inBook = ZU.xpath(maincontent, './/div[contains(@class, "aff_inline_book")]').length; return inBook ? "bookSection" : "book"; } //from bookshelf page var pdid = ZU.xpathText(doc, 'html/head/meta[@name="ncbi_pdid"]/@content'); if(pdid == "book-part") return 'bookSection'; if(pdid == "book-toc") return 'book'; return "journalArticle"; } function doWeb(doc, url) { var type = detectWeb(doc, url); if(type == "multiple") { var results = getResultList(doc); var items = {}; var title, uid; for(var i=0, n=results.length; i // See http://www.ncbi.nlm.nih.gov/pubmed?term=1173[page]+AND+1995[pdat]+AND+Morton[author]&cmd=detailssearch // Discussed http://forums.zotero.org/discussion/17662 uids = doc.evaluate('//dl[@class="rprtid"]/dd[1]', doc, nsResolver, XPathResult.ANY_TYPE, null); uid = uids.iterateNext(); } if (uid) { ids.push(uid.textContent.match(/\d+/)[0]); Zotero.debug("Found PMID: " + ids[ids.length - 1]); lookupPMIDs(ids, doc); } else { var uids= doc.evaluate('//meta[@name="ncbi_uidlist"]', doc, nsResolver, XPathResult.ANY_TYPE, null); var uid = uids.iterateNext()["content"].split(' '); if (uid) { ids.push(uid); Zotero.debug("Found PMID: " + ids[ids.length - 1]); lookupPMIDs(ids, doc); } } } */ } /******************************* * Search translator functions * *******************************/ //extract PMID from a context object function getPMID(co) { var coParts = co.split("&"); for each(part in coParts) { if(part.substr(0, 7) == "rft_id=") { var value = unescape(part.substr(7)); if(value.substr(0, 10) == "info:pmid/") { return value.substr(10); } } } } function detectSearch(item) { if(item.contextObject) { if(getPMID(item.contextObject)) { return true; } } //supply PMID as a string or array if(item.PMID && (typeof item.PMID == 'string' || item.PMID.length > 0) ) { return true; } return false; } function doSearch(item) { var pmid; if(item.contextObject) { pmid = getPMID(item.contextObject); } if(!pmid) pmid = item.PMID; if(typeof pmid == "string") pmid = [pmid]; lookupPMIDs(pmid); } /******************************* * Import translator functions * *******************************/ function detectImport() { Zotero.debug("Detecting Pubmed content...."); // Look for the PubmedArticle tag in the first 1000 characters var text = Zotero.read(1000); if (text.indexOf("") != -1) return "journalArticle"; return false; } function doImport() { var text = ""; var line; while((line = Zotero.read(4096)) !== false) { text += line; } return doImportFromText(text); } function processAuthors(newItem, authorsLists) { for(var j=0, m=authorsLists.length; j") == -1) { // Pubmed data in the wild, perhaps copied from the web site's search results, // can be missing the root tag. Let's add a pair! Zotero.debug("No root tag found, wrapping in a new root tag."); text = "" + text + ""; } // parse XML with DOMParser var parser = new DOMParser(); var doc = parser.parseFromString(text, "text/xml"); var pageRangeRE = /(\d+)-(\d+)/g; //handle journal articles var articles = ZU.xpath(doc, '/PubmedArticleSet/PubmedArticle'); for(var i=0, n=articles.length; i 0) { pageRangeEnd = pageRangeStart.substring(0,diff) + pageRangeEnd; var newRange = pageRangeStart + "-" + pageRangeEnd; fullPageRange = fullPageRange.substring(0, range.index) //everything before current range + newRange //insert the new range + fullPageRange.substring(range.index + range[0].length); //everything after the old range //adjust RE index pageRangeRE.lastIndex += newRange.length - range[0].length; } } newItem.pages = fullPageRange; } var journal = ZU.xpath(article, 'Journal')[0]; if(journal) { newItem.ISSN = ZU.xpathText(journal, 'ISSN'); var abbreviation; if((abbreviation = ZU.xpathText(journal, 'ISOAbbreviation'))) { newItem.journalAbbreviation = abbreviation; } else if((abbreviation = ZU.xpathText(journal, 'MedlineTA'))) { newItem.journalAbbreviation = abbreviation; } var title = ZU.xpathText(journal, 'Title'); if(title) { title = ZU.trimInternal(title); // Fix sentence-cased titles, but be careful... if(!( // of accronyms that could get messed up if we fix case /\b[A-Z]{2}/.test(title) // this could mean that there's an accronym in the title && (title.toUpperCase() != title // the whole title isn't in upper case, so bail || !(/\s/.test(title))) // it's all in upper case and there's only one word, so we can't be sure )) { title = ZU.capitalizeTitle(title, true); } newItem.publicationTitle = title; } else if(newItem.journalAbbreviation) { newItem.publicationTitle = newItem.journalAbbreviation; } // (do we want this?) if(newItem.publicationTitle) { newItem.publicationTitle = ZU.capitalizeTitle(newItem.publicationTitle); } var journalIssue = ZU.xpath(journal, 'JournalIssue')[0]; if(journalIssue) { newItem.volume = ZU.xpathText(journalIssue, 'Volume'); newItem.issue = ZU.xpathText(journalIssue, 'Issue'); var pubDate = ZU.xpath(journalIssue, 'PubDate')[0]; if(pubDate) { // try to get the date var day = ZU.xpathText(pubDate, 'Day'); var month = ZU.xpathText(pubDate, 'Month'); var year = ZU.xpathText(pubDate, 'Year'); if(day) { newItem.date = month+" "+day+", "+year; } else if(month) { newItem.date = month+" "+year; } else if(year) { newItem.date = year; } else { newItem.date = ZU.xpathText(pubDate, 'MedlineDate'); } } } } var authorLists = ZU.xpath(article, 'AuthorList'); processAuthors(newItem, authorLists); newItem.language = ZU.xpathText(article, 'Language'); var keywords = ZU.xpath(citation, 'MeshHeadingList/MeshHeading'); for(var j=0, m=keywords.length; j