commit 13f0b1bfd267029c882072ddb516f33c1b29efb0
parent 1b353fb2b2b0cf66eba6a1b78c3edda746de0ac4
Author: Simon Kornblith <simon@simonster.com>
Date: Tue, 6 Jul 2010 06:47:59 +0000
closes #1493, Style/Font Behavior In WP Plugins
closes #1325, better integration with word-processor styles
WinWord plug-in update is still to come
Diffstat:
4 files changed, 92 insertions(+), 55 deletions(-)
diff --git a/chrome/content/zotero/xpcom/cite.js b/chrome/content/zotero/xpcom/cite.js
@@ -231,10 +231,32 @@ Zotero.Cite.removeFromBibliography = function(bib, itemsToRemove) {
}
}
-Zotero.Cite.makeFormattedBibliography = function(cslEngine, format, customBibliographyText, omittedItems) {
- if(format) cslEngine.setOutputFormat(format);
+Zotero.Cite.getBibliographyFormatParameters = function(bib) {
+ var bibStyle = {"tabStops":[], "indent":0, "firstLineIndent":0,
+ "lineSpacing":(240*bib[0].linespacing),
+ "entrySpacing":(240*bib[0].entryspacing)};
+ if(bib[0].hangingindent) {
+ bibStyle.indent = 720; // 720 twips = 0.5 in
+ bibStyle.firstLineIndent = -720; // -720 twips = -0.5 in
+ } else if(bib[0]["second-field-align"]) {
+ // this is a really sticky issue. the below works for first fields that look like "[1]"
+ // and "1." otherwise, i have no idea. luckily, this will be good enough 99% of the time.
+ var alignAt = 24+bib[0].maxoffset*120;
+ bibStyle.firstLineIndent = -alignAt;
+ if(bib[0]["second-field-align"] == "margin") {
+ bibStyle.tabStops = [0];
+ } else {
+ bibStyle.indent = alignAt;
+ bibStyle.tabStops = [alignAt];
+ }
+ }
+
+ return bibStyle;
+}
+
+Zotero.Cite.makeFormattedBibliography = function(cslEngine, format) {
+ cslEngine.setOutputFormat(format);
var bib = cslEngine.makeBibliography();
- if(omittedItems) this.removeFromBibliography(bib, omittedItems);
if(format == "html") {
// TODO CSS
@@ -242,39 +264,12 @@ Zotero.Cite.makeFormattedBibliography = function(cslEngine, format, customBiblio
} else if(format == "text") {
return bib[0].bibstart+bib[1].join("")+bib[0].bibend;
} else if(format == "rtf") {
- var tabStop = null;
- var indent = 0;
- var firstLineIndent = 0;
- if(bib[0].hangingindent) {
- indent = 720; // 720 twips = 0.5 in
- firstLineIndent = -720; // -720 twips = -0.5 in
- } else if(bib[0]["second-field-align"]) {
- // this is a really sticky issue. the below works for first fields that look like "[1]"
- // and "1." otherwise, i have no idea. luckily, this will be good enough 99% of the time.
- var alignAt = 24+bib[0].maxoffset*120;
- firstLineIndent = -alignAt;
- if(bib[0]["second-field-align"] == "margin") {
- tabStop = 0;
- } else {
- indent = alignAt;
- tabStop = alignAt;
- }
- }
-
- var preamble = "";
- if(tabStop !== null) preamble += "\\tx"+tabStop+" ";
- preamble += "\\li"+indent+" \\fi"+firstLineIndent+" ";
- preamble += "\\sl"+(240*bib[0].linespacing)+" \\slmult1 ";
+ var bibStyle = Zotero.Cite.getBibliographyFormatParameters(bib);
- if(customBibliographyText) {
- // customBibliographyText is an optional map of strings to replace specific citations
- // in the bibliography (values) to item IDs (keys)
- for(var i in bib[0].entry_ids) {
- if(customBibliographyText[bib[0].entry_ids[i]]) {
- bib[1][i] = customBibliographyText[bib[0].entry_ids[i]];
- }
- }
- }
+ var preamble = (tabStops.length ? "\\tx"+tabStops.join(" \\tx")+" " : "");
+ preamble += "\\li"+indent+" \\fi"+firstLineIndent+" "
+ +"\\sl"+bibStyle.lineSpacing+" \\slmult1 "
+ +"\\sa"+bibStyle.entrySpacing+" ";
return bib[0].bibstart+preamble+bib[1].join("\\\r\n")+"\\\r\n"+bib[0].bibend;
} else {
diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js
@@ -7207,11 +7207,7 @@ CSL.Output.Formats.prototype.rtf = {
"bibend":"}",
"@display/block":"%%STRING%%\\line\r\n",
"@bibliography/entry": function(state,str){
- var spacing = [];
- for(var i=0; i<state.opt.entryspacing; i++) {
- spacing.push("\\\r\n ");
- }
- return str+spacing.join("");
+ return str+"\\\r\n";
},
"@display/left-margin": function(state,str){
return str+"\\tab ";
diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js
@@ -401,6 +401,11 @@ Zotero.Integration.Document.prototype._getSession = function(require, dontRunSet
} else {
var data = new Zotero.Integration.DocumentData(dataString);
if(data.dataVersion < DATA_VERSION) {
+ if(data.dataVersion == 1 && data.prefs.fieldType == "Field" && this._app.primaryFieldType == "ReferenceMark") {
+ // Converted OOo docs use ReferenceMarks, not fields
+ data.prefs.fieldType = "ReferenceMark";
+ }
+
var warning = this._doc.displayAlert(Zotero.getString("integration.upgradeWarning"),
Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_WARNING,
Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK_CANCEL);
@@ -411,11 +416,6 @@ Zotero.Integration.Document.prototype._getSession = function(require, dontRunSet
if(Zotero.Integration.sessions[data.sessionID]) {
this._session = Zotero.Integration.sessions[data.sessionID];
} else {
- if(data.prefs.fieldType == "Field" && this._app.primaryFieldType != "Field") {
- // Converted OOo docs use ReferenceMarks, not fields
- data.prefs.fieldType = "ReferenceMark";
- }
-
this._session = this._createNewSession(data);
// make sure style is defined
@@ -691,8 +691,25 @@ Zotero.Integration.Document.prototype._updateDocument = function(forceCitations,
field.setCode(BIBLIOGRAPHY_CODE+" "+bibliographyData);
}
}
-
- var bibliographyText = this._session.getBibliography();
+
+ // get bibliography and format as RTF
+ var bib = this._session.getBibliography();
+ var bibliographyText = bib[0].bibstart+bib[1].join("\\\r\n")+"\\\r\n"+bib[0].bibend;
+
+ // if bibliography style not set, set it
+ if(!this._session.data.bibliographyStyleHasBeenSet && this._doc.setBibliographyStyle) {
+ var bibStyle = Zotero.Cite.getBibliographyFormatParameters(bib);
+
+ // set bibliography style
+ this._doc.setBibliographyStyle(bibStyle.firstLineIndent, bibStyle.indent,
+ bibStyle.lineSpacing, bibStyle.entrySpacing, bibStyle.tabStops, bibStyle.tabStops.length);
+
+ // set bibliographyStyleHasBeenSet parameter to prevent further changes
+ this._session.data.bibliographyStyleHasBeenSet = true;
+ this._doc.setDocumentData(this._session.data.serializeXML());
+ }
+
+ // set bibliography text
for each(var field in this._bibliographyFields) {
if(bibliographyText) {
field.setText(bibliographyText, true);
@@ -1307,9 +1324,22 @@ Zotero.Integration.Session.prototype.deleteCitation = function(index) {
* Gets integration bibliography
*/
Zotero.Integration.Session.prototype.getBibliography = function() {
- // use real RTF, but chop off the first \n
this.updateUncitedItems();
- return Zotero.Cite.makeFormattedBibliography(this.style, "rtf", this.customBibliographyText, this.omittedItems);
+
+ // generate bibliography
+ var bib = this.style.makeBibliography();
+
+ // omit items
+ Zotero.Cite.removeFromBibliography(bib, this.omittedItems);
+
+ // replace items with their custom counterpars
+ for(var i in bib[0].entry_ids) {
+ if(this.customBibliographyText[bib[0].entry_ids[i]]) {
+ bib[1][i] = this.customBibliographyText[bib[0].entry_ids[i]];
+ }
+ }
+
+ return bib;
}
/**
@@ -1661,7 +1691,7 @@ Zotero.Integration.Session.prototype.editBibliography = function() {
* @class Interface for bibliography editor to alter document bibliography
* @constructor
* Creates a new bibliography editor interface
- * @param {Zotero.Integration.Session} session
+ * @param session {Zotero.Integration.Session}
*/
Zotero.Integration.Session.BibliographyEditInterface = function(session) {
this.session = session;
@@ -1802,9 +1832,11 @@ Zotero.Integration.DocumentData = function(string) {
* Serializes document-specific data as XML
*/
Zotero.Integration.DocumentData.prototype.serializeXML = function() {
- var xmlData = <data data-version={DATA_VERSION} zotero-version={Zotero.version}><session id={this.sessionID} />
- <style id={this.style.styleID} hasBibliography={this.style.hasBibliography ? 1 : 0}/>
- <prefs/>
+ var xmlData = <data data-version={DATA_VERSION} zotero-version={Zotero.version}>\
+ <session id={this.sessionID} />
+ <style id={this.style.styleID} hasBibliography={this.style.hasBibliography ? 1 : 0}
+ bibliographyStyleHasBeenSet={this.bibliographyStyleHasBeenSet ? 1 : 0}/>
+ <prefs/>
</data>;
for(var pref in this.prefs) {
@@ -1828,7 +1860,8 @@ Zotero.Integration.DocumentData.prototype.unserializeXML = function(xmlData) {
this.sessionID = xmlData.session.@id.toString();
this.style = {"styleID":xmlData.style.@id.toString(),
- "hasBibliography":(xmlData.style.@hasBibliography.toString() == 1)};
+ "hasBibliography":(xmlData.style.@hasBibliography.toString() == 1),
+ "bibliographyStyleHasBeenSet":(xmlData.style.@bibliographyStyleHasBeenSet.toString() == 1)};
this.prefs = {};
for each(var pref in xmlData.prefs.children()) {
this.prefs[pref.@name.toString()] = pref.@value.toString();
@@ -1854,7 +1887,8 @@ Zotero.Integration.DocumentData.prototype.unserialize = function(input) {
this.sessionID = prefParameters[0];
this.style = {"styleID":prefParameters[1],
- "hasBibliography":(prefParameters[3] == "1" || prefParameters[3] == "True")};
+ "hasBibliography":(prefParameters[3] == "1" || prefParameters[3] == "True"),
+ "bibliographyStyleHasBeenSet":false};
this.prefs = {"fieldType":((prefParameters[5] == "1" || prefParameters[5] == "True") ? "Bookmark" : "Field")};
if(prefParameters[2] == "note") {
if(prefParameters[4] == "1" || prefParameters[4] == "True") {
diff --git a/idl/zoteroIntegration.idl b/idl/zoteroIntegration.idl
@@ -25,6 +25,10 @@
#include "nsISupports.idl"
#include "nsISimpleEnumerator.idl"
+/**
+ * The zoteroIntegrationField interface corresponds to a field containing an individual citation
+ * or bibliography.
+ */
[scriptable, uuid(aedb37a0-48bb-11de-8a39-0800200c9a66)]
interface zoteroIntegrationField : nsISupports
{
@@ -116,6 +120,14 @@ interface zoteroIntegrationDocument : nsISupports
[array, size_is(count)] in unsigned short toNoteType, in unsigned long count);
/**
+ * Sets the bibliography style, overwriting the current values for this document
+ */
+ void setBibliographyStyle(in long firstLineIndent, in long bodyIndent,
+ in unsigned long lineSpacing, in unsigned long entrySpacing,
+ [array, size_is(tabStopCount)] in long tabStops,
+ in unsigned long tabStopCount);
+
+ /**
* Runs on function completion to clean up everything integration played with.
*/
void cleanup();