{ "translatorID": "05d07af9-105a-4572-99f6-a8e231c0daef", "label": "COinS", "creator": "Simon Kornblith", "target": "", "minVersion": "2.1", "maxVersion": "", "priority": 310, "inRepository": true, "translatorType": 6, "browserSupport": "gcsv", "lastUpdated": "2021-06-01 17:38:46" } /* ***** BEGIN LICENSE BLOCK ***** Copyright © 2021 Simon Kornblith and Abe Jellinek This file is part of Zotero. Zotero 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. Zotero 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 Zotero. If not, see . ***** END LICENSE BLOCK ***** */ function detectWeb(doc, _url) { var encounteredType = false; var spans = doc.querySelectorAll('span.Z3988[title]'); for (let span of spans) { // determine if it's a valid type var item = new Zotero.Item(); Zotero.Utilities.parseContextObject(span.title, item); if (item.itemType) { if (encounteredType) { return "multiple"; } else { encounteredType = item.itemType; } } } return encounteredType; } // Borrowed from Nature translator function supplementItem(item, supp, prefer, ignore) { if (!prefer) prefer = []; if (!ignore) ignore = []; for (var i in supp) { if (ignore.includes(i)) continue; if (i == 'creators' || i == 'attachments' || i == 'notes' || i == 'tags' || i == 'seeAlso' ) { if ((item.hasOwnProperty(i) && item[i].length) // Supplement only if completely empty || (!supp[i].length || typeof supp[i] == 'string') ) { continue; } } else if (!supp.hasOwnProperty(i) || (item.hasOwnProperty(i) && !prefer.includes(i))) { continue; } Z.debug('Supplementing item.' + i); item[i] = supp[i]; } return item; } // used to retrieve next COinS object when asynchronously parsing COinS objects // on a page function retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc) { if (needFullItems.length) { var item = needFullItems.shift(); Zotero.debug("Looking up contextObject"); var search = Zotero.loadTranslator("search"); search.setHandler("itemDone", function (obj, newItem) { supplementItem(newItem, item, [], ['contextObject', 'repository']); newItems.push(newItem); }); search.setHandler("done", function () { retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc); }); // Don't throw on error search.setHandler("error", function () { Zotero.debug("Failed to look up item:"); Zotero.debug(item); }); // look for translators search.setHandler("translators", function (obj, translators) { if (translators.length) { search.setTranslator(translators); search.translate(); } else { retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc); } }); search.setSearch(item); search.getTranslators(); } else { completeCOinS(newItems, couldUseFullItems, doc); Zotero.done(); } } // saves all COinS objects function completeCOinS(newItems, couldUseFullItems, doc) { if (newItems.length > 1) { var selectArray = new Array(newItems.length); for (var i in newItems) { selectArray[i] = newItems[i].title; } Zotero.selectItems(selectArray, function (selectArray) { if (!selectArray) return; var useIndices = []; for (var i in selectArray) { useIndices.push(i); } completeItems(newItems, useIndices, couldUseFullItems, doc); }); } else if (newItems.length) { completeItems(newItems, [0], couldUseFullItems, doc); } } function completeItems(newItems, useIndices, couldUseFullItems, doc) { if (!useIndices.length) { return; } var i = useIndices.shift(); // grab full item if the COinS was missing an author if (couldUseFullItems[i]) { Zotero.debug("Looking up contextObject"); var search = Zotero.loadTranslator("search"); var firstItem = false; search.setHandler("itemDone", function (obj, newItem) { supplementItem(newItem, newItems[i], [], ['contextObject', 'repository']); if (!firstItem) { // add doc as attachment newItem.attachments.push({ document: doc }); newItem.complete(); firstItem = true; } }); search.setHandler("done", function (_obj) { // if we didn't find anything, use what we had before (even if it // lacks the creator) if (!firstItem) { newItems[i].complete(); } // call next completeItems(newItems, useIndices, couldUseFullItems); }); // Don't throw on error search.setHandler("error", function () {}); search.setHandler("translators", function (obj, translators) { if (translators.length) { search.setTranslator(translators); search.translate(); } else { // add doc as attachment newItems[i].attachments.push({ document: doc }); newItems[i].complete(); // call next completeItems(newItems, useIndices, couldUseFullItems); } }); search.setSearch(newItems[i]); search.getTranslators(); } else { // add doc as attachment newItems[i].attachments.push({ document: doc }); newItems[i].complete(); // call next completeItems(newItems, useIndices, couldUseFullItems); } } function doWeb(doc, _url) { var newItems = []; var needFullItems = []; var couldUseFullItems = []; var spans = doc.querySelectorAll('span.Z3988[title]'); for (let span of spans) { var spanTitle = span.title; var newItem = new Zotero.Item(); newItem.repository = false; // do not save repository if (Zotero.Utilities.parseContextObject(spanTitle, newItem)) { if (newItem.title) { if (!newItem.creators.length) { // if we have a title but little other identifying // information, say we'll get full item later newItem.contextObject = spanTitle; couldUseFullItems[newItems.length] = true; } // title and creators are minimum data to avoid looking up newItems.push(newItem); } else { // retrieve full item newItem.contextObject = spanTitle; needFullItems.push(newItem); } } } Zotero.debug(needFullItems); if (needFullItems.length) { // retrieve full items asynchronously Zotero.wait(); retrieveNextCOinS(needFullItems, newItems, couldUseFullItems, doc); } else { completeCOinS(newItems, couldUseFullItems, doc); } } function doExport() { var item; var co; while ((item = Zotero.nextItem())) { co = Zotero.Utilities.createContextObject(item, "1.0"); if (co) { Zotero.write("\n"); } } } /** BEGIN TEST CASES **/ var testCases = [ { "type": "web", "url": "http://husdal.com/2011/06/19/disruptions-in-supply-networks/", "items": [ { "itemType": "journalArticle", "title": "Disruptions and supply networks: a multi-level, multi-theoretical relational perspective", "creators": [ { "firstName": "Phil", "lastName": "Greening", "creatorType": "author" }, { "firstName": "Christine", "lastName": "Rutherford", "creatorType": "author" } ], "date": "2011", "issue": "1", "pages": "104-126", "publicationTitle": "International Journal of Logistics Management", "shortTitle": "Disruptions and supply networks", "volume": "22", "attachments": [ { "mimeType": "text/html" } ], "tags": [], "notes": [], "seeAlso": [] } ] }, { "type": "web", "url": "http://gamblershouse.wordpress.com/2011/06/19/the-view-from-dolores/", "items": "multiple" }, { "type": "web", "url": "https://www.worldcat.org/title/genealogy-of-the-royal-family-of-great-britain-shewing-the-descent-of-queen-victoria-through-five-of-the-saxon-kings-who-were-crowned-at-kingston-upon-thames/oclc/559794003&referer=brief_results", "items": [ { "itemType": "book", "title": "The Genealogy of the Royal Family of Great Britain, shewing the descent of ... Queen Victoria, through five of the Saxon Kings who were crowned ... at Kingston-upon-Thames.", "creators": [ { "lastName": "Royal Families (England)", "isInstitution": true }, { "lastName": "GENEALOGY", "creatorType": "author" } ], "date": "1850", "place": "London", "publisher": "C. & E. Layton", "attachments": [ { "mimeType": "text/html" } ], "tags": [], "notes": [], "seeAlso": [] } ] } ] /** END TEST CASES **/