closes #1493, Style/Font Behavior In WP Plugins

closes #1325, better integration with word-processor styles

WinWord plug-in update is still to come
This commit is contained in:
Simon Kornblith 2010-07-06 06:47:59 +00:00
parent 1b353fb2b2
commit 13f0b1bfd2
4 changed files with 92 additions and 55 deletions

View file

@ -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 bibStyle = Zotero.Cite.getBibliographyFormatParameters(bib);
var preamble = "";
if(tabStop !== null) preamble += "\\tx"+tabStop+" ";
preamble += "\\li"+indent+" \\fi"+firstLineIndent+" ";
preamble += "\\sl"+(240*bib[0].linespacing)+" \\slmult1 ";
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 {

View file

@ -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 ";

View file

@ -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") {

View file

@ -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
{
@ -115,6 +119,14 @@ interface zoteroIntegrationDocument : nsISupports
void convert(in nsISimpleEnumerator fields, in string toFieldType,
[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.
*/