From 3b2cc93269e8405861d4bb01c75220379d1ed01d Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Fri, 1 Jul 2011 04:20:48 +0000 Subject: [PATCH] Move Zotero.Text.titleCase() to Zotero.Utilities(), since it's not used anywhere else in the Zotero code --- chrome/content/zotero/xpcom/utilities.js | 54 +++++++++++++++++++++--- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js index bb5ee8cd3..b667f23a7 100644 --- a/chrome/content/zotero/xpcom/utilities.js +++ b/chrome/content/zotero/xpcom/utilities.js @@ -489,13 +489,57 @@ Zotero.Utilities = { * @type String */ "capitalizeTitle":function(string, force) { + const skipWords = ["but", "or", "yet", "so", "for", "and", "nor", "a", "an", + "the", "at", "by", "from", "in", "into", "of", "on", "to", "with", "up", + "down", "as"]; + + // this may only match a single character + const delimiterRegexp = /([ \/\-–—])/; + string = this.trimInternal(string); string = string.replace(" : ", ": ", "g"); - if(Zotero.Prefs.get('capitalizeTitles') || force) { - // fix colons - string = Zotero.Text.titleCase(string); + if(!Zotero.Prefs.get('capitalizeTitles') && !force) return string; + if(!string) return ""; + + // split words + var words = string.split(delimiterRegexp); + var isUpperCase = string.toUpperCase() == string; + + var newString = ""; + var delimiterOffset = words[0].length; + var lastWordIndex = words.length-1; + var previousWordIndex = -1; + for(var i=0; i<=lastWordIndex; i++) { + // only do manipulation if not a delimiter character + if(words[i].length != 0 && (words[i].length != 1 || !delimiterRegexp.test(words[i]))) { + var upperCaseVariant = words[i].toUpperCase(); + var lowerCaseVariant = words[i].toLowerCase(); + + // only use if word does not already possess some capitalization + if(isUpperCase || words[i] == lowerCaseVariant) { + if( + // a skip word + skipWords.indexOf(lowerCaseVariant.replace(/[^a-zA-Z]+/, "")) != -1 + // not first or last word + && i != 0 && i != lastWordIndex + // does not follow a colon + && (previousWordIndex == -1 || words[previousWordIndex][words[previousWordIndex].length-1] != ":") + ) { + words[i] = lowerCaseVariant; + } else { + // this is not a skip word or comes after a colon; + // we must capitalize + words[i] = upperCaseVariant[0] + lowerCaseVariant.substr(1); + } + } + + previousWordIndex = i; + } + + newString += words[i]; } - return string; + + return newString; }, /** @@ -644,7 +688,7 @@ Zotero.Utilities = { } else if(element.documentElement) { var rootDoc = element; } else { - throw new Error("First argument must be either element(s) or document(s) in Zotero.Utilities.xpath()"); + throw new Error("First argument must be either element(s) or document(s) in Zotero.Utilities.xpath(elements, '"+xpath+"')"); } try {