{
"translatorID": "1a3506da-a303-4b0a-a1cd-f216e6138d86",
"label": "RefWorks Tagged Format",
"creator": "Simon Kornblith, Aurimas Vinckevicius, and Sebastian Karcher",
"target": "",
"minVersion": "3.0.4",
"maxVersion": "",
"priority": 100,
"displayOptions": {
"exportCharset": "UTF-8",
"exportNotes": true,
"exportFileData": true
},
"inRepository": true,
"translatorType": 3,
"browserSupport": "gcsv",
"lastUpdated": "2013-05-08 23:03:38"
}
/*This Translator mirrors closely Aurimas Vinckevicius' RIS translator
It may have several relics from that translator that aren't necessary for Refworks,
but since the formats are similar and having them in the translator won't hurt, I maintained them.
Most commenting also refers to RIS
The specifications are here:
http://www.refworks.com/refworks2/help/RefWorks_Tagged_Format.htm
*/
function detectImport() {
var line;
var i = 0;
while((line = Zotero.read()) !== false) {
line = line.replace(/^\s+/, "");
if(line != "") {
if(line.search(/^RT\s+./) != -1) {
return true;
} else {
if(i++ > 150) { //skip preamble
return false;
}
}
}
}
}
/********************
* Exported options *
********************/
var exportedOptions = {
itemType: false //allows translators to supply item type
};
/************************
* RT <-> itemType maps *
************************/
var DEFAULT_EXPORT_TYPE = 'Generic';
var DEFAULT_IMPORT_TYPE = 'journalArticle';
var exportTypeMap = {
artwork:"Artwork",
audioRecording:"Sound Recording", //consider MUSIC
bill:"Bills",
blogPost:"Web Page",
book:"Book, Whole",
bookSection:"Book, Section",
"case":"Case",
computerProgram:"Computer Program",
conferencePaper:"Conference Proceedings",
email:"Personal Communication",
film:"Motion Picture",
forumPost:"Online Discussion Forum",
hearing:"Hearing",
journalArticle:"Journal Article",
letter:"Personal Communication",
magazineArticle:"Magazine Article",
manuscript:"Unpublished Material",
map:"Map",
newspaperArticle:"Newspaper Article",
patent:"Patent",
report:"Report",
statute:"Statutes",
thesis:"Dissertation",
videoRecording:"Video",
webpage:"Web Page"
};
//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 RW types above
// or be different from the importTypeMap mappings
var degenerateExportTypeMap = {
interview:"Personal Communication",
instantMessage:"Personal Communication",
tvBroadcast:"Motion Picture",
radioBroadcast:"Sound Recording",
presentation:"Report",
podcast:"Sound Recording",
dictionaryEntry:"Book, Section",
encyclopediaArticle:"Book, Section",
document:"Generic" //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 = {
Abstract:"journalArticle",
"Book, Edited":"book",
"Court Decisions":"case",
DVD:"videoRecording",
Grant:"report",
"Journal, Electronic":"journalArticle",
Laws:"statute",
Monograph:"book",
"Music Score":"audioRecording",
Resolutions:"bill",
"Thesis, Unpublished":"thesis",
Thesis:"thesis"
};
//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 *
*****************************/
//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 RW types, see above)
var fieldMap = {
//same for all itemTypes
AB:"abstractNote",
CN:"callNumber",
DO:"DOI",
SL:"archive",
LL:"archiveLocation",
IS:"issue",
JO:"journalAbbreviation",
K1:"tags",
LK:"attachments/other",
NO:"notes",
ST:"shortTitle",
RD:"accessDate",
UL:"url",
//type specific
//tag => field:itemTypes
//if itemType not explicitly given, __default field is used
// unless itemType is excluded in __exclude
T1: {
"__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"],
seriesTitle:["audioRecording"]
},
//NOT HANDLED: reviewedAuthor, scriptwriter, contributor, guest
A1: {
"__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"],
"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", "report"]
},
A4: {
"__default":"creators/translator",
"creators/counsel":["case"],
"creators/contributor":["conferencePaper", "film"] //translator does not fit these
},
U1: {
filingDate:["patent"], //not in spec
"creators/castMember":["radioBroadcast", "tvBroadcast", "videoRecording"],
scale:["map"],
place:["conferencePaper"]
},
U2: {
issueDate:["patent"], //not in spec
"creators/bookAuthor":["bookSection"],
"creators/commenter":["blogPost"]
},
U3: {
artworkSize:["artwork"],
proceedingsTitle:["conferencePaper"],
country:["patent"]
},
U4: {
"creators/wordsBy":["audioRecording"], //not in spec
"creators/attorneyAgent":["patent"],
genre:["film"]
},
U5: {
references:["patent"],
audioRecordingFormat:["audioRecording", "radioBroadcast"],
videoRecordingFormat:["film", "tvBroadcast", "videoRecording"]
},
U6: {
legalStatus:["patent"],
},
PP: {
"__default":"place",
"__exclude":["conferencePaper"] //should be exported as C1
},
FD: {
"__default":"date",
dateEnacted:["statute"],
dateDecided:["case"],
issueDate:["patent"]
},
ED: {
"__default":"edition",
session:["bill", "hearing", "statute"],
version:["computerProgram"]
},
LA: {
"__default":"language",
programmingLanguage: ["computerProgram"]
},
CL: {
billNumber:["bill"],
system:["computerProgram"],
documentNumber:["hearing"],
applicationNumber:["patent"],
publicLawNumber:["statute"],
episodeNumber:["podcast", "radioBroadcast", "tvBroadcast"],
manuscriptType:["manuscript"],
mapType:["map"],
reportType:["report"],
thesisType:["thesis"],
websiteType:["blogPost", "webpage"],
postType:["forumPost"],
letterType:["letter"],
interviewMedium:["interview"],
presentationType:["presentation"],
artworkMedium:["artwork"],
audioFileType:["podcast"]
},
PB: {
"__default":"publisher",
label:["audioRecording"],
court:["case"],
distributor:["film"],
assignee:["patent"],
institution:["report"],
university:["thesis"],
company:["computerProgram"],
studio:["videoRecording"],
network:["radioBroadcast", "tvBroadcast"]
},
YR: { //duplicate of DA, but this will only output year
"__default":"date",
dateEnacted:["statute"],
dateDecided:["case"],
issueDate:["patent"]
},
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"]
},
VO: {
"__default":"volume",
codeNumber:["statute"],
codeVolume:["bill"],
reporterVolume:["case"],
"__exclude":["patent"]
}
};
//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 = {
OP: "pages",
JF: "publicationTitle",
JO: {
"__default": "journalAbbreviation",
conferenceName: ["conferencePaper"]
},
T2: "backupPublicationTitle", //most item types should be covered above
T3: {
series: ["book"]
}
};
//generic tag mapping object with caching
//not intended to be used directly
var TagMapper = function(mapList) {
this.cache = {};
this.mapList = mapList;
};
TagMapper.prototype.getFields = function(itemType, tag) {
if(!this.cache[itemType]) this.cache[itemType] = {};
//retrieve from cache if available
if(this.cache[itemType][tag]) {
return this.cache[itemType][tag];
}
var fields = [];
for(var i=0, n=this.mapList.length; i '
+ value.replace(/\n\n/g, ' ')
.replace(/\n/g, '
')
.replace(/\t/g, ' ')
.replace(/ /g, ' ')
+ '
" + note;
item.notes.push({note: note.trim(), tags: ['_RW import']});
}
}
item.unsupportedFields = undefined;
item.unknownFields = undefined;
item.complete();
}
//get the next RW entry that matches the RW format
//returns an array in the format [raw "line", tag, value]
//lines may be combined into one entry
var RW_format = /^([A-Z][A-Z0-9]) (?:(.*))?$/; //allow empty entries
function getLine() {
var entry, lastLineLength;
if(getLine.buffer) {
entry = getLine.buffer.match(RW_format); //this should always match
if(entry[2] === undefined) entry[2] = '';
lastLineLength = entry[2].length;
getLine.buffer = undefined;
}
var nextLine, temp;
while((nextLine = Zotero.read()) !== false) {
temp = nextLine.match(RW_format);
if(temp && temp[2] === undefined) temp[2] = '';
//if we are already processing an entry, then this is the next entry
//store this line for later and return
if(temp && entry) {
getLine.buffer = temp[0];
return entry;
//otherwise this is a new entry
} else if(temp) {
entry = temp;
lastLineLength = entry[2].length;
//if this line didn't match, then we just attach it to the current value
//Try to figure out if this is supposed to be on a new line or not
} else if(entry) {
//new lines would probably only be meaningful in notes and abstracts
if(entry[1] == 'AB' || entry[1] == 'NO') {
//if previous line was short, this would probably be on a new line
//Might consider looking for periods and capital letters
if(lastLineLength < 60) {
nextLine = "\r\n" + nextLine;
}
}
//don't remove new lines from keywords
if(entry[1] == 'K1') {
nextLine = "\r\n" + nextLine;
}
//check if we need to add a space
if(entry[2].substr(entry[2].length-1) != ' ') {
nextLine = ' ' + nextLine;
}
entry[0] += nextLine;
entry[2] += nextLine;
}
}
return entry;
}
//creates a new item of specified type
function getNewItem(type) {
var item = new Zotero.Item(type);
item.unknownFields = [];
item.unsupportedFields = [];
return item;
}
function doImport(attachments){
var entry;
//skip to the first RT entry
do {
entry = getLine();
} while(entry && entry[1] != 'RT');
var item;
var i = -1; //item counter for attachments
while(entry) {
switch(entry[1]) {
//new item
case 'RT':
if(item) completeItem(item);
var type = exportedOptions.itemType || importTypeMap[entry[2].trim()];
if(!type) {
type = DEFAULT_IMPORT_TYPE;
Z.debug("Unknown RW item type: " + entry[2] + ". Defaulting to " + type);
}
var item = getNewItem(type);
//add attachments
i++;
if(attachments && attachments[i]) {
item.attachments = attachments[i];
}
break;
default:
processTag(item, entry);
}
entry = getLine();
}
if(item) completeItem(item);
}
/********************
* Export Functions *
********************/
//[Not sure if this is true for RW but doesn't hurt] RW files have a certain structure, which is often meaningful
//Records always start with RT. This is hardcoded below
var exportOrder = {
"__default": ["T1", "A1", "T2", "A2", "T3", "A3", "A4", "AB", "U1", "U2", "U3",
"U4", "U5", "U6", "CN", "PP", "FD", "YR", "DO", "SL", "LL", "ED", "VO", "IS", "SP", "OP,",
"JO", "LA", "CL", "PB", "SN", "ST", "UL", "RD", "LK", "NO", "K1"],
//in bill sponsor (A2) and cosponsor (A3) should be together and not split by legislativeBody (T3)
"bill": ["T1", "A1", "T2", "A2", "A3", "T3", "A4", "AB", "U1", "U2", "U3",
"U4", "U5", "U6", "CN", "PP", "FD", "YR", "DO", "SL", "LL", "ED", "VO", "IS", "SP", "OP",
"JO", "LA", "CL", "PB", "SN", "ST", "UL", "RD", "LK", "NO", "K1"]
};
var newLineChar = "\r\n"; //from spec
//set up export field mapping
var exportFields = new TagMapper([fieldMap]);
function addTag(tag, value) {
if(!(value instanceof Array)) value = [value];
for(var i=0, n=value.length; i
Update Code: 20011116
" }, { "note": "The following values have no corresponding Zotero field:PO: Human; Male; Female; Adulthood (18 yrs & older); FE: References; Peer Reviewed; UD: 20020227; F1: 0191-8869,32,3,551-565,2002; A1: 20020227
" }, { "note": "The following values have no corresponding Zotero field:doi: 10.1086/374030
" }, { "note": "The following values have no corresponding Zotero field: