fixes #1030, CSL broken on trunk due to XML namespace change

closes #704, EndNote to Zotero style converter (won't actually convert styles due to copyright concerns, but will load them into the DB)
also adds CSL style manager
This commit is contained in:
Simon Kornblith 2008-06-20 06:40:05 +00:00
parent d65e75fbc9
commit d8868cd9cb
10 changed files with 1642 additions and 39 deletions

View file

@ -31,6 +31,7 @@ function init()
rows[i].firstChild.nextSibling.value = Zotero.isMac ? 'Cmd+Shift+' : 'Ctrl+Alt+';
}
refreshStylesList();
populateQuickCopyList();
updateQuickCopyInstructions();
initSearchPane();
@ -913,3 +914,133 @@ function onOpenURLCustomized()
{
document.getElementById('openURLMenu').value = "custom";
}
/** STYLES **/
/**
* Refreshes the list of styles in the styles pane
**/
function refreshStylesList(cslID) {
var treechildren = document.getElementById('styleManager-rows');
while (treechildren.hasChildNodes()) {
treechildren.removeChild(treechildren.firstChild);
}
var sql = "SELECT cslID, title, updated FROM csl ORDER BY title";
var styleData = Zotero.DB.query(sql);
if (!styleData) return;
Zotero.debug("ASKED FOR "+cslID);
var selectIndex = false;
for (var i=0; i<styleData.length; i++) {
var treeitem = document.createElement('treeitem');
var treerow = document.createElement('treerow');
var titleCell = document.createElement('treecell');
var updatedCell = document.createElement('treecell');
var updatedDate = Zotero.Date.formatDate(Zotero.Date.strToDate(styleData[i].updated), true);
treeitem.setAttribute('id', 'zotero-csl-'+styleData[i].cslID);
titleCell.setAttribute('label', styleData[i].title);
updatedCell.setAttribute('label', updatedDate);
treerow.appendChild(titleCell);
treerow.appendChild(updatedCell);
treeitem.appendChild(treerow);
treechildren.appendChild(treeitem);
if(cslID == styleData[i].cslID) {
document.getElementById('styleManager').view.selection.select(i);
}
}
}
/**
* Adds a new style to the style pane
**/
function addStyle() {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString("zotero.preferences.styles.addStyle"), nsIFilePicker.modeOpen);
fp.appendFilter("CSL Style", "*.csl");
fp.appendFilter("EndNote Style", "*.ens");
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var file = fp.file;
// read file
var iStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
iStream.init(file, 0x01, 0664, 0);
var bStream = Components.classes["@mozilla.org/binaryinputstream;1"]
.createInstance(Components.interfaces.nsIBinaryInputStream);
bStream.setInputStream(iStream);
var read = bStream.readBytes(6);
if(read == "\x00\x08\xFF\x00\x00\x00") {
// EndNote style
// read the rest of the bytes in the file
read += bStream.readBytes(file.fileSize-6);
// get fallback name and modification date
var fallbackName = file.leafName;
fallbackName = fallbackName.replace(/\.ens$/i, "");
var date = new Date(file.lastModifiedTime);
Zotero.debug(file.lastModifiedTime);
Zotero.debug(date);
try {
var enConverter = new Zotero.ENConverter(read, date, fallbackName);
var xml = enConverter.parse();
} catch(e) {
styleImportError();
throw e;
}
var cslID = Zotero.Cite.installStyle(xml.toXMLString());
} else {
// This _should_ get the right charset for us automatically
var fileURI = Components.classes["@mozilla.org/network/protocol;1?name=file"]
.getService(Components.interfaces.nsIFileProtocolHandler)
.getURLSpecFromFile(file);
var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance();
req.open("GET", fileURI, false);
req.overrideMimeType("text/plain");
try {
req.send(null);
} catch(e) {
styleImportError();
throw e;
}
var cslID = Zotero.Cite.installStyle(req.responseText);
}
}
if(cslID !== false) this.refreshStylesList(cslID);
}
/**
* Deletes a style from the style pane
**/
function deleteStyle() {
var tree = document.getElementById('styleManager');
var treeitem = tree.lastChild.childNodes[tree.currentIndex];
Zotero.debug(treeitem.getAttribute('id'));
var cslID = treeitem.getAttribute('id').substr(11);
Zotero.Cite.deleteStyle(cslID);
this.refreshStylesList();
}
/**
* Shows an error if import fails
**/
function styleImportError() {
alert(Zotero.getString('styles.installError', "This"));
}

View file

@ -323,6 +323,29 @@ To add a new preference:
<separator/>
<label id="quickCopy-macWarning" hidden="true" value="&zotero.preferences.quickCopy.macWarning;"/>
</groupbox>
</prefpane>
<prefpane id="zotero-prefpane-styles"
label="&zotero.preferences.prefpane.styles;"
image="chrome://zotero/skin/prefs-styles.png">
<groupbox flex="1">
<caption label="&zotero.preferences.styles.styleManager;"/>
<tree flex="1" id="styleManager" hidecolumnpicker="true" rows="6"
onkeypress="if (event.keyCode == event.DOM_VK_DELETE) { deleteSelectedStyle(); }">
<treecols>
<treecol id="styleManager-title" label="&zotero.preferences.styles.styleManager.title;" flex="3"/>
<treecol id="styleManager-updated" label="&zotero.preferences.styles.styleManager.updated;" flex="1"/>
</treecols>
<treechildren id="styleManager-rows"/>
</tree>
<separator class="thin"/>
<hbox pack="end">
<button label="-" onclick="deleteStyle()"/>
<button label="+" onclick="addStyle()"/>
</hbox>
<separator/>
<label class="text-link" href="http://www.zotero.org/styles/" value="&zotero.preferences.export.getAdditionalStyles;"/>
</groupbox>

View file

@ -25,9 +25,9 @@
* this class handles pulling the CSL file and item data out of the database,
* while CSL, below, handles the actual generation of the bibliography
*/
Zotero.Cite = new function() {
default xml namespace = "http://purl.org/net/xbiblio/csl";
default xml namespace = "http://purl.org/net/xbiblio/csl";
Zotero.Cite = new function() {
var _lastCSL = null;
var _lastStyle = null;
@ -35,6 +35,7 @@ Zotero.Cite = new function() {
this.getStyleClass = getStyleClass;
this.getStyle = getStyle;
this.installStyle = installStyle;
this.deleteStyle = deleteStyle;
/*
* returns an associative array of cslID => styleName pairs
@ -105,8 +106,8 @@ Zotero.Cite = new function() {
}
if (!xml || error) {
alert(Zotero.getString('styles.installError', loadURI));
return;
alert(Zotero.getString('styles.installError', (loadURI ? loadURI : "This")));
return false;
}
var uri = xml.info.id.toString();
@ -123,10 +124,18 @@ Zotero.Cite = new function() {
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
if (existingTitle) {
var text = Zotero.getString('styles.updateStyle', [existingTitle, title, loadURI]);
if(loadURI) {
var text = Zotero.getString('styles.updateStyleURI', [existingTitle, title, loadURI]);
} else {
var text = Zotero.getString('styles.updateStyle', [existingTitle, title]);
}
}
else {
var text = Zotero.getString('styles.installStyle', [title, loadURI]);
if(loadURI) {
var text = Zotero.getString('styles.installStyleURI', [title, loadURI]);
} else {
var text = Zotero.getString('styles.installStyle', [title]);
}
}
var acceptButton = Zotero.getString('general.install');
@ -142,6 +151,27 @@ Zotero.Cite = new function() {
var sql = "REPLACE INTO csl VALUES (?,?,?,?)";
Zotero.DB.query(sql, [uri, updated, title, cslString]);
alert(Zotero.getString('styles.installed', title));
return uri;
}
}
/**
* deletes a style
**/
function deleteStyle(uri) {
var sql = "SELECT title FROM csl WHERE cslID=?";
var title = Zotero.DB.valueQuery(sql, uri);
if(!title) throw "Cite: style to delete does not exist!"
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
var text = Zotero.getString('styles.deleteStyle', [title]);
if(ps.confirm(null, '', text)) {
var sql = "DELETE FROM csl WHERE cslID=?";
Zotero.DB.query(sql, uri);
}
}
}
@ -277,7 +307,7 @@ Zotero.Cite.MIMEHandler.StreamListener.prototype.onStopRequest = function(channe
* want to use the Scholar data model, but does want to use CSL in JavaScript
*/
Zotero.CSL = function(csl) {
default xml namespace = "http://purl.org/net/xbiblio/csl";
default xml namespace = "http://purl.org/net/xbiblio/csl"; with ({});
this._csl = new XML(Zotero.CSL.Global.cleanXML(csl));
@ -292,6 +322,7 @@ Zotero.CSL = function(csl) {
Zotero.debug("CSL: style class is "+this.class);
this.hasBibliography = (this._csl.bibliography.length() ? 1 : 0);
Zotero.debug("hasBibliography "+this.hasBibliography);
}
/*
@ -344,6 +375,8 @@ Zotero.CSL._firstNameRegexp = /^[^\s]*/;
Zotero.CSL._textCharRegexp = /[a-zA-Z0-9]/;
Zotero.CSL._numberRegexp = /\d+/;
Zotero.CSL.prototype.formatCitation = function(citation, format) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
var context = this._csl.citation;
if(!context) {
throw "CSL: formatCitation called on style with no citation context";
@ -535,6 +568,8 @@ Zotero.CSL.prototype.formatCitation = function(citation, format) {
* create a bibliography
*/
Zotero.CSL.prototype.formatBibliography = function(itemSet, format) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
var context = this._csl.bibliography;
if(!context.length()) {
context = this._csl.citation;
@ -770,6 +805,8 @@ Zotero.CSL.prototype._getTerm = function(term, plural, form, includePeriod) {
* non-Western names better than ours, this would be the function to change
*/
Zotero.CSL.prototype._processNames = function(item, element, formattedString, context, citationItem, variables) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
var children = element.children();
if(!children.length()) return false;
var variableSucceeded = false;
@ -953,6 +990,8 @@ Zotero.CSL.prototype._processNames = function(item, element, formattedString, co
*/
Zotero.CSL.prototype._processElements = function(item, element, formattedString,
context, citationItem, ignore, isSingle) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
if(!ignore) {
ignore = [[], []];
// ignore[0] is for variables; ignore[1] is for macros
@ -1381,6 +1420,8 @@ Zotero.CSL.prototype._processElements = function(item, element, formattedString,
* Returns -1 if A comes before B, 1 if B comes before A, or 0 if they are equal
*/
Zotero.CSL.prototype._compareItem = function(a, b, context, cache) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
var sortA = [];
var sortB = [];
@ -1496,6 +1537,8 @@ Zotero.CSL.prototype.cachedSort = function(items, context, field) {
}
Zotero.CSL.prototype.getEqualCitations = function(items) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
var citationsEqual = [];
if(items) {
@ -1524,6 +1567,8 @@ Zotero.CSL.prototype.getEqualCitations = function(items) {
* Compares two citations; returns true if they are different, false if they are equal
*/
Zotero.CSL.prototype.compareCitations = function(a, b, context) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
if((!a && b) || (a && !b)) {
return true;
} else if(!a && !b) {
@ -1549,7 +1594,7 @@ Zotero.CSL.Global = new function() {
this.cleanXML = cleanXML;
this.parseLocales = parseLocales;
default xml namespace = "http://purl.org/net/xbiblio/csl";
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
this.ns = "http://purl.org/net/xbiblio/csl";
this.__defineGetter__("locale", function() {
@ -1810,6 +1855,8 @@ Zotero.CSL.CitationItem = function(item) {
* the Citation object represents a citation.
*/
Zotero.CSL.Citation = function(citationItems, csl) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
if(csl) {
this._csl = csl;
this._citation = csl._csl.citation;
@ -1893,8 +1940,6 @@ Zotero.CSL.Citation.prototype.clone = function() {
* with "_") are implemented.
*/
Zotero.CSL.Item = function(item) {
default xml namespace = "http://purl.org/net/xbiblio/csl";
if(item instanceof Zotero.Item) {
this.zoteroItem = item;
} else if(parseInt(item, 10) == item) {
@ -2337,7 +2382,7 @@ Zotero.CSL.Item.Name = function(zoteroCreator) {
* lastName - last name
*/
Zotero.CSL.Item.Name.prototype.getNameVariable = function(variable) {
return this._zoteroCreator[variable] ? this._zoteroCreator[variable] : "";
return this._zoteroCreator.ref[variable] ? this._zoteroCreator.ref[variable] : "";
}
/*
@ -2345,7 +2390,7 @@ Zotero.CSL.Item.Name.prototype.getNameVariable = function(variable) {
* in an item wrapper.
*/
Zotero.CSL.ItemSet = function(items, csl) {
default xml namespace = "http://purl.org/net/xbiblio/csl";
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
this.csl = csl;
@ -2465,6 +2510,8 @@ Zotero.CSL.ItemSet.prototype.remove = function(items) {
* citations have changed
*/
Zotero.CSL.ItemSet.prototype.resort = function() {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
// sort
this.items = this.csl.cachedSort(this.items, this.bibliography);
@ -2722,7 +2769,7 @@ Zotero.CSL.ItemSet.prototype._copyDisambiguation = function(fromItem, toItem) {
}
Zotero.CSL.FormattedString = function(context, format, delimiter, subsequent) {
default xml namespace = "http://purl.org/net/xbiblio/csl";
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
this.context = context;
this.option = context ? context.option : new XMLList();
@ -2754,6 +2801,8 @@ Zotero.CSL.FormattedString._punctuation = "!.,?:";
* attaches another formatted string to the end of the current one
*/
Zotero.CSL.FormattedString.prototype.concat = function(formattedString, element) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
if(!formattedString || !formattedString.string) {
return false;
}
@ -2798,6 +2847,7 @@ Zotero.CSL.FormattedString._rtfEscapeFunction = function(aChar) {
* appends a string (with format parameters) to the current one
*/
Zotero.CSL.FormattedString.prototype.append = function(string, element, dontDelimit, dontEscape) {
default xml namespace = "http://purl.org/net/xbiblio/csl"; with({});
if(!string && string !== 0) return false;

File diff suppressed because it is too large Load diff

View file

@ -1450,31 +1450,42 @@ Zotero.Date = new function(){
return date;
}
/*
/**
* does pretty formatting of a date object returned by strToDate()
*
* |date| is *not* a JS Date object
*/
function formatDate(date) {
var string = "";
* @param {Object} date A date object, as returned from strToDate()
* @param {Boolean} shortFormat Whether to return a short (12/1/95) date
* @return A formatted date string
* @type String
**/
function formatDate(date, shortFormat) {
if(shortFormat) {
var localeDateOrder = getLocaleDateOrder();
var string = localeDateOrder[0]+"/"+localeDateOrder[1]+"/"+localeDateOrder[2];
return string.replace("y", (date.year !== undefined ? date.year : "00"))
.replace("m", (date.month !== undefined ? 1+date.month : "0"))
.replace("d", (date.day !== undefined ? date.day : "0"));
} else {
var string = "";
if(date.part) {
string += date.part+" ";
}
var months = Zotero.CSL.Global.getMonthStrings("long");
if(date.month != undefined && months[date.month]) {
// get short month strings from CSL interpreter
string += months[date.month];
if(date.day) {
string += " "+date.day+", ";
} else {
string += " ";
if(date.part) {
string += date.part+" ";
}
}
if(date.year) {
string += date.year;
var months = Zotero.CSL.Global.getMonthStrings("long");
if(date.month != undefined && months[date.month]) {
// get short month strings from CSL interpreter
string += months[date.month];
if(date.day) {
string += " "+date.day+", ";
} else {
string += " ";
}
}
if(date.year) {
string += date.year;
}
}
return string;

View file

@ -60,6 +60,10 @@
<!ENTITY zotero.preferences.quickCopy.siteEditor.domainPath.example "(e.g. wikipedia.org)">
<!ENTITY zotero.preferences.quickCopy.siteEditor.outputFormat "Output Format">
<!ENTITY zotero.preferences.prefpane.styles "Styles">
<!ENTITY zotero.preferences.styles.styleManager "Style Manager">
<!ENTITY zotero.preferences.styles.styleManager.title "Title">
<!ENTITY zotero.preferences.styles.styleManager.updated "Updated">
<!ENTITY zotero.preferences.export.getAdditionalStyles "Get additional styles...">
<!ENTITY zotero.preferences.prefpane.keys "Shortcut Keys">

View file

@ -380,6 +380,7 @@ zotero.preferences.search.pdf.tryAgainOrViewManualInstructions = Please try aga
zotero.preferences.export.quickCopy.bibStyles = Bibliographic Styles
zotero.preferences.export.quickCopy.exportFormats = Export Formats
zotero.preferences.export.quickCopy.instructions = Quick Copy allows you to copy selected references to the clipboard by pressing a shortcut key (%S) or dragging items into a text box on a web page.
zotero.preferences.styles.addStyle = Add Style
zotero.preferences.advanced.resetTranslatorsAndStyles = Reset Translators and Styles
zotero.preferences.advanced.resetTranslatorsAndStyles.changesLost = Any new or modified translators or styles will be lost.
@ -489,6 +490,10 @@ integration.regenerate.saveBehavior = Always follow this selection.
integration.deleteCitedItem.title = Are you sure you want to remove this reference?
integration.deleteCitedItem.body = This reference is cited in the text of your document. Deleting it will remove all citations.
styles.installStyle = Install style "%1$S" from %2$S?
styles.installStyleURI = Install style "%1$S" from %2$S?
styles.installStyle = Install style "%1$S"?
styles.updateStyleURI = Update existing style "%1$S" with "%2$S" from %3$S?
styles.updateStyle = Update existing style "%1$S" with "%2$S"?
styles.installed = The style "%S" was installed successfully.
styles.installError = %S does not appear to be a valid CSL file.
styles.deleteStyle = Are you sure you want to delete the style "%1$S"?

View file

@ -113,6 +113,11 @@ grid row hbox:first-child
min-height: 1.5em; /* Fix collapse on Windows */
}
/* Styles pane */
#styleManager
{
height: 250px;
}
/* Shortcut Keys pane */
#zotero-prefpane-keys row

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -18,8 +18,8 @@ var xpcomFiles = ['zotero',
'annotate', 'attachments', 'cite', 'cite_compat', 'collectionTreeView',
'dataServer', 'data_access', 'data/item', 'data/items', 'data/collection',
'data/collections', 'data/cachedTypes', 'data/creator', 'data/creators',
'data/itemFields', 'data/notes', 'data/tag', 'data/tags', 'db', 'file',
'fulltext', 'id', 'ingester', 'integration', 'itemTreeView', 'mime',
'data/itemFields', 'data/notes', 'data/tag', 'data/tags', 'db', 'enstyle',
'file', 'fulltext', 'id', 'ingester', 'integration', 'itemTreeView', 'mime',
'notifier', 'progressWindow', 'quickCopy', 'report', 'schema', 'search',
'sync', 'timeline', 'translate', 'utilities', 'zeroconf'];