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:
parent
0515e4cb9e
commit
10f4b28c63
BIN
Zotero.dot.dmg
BIN
Zotero.dot.dmg
Binary file not shown.
|
@ -265,7 +265,9 @@ var Scholar_File_Interface = new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate bibliography
|
// 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") {
|
if(io.output == "print") {
|
||||||
// printable bibliography, using a hidden browser
|
// printable bibliography, using a hidden browser
|
||||||
|
@ -343,7 +345,7 @@ var Scholar_File_Interface = new function() {
|
||||||
transferable.addDataFlavor("text/html");
|
transferable.addDataFlavor("text/html");
|
||||||
transferable.setTransferData("text/html", str, bibliography.length*2);
|
transferable.setTransferData("text/html", str, bibliography.length*2);
|
||||||
// add text
|
// 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"].
|
var str = Components.classes["@mozilla.org/supports-string;1"].
|
||||||
createInstance(Components.interfaces.nsISupportsString);
|
createInstance(Components.interfaces.nsISupportsString);
|
||||||
str.data = bibliography;
|
str.data = bibliography;
|
||||||
|
|
|
@ -10,9 +10,7 @@ Scholar.Cite = new function() {
|
||||||
var _lastStyle = null;
|
var _lastStyle = null;
|
||||||
|
|
||||||
this.getStyles = getStyles;
|
this.getStyles = getStyles;
|
||||||
this.getStyleClass = getStyleClass;
|
this.getStyle = getStyle;
|
||||||
this.getBibliography = getBibliography;
|
|
||||||
this.getCitation = getCitation;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns an associative array of cslID => styleName pairs
|
* returns an associative array of cslID => styleName pairs
|
||||||
|
@ -30,46 +28,11 @@ Scholar.Cite = new function() {
|
||||||
|
|
||||||
return stylesObject;
|
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,
|
* gets CSL from the database, or, if it's the most recently used style,
|
||||||
* from the cache
|
* from the cache
|
||||||
*/
|
*/
|
||||||
function _getCSL(cslID) {
|
function getStyle(cslID) {
|
||||||
if(_lastStyle != cslID || Scholar.Prefs.get("cacheTranslatorData") == false) {
|
if(_lastStyle != cslID || Scholar.Prefs.get("cacheTranslatorData") == false) {
|
||||||
// get style
|
// get style
|
||||||
var sql = "SELECT csl FROM csl WHERE cslID = ?";
|
var sql = "SELECT csl FROM csl WHERE cslID = ?";
|
||||||
|
@ -111,56 +74,126 @@ CSL = function(csl) {
|
||||||
}
|
}
|
||||||
// load defaults from CSL
|
// load defaults from CSL
|
||||||
this._parseFieldDefaults(this._csl.defaults);
|
this._parseFieldDefaults(this._csl.defaults);
|
||||||
// parse bibliography options, since these will be necessary for
|
// parse bibliography and citation options
|
||||||
// disambiguation purposes even for citations
|
|
||||||
this._parseBibliographyOptions();
|
this._parseBibliographyOptions();
|
||||||
|
this._parseCitationOptions();
|
||||||
// if no bibliography exists, parse citation element as bibliography
|
// if no bibliography exists, parse citation element as bibliography
|
||||||
if(!this._bib) {
|
if(!this._bib) {
|
||||||
Scholar.debug("CSL: using citation element");
|
Scholar.debug("CSL: using citation element for bibliography");
|
||||||
if(!this._cit) {
|
|
||||||
this._parseCitationOptions();
|
|
||||||
}
|
|
||||||
this._bib = this._cit;
|
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) {
|
CSL.prototype.preprocessItems = function(items) {
|
||||||
// create a serialized string of all of the unique items
|
Scholar.debug("CSL: preprocessing items");
|
||||||
var serializedItemString = "";
|
|
||||||
|
|
||||||
this._items = items;
|
// get data necessary to generate citations before sorting
|
||||||
this._uniqueItems = new Array();
|
for(var i in items) {
|
||||||
var existingItems = new Object();
|
var item = items[i];
|
||||||
for each(var item in items) {
|
var dateModified = item.getField("dateModified");
|
||||||
var itemID = item.getID();
|
|
||||||
if(!existingItems[itemID]) {
|
if(!item._csl || item._csl.dateModified != dateModified) {
|
||||||
existingItems[itemID] = true;
|
// namespace everything in item._csl so there's no chance of overlap
|
||||||
this._uniqueItems.push(item);
|
item._csl = new Object();
|
||||||
serializedItemString += itemID+",";
|
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) {
|
// disambiguate items after preprocessing and sorting
|
||||||
// only re-process if there are new items
|
var usedCitations = new Array();
|
||||||
this._serializedItemString = serializedItemString;
|
var lastAuthor;
|
||||||
this._preprocessItems();
|
|
||||||
//}
|
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)
|
* 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());
|
Scholar.debug("CSL: creating citation for item "+items[0].getID());
|
||||||
if(!this._cit) {
|
|
||||||
this._parseCitationOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(types == 2) {
|
||||||
|
var string = this._getTerm("ibid", (items.length > 1 ? true : false));
|
||||||
|
string = string[0].toUpperCase()+string.substr(1);
|
||||||
|
} else {
|
||||||
var string = "";
|
var string = "";
|
||||||
for(var i in items) {
|
for(var i in items) {
|
||||||
if(this._cit.format && this._cit.format.delimiter && string) {
|
if(this._cit.format && this._cit.format.delimiter && string) {
|
||||||
|
@ -168,7 +201,8 @@ CSL.prototype.createCitation = function(items, format) {
|
||||||
// with content
|
// with content
|
||||||
string += this._cit.format.delimiter;
|
string += this._cit.format.delimiter;
|
||||||
}
|
}
|
||||||
string += this._getCitation(items[i], format, this._cit);
|
string += this._getCitation(items[i], (types[i] == 1 ? "first" : "subsequent"), format, this._cit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add format
|
// add format
|
||||||
|
@ -189,11 +223,7 @@ CSL.prototype.createCitation = function(items, format) {
|
||||||
* create a bibliography
|
* create a bibliography
|
||||||
* (items is expected to be an array of items)
|
* (items is expected to be an array of items)
|
||||||
*/
|
*/
|
||||||
CSL.prototype.createBibliography = function(format) {
|
CSL.prototype.createBibliography = function(items, format) {
|
||||||
// preprocess this._items
|
|
||||||
Scholar.debug("CSL: preprocessing items");
|
|
||||||
this._preprocessItems();
|
|
||||||
|
|
||||||
// process this._items
|
// process this._items
|
||||||
var output = "";
|
var output = "";
|
||||||
|
|
||||||
|
@ -212,10 +242,10 @@ CSL.prototype.createBibliography = function(format) {
|
||||||
output += "\r\n";
|
output += "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var i in this._uniqueItems) {
|
for(var i in items) {
|
||||||
var item = this._uniqueItems[i];
|
var item = items[i];
|
||||||
|
|
||||||
var string = this._getCitation(item, format, this._bib);
|
var string = this._getCitation(item, "first", format, this._bib);
|
||||||
|
|
||||||
// add format
|
// add format
|
||||||
if(this._bib.format) {
|
if(this._bib.format) {
|
||||||
|
@ -516,7 +546,7 @@ CSL.prototype._parseFieldDefaults = function(ref) {
|
||||||
/*
|
/*
|
||||||
* parses a list of fields into an array of objects
|
* 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();
|
var typeDesc = new Array();
|
||||||
for each(var element in ref) {
|
for each(var element in ref) {
|
||||||
if(element.namespace() == CSL.ns) { // ignore elements in other namespaces
|
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);
|
itemDesc._serialized = this._serializeElement(itemDesc.name, itemDesc);
|
||||||
// add to serialization for type
|
// add to serialization for type
|
||||||
if(bibCitElement) {
|
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();
|
var children = element.children();
|
||||||
if(children.length()) {
|
if(children.length()) {
|
||||||
itemDesc.children = this._parseFields(children, type, bibCitElement);
|
itemDesc.children = this._parseFields(children, position, type, bibCitElement);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// parse attributes on this field
|
// parse attributes on this field
|
||||||
|
@ -640,7 +670,7 @@ CSL.prototype._parseBibliographyOptions = function() {
|
||||||
this._bib.sortOrder[0].name = "cited";
|
this._bib.sortOrder[0].name = "cited";
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// parse et al
|
||||||
|
@ -683,22 +713,32 @@ CSL.prototype._parseTypes = function(itemElements, bibCitElement) {
|
||||||
|
|
||||||
// find the type item without position="subsequent"
|
// find the type item without position="subsequent"
|
||||||
for each(var itemElement in itemElements) {
|
for each(var itemElement in itemElements) {
|
||||||
if(itemElement.@position.toString() == "subsequent") {
|
var position = itemElement.@position.toString();
|
||||||
// bind subsequent element to position 1
|
if(position) {
|
||||||
bibCitElement._types[1] = itemElement;
|
// handle ibids
|
||||||
bibCitElement._serializations[1] = new Object();
|
if(position == "subsequent" &&
|
||||||
|
itemElement.@ibid.toString() == "true") {
|
||||||
|
this.ibid = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
position = "first";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bibCitElement._types[position]) {
|
||||||
|
bibCitElement._types[position] = new Object();
|
||||||
|
bibCitElement._serializations[position] = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
// create an associative array of available types
|
// create an associative array of available types
|
||||||
if(itemElement.choose.length()) {
|
if(itemElement.choose.length()) {
|
||||||
for each(var type in itemElement.choose.type) {
|
for each(var type in itemElement.choose.type) {
|
||||||
bibCitElement._types[type.@name] = type;
|
bibCitElement._types[position][type.@name] = type;
|
||||||
bibCitElement._serializations[type.@name] = new Object();
|
bibCitElement._serializations[position][type.@name] = new Object();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if there's only one type, bind it to index 0
|
// if there's only one type, bind it to index 0
|
||||||
bibCitElement._types[0] = itemElement;
|
bibCitElement._types[position][0] = itemElement;
|
||||||
bibCitElement._serializations[0] = new Object();
|
bibCitElement._serializations[position][0] = new Object();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -706,21 +746,22 @@ CSL.prototype._parseTypes = function(itemElements, bibCitElement) {
|
||||||
/*
|
/*
|
||||||
* convert reference types to native structures for speed
|
* convert reference types to native structures for speed
|
||||||
*/
|
*/
|
||||||
CSL.prototype._getTypeObject = function(reftype, bibCitElement) {
|
CSL.prototype._getTypeObject = function(position, reftype, bibCitElement) {
|
||||||
if(!bibCitElement._types[reftype]) {
|
if(!bibCitElement._types[position][reftype]) {
|
||||||
// no type available
|
// no type available
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse type if necessary
|
// parse type if necessary
|
||||||
if(typeof(bibCitElement._types[reftype]) == "xml") {
|
if(typeof(bibCitElement._types[position][reftype]) == "xml") {
|
||||||
Scholar.debug("CSL: parsing XML for "+reftype);
|
Scholar.debug("CSL: parsing XML for "+reftype);
|
||||||
bibCitElement._types[reftype] = this._parseFields(bibCitElement._types[reftype].children(),
|
bibCitElement._types[position][reftype] = this._parseFields(
|
||||||
reftype, bibCitElement, true);
|
bibCitElement._types[position][reftype].children(),
|
||||||
|
position, reftype, bibCitElement, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.debug("CSL: got object for "+reftype);
|
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;
|
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
|
* handles sorting of items
|
||||||
*/
|
*/
|
||||||
|
@ -1209,11 +1155,10 @@ CSL.prototype._processCreators = function(type, element, creators, format, bibCi
|
||||||
authorStrings[maxCreators-1] = and+" "+authorStrings[maxCreators-1];
|
authorStrings[maxCreators-1] = and+" "+authorStrings[maxCreators-1];
|
||||||
// skip the comma if there are only two creators and no
|
// skip the comma if there are only two creators and no
|
||||||
// et al, and name as sort is no
|
// et al, and name as sort is no
|
||||||
if(maxCreators == 2 &&
|
if((maxCreators == 2 && child["delimiter-precedes-last"] != "always") ||
|
||||||
(!element["name-as-sort-order"]
|
(maxCreators > 2 && child["delimiter-precedes-last"] == "never")) {
|
||||||
|| (element["name-as-sort-order"] != "first"
|
var lastString = authorStrings.pop();
|
||||||
&& element["name-as-sort-order"] != "all"))) {
|
authorStrings[maxCreators-2] = authorStrings[maxCreators-2]+" "+lastString;
|
||||||
joinString = " ";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1237,18 +1182,22 @@ CSL.prototype._processCreators = function(type, element, creators, format, bibCi
|
||||||
/*
|
/*
|
||||||
* get a citation, given an item and bibCitElement
|
* 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());
|
Scholar.debug("CSL: generating citation for item "+item.getID());
|
||||||
|
|
||||||
|
if(!bibCitElement._types[position]) {
|
||||||
|
position = "first";
|
||||||
|
}
|
||||||
|
|
||||||
// determine mapping
|
// determine mapping
|
||||||
if(bibCitElement._types[0]) {
|
if(bibCitElement._types[position][0]) {
|
||||||
// only one element
|
// only one element
|
||||||
var typeName = 0;
|
var typeName = 0;
|
||||||
var type = this._getTypeObject(typeName, bibCitElement);
|
var type = this._getTypeObject(position, typeName, bibCitElement);
|
||||||
} else {
|
} else {
|
||||||
var typeNames = this._getTypeFromItem(item);
|
var typeNames = this._getTypeFromItem(item);
|
||||||
for each(var typeName in typeNames) {
|
for each(var typeName in typeNames) {
|
||||||
var type = this._getTypeObject(typeName, bibCitElement);
|
var type = this._getTypeObject(position, typeName, bibCitElement);
|
||||||
if(type) {
|
if(type) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1263,7 +1212,7 @@ CSL.prototype._getCitation = function(item, format, bibCitElement) {
|
||||||
var string = "";
|
var string = "";
|
||||||
for(var j in type) {
|
for(var j in type) {
|
||||||
var value = this._getFieldValue(type[j].name, type[j], item, format,
|
var value = this._getFieldValue(type[j].name, type[j], item, format,
|
||||||
bibCitElement, typeName);
|
bibCitElement, position, typeName);
|
||||||
string += value;
|
string += value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1273,7 +1222,7 @@ CSL.prototype._getCitation = function(item, format, bibCitElement) {
|
||||||
/*
|
/*
|
||||||
* processes an element from a (pre-processed) item into text
|
* 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 = "";
|
var data = "";
|
||||||
|
|
||||||
if(element._serialized && item._csl.ignore[element._serialized]) {
|
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 child = element.children[i];
|
||||||
|
|
||||||
var string = this._getFieldValue(child.name, child, item,
|
var string = this._getFieldValue(child.name, child, item,
|
||||||
format, typeName, bibCitElement);
|
format, bibCitElement, position,
|
||||||
|
typeName);
|
||||||
if(string) {
|
if(string) {
|
||||||
childData.push(string);
|
childData.push(string);
|
||||||
}
|
}
|
||||||
|
@ -1427,9 +1377,10 @@ CSL.prototype._getFieldValue = function(name, element, item, format, bibCitEleme
|
||||||
inheritElement = element;
|
inheritElement = element;
|
||||||
} else {
|
} else {
|
||||||
// search for elements with the same serialization
|
// search for elements with the same serialization
|
||||||
if(typeName != undefined && bibCitElement._serializations[typeName]
|
if(typeName != undefined && bibCitElement._serializations[position]
|
||||||
&& bibCitElement._serializations[typeName][serialization]) {
|
&& bibCitElement._serializations[position][typeName]
|
||||||
inheritElement = bibCitElement._serializations[typeName][serialization];
|
&& bibCitElement._serializations[position][typeName][serialization]) {
|
||||||
|
inheritElement = bibCitElement._serializations[position][typeName][serialization];
|
||||||
} else {
|
} else {
|
||||||
// otherwise, use defaults
|
// otherwise, use defaults
|
||||||
inheritElement = this._getFieldDefaults(substituteElement.name);
|
inheritElement = this._getFieldDefaults(substituteElement.name);
|
||||||
|
|
|
@ -51,8 +51,7 @@ Scholar.Integration = new function() {
|
||||||
* handles a SOAP envelope
|
* handles a SOAP envelope
|
||||||
*/
|
*/
|
||||||
function handleEnvelope(envelope) {
|
function handleEnvelope(envelope) {
|
||||||
Scholar.debug("Integration: got SOAP envelope");
|
Scholar.debug("Integration: SOAP Request\n"+envelope);
|
||||||
Scholar.debug(envelope);
|
|
||||||
envelope = envelope.replace(_XMLRe, "");
|
envelope = envelope.replace(_XMLRe, "");
|
||||||
|
|
||||||
var env = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
|
var env = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
|
||||||
|
@ -116,9 +115,12 @@ Scholar.Integration = new function() {
|
||||||
</SOAP-ENV:Body>
|
</SOAP-ENV:Body>
|
||||||
</SOAP-ENV:Envelope>;
|
</SOAP-ENV:Envelope>;
|
||||||
|
|
||||||
|
var response = responseEnvelope.toXMLString();
|
||||||
|
Scholar.debug("Integration: SOAP Response\n"+response);
|
||||||
|
|
||||||
// return OK
|
// return OK
|
||||||
return _generateResponse("200 OK", 'text/xml; charset="utf-8"',
|
return _generateResponse("200 OK", 'text/xml; charset="utf-8"',
|
||||||
responseEnvelope.toXMLString());
|
response);
|
||||||
} else {
|
} else {
|
||||||
Scholar.debug("Integration: SOAP method not supported");
|
Scholar.debug("Integration: SOAP method not supported");
|
||||||
}
|
}
|
||||||
|
@ -294,10 +296,11 @@ Scholar.Integration.DataListener.prototype._requestFinished = function(response)
|
||||||
|
|
||||||
Scholar.Integration.SOAP = new function() {
|
Scholar.Integration.SOAP = new function() {
|
||||||
this.init = init;
|
this.init = init;
|
||||||
this.getCitation = getCitation;
|
this.update = update;
|
||||||
this.getBibliography = getBibliography;
|
this.restoreSession = restoreSession;
|
||||||
this.setDocPrefs = setDocPrefs;
|
this.setDocPrefs = setDocPrefs;
|
||||||
|
|
||||||
|
var _sessions = new Array();
|
||||||
var window;
|
var window;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
@ -308,76 +311,304 @@ Scholar.Integration.SOAP = new function() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* generates a new citation for a given item
|
* generates a new citation for a given item
|
||||||
* ACCEPTS: style[, itemString, newItemIndex]
|
* ACCEPTS: sessionID, bibliographyMode, citationMode(, fieldIndex, fieldName)+
|
||||||
* RETURNS: (newItem, citation)
|
* RETURNS: bibliography(, fieldIndex, fieldRename, fieldContent)+
|
||||||
*/
|
*/
|
||||||
function getCitation(vars) {
|
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
|
// get items
|
||||||
var io = {dataIn: null, dataOut: null};
|
var io = {dataIn: null, dataOut: null};
|
||||||
window.openDialog('chrome://scholar/content/selectItemsDialog.xul','',
|
window.openDialog('chrome://scholar/content/selectItemsDialog.xul','',
|
||||||
'chrome,popup,modal,centerscreen',io);
|
'chrome,popup,modal,centerscreen',io);
|
||||||
|
|
||||||
if(io.dataOut) { // cancel was not pressed
|
if(io.dataOut) { // cancel was not pressed
|
||||||
var selectedItemIDs = io.dataOut;
|
var field = (io.dataOut.join(","))+"_"+Scholar.randomString();
|
||||||
var selectedItems = Scholar.Items.get(selectedItemIDs);
|
|
||||||
|
|
||||||
var style = vars[0];
|
// set so that itemID works
|
||||||
if(vars[1]) { // some items already exist in the document
|
vars[newFieldArrayIndex] = field;
|
||||||
var itemString = vars[1]; // underscore-delimited string
|
// set so that field name will get changed
|
||||||
|
newField[newFieldIndex] = field;
|
||||||
var newItemIndex = parseInt(vars[2]); // index at which the
|
} else {
|
||||||
// item belongs in
|
vars[newFieldArrayIndex] = "!";
|
||||||
// itemString
|
newField[newFieldIndex] = "!";
|
||||||
|
}
|
||||||
// splice in the new item ID
|
}
|
||||||
if(newItemIndex == -1) { // at beginning
|
|
||||||
var items = selectedItems.concat(Scholar.Items.get(itemString.split("_")));
|
var regenerateItemList = _inspectCitationPairs(vars, 3, session, style,
|
||||||
} else { // at newItemIndex
|
encounteredItem, newField, regenerate,
|
||||||
var items = Scholar.Items.get(itemString.substr(0, newItemIndex).split("_")).
|
(citationMode == "all"));
|
||||||
concat(selectedItems);
|
|
||||||
|
if(!regenerateItemList) {
|
||||||
if(newItemIndex != itemString.length) { // not at the end
|
// if we're not already regenerating the item list, ensure no
|
||||||
items = items.concat(Scholar.Items.get(itemString.substr(newItemIndex+1).split("_")))
|
// citations have been deleted
|
||||||
|
for(var i in session.encounteredItem) {
|
||||||
|
if(!encounteredItem[i]) {
|
||||||
|
regenerateItemList = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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");
|
var output = new Array();
|
||||||
|
|
||||||
return [selectedItemIDs.join("_"), citation];
|
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
|
* restores a session, given all citations
|
||||||
* ACCEPTS: style, itemString
|
* ACCEPTS: styleID(, fieldIndex, fieldName)+
|
||||||
* RETURNS: bibliography
|
* RETURNS: sessionID
|
||||||
*/
|
*/
|
||||||
function getBibliography(vars) {
|
function restoreSession(vars) {
|
||||||
// get items
|
var sessionID = Scholar.randomString();
|
||||||
var itemIDs = vars[1].split("_");
|
var session = _generateSession(sessionID);
|
||||||
var items = Scholar.Items.get(itemIDs);
|
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
|
* sets document preferences
|
||||||
* ACCEPTS: [currentStyle]
|
* ACCEPTS: (sessionID)?
|
||||||
* RETURNS: (style, styleClass)
|
* RETURNS: sessionID, styleID, style-class
|
||||||
*/
|
*/
|
||||||
function setDocPrefs(vars) {
|
function setDocPrefs(vars) {
|
||||||
var io = new Object();
|
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','',
|
window.openDialog('chrome://scholar/content/integrationDocPrefs.xul','',
|
||||||
'chrome,popup,modal,centerscreen',io);
|
'chrome,popup,modal,centerscreen',io);
|
||||||
var styleClass = Scholar.Cite.getStyleClass(io.style);
|
session.styleID = io.style;
|
||||||
return [io.style, styleClass];
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5969,7 +5969,7 @@ REPLACE INTO "csl" VALUES('http://purl.org/net/xbiblio/csl/styles/apa.csl', '200
|
||||||
<access>
|
<access>
|
||||||
<text term-name="retrieved" text-transform="capitalize"/>
|
<text term-name="retrieved" text-transform="capitalize"/>
|
||||||
<date suffix=", ">
|
<date suffix=", ">
|
||||||
<month/>
|
<month suffix=" "/>
|
||||||
<day suffix=", "/>
|
<day suffix=", "/>
|
||||||
<year/>
|
<year/>
|
||||||
</date>
|
</date>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user