Restructure and comment cite.js

This commit is contained in:
Simon Kornblith 2012-07-14 22:26:29 -04:00
parent 0deb2573cc
commit de2d1669fe

View File

@ -1,152 +1,22 @@
Zotero.Cite = function(){} /**
Zotero.Cite.System = function(){}; * Utility functions for dealing with citations
* @namespace
*/
Zotero.Cite = {
/**
* Locator labels
*/
"labels":["page", "book", "chapter", "column", "figure", "folio",
"issue", "line", "note", "opus", "paragraph", "part", "section", "sub verbo",
"volume", "verse"],
Zotero.Cite.System._quotedRegexp = /^".+"$/; /**
* Remove specified item IDs in-place from a citeproc-js bibliography object returned
// TODO: Clear this cache from time to time * by makeBibliography()
Zotero.Cite.System._cache = new Object(); * @param {bib} citeproc-js bibliography object
* @param {Array} itemsToRemove Array of items to remove
Zotero.Cite.System.retrieveItem = function(item) { */
var zoteroItem, slashIndex; "removeFromBibliography":function(bib, itemsToRemove) {
if(item instanceof Zotero.Item) {
//if(this._cache[item.id]) return this._cache[item.id];
zoteroItem = item;
} else {
var type = typeof item;
if(type === "string" && (slashIndex = item.indexOf("/")) !== -1) {
// is an embedded item
var sessionID = item.substr(0, slashIndex);
var session = Zotero.Integration.sessions[sessionID]
if(session) {
var embeddedCitation = session.embeddedItems[item.substr(slashIndex+1)];
if(embeddedCitation) {
embeddedCitation.id = item;
return embeddedCitation;
}
}
} else {
// is an item ID
//if(this._cache[item]) return this._cache[item];
zoteroItem = Zotero.Items.get(item);
}
}
if(!zoteroItem) {
throw "Zotero.Cite.getCSLItem called to wrap a non-item "+item;
}
// don't return URL or accessed information for journal articles if a
// pages field exists
var itemType = Zotero.ItemTypes.getName(zoteroItem.itemTypeID);
var cslType = CSL_TYPE_MAPPINGS[itemType];
if(!cslType) cslType = "article";
var ignoreURL = ((zoteroItem.getField("accessDate", true, true) || zoteroItem.getField("url", true, true)) &&
["journalArticle", "newspaperArticle", "magazineArticle"].indexOf(itemType) !== -1
&& zoteroItem.getField("pages")
&& !Zotero.Prefs.get("export.citePaperJournalArticleURL"));
var cslItem = {
'id':zoteroItem.id,
'type':cslType
};
// get all text variables (there must be a better way)
// TODO: does citeproc-js permit short forms?
for(var variable in CSL_TEXT_MAPPINGS) {
var fields = CSL_TEXT_MAPPINGS[variable];
if(variable == "URL" && ignoreURL) continue;
for each(var field in fields) {
var value = zoteroItem.getField(field, false, true).toString();
if(value != "") {
// Strip enclosing quotes
if(value.match(Zotero.Cite.System._quotedRegexp)) {
value = value.substr(1, value.length-2);
}
cslItem[variable] = value;
break;
}
}
}
// separate name variables
var authorID = Zotero.CreatorTypes.getPrimaryIDForType(zoteroItem.itemTypeID);
var creators = zoteroItem.getCreators();
for each(var creator in creators) {
if(creator.creatorTypeID == authorID) {
var creatorType = "author";
} else {
var creatorType = Zotero.CreatorTypes.getName(creator.creatorTypeID);
}
var creatorType = CSL_NAMES_MAPPINGS[creatorType];
if(!creatorType) continue;
var nameObj = {'family':creator.ref.lastName, 'given':creator.ref.firstName};
if(cslItem[creatorType]) {
cslItem[creatorType].push(nameObj);
} else {
cslItem[creatorType] = [nameObj];
}
}
// get date variables
for(var variable in CSL_DATE_MAPPINGS) {
var date = zoteroItem.getField(CSL_DATE_MAPPINGS[variable], false, true);
if(date) {
var dateObj = Zotero.Date.strToDate(date);
// otherwise, use date-parts
var dateParts = [];
if(dateObj.year) {
// add year, month, and day, if they exist
dateParts.push(dateObj.year);
if(dateObj.month !== undefined) {
dateParts.push(dateObj.month+1);
if(dateObj.day) {
dateParts.push(dateObj.day);
}
}
cslItem[variable] = {"date-parts":[dateParts]};
// if no month, use season as month
if(dateObj.part && !dateObj.month) {
cslItem[variable].season = dateObj.part;
}
} else {
// if no year, pass date literally
cslItem[variable] = {"literal":date};
}
}
}
//this._cache[zoteroItem.id] = cslItem;
return cslItem;
};
Zotero.Cite.System.retrieveLocale = function(lang) {
var protHandler = Components.classes["@mozilla.org/network/protocol;1?name=chrome"]
.createInstance(Components.interfaces.nsIProtocolHandler);
try {
var channel = protHandler.newChannel(protHandler.newURI("chrome://zotero/content/locale/csl/locales-"+lang+".xml", "UTF-8", null));
var rawStream = channel.open();
} catch(e) {
return false;
}
var converterStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
converterStream.init(rawStream, "UTF-8", 65535,
Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
var str = {};
converterStream.readString(channel.contentLength, str);
converterStream.close();
return str.value;
};
Zotero.Cite.System.getAbbreviations = function() {
return {};
}
Zotero.Cite.removeFromBibliography = function(bib, itemsToRemove) {
var removeItems = []; var removeItems = [];
for(let i in bib[0].entry_ids) { for(let i in bib[0].entry_ids) {
for(let j in bib[0].entry_ids[i]) { for(let j in bib[0].entry_ids[i]) {
@ -160,9 +30,15 @@ Zotero.Cite.removeFromBibliography = function(bib, itemsToRemove) {
bib[0].entry_ids.splice(removeItems[i], 1); bib[0].entry_ids.splice(removeItems[i], 1);
bib[1].splice(removeItems[i], 1); bib[1].splice(removeItems[i], 1);
} }
} },
Zotero.Cite.getBibliographyFormatParameters = function(bib) { /**
* Convert formatting data from citeproc-js bibliography object into explicit format
* parameters for RTF or word processors
* @param {bib} citeproc-js bibliography object
* @return {Object} Bibliography style parameters.
*/
"getBibliographyFormatParameters":function getBibliographyFormatParameters(bib) {
var bibStyle = {"tabStops":[], "indent":0, "firstLineIndent":0, var bibStyle = {"tabStops":[], "indent":0, "firstLineIndent":0,
"lineSpacing":(240*bib[0].linespacing), "lineSpacing":(240*bib[0].linespacing),
"entrySpacing":(240*bib[0].entryspacing)}; "entrySpacing":(240*bib[0].entryspacing)};
@ -183,16 +59,17 @@ Zotero.Cite.getBibliographyFormatParameters = function(bib) {
} }
return bibStyle; return bibStyle;
} },
/** /**
* Makes a formatted bibliography, if the style defines one; otherwise makes a formatted list of * Makes a formatted bibliography, if the style defines one; otherwise makes a
* items * formatted list of items
* @param {Zotero.Style} style The style to use * @param {Zotero.Style} style The style to use
* @param {Zotero.Item[]} items An array of items * @param {Zotero.Item[]} items An array of items
* @param {String} format The format of the output * @param {String} format The format of the output (html, text, or rtf)
* @return {String} Bibliography or item list in specified format
*/ */
Zotero.Cite.makeFormattedBibliographyOrCitationList = function(style, items, format) { "makeFormattedBibliographyOrCitationList":function(style, items, format) {
var cslEngine = style.csl; var cslEngine = style.csl;
cslEngine.setOutputFormat(format); cslEngine.setOutputFormat(format);
cslEngine.updateItems([item.id for each(item in items)]); cslEngine.updateItems([item.id for each(item in items)]);
@ -237,14 +114,15 @@ Zotero.Cite.makeFormattedBibliographyOrCitationList = function(style, items, for
return "<\\rtf \n"+citations.join("\\\n")+"\n}"; return "<\\rtf \n"+citations.join("\\\n")+"\n}";
} }
} }
} },
/** /**
* Makes a formatted bibliography * Makes a formatted bibliography
* @param {Zotero.Style} style The style * @param {Zotero.Style} style The style
* @param {Zotero.Item[]} items An array of items * @param {String} format The format of the output (html, text, or rtf)
* @return {String} Bibliography in specified format
*/ */
Zotero.Cite.makeFormattedBibliography = function(cslEngine, format) { "makeFormattedBibliography":function makeFormattedBibliography(cslEngine, format) {
cslEngine.setOutputFormat(format); cslEngine.setOutputFormat(format);
var bib = cslEngine.makeBibliography(); var bib = cslEngine.makeBibliography();
if(!bib) return false; if(!bib) return false;
@ -406,14 +284,15 @@ Zotero.Cite.makeFormattedBibliography = function(cslEngine, format) {
} else { } else {
throw "Unimplemented bibliography format "+format; throw "Unimplemented bibliography format "+format;
} }
} },
/** /**
* Get an item by ID, either by retrieving it from the library or looking for the document it * Get an item by ID, either by retrieving it from the library or looking for the document it
* belongs to. * belongs to.
* @param {String|Number|Array} id * @param {String|Number|Array} id
* @return {Zotero.Item} item
*/ */
Zotero.Cite.getItem = function(id) { "getItem":function getItem(id) {
var slashIndex; var slashIndex;
if(id instanceof Array) { if(id instanceof Array) {
@ -435,8 +314,168 @@ Zotero.Cite.getItem = function(id) {
} else { } else {
return Zotero.Items.get(id); return Zotero.Items.get(id);
} }
} }
};
Zotero.Cite.labels = ["page", "book", "chapter", "column", "figure", "folio", /**
"issue", "line", "note", "opus", "paragraph", "part", "section", "sub verbo", * citeproc-js system object
"volume", "verse"]; * @namespace
*/
Zotero.Cite.System = {
/**
* citeproc-js system function for getting items
* See http://gsl-nagoya-u.net/http/pub/citeproc-doc.html#retrieveitem
* @param {String|Integer} Item ID, or string item for embedded citations
* @return {Object} citeproc-js item
*/
"retrieveItem":function retrieveItem(item) {
var zoteroItem, slashIndex;
if(item instanceof Zotero.Item) {
//if(this._cache[item.id]) return this._cache[item.id];
zoteroItem = item;
} else {
var type = typeof item;
if(type === "string" && (slashIndex = item.indexOf("/")) !== -1) {
// is an embedded item
var sessionID = item.substr(0, slashIndex);
var session = Zotero.Integration.sessions[sessionID]
if(session) {
var embeddedCitation = session.embeddedItems[item.substr(slashIndex+1)];
if(embeddedCitation) {
embeddedCitation.id = item;
return embeddedCitation;
}
}
} else {
// is an item ID
//if(this._cache[item]) return this._cache[item];
zoteroItem = Zotero.Items.get(item);
}
}
if(!zoteroItem) {
throw "Zotero.Cite.getCSLItem called to wrap a non-item "+item;
}
// don't return URL or accessed information for journal articles if a
// pages field exists
var itemType = Zotero.ItemTypes.getName(zoteroItem.itemTypeID);
var cslType = CSL_TYPE_MAPPINGS[itemType];
if(!cslType) cslType = "article";
var ignoreURL = ((zoteroItem.getField("accessDate", true, true) || zoteroItem.getField("url", true, true)) &&
["journalArticle", "newspaperArticle", "magazineArticle"].indexOf(itemType) !== -1
&& zoteroItem.getField("pages")
&& !Zotero.Prefs.get("export.citePaperJournalArticleURL"));
var cslItem = {
'id':zoteroItem.id,
'type':cslType
};
// get all text variables (there must be a better way)
// TODO: does citeproc-js permit short forms?
for(var variable in CSL_TEXT_MAPPINGS) {
var fields = CSL_TEXT_MAPPINGS[variable];
if(variable == "URL" && ignoreURL) continue;
for each(var field in fields) {
var value = zoteroItem.getField(field, false, true).toString();
if(value != "") {
// Strip enclosing quotes
if(value.match(/^".+"$/)) {
value = value.substr(1, value.length-2);
}
cslItem[variable] = value;
break;
}
}
}
// separate name variables
var authorID = Zotero.CreatorTypes.getPrimaryIDForType(zoteroItem.itemTypeID);
var creators = zoteroItem.getCreators();
for each(var creator in creators) {
if(creator.creatorTypeID == authorID) {
var creatorType = "author";
} else {
var creatorType = Zotero.CreatorTypes.getName(creator.creatorTypeID);
}
var creatorType = CSL_NAMES_MAPPINGS[creatorType];
if(!creatorType) continue;
var nameObj = {'family':creator.ref.lastName, 'given':creator.ref.firstName};
if(cslItem[creatorType]) {
cslItem[creatorType].push(nameObj);
} else {
cslItem[creatorType] = [nameObj];
}
}
// get date variables
for(var variable in CSL_DATE_MAPPINGS) {
var date = zoteroItem.getField(CSL_DATE_MAPPINGS[variable], false, true);
if(date) {
var dateObj = Zotero.Date.strToDate(date);
// otherwise, use date-parts
var dateParts = [];
if(dateObj.year) {
// add year, month, and day, if they exist
dateParts.push(dateObj.year);
if(dateObj.month !== undefined) {
dateParts.push(dateObj.month+1);
if(dateObj.day) {
dateParts.push(dateObj.day);
}
}
cslItem[variable] = {"date-parts":[dateParts]};
// if no month, use season as month
if(dateObj.part && !dateObj.month) {
cslItem[variable].season = dateObj.part;
}
} else {
// if no year, pass date literally
cslItem[variable] = {"literal":date};
}
}
}
//this._cache[zoteroItem.id] = cslItem;
return cslItem;
},
/**
* citeproc-js system function for getting locale
* See http://gsl-nagoya-u.net/http/pub/citeproc-doc.html#retrieveLocale
* @param {String} lang Language to look for a locale for
* @return {String|Boolean} The locale as a string if it exists, or false if it doesn't
*/
"retrieveLocale":function retrieveLocale(lang) {
var protHandler = Components.classes["@mozilla.org/network/protocol;1?name=chrome"]
.createInstance(Components.interfaces.nsIProtocolHandler);
try {
var channel = protHandler.newChannel(protHandler.newURI("chrome://zotero/content/locale/csl/locales-"+lang+".xml", "UTF-8", null));
var rawStream = channel.open();
} catch(e) {
return false;
}
var converterStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
converterStream.init(rawStream, "UTF-8", 65535,
Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
var str = {};
converterStream.readString(channel.contentLength, str);
converterStream.close();
return str.value;
},
/**
* citeproc-js system function for getting abbreviations
* See http://gsl-nagoya-u.net/http/pub/citeproc-doc.html#getabbreviations
* Not currently used because it doesn't scale well to large lists
*/
"getAbbreviations":function getAbbreviations() {
return {};
}
};