|
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 = /([ \/\u002D\u00AD\u2010-\u2015\u2212\u2E3A\u2E3B])/; |
|
|
|
string = this.trimInternal(string); |
|
string = string.replace(/ : /g, ": "); |
|
if (Zotero.Prefs && !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].search(/[:\?!]/)==-1) |
|
) { |
|
words[i] = lowerCaseVariant; |
|
} else { |
|
// this is not a skip word or comes after a colon; |
|
// we must capitalize |
|
// handle punctuation in the beginning, including multiple, as in "¿Qué pasa?" |
|
var punct = words[i].match(/^[\'\"¡¿“‘„«\s]+/); |
|
punct = punct ? punct[0].length+1 : 1; |
|
words[i] = words[i].length ? words[i].substr(0, punct).toUpperCase() + |
|
words[i].substr(punct).toLowerCase() : words[i]; |
|
} |
|
} |
|
|
|
previousWordIndex = i; |
|
} |
|
|
|
newString += words[i]; |
|
} |
|
|
|
return newString; |
|
}, |
In my experience, when I hit the "Title Case" context menu for entry titles, I want words that follow colons and round braces to be capitalized. What is the reason this is not the case?
I'm not familiar with the Zotero codebase but I believe that line 962 sets those delimiters but I see there is explicit design for not capitalizing words following colons (990-1).
utilities/utilities.js
Lines 956 to 1012 in 48df1de