closes #280, BibTeX translator

- fixes date bugs
- fixes (again) an issue that would cause the "unresponsive script" dialog to appear when importing or exporting
This commit is contained in:
Simon Kornblith 2006-09-07 22:10:26 +00:00
parent f011c9b8be
commit 5028880d38
3 changed files with 466 additions and 11 deletions

View file

@ -188,8 +188,8 @@ var Scholar_File_Interface = new function() {
function _disableUnresponsive() {
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
_unresponsiveScriptPreference = prefService.getIntPref("dom.max_script_run_time");
prefService.setIntPref("dom.max_script_run_time", 0);
_unresponsiveScriptPreference = prefService.getIntPref("dom.max_chrome_script_run_time");
prefService.setIntPref("dom.max_chrome_script_run_time", 0);
}
/*
@ -198,7 +198,7 @@ var Scholar_File_Interface = new function() {
function _restoreUnresponsive() {
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
prefService.setIntPref("dom.max_script_run_time", _unresponsiveScriptPreference);
prefService.setIntPref("dom.max_chrome_script_run_time", _unresponsiveScriptPreference);
}
/*

View file

@ -787,22 +787,22 @@ Scholar.Date = new function(){
function formatDate(date) {
var string = "";
if(date.part != undefined) {
if(date.part) {
string += date.part+" ";
}
if(date.month != undefined) {
if(date.month != undefined && months[date.month]) {
// get short month strings from CSL interpreter
var months = CSL.getMonthStrings("long");
string += months[date.month];
if(date.day != undefined) {
if(date.day) {
string += " "+date.day+", ";
} else {
string += " ";
}
}
if(date.year != undefined) {
if(date.year) {
string += date.year;
}

View file

@ -1,4 +1,4 @@
-- 82
-- 83
-- Set the following timestamp to the most recent scraper update date
REPLACE INTO "version" VALUES ('repository', STRFTIME('%s', '2006-08-31 22:44:00'));
@ -5589,7 +5589,7 @@ var inputFieldMap = {
CY:"place"
};
// TODO: figure out if these are the best types for letter, interview, website, manuscript
// TODO: figure out if these are the best types for letter, interview, website
var typeMap = {
book:"BOOK",
bookSection:"CHAP",
@ -5598,7 +5598,7 @@ var typeMap = {
newspaperArticle:"NEWS",
thesis:"THES",
letter:"PCOMM",
manuscript:"UNPB",
manuscript:"PAMP",
interview:"PCOMM",
film:"MPCT",
artwork:"ART",
@ -5677,6 +5677,8 @@ function processTag(item, tag, value) {
var month = parseInt(dateParts[1]);
if(month) {
month--;
} else {
month = undefined;
}
item.date = Scholar.Utilities.formatDate({year:dateParts[0],
@ -5920,6 +5922,460 @@ function doExport() {
}
}');
REPLACE INTO "translators" VALUES ('9cb70025-a888-4a29-a210-93ec52da40d4', '2006-09-06 21:28:00', 3, 'BibTeX', 'Simon Kornblith', 'bib',
'Scholar.configure("dataMode", "block");
function detectImport() {
var block = "";
var read;
// read 20 chars out of the file
while(read = Scholar.read(1)) {
if(read == "%") {
// read until next newline
block = "";
while(Scholar.read(1) != "\n") {}
} else if(read == "\n" && block) {
break;
} else if(" \n\r\t".indexOf(read) == -1) {
block += read;
}
}
var re = /^@[a-zA-Z]+[\(\{]/;
if(re.test(block)) {
return true;
}
}',
'var fieldMap = {
address:"place",
chapter:"section",
edition:"edition",
number:"issue",
type:"type",
series:"series",
title:"title",
volume:"volume",
copyright:"rights",
isbn:"ISBN",
issn:"ISSN",
location:"archiveLocation",
url:"url"
};
var inputFieldMap = {
booktitle :"publicationTitle",
journal:"publicationTitle",
school:"publisher",
publisher:"publisher"
};
// TODO: figure out if these are the best types for letter, interview, website
var typeMap = {
book:"book",
bookSection:"inbook",
journalArticle:"article",
magazineArticle:"article",
newspaperArticle:"article",
thesis:"phdthesis",
letter:"misc",
manuscript:"unpublished",
interview:"misc",
film:"misc",
artwork:"misc",
website:"misc"
};
// supplements outputTypeMap for importing
// TODO: conference, inproceedings, techreport
var inputTypeMap = {
booklet:"book",
incollection:"bookSection",
manual:"book",
mastersthesis:"thesis",
misc:"book",
proceedings:"book"
};
/*
* three-letter month abbreviations. i assume these are the same ones that the
* docs say are defined in some appendix of the LaTeX book. (i don''t have the
* LaTeX book.)
*/
var months = ["jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"]
/*
* this is the character table for converting TeX to Unicode. sorry, Czech
* speakers; you''ll have to add your own (or stop using BibTeX!)
*/
var accentedCharacters = {
// grave accents
192:"\\`A", 224:"\\`a",
200:"\\`E", 232:"\\`e",
204:"\\`I", 236:"\\`i",
210:"\\`O", 242:"\\`o",
217:"\\`U", 249:"\\`u",
// acute accents
193:"\\''A", 225:"\\''a",
201:"\\''E", 233:"\\''e",
205:"\\''I", 237:"\\''i",
211:"\\''O", 243:"\\''o",
218:"\\''U", 250:"\\''u",
// circumflexes
194:"\\^A", 226:"\\^a",
202:"\\^E", 234:"\\^e",
206:"\\^I", 238:"\\^i",
212:"\\^O", 244:"\\^o",
219:"\\^U", 251:"\\^u",
// tildes
195:"\\~A", 227:"\\~a",
213:"\\~O", 245:"\\~o",
209:"\\~N", 241:"\\~n",
// umlauts
196:''\\"A'', 228:''\\"a'',
203:''\\"E'', 235:''\\"e'',
207:''\\"I'', 239:''\\"i'',
214:''\\"O'', 246:''\\"o'',
220:''\\"U'', 252:''\\"u'',
// cidillas
191:"\\c{C}", 231:"\\c{c}",
// AE norwegian tings
198:"{\\AE}", 230:"{\\ae}",
// o norwegian things
216:"{\\o}", 248:"{\\O}",
// a norweigan things
197:"{\\AA}", 229:"{\\aa}"
};
function processField(item, field, value) {
if(fieldMap[field]) {
item[fieldMap[field]] = value;
} else if(inputFieldMap[field]) {
item[inputFieldMap[field]] = value;
} else if(field == "author" || field == "editor") {
// parse authors/editors
var names = value.split(" and ");
for each(var name in names) {
item.creators.push(Scholar.Utilities.cleanAuthor(name, field,
(name.indexOf(",") != -1)));
}
} else if(field == "institution" || field == "organization") {
item.backupPublisher = value;
} else if(field == "month") {
var monthIndex = months.indexOf(value.toLowerCase());
if(monthIndex != -1) {
value = Scholar.Utilities.formatDate({month:monthIndex});
} else {
value += " ";
}
if(item.date) {
if(value.indexOf(item.date) != -1) {
// value contains year and more
item.date = value;
} else {
item.date = value+item.date;
}
} else {
item.date = value;
}
} else if(field == "year") {
if(item.date) {
if(item.date.indexOf(value) == -1) {
// date does not already contain year
item.date += value;
}
} else {
item.date = value;
}
} else if(field == "pages") {
item.pages = value.replace(/--/g, "-");
} else if(field == "note" || field == "annote") {
item.extra += "\n"+value;
} else if(field == "howpublished") {
item.extra += "\nPublished: "+value;
} else if(field == "keywords") {
if(value.indexOf(",") == -1) {
// keywords/tags
item.tags = value.split(" ");
} else {
item.tags = value.split(/, ?/g);
}
}
}
function getFieldValue() {
// read whitespace
var read = Scholar.read(1);
while(" \n\r\t".indexOf(read) != -1) {
read = Scholar.read(1);
}
var value = "";
// now, we have the first character of the field
if("0123456789".indexOf(read) != -1) {
// character is a number
while((read = Scholar.read(1)) && ("0123456789".indexOf(read) != -1)) {
value += read;
}
} else if(read == "{") {
// character is a brace
var openBraces = 1;
while(read = Scholar.read(1)) {
if(read == "{" && value[value.length-1] != "\\") {
openBraces++;
value += "{";
} else if(read == "}" && value[value.length-1] != "\\") {
openBraces--;
if(openBraces == 0) {
break;
} else {
value += "}";
}
} else {
value += read;
}
}
} else if(read == ''"'') {
var openBraces = 0;
while(read = Scholar.read(1)) {
if(read == "{" && value[value.length-1] != "\\") {
openBraces++;
value += "{";
} else if(read == "}" && value[value.length-1] != "\\") {
openBraces--;
value += "}";
} else if(read == ''"'' && openBraces == 0) {
break;
} else {
value += read;
}
}
}
if(value.length > 1) {
// replace accented characters (yucky slow)
for(var i in accentedCharacters) {
value = value.replace(accentedCharacters[i], i);
}
// kill braces
value = value.replace(/([^\\])[{}]+/g, "$1");
if(value[0] == "{") {
value = value.substr(1);
}
// chop off backslashes
value = value.replace(/([^\\])\\([#$%&~_^\\{}])/g, "$1$2");
value = value.replace(/([^\\])\\([#$%&~_^\\{}])/g, "$1$2");
if(value[0] == "\\" && "#$%&~_^\\{}".indexOf(value[1]) != -1) {
value = value.substr(1);
}
if(value[value.length-1] == "\\" && "#$%&~_^\\{}".indexOf(value[value.length-2]) != -1) {
value = value.substr(0, value.length-1);
}
value = value.replace(/\\\\/g, "\\");
value = value.replace(/\s+/g, " ");
}
return value;
}
function beginRecord(type, closeChar) {
type = type.toLowerCase()
if(inputTypeMap[type]) {
var item = new Scholar.Item(inputTypeMap[type]);
} else {
for(var i in typeMap) {
if(typeMap[i] == type) {
var item = new Scholar.Item(i);
break;
}
}
if(!item) {
Scholar.Utilities.debug("discarded item from BibTeX; type was "+type);
}
}
var field = "";
while(read = Scholar.read(1)) {
if(read == "=") { // equals begin a field
var value = getFieldValue();
if(item) {
processField(item, field.toLowerCase(), value);
}
field = "";
} else if(read == ",") { // commas reset
field = "";
} else if(read == closeChar) {
if(item) {
if(item.extra) item.extra = item.extra.substr(1); // chop \n
item.complete();
}
return;
} else if(" \n\r\t".indexOf(read) == -1) { // skip whitespace
field += read;
}
}
}
function doImport(attachments) {
// make regular expressions out of values
var newArray = new Array();
for(var i in accentedCharacters) {
newArray[String.fromCharCode(i)] = new RegExp(accentedCharacters[i].replace(/\\/g, "\\\\"), "g");
}
accentedCharacters = newArray;
var read = "", text = "", recordCloseElement = false;
var type = false;
while(read = Scholar.read(1)) {
if(read == "@") {
type = "";
} else if(type !== false) {
if(read == "{") { // possible open character
beginRecord(type, "}");
type = false;
} else if(read == "(") { // possible open character
beginRecord(type, ")");
type = false;
} else {
type += read;
}
}
}
}
function writeField(field, value) {
if(!value) return;
value = value.toString();
// replace naughty chars
value = value.replace(/([#$%&~_^\\{}])/g, "\\$1");
// replace accented characters
for(var i in accentedCharacters) {
value = value.replace(accentedCharacters[i], i);
}
// replace other accented characters
value = value.replace(/[\u0080-\uFFFF]/g, "?")
// write
Scholar.write(",\n\t"+field+" = {"+value+"}");
}
var numberRe = /^[0-9]+/;
function doExport() {
// switch keys and values of accented characters
var newArray = new Array();
for(var i in accentedCharacters) {
newArray["{"+accentedCharacters[i]+"}"] = new RegExp(String.fromCharCode(i), "g");
}
accentedCharacters = newArray;
Scholar.write("% BibTeX export generated by Zotero "+Scholar.Utilities.getVersion());
var first = true;
var citekeys = new Object();
var item;
while(item = Scholar.nextItem()) {
// determine type
if(!typeMap[item.itemType]) {
continue;
}
// create a unique citation key
var basekey = "";
if(item.creators && item.creators[0] && item.creators[0].lastName) {
basekey = item.creators[0].lastName.toLowerCase();
}
if(item.date) {
var date = Scholar.Utilities.strToDate(item.date);
if(date.year && numberRe.test(date.year)) {
basekey += date.year;
}
}
var citekey = basekey;
var i = 0;
while(citekeys[citekey]) {
i++;
citekey = basekey+"-"+i;
}
citekeys[citekey] = true;
// write citation key
Scholar.write((first ? "" : ",") + "\n\n@"+typeMap[item.itemType]+"{"+citekey);
first = false;
for(var field in fieldMap) {
if(item[fieldMap[field]]) {
writeField(field, item[fieldMap[field]]);
}
}
if(item.publicationTitle) {
if(item.itemType == "chapter") {
writeField("booktitle", item.publicationTitle);
} else {
writeField("journal", item.publicationTitle);
}
}
if(item.publisher) {
if(item.itemType == "thesis") {
writeField("school", item.publisher);
} else {
writeField("publisher", item.publisher);
}
}
if(item.creators && item.creators.length) {
// split creators into subcategories
var author = "";
var editor = "";
for each(var creator in item.creators) {
var creatorString = creator.lastName;
if(creator.firstName) creatorString += ", "+creator.firstName;
if(creator.creatorType == "editor") {
author += " and "+creatorString;
} else {
editor += " and "+creatorString;
}
}
if(author) {
writeField("author", author.substr(5));
}
if(editor) {
writeField("author", editor.substr(5));
}
}
if(item.date) {
// need to use non-localized abbreviation
if(date.month) {
writeField("month", months[date.month]);
}
if(date.year) {
writeField("year", date.year);
}
}
if(item.extra) {
writeField("note", item.extra);
}
if(item.tags && item.tags.length) {
writeField("keywords", item.tags.join(","));
}
Scholar.write("\n}");
}
}');
REPLACE INTO "translators" VALUES ('a6ee60df-1ddc-4aae-bb25-45e0537be973', '2006-07-16 17:18:00', 1, 'MARC', 'Simon Kornblith', 'marc',
'function detectImport() {
var marcRecordRegexp = /^[0-9]{5}[a-z ]{3}$/
@ -6039,7 +6495,6 @@ record.prototype.importBinary = function(record) {
// add a field to this record
record.prototype.addField = function(field, indicator, value) {
Scholar.Utilities.debug("adding field "+field+": "+value);
field = parseInt(field, 10);
// make sure indicator is the right length
if(indicator.length > this.indicatorLength) {