From 9a40d041b34b2ad4e526562d70819d10597800d3 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Wed, 19 Sep 2007 05:06:16 +0000 Subject: [PATCH] - closes #536, Hanging indent missing in APA citations in Word - closes #736, bring Zotero up to date with latest CSL revisions - allows citing multiple sources in IEEE and Nature styles, collapse citation numbers, and sort citations by citation number - fixes a bug in the add citation dialog when adding items to the "Multiple Sources" pane, then turning off multiple sources --- chrome/content/zotero/addCitationDialog.js | 20 +- chrome/content/zotero/xpcom/cite.js | 332 ++++++++++++++------- chrome/content/zotero/xpcom/ingester.js | 42 +-- chrome/content/zotero/xpcom/integration.js | 20 +- chrome/locale/en-US/zotero/locales.xml | 1 + scrapers.sql | 64 ++-- 6 files changed, 319 insertions(+), 160 deletions(-) diff --git a/chrome/content/zotero/addCitationDialog.js b/chrome/content/zotero/addCitationDialog.js index 552ab778e..63fefcc0c 100644 --- a/chrome/content/zotero/addCitationDialog.js +++ b/chrome/content/zotero/addCitationDialog.js @@ -165,6 +165,9 @@ var Zotero_Citation_Dialog = new function () { // delete item list _itemData = new Object(); + + // delete all items + _clearCitationList(); } _updateAccept(); _updatePreview(); @@ -254,14 +257,11 @@ var Zotero_Citation_Dialog = new function () { _getCitation(); // delete all existing items from list - var citationList = document.getElementById("citation-list"); - while(citationList.firstChild) { - citationList.removeChild(citationList.firstChild); - } + _clearCitationList(); // run preview function to re-sort, if it hasn't already been // run - if(!_previewShown) io.previewFunction(); + io.previewFunction(); // add items back to list for(var i=0; i maxFirstFieldLength) { + maxFirstFieldLength = tab; + } + } // add line feeds if(format == "HTML") { @@ -406,6 +435,9 @@ Zotero.CSL.prototype.formatBibliography = function(itemSet, format) { if(this.class == "note" && isCitation) { output += "
  • "+string+span+"
  • \r\n"; + } else if(secondFieldAlign) { + output += ''+string+span+"\r\n" + +' \r\n'; } else { output += "

    "+string+span+"

    \r\n"; } @@ -422,25 +454,54 @@ Zotero.CSL.prototype.formatBibliography = function(itemSet, format) { } // attach \n on mac (since both \r and \n count as newlines for // clipboard purposes) - output += string+(Zotero.isMac ? "\n\n" : "\r\n\r\n"); + output += string+(Zotero.isWin ? "\r\n\r\n" : "\n\n"); } } if(format == "HTML") { if(this.class == "note" && isCitation) { output += ''; - } else if(hangingIndent) { - output += ''; + } else { + if(secondFieldAlign) { + output += ''; + } + if(hangingIndent) { + output += ''; + } } - } else if(format == "RTF") { - // drop last 6 characters of output (last two returns) - output = output.substr(0, output.length-6)+"}"; - } else { - // drop last 4 characters (last two returns) - output = output.substr(0, (Zotero.isMac ? output.length-2 : output.length-4)); + } else if(format == "RTF" || format == "Integration") { + if(secondFieldAlign) { + // 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+maxFirstFieldLength*120; + + if(secondFieldAlign == "margin") { + firstLineIndent -= alignAt; + tabStop = 0; + } else { + indent += alignAt; + firstLineIndent = -indent; + tabStop = indent; + } + } + + preamble += "\\li"+indent+" \\fi"+firstLineIndent+" "; + if(tabStop !== null) { + preamble += "\\tx"+tabStop+" "; + } + + if(format == "RTF") { + // drop last 6 characters of output (last two returns) + output = output.substr(0, output.length-6)+"}"; + } else { + // drop last 4 characters (last two returns) + output = output.substr(0, (Zotero.isWin ? output.length-4 : output.length-2)); + } + preamble += "\r\n"; } - return output; + return preamble+output; } /* @@ -923,6 +984,7 @@ Zotero.CSL.prototype._processElements = function(item, element, formattedString, || newChild.localName() == "else-if") { var matchAny = newChild.@match == "any"; + var matchNone = newChild.@match == "none"; if(matchAny) { // if matching any, begin with false, then set to true // if a condition is true @@ -934,10 +996,14 @@ Zotero.CSL.prototype._processElements = function(item, element, formattedString, } // inspect variables - for each(var attribute in ["variable", "type", "disambiguate", "locator", "position"]) { + var done = false; + var attributes = ["variable", "type", "disambiguate", "locator", "position"]; + for(var k=0; !done && k - newString += '>'; - break; - case 8211: // en-dash - newString += '–' - break; - case 8212: // em-dash - newString += '—' - break; - default: - newString += string[i]; - } - } - - string = newString; - + string = string.replace("<", "<", "g") + .replace(">", ">", "g") + .replace("&", "&", "g") + .replace(/(\r\n|\r|\n)/g, "
    ") + .replace(/[\x00-\x1F]/g, ""); } else if(this.format == "RTF") { - var newString = ""; - - // go through and fix up unicode entities - for(var i=0; i 127) { // encode unicode - newString += "{\\uc0\\u"+charCode.toString()+"}"; - } else if(charCode == 92) { // double backslashes - newString += "\\\\"; - } else { - newString += string[i]; - } - } - - string = newString; + string = string.replace(/[\x7F-\uFFFF]/g, Zotero.CSL.FormattedString._rtfEscapeFunction) + .replace("\\", "\\\\", "g") + .replace("\t", "\\tab ", "g") + .replace(/(\r\n|\r|\n)/g, "\\line "); } else if(this.format == "Integration") { - string = string.replace(/\\/g, "\\\\"); + string = string.replace(/\\/g, "\\\\") + .replace(/(\r\n|\r|\n)/g, "\\line "); + } else { + string = string.replace(/(\r\n|\r|\n)/g, (Zotero.isWin ? "\r\n" : "\n")); } } if(element) { + // style attributes if(this.format == "HTML") { var style = ""; var cssAttributes = ["font-family", "font-style", "font-variant", - "font-weight"]; + "font-weight", "vertical-align", "display"]; for(var j in cssAttributes) { var value = element["@"+cssAttributes[j]].toString(); if(value && value.indexOf('"') == -1) { - style += cssAttributes[j]+":"+value; + style += cssAttributes[j]+":"+value+";"; } } - if(style) { + if(element["@display"] == "block") { + if(this.option.(@name == "hanging-indent").@value == "true") { + style += "text-indent:0.5in;" + } + + if(style) { + string = '
    '+string+'
    '; + } else { + string = '
    '+string+'
    '; + } + } else if(style) { string = ''+string+''; } - } else if(this.format == "RTF" || this.format == "Integration") { - if(element["@font-style"] == "oblique" || element["@font-style"] == "italic") { - string = "\\i "+string+"\\i0 "; + } else { + if(this.format == "RTF" || this.format == "Integration") { + if(element["@font-style"] == "oblique" || element["@font-style"] == "italic") { + string = "\\i "+string+"\\i0 "; + } + + if(element["@font-variant"] == "small-caps") { + string = "\\scaps "+string+"\\scaps0 "; + } + + if(element["@font-weight"] == "bold") { + string = "\\b "+string+"\\b0 "; + } + + if(element["@text-decoration"] == "underline") { + string = "\\ul "+string+"\\ul0 "; + } + + if(element["@vertical-align"] == "sup") { + string = "\\super "+string+"\\super0 "; + } else if(element["@vertical-align"] == "sub") { + string = "\\sub "+string+"\\sub0 "; + } } - if(element["@font-variant"] == "small-caps") { - string = "\\scaps "+string+"\\scaps0 "; - } - if(element["@font-weight"] == "bold") { - string = "\\b "+string+"\\b0 "; - } - if(element["@text-decoration"] == "underline") { - string = "\\ul "+string+"\\ul0 "; + + if(element["@display"] == "block" || this.appendLine) { + if(this.format == "RTF") { + string = "\r\n\\line "+string; + } else if(this.format == "Integration") { + string = "\x0B"+string; + } else { + string = (Zotero.isWin ? "\r\n" : "\n")+string; + } + this.appendLine = element["@display"] == "block"; } } @@ -2227,6 +2326,25 @@ Zotero.CSL.FormattedString.prototype.append = function(string, element, dontDeli this.append(element.@suffix.toString(), null, true); } + // save for second-field-align + if(!dontDelimit && this.insertTabAfterField) { + // replace any space following this entry + this.string = this.string.replace(/\s+$/, ""); + + if(this.format == "HTML") { + this.string += ''; + } else if(this.format == "RTF") { + this.string += "\\tab "; + } else if(this.format == "Integration") { + this.string += "\t"; + } else { + this.string += " "; + } + + this.insertTabAfterField = false; + this.suppressLeadingWhitespace = true; + } + return true; } @@ -2241,7 +2359,7 @@ Zotero.CSL.FormattedString.prototype.get = function() { * creates a new formatted string with the same formatting parameters as this one */ Zotero.CSL.FormattedString.prototype.clone = function(delimiter) { - return new Zotero.CSL.FormattedString(this.CSL, this.format, delimiter); + return new Zotero.CSL.FormattedString(this.context, this.format, delimiter, true); } /* diff --git a/chrome/content/zotero/xpcom/ingester.js b/chrome/content/zotero/xpcom/ingester.js index a0304f64f..c39f112ac 100644 --- a/chrome/content/zotero/xpcom/ingester.js +++ b/chrome/content/zotero/xpcom/ingester.js @@ -283,11 +283,11 @@ Zotero.OpenURL = new function() { } else { co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&rft.genre=article"; } - co += _mapTag(item.title, "atitle", version) - co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "jtitle"), version) - co += _mapTag(item.journalAbbreviation, "stitle", version); - co += _mapTag(item.volume, "volume", version); - co += _mapTag(item.issue, "issue", version); + if(item.title) co += _mapTag(item.title, "atitle", version) + if(item.publicationTitle) co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "jtitle"), version) + if(item.journalAbbreviation) co += _mapTag(item.journalAbbreviation, "stitle", version); + if(item.volume) co += _mapTag(item.volume, "volume", version); + if(item.issue) co += _mapTag(item.issue, "issue", version); } else if(item.itemType == "book" || item.itemType == "bookitem") { if(version == "0.1") { co += "&genre=book"; @@ -297,29 +297,29 @@ Zotero.OpenURL = new function() { if(item.itemType == "book") { co += "&rft.genre=book"; - co += _mapTag(item.title, (version == "0.1" ? "title" : "btitle"), version); + if(item.title) co += _mapTag(item.title, (version == "0.1" ? "title" : "btitle"), version); } else { co += "&rft.genre=bookitem"; - co += _mapTag(item.title, "atitle", version) - co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "btitle"), version); + if(item.title) co += _mapTag(item.title, "atitle", version) + if(item.publicationTitle) co += _mapTag(item.publicationTitle, (version == "0.1" ? "title" : "btitle"), version); } - co += _mapTag(item.place, "place", version); - co += _mapTag(item.publisher, "publisher", version) - co += _mapTag(item.edition, "edition", version); - co += _mapTag(item.series, "series", version); + if(item.place) co += _mapTag(item.place, "place", version); + if(item.publisher) co += _mapTag(item.publisher, "publisher", version) + if(item.edition) co += _mapTag(item.edition, "edition", version); + if(item.series) co += _mapTag(item.series, "series", version); } else if(item.itemType == "thesis" && version == "1.0") { co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adissertation"; - _mapTag(item.title, "title", version); - _mapTag(item.publisher, "inst", version); - _mapTag(item.type, "degree", version); + if(item.title) co += _mapTag(item.title, "title", version); + if(item.publisher) co += _mapTag(item.publisher, "inst", version); + if(item.type) co += _mapTag(item.type, "degree", version); } else if(item.itemType == "patent" && version == "1.0") { co += "&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Apatent"; - _mapTag(item.title, "title", version); - _mapTag(item.assignee, "assignee", version); - _mapTag(item.patentNumber, "number", version); + if(item.title) co += _mapTag(item.title, "title", version); + if(item.assignee) co += _mapTag(item.assignee, "assignee", version); + if(item.patentNumber) co += _mapTag(item.patentNumber, "number", version); if(item.issueDate) { co += _mapTag(Zotero.Date.strToISO(item.issueDate), "date", version); @@ -352,9 +352,9 @@ Zotero.OpenURL = new function() { if(item.date) { co += _mapTag(Zotero.Date.strToISO(item.date), (item.itemType == "patent" ? "appldate" : "date"), version); } - co += _mapTag(item.pages, "pages", version); - co += _mapTag(item.ISBN, "isbn", version); - co += _mapTag(item.ISSN, "issn", version); + if(item.pages) co += _mapTag(item.pages, "pages", version); + if(item.ISBN) co += _mapTag(item.ISBN, "isbn", version); + if(item.ISSN) co += _mapTag(item.ISSN, "issn", version); if(version == "0.1") { // chop off leading & sign if version is 0.1 diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js index 06eb6d024..8f4d44453 100644 --- a/chrome/content/zotero/xpcom/integration.js +++ b/chrome/content/zotero/xpcom/integration.js @@ -915,9 +915,15 @@ Zotero.Integration.Session.prototype.updateItemSet = function() { Zotero.Integration.Session.prototype.sortItemSet = function() { if(!this.itemSetIsSorted) { if(!this.itemSet.sortable) { - // sort by order in document + // sort by order in document. we need a stable sort, so first we + // collect old indices. + var oldItemIndices = new Object(); + for(var i=0; i + at in ibid accessed diff --git a/scrapers.sql b/scrapers.sql index 0c7c1b9d2..62410a170 100644 --- a/scrapers.sql +++ b/scrapers.sql @@ -17491,10 +17491,10 @@ REPLACE INTO csl VALUES('http://purl.org/net/xbiblio/csl/styles/asa.csl', '2007- '); -REPLACE INTO csl VALUES('http://purl.org/net/xbiblio/csl/styles/nature.csl', '2007-09-06 19:30:00', 'Nature Journal', +REPLACE INTO csl VALUES('http://purl.org/net/xbiblio/csl/styles/nature.csl', '2007-09-19 04:01:40', 'Nature Journal', ' -' ); -REPLACE INTO csl VALUES('http://purl.org/net/xbiblio/csl/styles/nlm.csl', '2007-09-06 19:30:00', 'National Library of Medicine', +REPLACE INTO csl VALUES('http://purl.org/net/xbiblio/csl/styles/nlm.csl', '2007-09-19 04:01:40', 'National Library of Medicine', ' '); -REPLACE INTO csl VALUES('http://purl.org/net/xbiblio/csl/styles/ieee.csl', '2007-09-06 19:35:00', 'IEEE', +REPLACE INTO csl VALUES('http://purl.org/net/xbiblio/csl/styles/ieee.csl', '2007-09-19 04:01:40', 'IEEE', '