closes #214, add footnote support to word integration

closes #215, allow user to select desired citation style and change citation styles on the fly
This commit is contained in:
Simon Kornblith 2006-09-04 04:13:12 +00:00
parent 0515e4cb9e
commit 10f4b28c63
5 changed files with 463 additions and 279 deletions

Binary file not shown.

View File

@ -265,7 +265,9 @@ var Scholar_File_Interface = new function() {
}
// generate bibliography
var bibliography = Scholar.Cite.getBibliography(io.style, items, format);
var csl = Scholar.Cite.getStyle(io.style);
csl.preprocessItems(items);
var bibliography = csl.createBibliography(items, format);
if(io.output == "print") {
// printable bibliography, using a hidden browser
@ -343,7 +345,7 @@ var Scholar_File_Interface = new function() {
transferable.addDataFlavor("text/html");
transferable.setTransferData("text/html", str, bibliography.length*2);
// add text
var bibliography = Scholar.Cite.getBibliography(io.style, items, "Text");
var bibliography = csl.createBibliography(items, "Text");
var str = Components.classes["@mozilla.org/supports-string;1"].
createInstance(Components.interfaces.nsISupportsString);
str.data = bibliography;

View File

@ -10,9 +10,7 @@ Scholar.Cite = new function() {
var _lastStyle = null;
this.getStyles = getStyles;
this.getStyleClass = getStyleClass;
this.getBibliography = getBibliography;
this.getCitation = getCitation;
this.getStyle = getStyle;
/*
* returns an associative array of cslID => styleName pairs
@ -30,46 +28,11 @@ Scholar.Cite = new function() {
return stylesObject;
}
/*
* returns the class of a given style
*/
function getStyleClass(cslID) {
var csl = _getCSL(cslID);
return csl.class;
}
/*
* generates a bibliography
*/
function getBibliography(cslID, items, format) {
var csl = _getCSL(cslID);
// set items
csl.setItems(items);
// generate bibliography
return csl.createBibliography(format);
}
/*
* generates a bibliography
*/
function getCitation(cslID, item, items, format) {
var csl = _getCSL(cslID);
// set items
csl.setItems(items);
// generate bibliography
return csl.createCitation(item, format);
}
/*
* gets CSL from the database, or, if it's the most recently used style,
* from the cache
*/
function _getCSL(cslID) {
function getStyle(cslID) {
if(_lastStyle != cslID || Scholar.Prefs.get("cacheTranslatorData") == false) {
// get style
var sql = "SELECT csl FROM csl WHERE cslID = ?";
@ -111,64 +74,135 @@ CSL = function(csl) {
}
// load defaults from CSL
this._parseFieldDefaults(this._csl.defaults);
// parse bibliography options, since these will be necessary for
// disambiguation purposes even for citations
// parse bibliography and citation options
this._parseBibliographyOptions();
this._parseCitationOptions();
// if no bibliography exists, parse citation element as bibliography
if(!this._bib) {
Scholar.debug("CSL: using citation element");
if(!this._cit) {
this._parseCitationOptions();
}
Scholar.debug("CSL: using citation element for bibliography");
this._bib = this._cit;
}
}
/*
* set items - convert to array and pre-process
* preprocess items, separating authors, editors, and translators arrays into
* separate properties
*
* must be called prior to generating citations or bibliography with a new set
* of items
*/
CSL.prototype.setItems = function(items) {
// create a serialized string of all of the unique items
var serializedItemString = "";
CSL.prototype.preprocessItems = function(items) {
Scholar.debug("CSL: preprocessing items");
this._items = items;
this._uniqueItems = new Array();
var existingItems = new Object();
for each(var item in items) {
var itemID = item.getID();
if(!existingItems[itemID]) {
existingItems[itemID] = true;
this._uniqueItems.push(item);
serializedItemString += itemID+",";
// get data necessary to generate citations before sorting
for(var i in items) {
var item = items[i];
var dateModified = item.getField("dateModified");
if(!item._csl || item._csl.dateModified != dateModified) {
// namespace everything in item._csl so there's no chance of overlap
item._csl = new Object();
item._csl.ignore = new Array();
item._csl.dateModified = dateModified;
// separate item into authors, editors, translators
var creators = this._separateItemCreators(item);
item._csl.authors = creators[0];
item._csl.editors = creators[1];
item._csl.translators = creators[2];
// parse date
item._csl.date = CSL.prototype._processDate(item.getField("date"));
} else {
// clear disambiguation and subsequent author substitute
if(item._csl.disambiguation) item._csl.date.disambiguation = undefined;
if(item._csl.subsequentAuthorSubstitute) item._csl.subsequentAuthorSubstitute = undefined;
}
}
Scholar.debug("CSL: items set to "+serializedItemString);
// sort by sort order
if(this._bib.sortOrder) {
Scholar.debug("CSL: sorting items");
var me = this;
items.sort(function(a, b) {
return me._compareItem(a, b);
});
}
//if(serializedItemString != this._serializedItemString) {
// only re-process if there are new items
this._serializedItemString = serializedItemString;
this._preprocessItems();
//}
// disambiguate items after preprocessing and sorting
var usedCitations = new Array();
var lastAuthor;
for(var i in items) {
var item = items[i];
var author = this._getFieldValue("author",
this._getFieldDefaults("author"),
item, "disambiguate", this._bib);
// handle (2006a) disambiguation for author-date styles
if(this.class == "author-date") {
var citation = author+" "+this._getFieldValue("date",
this._getFieldDefaults("date"),
item, "disambiguate", this._bib);
if(usedCitations[citation]) {
if(!usedCitations[citation]._csl.date.disambiguation) {
usedCitations[citation]._csl.date.disambiguation = "a";
item._csl.date.disambiguation = "b";
} else {
// get all but last character
var oldLetter = usedCitations[citation]._csl.date.disambiguation;
if(oldLetter.length > 1) {
item._csl.date.disambiguation = oldLetter.substr(0, oldLetter.length-1);
} else {
item._csl.date.disambiguation = "";
}
var charCode = oldLetter.charCodeAt(oldLetter.length-1);
if(charCode == 122) {
// item is z; add another letter
item._csl.date.disambiguation += "za";
} else {
// next lowercase letter
item._csl.date.disambiguation += String.fromCharCode(charCode+1);
}
}
}
usedCitations[citation] = item;
}
// add numbers to each
item._csl.number = i;
// handle subsequent author substitutes
if(this._bib.subsequentAuthorSubstitute && lastAuthor == author) {
item._csl.subsequentAuthorSubstitute = true;
}
lastAuthor = author;
}
}
/*
* create a citation (in-text or footnote)
*/
CSL.prototype.createCitation = function(items, format) {
CSL.prototype.createCitation = function(items, types, format) {
Scholar.debug("CSL: creating citation for item "+items[0].getID());
if(!this._cit) {
this._parseCitationOptions();
}
var string = "";
for(var i in items) {
if(this._cit.format && this._cit.format.delimiter && string) {
// add delimiter if one exists, and this isn't the first element
// with content
string += this._cit.format.delimiter;
if(types == 2) {
var string = this._getTerm("ibid", (items.length > 1 ? true : false));
string = string[0].toUpperCase()+string.substr(1);
} else {
var string = "";
for(var i in items) {
if(this._cit.format && this._cit.format.delimiter && string) {
// add delimiter if one exists, and this isn't the first element
// with content
string += this._cit.format.delimiter;
}
string += this._getCitation(items[i], (types[i] == 1 ? "first" : "subsequent"), format, this._cit);
}
string += this._getCitation(items[i], format, this._cit);
}
// add format
@ -189,11 +223,7 @@ CSL.prototype.createCitation = function(items, format) {
* create a bibliography
* (items is expected to be an array of items)
*/
CSL.prototype.createBibliography = function(format) {
// preprocess this._items
Scholar.debug("CSL: preprocessing items");
this._preprocessItems();
CSL.prototype.createBibliography = function(items, format) {
// process this._items
var output = "";
@ -212,10 +242,10 @@ CSL.prototype.createBibliography = function(format) {
output += "\r\n";
}
for(var i in this._uniqueItems) {
var item = this._uniqueItems[i];
for(var i in items) {
var item = items[i];
var string = this._getCitation(item, format, this._bib);
var string = this._getCitation(item, "first", format, this._bib);
// add format
if(this._bib.format) {
@ -516,7 +546,7 @@ CSL.prototype._parseFieldDefaults = function(ref) {
/*
* parses a list of fields into an array of objects
*/
CSL.prototype._parseFields = function(ref, type, bibCitElement, inheritFormat) {
CSL.prototype._parseFields = function(ref, position, type, bibCitElement, inheritFormat) {
var typeDesc = new Array();
for each(var element in ref) {
if(element.namespace() == CSL.ns) { // ignore elements in other namespaces
@ -535,7 +565,7 @@ CSL.prototype._parseFields = function(ref, type, bibCitElement, inheritFormat) {
itemDesc._serialized = this._serializeElement(itemDesc.name, itemDesc);
// add to serialization for type
if(bibCitElement) {
bibCitElement._serializations[type][itemDesc._serialized] = itemDesc;
bibCitElement._serializations[position][type][itemDesc._serialized] = itemDesc;
}
}
@ -546,7 +576,7 @@ CSL.prototype._parseFields = function(ref, type, bibCitElement, inheritFormat) {
var children = element.children();
if(children.length()) {
itemDesc.children = this._parseFields(children, type, bibCitElement);
itemDesc.children = this._parseFields(children, position, type, bibCitElement);
}
} else {
// parse attributes on this field
@ -640,7 +670,7 @@ CSL.prototype._parseBibliographyOptions = function() {
this._bib.sortOrder[0].name = "cited";
}
} else {
this._bib.sortOrder = this._parseFields(bibliography.sort, false, this._bib);
this._bib.sortOrder = this._parseFields(bibliography.sort, "first", false, this._bib);
}
// parse et al
@ -683,22 +713,32 @@ CSL.prototype._parseTypes = function(itemElements, bibCitElement) {
// find the type item without position="subsequent"
for each(var itemElement in itemElements) {
if(itemElement.@position.toString() == "subsequent") {
// bind subsequent element to position 1
bibCitElement._types[1] = itemElement;
bibCitElement._serializations[1] = new Object();
} else {
// create an associative array of available types
if(itemElement.choose.length()) {
for each(var type in itemElement.choose.type) {
bibCitElement._types[type.@name] = type;
bibCitElement._serializations[type.@name] = new Object();
}
} else {
// if there's only one type, bind it to index 0
bibCitElement._types[0] = itemElement;
bibCitElement._serializations[0] = new Object();
var position = itemElement.@position.toString();
if(position) {
// handle ibids
if(position == "subsequent" &&
itemElement.@ibid.toString() == "true") {
this.ibid = true;
}
} else {
position = "first";
}
if(!bibCitElement._types[position]) {
bibCitElement._types[position] = new Object();
bibCitElement._serializations[position] = new Object();
}
// create an associative array of available types
if(itemElement.choose.length()) {
for each(var type in itemElement.choose.type) {
bibCitElement._types[position][type.@name] = type;
bibCitElement._serializations[position][type.@name] = new Object();
}
} else {
// if there's only one type, bind it to index 0
bibCitElement._types[position][0] = itemElement;
bibCitElement._serializations[position][0] = new Object();
}
}
}
@ -706,21 +746,22 @@ CSL.prototype._parseTypes = function(itemElements, bibCitElement) {
/*
* convert reference types to native structures for speed
*/
CSL.prototype._getTypeObject = function(reftype, bibCitElement) {
if(!bibCitElement._types[reftype]) {
CSL.prototype._getTypeObject = function(position, reftype, bibCitElement) {
if(!bibCitElement._types[position][reftype]) {
// no type available
return false;
}
// parse type if necessary
if(typeof(bibCitElement._types[reftype]) == "xml") {
if(typeof(bibCitElement._types[position][reftype]) == "xml") {
Scholar.debug("CSL: parsing XML for "+reftype);
bibCitElement._types[reftype] = this._parseFields(bibCitElement._types[reftype].children(),
reftype, bibCitElement, true);
bibCitElement._types[position][reftype] = this._parseFields(
bibCitElement._types[position][reftype].children(),
position, reftype, bibCitElement, true);
}
Scholar.debug("CSL: got object for "+reftype);
return bibCitElement._types[reftype];
return bibCitElement._types[position][reftype];
}
/*
@ -1008,101 +1049,6 @@ CSL.prototype._lpad = function(string, pad, length) {
return string;
}
/*
* preprocess items, separating authors, editors, and translators arrays into
* separate properties
*/
CSL.prototype._preprocessItems = function() {
// get data necessary to generate citations before sorting
for(var i in this._uniqueItems) {
var item = this._uniqueItems[i];
var dateModified = item.getField("dateModified");
if(!item._csl || item._csl.dateModified != dateModified) {
// namespace everything in item._csl so there's no chance of overlap
item._csl = new Object();
item._csl.ignore = new Array();
item._csl.dateModified = dateModified;
// separate item into authors, editors, translators
var creators = this._separateItemCreators(item);
item._csl.authors = creators[0];
item._csl.editors = creators[1];
item._csl.translators = creators[2];
// parse date
item._csl.date = CSL.prototype._processDate(item.getField("date"));
} else {
// clear disambiguation and subsequent author substitute
if(item._csl.disambiguation) item._csl.disambiguation = undefined;
if(item._csl.subsequentAuthorSubstitute) item._csl.subsequentAuthorSubstitute = undefined;
}
}
// sort by sort order
if(this._bib.sortOrder) {
Scholar.debug("CSL: sorting items");
var me = this;
this._uniqueItems.sort(function(a, b) {
return me._compareItem(a, b);
});
}
// disambiguate items after preprocessing and sorting
var usedCitations = new Array();
var lastAuthor;
for(var i in this._uniqueItems) {
var item = this._uniqueItems[i];
var author = this._getFieldValue("author",
this._getFieldDefaults("author"),
item, "disambiguate", this._bib);
// handle (2006a) disambiguation for author-date styles
if(this.class == "author-date") {
var citation = author+" "+this._getFieldValue("date",
this._getFieldDefaults("date"),
item, "disambiguate", this._bib);
if(usedCitations[citation]) {
if(!usedCitations[citation]._csl.date.disambiguation) {
usedCitations[citation]._csl.date.disambiguation = "a";
item._csl.date.disambiguation = "b";
} else {
// get all but last character
var oldLetter = usedCitations[citation]._csl.date.disambiguation;
if(oldLetter.length > 1) {
item._csl.date.disambiguation = oldLetter.substr(0, oldLetter.length-1);
} else {
item._csl.date.disambiguation = "";
}
var charCode = oldLetter.charCodeAt(oldLetter.length-1);
if(charCode == 122) {
// item is z; add another letter
item._csl.date.disambiguation += "za";
} else {
// next lowercase letter
item._csl.date.disambiguation += String.fromCharCode(charCode+1);
}
}
}
usedCitations[citation] = item;
}
// add numbers to each
item._csl.number = i;
// handle subsequent author substitutes
if(this._bib.subsequentAuthorSubstitute && lastAuthor == author) {
item._csl.subsequentAuthorSubstitute = true;
}
lastAuthor = author;
}
}
/*
* handles sorting of items
*/
@ -1209,11 +1155,10 @@ CSL.prototype._processCreators = function(type, element, creators, format, bibCi
authorStrings[maxCreators-1] = and+" "+authorStrings[maxCreators-1];
// skip the comma if there are only two creators and no
// et al, and name as sort is no
if(maxCreators == 2 &&
(!element["name-as-sort-order"]
|| (element["name-as-sort-order"] != "first"
&& element["name-as-sort-order"] != "all"))) {
joinString = " ";
if((maxCreators == 2 && child["delimiter-precedes-last"] != "always") ||
(maxCreators > 2 && child["delimiter-precedes-last"] == "never")) {
var lastString = authorStrings.pop();
authorStrings[maxCreators-2] = authorStrings[maxCreators-2]+" "+lastString;
}
}
}
@ -1237,18 +1182,22 @@ CSL.prototype._processCreators = function(type, element, creators, format, bibCi
/*
* get a citation, given an item and bibCitElement
*/
CSL.prototype._getCitation = function(item, format, bibCitElement) {
CSL.prototype._getCitation = function(item, position, format, bibCitElement) {
Scholar.debug("CSL: generating citation for item "+item.getID());
if(!bibCitElement._types[position]) {
position = "first";
}
// determine mapping
if(bibCitElement._types[0]) {
if(bibCitElement._types[position][0]) {
// only one element
var typeName = 0;
var type = this._getTypeObject(typeName, bibCitElement);
var type = this._getTypeObject(position, typeName, bibCitElement);
} else {
var typeNames = this._getTypeFromItem(item);
for each(var typeName in typeNames) {
var type = this._getTypeObject(typeName, bibCitElement);
var type = this._getTypeObject(position, typeName, bibCitElement);
if(type) {
break;
}
@ -1263,7 +1212,7 @@ CSL.prototype._getCitation = function(item, format, bibCitElement) {
var string = "";
for(var j in type) {
var value = this._getFieldValue(type[j].name, type[j], item, format,
bibCitElement, typeName);
bibCitElement, position, typeName);
string += value;
}
@ -1273,7 +1222,7 @@ CSL.prototype._getCitation = function(item, format, bibCitElement) {
/*
* processes an element from a (pre-processed) item into text
*/
CSL.prototype._getFieldValue = function(name, element, item, format, bibCitElement, typeName) {
CSL.prototype._getFieldValue = function(name, element, item, format, bibCitElement, position, typeName) {
var data = "";
if(element._serialized && item._csl.ignore[element._serialized]) {
@ -1389,7 +1338,8 @@ CSL.prototype._getFieldValue = function(name, element, item, format, bibCitEleme
var child = element.children[i];
var string = this._getFieldValue(child.name, child, item,
format, typeName, bibCitElement);
format, bibCitElement, position,
typeName);
if(string) {
childData.push(string);
}
@ -1427,9 +1377,10 @@ CSL.prototype._getFieldValue = function(name, element, item, format, bibCitEleme
inheritElement = element;
} else {
// search for elements with the same serialization
if(typeName != undefined && bibCitElement._serializations[typeName]
&& bibCitElement._serializations[typeName][serialization]) {
inheritElement = bibCitElement._serializations[typeName][serialization];
if(typeName != undefined && bibCitElement._serializations[position]
&& bibCitElement._serializations[position][typeName]
&& bibCitElement._serializations[position][typeName][serialization]) {
inheritElement = bibCitElement._serializations[position][typeName][serialization];
} else {
// otherwise, use defaults
inheritElement = this._getFieldDefaults(substituteElement.name);

View File

@ -51,8 +51,7 @@ Scholar.Integration = new function() {
* handles a SOAP envelope
*/
function handleEnvelope(envelope) {
Scholar.debug("Integration: got SOAP envelope");
Scholar.debug(envelope);
Scholar.debug("Integration: SOAP Request\n"+envelope);
envelope = envelope.replace(_XMLRe, "");
var env = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
@ -116,9 +115,12 @@ Scholar.Integration = new function() {
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>;
var response = responseEnvelope.toXMLString();
Scholar.debug("Integration: SOAP Response\n"+response);
// return OK
return _generateResponse("200 OK", 'text/xml; charset="utf-8"',
responseEnvelope.toXMLString());
response);
} else {
Scholar.debug("Integration: SOAP method not supported");
}
@ -294,10 +296,11 @@ Scholar.Integration.DataListener.prototype._requestFinished = function(response)
Scholar.Integration.SOAP = new function() {
this.init = init;
this.getCitation = getCitation;
this.getBibliography = getBibliography;
this.update = update;
this.restoreSession = restoreSession;
this.setDocPrefs = setDocPrefs;
var _sessions = new Array();
var window;
function init() {
@ -308,76 +311,304 @@ Scholar.Integration.SOAP = new function() {
/*
* generates a new citation for a given item
* ACCEPTS: style[, itemString, newItemIndex]
* RETURNS: (newItem, citation)
* ACCEPTS: sessionID, bibliographyMode, citationMode(, fieldIndex, fieldName)+
* RETURNS: bibliography(, fieldIndex, fieldRename, fieldContent)+
*/
function getCitation(vars) {
// get items
var io = {dataIn: null, dataOut: null};
window.openDialog('chrome://scholar/content/selectItemsDialog.xul','',
'chrome,popup,modal,centerscreen',io);
if(io.dataOut) { // cancel was not pressed
var selectedItemIDs = io.dataOut;
var selectedItems = Scholar.Items.get(selectedItemIDs);
var style = vars[0];
if(vars[1]) { // some items already exist in the document
var itemString = vars[1]; // underscore-delimited string
var newItemIndex = parseInt(vars[2]); // index at which the
// item belongs in
// itemString
// splice in the new item ID
if(newItemIndex == -1) { // at beginning
var items = selectedItems.concat(Scholar.Items.get(itemString.split("_")));
} else { // at newItemIndex
var items = Scholar.Items.get(itemString.substr(0, newItemIndex).split("_")).
concat(selectedItems);
if(newItemIndex != itemString.length) { // not at the end
items = items.concat(Scholar.Items.get(itemString.substr(newItemIndex+1).split("_")))
}
}
} else { // this is the first item and the only item to worry
// about
var items = selectedItems;
}
var citation = Scholar.Cite.getCitation(style, selectedItems, items, "Integration");
return [selectedItemIDs.join("_"), citation];
function update(vars) {
if(!_sessions[vars[0]]) {
return "ERROR:sessionExpired";
}
var session = _sessions[vars[0]];
var returnString = "";
var bibliographyMode = vars[1];
var citationMode = vars[2];
var style = Scholar.Cite.getStyle(session.styleID);
var encounteredItem = new Object();
var newField = new Object();
var regenerate = new Object();
var newFieldArrayIndex = vars.indexOf("X", 2);
if(newFieldArrayIndex != -1) {
var newFieldIndex = vars[newFieldArrayIndex-1];
// get items
var io = {dataIn: null, dataOut: null};
window.openDialog('chrome://scholar/content/selectItemsDialog.xul','',
'chrome,popup,modal,centerscreen',io);
if(io.dataOut) { // cancel was not pressed
var field = (io.dataOut.join(","))+"_"+Scholar.randomString();
// set so that itemID works
vars[newFieldArrayIndex] = field;
// set so that field name will get changed
newField[newFieldIndex] = field;
} else {
vars[newFieldArrayIndex] = "!";
newField[newFieldIndex] = "!";
}
}
var regenerateItemList = _inspectCitationPairs(vars, 3, session, style,
encounteredItem, newField, regenerate,
(citationMode == "all"));
if(!regenerateItemList) {
// if we're not already regenerating the item list, ensure no
// citations have been deleted
for(var i in session.encounteredItem) {
if(!encounteredItem[i]) {
regenerateItemList = true;
}
}
}
var output = new Array();
if(regenerateItemList || bibliographyMode == "true") {
Scholar.debug("Integration: Regenerating Item List");
// need to re-process items
var items = new Array();
for(var i in encounteredItem) {
items.push(Scholar.Items.get(i));
}
style.preprocessItems(items);
// EBNF: bibliography-data
if(bibliographyMode != "false") {
output.push(style.createBibliography(items, "Integration"));
} else {
output.push("!");
}
} else {
// EBNF: bibliography-data
output.push("!");
}
// state which citations to update
// EBNF: citation-output-triple
for(var i in regenerate) {
// EBNF: citation-index
output.push(i);
if(regenerate[i] === false) {
// if marked for deletion, delete
output.push("!");
output.push("!");
} else if(regenerate[i] === true) {
// if marked for name change, change name
output.push(newField[i]);
output.push("!");
} else {
// EBNF: citation-field
if(newField[i]) {
output.push(newField[i]);
} else {
output.push("!");
}
// EBNF: citation-data
var items = Scholar.Items.get(regenerate[i][0]);
output.push(style.createCitation(items, regenerate[i][1], "Integration"));
}
}
session.encounteredItem = encounteredItem;
return output;
}
/*
* gets a bibliography
* ACCEPTS: style, itemString
* RETURNS: bibliography
* restores a session, given all citations
* ACCEPTS: styleID(, fieldIndex, fieldName)+
* RETURNS: sessionID
*/
function getBibliography(vars) {
// get items
var itemIDs = vars[1].split("_");
var items = Scholar.Items.get(itemIDs);
function restoreSession(vars) {
var sessionID = Scholar.randomString();
var session = _generateSession(sessionID);
session.styleID = vars[0];
return Scholar.Cite.getBibliography(vars[0], items, "Integration");
var style = Scholar.Cite.getStyle(session.styleID);
var encounteredItem = new Object();
var newField = new Object();
var regenerate = new Object();
_inspectCitationPairs(vars, 1, session, style);
return [sessionID];
}
/*
* sets document preferences
* ACCEPTS: [currentStyle]
* RETURNS: (style, styleClass)
* ACCEPTS: (sessionID)?
* RETURNS: sessionID, styleID, style-class
*/
function setDocPrefs(vars) {
var io = new Object();
if(vars && vars[0]) {
io.style = vars[0];
if(!vars || vars[0] == "!") {
// no session ID; generate a new one
var sessionID = Scholar.randomString();
var session = _generateSession(sessionID);
} else {
// session ID exists
var sessionID = vars[0];
var session = _sessions[sessionID];
var originalStyle = session.styleID;
io.style = originalStyle;
}
window.openDialog('chrome://scholar/content/integrationDocPrefs.xul','',
'chrome,popup,modal,centerscreen',io);
var styleClass = Scholar.Cite.getStyleClass(io.style);
return [io.style, styleClass];
session.styleID = io.style;
var style = Scholar.Cite.getStyle(io.style);
return [sessionID, io.style, style.class];
}
/*
* inspects citation pairs to determine which are in need of an update
*
* vars - the set of variables
*
* startIndex - the place in the set of variables at which the citations
* begin
*
* session - the session variable (see _generateSession())
*
* encounteredItem - an object representing whether a given item ID has been
* encountered, in the format itemID => true
*
* newField - an object representing whether a given field needs to be
* renamed, in the format fieldIndex => newFieldName
*
* regenerate - an object representing whether the contents of a given field
* need to be modified, in the format:
* index => [[itemID1, itemID2], ([format1, format2] | "2")]
* formats are as follows:
* 1 => first occurance of a given item. use full citation.
* 2 => item occurred directly previously. use ibid. (never
* used as an array, only a single item)
* 3 => subsequent entry.
*/
function _inspectCitationPairs(vars, startIndex, session, style, encounteredItem, newField, regenerate, regenerateAll) {
var newItemFound = false;
var encounteredField = new Object();// keep track of field names, to see
// if there are duplicates
if(!encounteredItem) {
encounteredItem = new Object();
}
var lastItemIDString = null;
var index, field, lastItemID, itemIDs, itemID, itemSetValue;
for(var i=startIndex; i<vars.length; i+=2) {
index = vars[i];
field = vars[i+1];
if(regenerate && field == "!") {
// mark for deletion if necessary
Scholar.debug("Integration: Marking "+index+" for deletion");
regenerate[index] = false;
continue;
}
itemIDString = field.substr(0, field.indexOf("_"));
itemIDs = itemIDString.split(",");
itemSetValue = null;
if(itemIDString == lastItemIDString && style.ibid) {
// use ibid if possible
itemSetValue = 2;
} else {
// loop through to see which are first citations
itemSetValue = new Array();
for each(itemID in itemIDs) {
if(!encounteredItem[itemID]) {
encounteredItem[itemID] = true;
itemSetValue.push(1);
if(!session.encounteredItem[itemID]) {
newItemFound = true;
}
} else {
itemSetValue.push(3);
}
}
}
if(regenerateAll) {
// regenerate all citations if requested
var update = true;
} else {
// test to see if this itemSetValue is different from the
// version stored in the session
var update = false;
if(typeof(itemSetValue) == "object" &&
typeof(session.itemSet[field]) == "object") {
// loop through, looking for differences
for(var j in itemSetValue) {
if(itemSetValue[j] != session.itemSet[field][j]) {
update = true;
break;
}
}
} else if(itemSetValue != session.itemSet[field]) {
update = true;
}
}
if(update) {
Scholar.debug("Integration: field "+field+" at index "+index+" was "+(session.itemSet[field] ? session.itemSet[field].toSource() : "undefined")+" but is now "+itemSetValue.toSource());
// positioning has changed
if(encounteredField[field]) {
if(regenerate) {
// someone copy and pasted a citation from this document,
// since this field appears twice. and we have to change it.
newField[index] = itemIDString+"_"+Scholar.randomString();
session.itemSet[newField[index]] = itemSetValue;
}
} else {
session.itemSet[field] = itemSetValue;
}
if(regenerate) {
// regenerate citation
regenerate[index] = [itemIDs, itemSetValue];
}
} else if(encounteredField[field]) {
// someone copy and pasted a citation from this document,
// since this field appears twice. we don't have to change it,
// but we do need to change its name
session.itemSet[newField[index]] = itemSetValue;
if(regenerate) {
newField[index] = itemIDString+"_"+Scholar.randomString();
regenerate[index] = true; // true means name change without
// field value change
}
}
encounteredField[field] = true;
lastItemIDString = itemIDString;
}
return newItemFound;
}
/*
* generates, stores, and returns a new session object
*/
function _generateSession(sessionID) {
var session = _sessions[sessionID] = new Object();
session.encounteredItem = new Object();
session.itemSet = new Object();
return session;
}
}

View File

@ -5969,7 +5969,7 @@ REPLACE INTO "csl" VALUES('http://purl.org/net/xbiblio/csl/styles/apa.csl', '200
<access>
<text term-name="retrieved" text-transform="capitalize"/>
<date suffix=", ">
<month/>
<month suffix=" "/>
<day suffix=", "/>
<year/>
</date>