{
	"translatorID": "25f4c5e2-d790-4daa-a667-797619c7e2f2",
	"label": "CSV",
	"creator": "Philipp Zumstein and Aurimas Vinckevicius",
	"target": "csv",
	"minVersion": "4.0.26",
	"maxVersion": "",
	"priority": 100,
	"displayOptions": {
		"exportCharset": "UTF-8xBOM",
		"exportNotes": false
	},
	"inRepository": true,
	"translatorType": 2,
	"lastUpdated": "2022-06-28 19:45:59"
}

/*
	***** BEGIN LICENSE BLOCK *****

	Copyright © 2014 Philipp Zumstein, Aurimas Vinckevicius

	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 <http://www.gnu.org/licenses/>.

	***** END LICENSE BLOCK *****
*/

// The export will be stuck if you try to export to a csv-file
// which is already opend with Excel. Thus, close it before or rename
// the new csv-file.

var recordDelimiter = "\n",
	fieldDelimiter = ",",
	fieldWrapperCharacter = '"',
	replaceNewlinesWith = " ", // Set to `false` for no replacement
	valueSeparator = "; "; // For multi-value fields, like creators, tags, etc.
var normalizeDate = true; // Set to `false` if the date should be written as it is

// Exported columns in order of export
var exportedFields = [
	// "Important" metadata
	"key",
	"itemType",
	"publicationYear",
	"creators/author",
	"title",
	"publicationTitle",
	"ISBN",
	"ISSN",
	"DOI",
	"url",
	"abstractNote",
	"date",
	"dateAdded",
	"dateModified",
	// Other common fields
	"accessDate",
	"pages",
	"numPages",
	"issue",
	"volume",
	"numberOfVolumes",
	"journalAbbreviation",
	"shortTitle",
	"series",
	"seriesNumber",
	"seriesText",
	"seriesTitle",
	"publisher",
	"place",
	"language",
	"rights",
	"type",
	"archive",
	"archiveLocation",
	"libraryCatalog",
	"callNumber",
	"extra",
	"notes",
	"attachments/path",
	"attachments/url",
	"tags/own",
	"tags/automatic",
	// Creators
	"creators/editor",
	"creators/seriesEditor",
	"creators/translator",
	"creators/contributor",
	"creators/attorneyAgent",
	"creators/bookAuthor",
	"creators/castMember",
	"creators/commenter",
	"creators/composer",
	"creators/cosponsor",
	"creators/counsel",
	"creators/interviewer",
	"creators/producer",
	"creators/recipient",
	"creators/reviewedAuthor",
	"creators/scriptwriter",
	"creators/wordsBy",
	"creators/guest",
	// Other fields
	"number",
	"edition",
	"runningTime",
	"scale",
	"medium",
	"artworkSize",
	"filingDate",
	"applicationNumber",
	"assignee",
	"issuingAuthority",
	"country",
	"meetingName",
	"conferenceName",
	"court",
	"references",
	"reporter",
	"legalStatus",
	"priorityNumbers",
	"programmingLanguage",
	"version",
	"system",
	"code",
	"codeNumber",
	"section",
	"session",
	"committee",
	"history",
	"legislativeBody"
];

// Creators that should map to base type
var creatorBaseTypes = {
	interviewee: 'author',
	director: 'author',
	artist: 'author',
	sponsor: 'author',
	contributor: 'author',
	inventor: 'author',
	cartographer: 'author',
	performer: 'author',
	presenter: 'author',
	podcaster: 'author',
	programmer: 'author'
};

var exportNotes;
function doExport() {
	exportNotes = Zotero.getOption("exportNotes");
	// Until we fix UTF-8xBOM export, we'll write the BOM manually
	Zotero.write("\uFEFF");
	writeColumnHeaders();
	var item;
	while ((item = Zotero.nextItem())) {
		if (item.itemType == "note" || item.itemType == "attachment") continue;
		let line = '';
		for (let i = 0; i < exportedFields.length; i++) {
			line += (i ? fieldDelimiter : recordDelimiter)
				+ getValue(item, exportedFields[i]);
		}
		Zotero.write(line);
	}
}

var escapeRE = new RegExp(fieldWrapperCharacter, 'g');
function escapeValue(str) {
	if (typeof replaceNewlinesWith == 'string') {
		str = str.replace(/[\r\n]+/g, replaceNewlinesWith);
	}
	
	return str.replace(escapeRE, fieldWrapperCharacter + '$&');
}

function writeColumnHeaders() {
	var line = '';
	for (let i = 0; i < exportedFields.length; i++) {
		line += (i ? fieldDelimiter : '') + fieldWrapperCharacter;
		var label = exportedFields[i].split('/');
		switch (label[0]) {
			case 'creators':
				label = label[1];
				break;
			case 'tags':
				label = (label[1] == 'own' ? 'Manual Tags' : 'Automatic Tags');
				break;
			case 'attachments':
				label = (label[1] == 'url' ? 'Link Attachments' : 'File Attachments');
				break;
			default:
				label = label[0];
		}
		// Split individual words in labels and capitalize property
		label = label[0].toUpperCase() + label.substr(1);
		label = label.replace(/([a-z])([A-Z])/g, '$1 $2');
		
		line += escapeValue(label) + fieldWrapperCharacter;
	}
	Zotero.write(line);
}

function getValue(item, field) {
	var split = field.split('/'), value = fieldWrapperCharacter;
	switch (split[0]) {
		// Get key from URI (which on translation-server might just be the key)
		case 'key':
			value += item.uri.match(/([A-Z0-9]+)$/)[1];
			break;
		case 'publicationYear':
			if (item.date) {
				var date = ZU.strToDate(item.date);
				if (date.year) value += escapeValue(date.year);
			}
			break;
		case 'creators':
			var creators = [];
			for (let i = 0; i < item.creators.length; i++) {
				var creator = item.creators[i];
				var baseCreator = creatorBaseTypes[creator.creatorType];
				if (creator.creatorType != split[1] && baseCreator !== split[1]) {
					continue;
				}
				creators.push(creator.lastName
					+ (creator.firstName ? ', ' + creator.firstName : ''));
			}
			value += escapeValue(creators.join(valueSeparator));
			break;
		case 'tags':
			var tags = [];
			var tagType = split[1] == 'automatic' ? 1 : 0;
			for (let i = 0; i < item.tags.length; i++) {
				if ((item.tags[i].type || 0) === tagType) {
					tags.push(item.tags[i].tag);
				}
			}
			value += escapeValue(tags.join(valueSeparator));
			break;
		case 'attachments':
			var paths = [];
			for (let i = 0; i < item.attachments.length; i++) {
				if (split[1] == 'path') {
					paths.push(item.attachments[i].localPath);
				}
				else if (split[1] == 'url' && !item.attachments[i].localPath) {
					paths.push(item.attachments[i].url);
				}
			}
			value += escapeValue(paths.join(valueSeparator));
			break;
		case 'notes':
			if (!exportNotes) break;
			var notes = [];
			for (let i = 0; i < item.notes.length; i++) {
				notes.push(item.notes[i].note);
			}
			value += escapeValue(notes.join(valueSeparator));
			break;
		case 'date':
			if (item.date) {
				var dateISO = ZU.strToISO(item.date);
				if (normalizeDate && dateISO) {
					value += dateISO;
				}
				else {
					value += item.date;
				}
			}
			break;
		default:
			if (item[field] || (item.uniqueFields && item.uniqueFields[field])) {
				value += escapeValue('' + (item[field] || (item.uniqueFields && item.uniqueFields[field])));
			}
	}
	return value + fieldWrapperCharacter;
}

/** BEGIN TEST CASES **/
var testCases = [
]
/** END TEST CASES **/
