{ "translatorID": "32d59d2d-b65a-4da4-b0a3-bdd3cfb979e7", "label": "RIS", "creator": "Simon Kornblith and Aurimas Vinckevicius", "target": "ris", "minVersion": "3.0.4", "maxVersion": "", "priority": 100, "configOptions": { "getCollections": "true" }, "displayOptions": { "exportCharset": "UTF-8", "exportNotes": true, "exportFileData": false }, "inRepository": true, "translatorType": 3, "browserSupport": "gcsv", "lastUpdated": "2014-06-10 04:10:54" } function detectImport() { var line; var i = 0; while((line = Zotero.read()) !== false) { line = line.replace(/^\s+/, ""); if(line != "") { if(line.substr(0, 6).match(/^TY {1,2}- /)) { return true; } else { if(i++ > 3) { return false; } } } } } /******************** * Exported options * ********************/ //exported as translatorObject.options var exportedOptions = { itemType: false, //allows translators to override item type defaultItemType: false, //item type to default to typeMap: false, fieldMap: false }; /************************ * TY <-> itemType maps * ************************/ var DEFAULT_EXPORT_TYPE = 'GEN'; var DEFAULT_IMPORT_TYPE = 'journalArticle'; var exportTypeMap = { artwork:"ART", audioRecording:"SOUND", //consider MUSIC bill:"BILL", blogPost:"BLOG", book:"BOOK", bookSection:"CHAP", "case":"CASE", computerProgram:"COMP", conferencePaper:"CONF", dictionaryEntry:"DICT", encyclopediaArticle:"ENCYC", email:"ICOMM", film:"MPCT", hearing:"HEAR", journalArticle:"JOUR", letter:"PCOMM", magazineArticle:"MGZN", manuscript:"MANSCPT", map:"MAP", newspaperArticle:"NEWS", patent:"PAT", presentation:"SLIDE", report:"RPRT", statute:"STAT", thesis:"THES", videoRecording:"VIDEO", webpage:"ELEC" }; //These export type maps are degenerate //They will cause loss of information when exported and reimported //These should either be duplicates of some of the RIS types above // or be different from the importTypeMap mappings var degenerateExportTypeMap = { interview:"PCOMM", instantMessage:"ICOMM", forumPost:"ICOMM", tvBroadcast:"MPCT", radioBroadcast:"SOUND", podcast:"SOUND", document:"GEN" //imported as journalArticle }; //These are degenerate types that are not exported as the same TY value //These should not include any types from exportTypeMap //We add the rest from exportTypeMap var importTypeMap = { ABST:"journalArticle", ADVS:"film", AGGR:"document", //how can we handle "database" citations? ANCIENT:"document", CHART:"artwork", CLSWK:"book", CPAPER:"conferencePaper", CTLG:"magazineArticle", DATA:"document", //dataset DBASE:"document", //database EBOOK:"book", ECHAP:"bookSection", EDBOOK:"book", EJOUR:"journalArticle", EQUA:"document", //what's a good way to handle this? FIGURE:"artwork", GEN:"journalArticle", GOVDOC:"report", GRNT:"document", INPR:"manuscript", JFULL:"journalArticle", LEGAL:"case", //is this what they mean? MULTI:"videoRecording", //maybe? MUSIC:"audioRecording", PAMP:"manuscript", SER:"book", STAND:"report", UNBILL:"manuscript", UNPD:"manuscript", WEB:"webpage" //not in spec, but used by EndNote }; //supplement input map with export var ty; for(ty in exportTypeMap) { importTypeMap[exportTypeMap[ty]] = ty; } //merge degenerate export type map into main list for(ty in degenerateExportTypeMap) { exportTypeMap[ty] = degenerateExportTypeMap[ty]; } /***************************** * Tag <-> zotero field maps * *****************************/ /** Syntax * { * RIS-TAG: * String, Zotero field used for any item type * List, item-type dependent mapping * { * Zotero field: Zotero item type array. Map RIS tag to the specified Zotero field for indicated item types * "__ignore": Zotero item type array. Ignore this RIS tag for indicated item types. Do not place it in a note * "__default": Zotero field. If not matched by above, map RIS tag to this field, unless... * "__exclude": Zotero item type array. Do not use the __default mapping for these item types * } * } * * Special "Zotero fields" * "attachments/[PDF|HTML|other]": import as attachment with a provided path/url * "creators/...": map to a specified creator type * "unsupported/...": there is no corresponding Zotero field, but we can provide a human-readable label for the data and attach it as note */ //used for exporting and importing //this ensures that we can mostly reimport everything the same way //(except for item types that do not have unique RIS types, see above) var fieldMap = { //same for all itemTypes AB:"abstractNote", AN:"archiveLocation", CN:"callNumber", DB:"archive", DO:"DOI", DP:"libraryCatalog", J2:"journalAbbreviation", KW:"tags", L1:"attachments/PDF", L2:"attachments/HTML", L4:"attachments/other", N1:"notes", ST:"shortTitle", UR:"url", Y2:"accessDate", //type specific //tag => field:itemTypes //if itemType not explicitly given, __default field is used // unless itemType is excluded in __exclude TI: { "__default":"title", subject:["email"], caseName:["case"], nameOfAct:["statute"] }, T2: { code:["bill", "statute"], bookTitle:["bookSection"], blogTitle:["blogPost"], conferenceName:["conferencePaper"], dictionaryTitle:["dictionaryEntry"], encyclopediaTitle:["encyclopediaArticle"], committee:["hearing"], forumTitle:["forumPost"], websiteTitle:["webpage"], programTitle:["radioBroadcast", "tvBroadcast"], meetingName:["presentation"], seriesTitle:["computerProgram", "map", "report"], series: ["book"], publicationTitle:["journalArticle", "magazineArticle", "newspaperArticle"] }, T3: { legislativeBody:["hearing", "bill"], series:["bookSection", "conferencePaper", "journalArticle"], seriesTitle:["audioRecording"] }, //NOT HANDLED: reviewedAuthor, scriptwriter, contributor, guest AU: { "__default":"creators/author", "creators/artist":["artwork"], "creators/cartographer":["map"], "creators/composer":["audioRecording"], "creators/director":["film", "radioBroadcast", "tvBroadcast", "videoRecording"], //this clashes with audioRecording "creators/interviewee":["interview"], "creators/inventor":["patent"], "creators/podcaster":["podcast"], "creators/programmer":["computerProgram"] }, A2: { "creators/sponsor":["bill"], "creators/performer":["audioRecording"], "creators/presenter":["presentation"], "creators/interviewer":["interview"], "creators/editor":["journalArticle", "bookSection", "conferencePaper", "dictionaryEntry", "document", "encyclopediaArticle"], "creators/seriesEditor":["book", "report"], "creators/recipient":["email", "instantMessage", "letter"], reporter:["case"], issuingAuthority:["patent"] }, A3: { "creators/cosponsor":["bill"], "creators/producer":["film", "tvBroadcast", "videoRecording", "radioBroadcast"], "creators/editor":["book"], "creators/seriesEditor":["bookSection", "conferencePaper", "dictionaryEntry", "encyclopediaArticle", "map"] }, A4: { "__default":"creators/translator", "creators/counsel":["case"], "creators/contributor":["conferencePaper", "film"] //translator does not fit these }, C1: { filingDate:["patent"], //not in spec "creators/castMember":["radioBroadcast", "tvBroadcast", "videoRecording"], scale:["map"], place:["conferencePaper"] }, C2: { issueDate:["patent"], //not in spec "creators/bookAuthor":["bookSection"], "creators/commenter":["blogPost"] }, C3: { artworkSize:["artwork"], proceedingsTitle:["conferencePaper"], country:["patent"] }, C4: { "creators/wordsBy":["audioRecording"], //not in spec "creators/attorneyAgent":["patent"], genre:["film"] }, C5: { references:["patent"], audioRecordingFormat:["audioRecording", "radioBroadcast"], videoRecordingFormat:["film", "tvBroadcast", "videoRecording"] }, C6: { legalStatus:["patent"], }, CY: { "__default":"place", "__exclude":["conferencePaper"] //should be exported as C1 }, DA: { //also see PY when editing "__default":"date", dateEnacted:["statute"], dateDecided:["case"], issueDate:["patent"] }, ET: { "__default":"edition", // "__ignore":["journalArticle"], //EPubDate session:["bill", "hearing", "statute"], version:["computerProgram"] }, IS: { "__default":"issue", numberOfVolumes: ["bookSection"] }, LA: { "__default":"language", programmingLanguage: ["computerProgram"] }, M1: { seriesNumber:["book"], billNumber:["bill"], system:["computerProgram"], documentNumber:["hearing"], applicationNumber:["patent"], publicLawNumber:["statute"], episodeNumber:["podcast", "radioBroadcast", "tvBroadcast"] }, M3: { manuscriptType:["manuscript"], mapType:["map"], reportType:["report"], thesisType:["thesis"], websiteType:["blogPost", "webpage"], postType:["forumPost"], letterType:["letter"], interviewMedium:["interview"], presentationType:["presentation"], artworkMedium:["artwork"], audioFileType:["podcast"] }, NV: { "__default": "numberOfVolumes", "__exclude": ["bookSection"] //IS }, OP: { history:["hearing", "statute", "bill", "case"], priorityNumbers:["patent"] }, PB: { "__default":"publisher", label:["audioRecording"], court:["case"], distributor:["film"], assignee:["patent"], institution:["report"], university:["thesis"], company:["computerProgram"], studio:["videoRecording"], network:["radioBroadcast", "tvBroadcast"] }, PY: { //duplicate of DA, but this will only output year "__default":"date", dateEnacted:["statute"], dateDecided:["case"], issueDate:["patent"] }, SE: { "__default": "section", //though this can refer to pages, start page, etc. for some types. Zotero does not support any of those combinations, however. "__exclude": ["case"] }, SN: { "__default":"ISBN", ISSN:["journalArticle", "magazineArticle", "newspaperArticle"], patentNumber:["patent"], reportNumber:["report"], }, SP: { "__default":"pages", //needs extra processing codePages:["bill"], //bill numPages:["book", "thesis", "manuscript"], //manuscript not really in spec firstPage:["case"], runningTime:["film"] }, SV: { seriesNumber: ["bookSection"], docketNumber: ["case"] //not in spec. EndNote exports this way }, VL: { "__default":"volume", codeNumber:["statute"], codeVolume:["bill"], reporterVolume:["case"], "__exclude":["patent", "webpage"] } }; //non-standard or degenerate field maps //used ONLY for importing and only if these fields are not specified above (e.g. M3) //these are not exported the same way var degenerateImportFieldMap = { A1: fieldMap["AU"], AD: { "__default": "unsupported/Author Address", "unsupported/Inventor Address": ["patent"] }, AV: "archiveLocation", //REFMAN BT: { title: ["book", "manuscript"], bookTitle: ["bookSection"], "__default": "backupPublicationTitle" //we do more filtering on this later }, CA: "unsupported/Caption", CR: "rights", CT: "title", ED: "creators/editor", EP: "pages", ID: "__ignore", JA: "journalAbbreviation", JF: "publicationTitle", JO: { "__default": "journalAbbreviation", conferenceName: ["conferencePaper"] }, LB: "unsupported/Label", M1: { "__default":"extra", issue: ["journalArticle"], //EndNote hack numberOfVolumes: ["bookSection"], //EndNote exports here instead of IS accessDate: ["webpage"] //this is access date when coming from EndNote }, M2: "extra", //not in spec M3: "DOI", N2: "abstractNote", NV: "numberOfVolumes", OP: { "__default": "unsupported/Original Publication", "unsupported/Content": ["blogPost", "computerProgram", "film", "presentation", "report", "videoRecording", "webpage"] }, RI: { "__default":"unsupported/Reviewed Item", "unsupported/Article Number": ["statute"] }, RN: "unsupported/Research Notes", SE: { "unsupported/File Date": ["case"] }, T1: fieldMap["TI"], T2: "backupPublicationTitle", //most item types should be covered above T3: { series: ["book"] }, TA: "unsupported/Translated Author", TT: "unsupported/Translated Title", VL: { "unsupported/Patent Version Number":['patent'], accessDate: ["webpage"] //technically access year according to EndNote }, Y1: fieldMap["PY"] }; /** * @class Generic tag mapping with caching * * @param {Tag <-> zotero field map []} mapList An array of field map lists as * described above. Lists are matched in order they are supplied. If a tag is * not present in the list, the next list is checked. If the RIS tag is * present, but an item type does not match (no __default) or is explicit * excluded from matching (__exclude), the next list is checked. */ var TagMapper = function(mapList) { this.cache = {}; this.reverseCache = {}; this.mapList = mapList; }; /** * Given an item type and a RIS tag, return Zotero field data should be mapped to. * Mappings are cached. * * @param {String} itemType Zotero item type * @param {String} tag RIS tag * @return {String} Zotero field */ TagMapper.prototype.getField = function(itemType, tag) { if(!this.cache[itemType]) this.cache[itemType] = {}; //retrieve from cache if available //it can be false if previous search did not find a mapping if(this.cache[itemType][tag] !== undefined) { return this.cache[itemType][tag]; } var field = false; for(var i=0, n=this.mapList.length; i