{ "translatorID": "a6ee60df-1ddc-4aae-bb25-45e0537be973", "label": "MARC", "creator": "Simon Kornblith, Sylvain Machefert", "target": "marc", "minVersion": "2.1.9", "maxVersion": "", "priority": 100, "inRepository": true, "translatorType": 1, "browserSupport": "gcsv", "lastUpdated": "2014-03-09 19:19:22" } function detectImport() { var marcRecordRegexp = /^[0-9]{5}[a-z ]{3}$/ var read = Zotero.read(8); if(marcRecordRegexp.test(read)) { return true; } } //test var fieldTerminator = "\x1E"; var recordTerminator = "\x1D"; var subfieldDelimiter = "\x1F"; /* * CLEANING FUNCTIONS */ // general purpose cleaning function clean(value) { value = value.replace(/^[\s\.\,\/\:;]+/, ''); value = value.replace(/[\s\.\,\/\:;]+$/, ''); value = value.replace(/ +/g, ' '); var char1 = value.substr(0, 1); var char2 = value.substr(value.length-1); if((char1 == "[" && char2 == "]") || (char1 == "(" && char2 == ")")) { // chop of extraneous characters return value.substr(1, value.length-2); } return value; } // number extraction function pullNumber(text) { var pullRe = /[0-9]+/; var m = pullRe.exec(text); if(m) { return m[0]; } } // ISBN extraction function pullISBN(text) { var pullRe = /[0-9X\-]+/; var m = pullRe.exec(text); if(m) { return m[0]; } } // corporate author extraction function corpAuthor(author) { return {lastName:author, fieldMode:true}; } // regular author extraction function author(author, type, useComma) { return Zotero.Utilities.cleanAuthor(author, type, useComma); } /* * END CLEANING FUNCTIONS */ var record = function() { this.directory = new Object(); this.leader = ""; this.content = ""; // defaults this.indicatorLength = 2; this.subfieldCodeLength = 2; } // import a binary MARC record into this record record.prototype.importBinary = function(record) { // get directory and leader var directory = record.substr(0, record.indexOf(fieldTerminator)); this.leader = directory.substr(0, 24); var directory = directory.substr(24); // get various data this.indicatorLength = parseInt(this.leader.substr(10, 1), 10); this.subfieldCodeLength = parseInt(this.leader.substr(11, 1), 10); var baseAddress = parseInt(this.leader.substr(12, 5), 10); // get record data var contentTmp = record.substr(baseAddress); // MARC wants one-byte characters, so when we have multi-byte UTF-8 // sequences, add null characters so that the directory shows up right. we // can strip the nulls later. this.content = ""; for(i=0; i 0x00FFFF) { this.content += "\x00\x00\x00"; } else if(contentTmp.charCodeAt(i) > 0x0007FF) { this.content += "\x00\x00"; } else if(contentTmp.charCodeAt(i) > 0x00007F) { this.content += "\x00"; } } // read directory for(var i=0; i this.indicatorLength) { indicator = indicator.substr(0, this.indicatorLength); } else if(indicator.length != this.indicatorLength) { indicator = Zotero.Utilities.lpad(indicator, " ", this.indicatorLength); } // add terminator value = indicator+value+fieldTerminator; // add field to directory if(!this.directory[field]) { this.directory[field] = new Array(); } this.directory[field].push([this.content.length, value.length]); // add field to record this.content += value; } // get all fields with a certain field number record.prototype.getField = function(field) { field = parseInt(field, 10); var fields = new Array(); // make sure fields exist if(!this.directory[field]) { return fields; } // get fields for(var i in this.directory[field]) { var location = this.directory[field][i]; // add to array, replacing null characters fields.push([this.content.substr(location[0], this.indicatorLength), this.content.substr(location[0]+this.indicatorLength, location[1]-this.indicatorLength-1).replace(/\x00/g, "")]); } return fields; } //given a field string, split it into subfields record.prototype.extractSubfields = function(fieldStr, tag /*for error message only*/) { if(!tag) tag = ''; returnSubfields = new Object(); var subfields = fieldStr.split(subfieldDelimiter); if (subfields.length == 1) { returnSubfields["?"] = fieldStr; } else { for(var j in subfields) { if(subfields[j]) { var subfieldIndex = subfields[j].substr(0, this.subfieldCodeLength-1); if(!returnSubfields[subfieldIndex]) { returnSubfields[subfieldIndex] = subfields[j].substr(this.subfieldCodeLength-1); } else { // Duplicate subfield Zotero.debug("Duplicate subfield '"+tag+" "+subfieldIndex+"="+subfields[j]); returnSubfields[subfieldIndex] = returnSubfields[subfieldIndex] + " " + subfields[j].substr(this.subfieldCodeLength-1); } } } } return returnSubfields; } // get subfields from a field record.prototype.getFieldSubfields = function(tag) { // returns a two-dimensional array of values var fields = this.getField(tag); var returnFields = new Array(); for(var i=0, n=fields.length; i=2 digits if (!pagerange) pagerange - locators.match(/(\d\d+\-\d+)/); if (pagerange) item.pages = pagerange[1]; var date = locators. match(/((Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\.?\s*)?\d{4}/); if (date){ item.date = date[0]; } if (locators.match(/vol\.\s*(\d+)/)) { item.volume = locators.match(/vol\.\s*(\d+)/i)[1]; } if (locators.match(/vol\.\s*\d+\s*,\s*no\.\s*(\d+)/i)) { item.issue = locators.match(/vol\.\s*\d+\s*,\s*no\.\s*(\d+)/i)[1]; } if(!item.volume && locators.match(/\d+:\d+/)){ item.volume = locators.match(/(\d+):\d+/)[1]; item.issue = locators.match(/\d+:(\d+)/)[1] } item.ISSN = container['x']; } } } } //editors get mapped as contributors - but so do many others who should be // --> for books that don't have an author, turn contributors into editors. if (item.itemType=="book"){ var hasAuthor = false; for (var i=0; i 1) { records[0] = holdOver + records[0]; holdOver = records.pop(); // skip last record, since it's not done for(var i in records) { var newItem = new Zotero.Item(); // create new record var rec = new record(); rec.importBinary(records[i]); rec.translate(newItem); newItem.complete(); } } else { holdOver += text; } } } var exports = { "record":record, "fieldTerminator":fieldTerminator, "recordTerminator":recordTerminator, "subfieldDelimiter":subfieldDelimiter }; /** BEGIN TEST CASES **/ var testCases = [ { "type": "import", "input": "01841cam a2200385Ma 45\u00020001000700000005001700007008004100024010001700065035002300082035001800105040003000123043001200153050001500165049001500180100003900195245028100234260005900515300006100574500019500635500014500830510003000975510002701005510004501032500002601077610004401103600004001147600004801187650004501235610004501280852005801325946003101383910001001414994001201424947001901436\u001e790862\u001e20080120004008.0\u001e880726s1687 sp bf 000 0cspa d\u001e \u001fa 03021876 \u001e \u001fa(OCoLC)ocm29051663\u001e \u001fa(NBYdb)790862\u001e \u001faMNU\u001fcMNU\u001fdOCL\u001fdDIBAM\u001fdIBV\u001e \u001fas-py---\u001e0 \u001faF2681\u001fb.X3\u001e \u001faIBVA\u001flbklr\u001e1 \u001faXarque, Francisco,\u001fdca. 1609-1691.\u001e10\u001faInsignes missioneros de la Compañia de Jesus en la prouincia del Paraguay :\u001fbestado presente de sus missiones en Tucuman, Paraguay, y Rio de la Plata, que comprehende su distrito /\u001fcpor el doct. d. Francisco Xarque, dean de la Catredral [sic] de Santa Maria de Albarrazin ...\u001e \u001faEn Pamplona :\u001fbPor Juan Micòn, Impressor,\u001fcaño 1687.\u001e \u001fa[24], 432 p., [1] folded leaf of plates :\u001fbmap ;\u001fc22 cm.\u001e \u001faBrunet and Graesse both mention a map of Paraguay; this copy has a map of Chile with title: Tabula geocraphica [sic] regni Chile / studio et labore P. Procuratoris Chilensis Societatis Jesu.\u001e \u001faIn 3 books; the first two are biographies of Jesuits, Simon Mazeta and Francisco Diaz Taño, the 3rd deals with Jesuit missions in Paraguay.\u001e4 \u001faNUC pre-1956,\u001fcNX0000604.\u001e4 \u001faSabin,\u001fc105716 (v.29).\u001e4 \u001faPalau y Dulcet (2nd ed.),\u001fc123233 (v.7).\u001e \u001faHead and tail pieces.\u001e20\u001faJesuits\u001fzParaguay\u001fvEarly works to 1800.\u001e10\u001faMasseta, Simon,\u001fdca. 1582-ca. 1656.\u001e10\u001faCuellar y Mosquera, Gabriel de,\u001fd1593-1677.\u001e 0\u001faMissions\u001fzParaguay\u001fvEarly works to 1800.\u001e20\u001faJesuits\u001fvBiography\u001fvEarly works to 1800.\u001e8 \u001fbvau,ayer\u001fkVAULT\u001fhAyer\u001fi1343\u001fi.J515\u001fiP211\u001fiX2\u001fi1687\u001ft1\u001e \u001faOCLC RECON PROJECT\u001farc3758\u001e \u001fa35535\u001e \u001fa02\u001fbIBV\u001e \u001faMARS\u001fa20071227\u001e\u001d", "items": [ { "itemType": "book", "creators": [ { "firstName": "Francisco", "lastName": "Xarque", "creatorType": "author" } ], "notes": [ { "note": "Brunet and Graesse both mention a map of Paraguay; this copy has a map of Chile with title: Tabula geocraphica [sic] regni Chile / studio et labore P. Procuratoris Chilensis Societatis Jesu In 3 books; the first two are biographies of Jesuits, Simon Mazeta and Francisco Diaz Taño, the 3rd deals with Jesuit missions in Paraguay Head and tail pieces" } ], "tags": [ "Masseta, Simon", "Cuellar y Mosquera, Gabriel de", "Missions", "Paraguay" ], "seeAlso": [], "attachments": [], "title": "Insignes missioneros de la Compañia de Jesus en la prouincia del Paraguay: estado presente de sus missiones en Tucuman, Paraguay, y Rio de la Plata, que comprehende su distrito", "place": "En Pamplona", "publisher": "Por Juan Micòn, Impressor", "date": "1687", "numPages": "24", "callNumber": "VAULT Ayer 1343 .J515 P211 X2 1687" } ] } ] /** END TEST CASES **/