Restructure and comment cite.js
This commit is contained in:
parent
0deb2573cc
commit
de2d1669fe
|
@ -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 {};
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user