Describe the bug
Function capitalize() also capitalizes the 's used to indicate possession.
To Reproduce
Steps to reproduce the behavior:
[r: capitalize("a bug's life")]A Bug'S LifeExpected behavior
The 's is not capitalized.
MapTool Info
Desktop (please complete the following information):
I believe there was a discussion about this on Discord at the time it was added and it was thought better to handle capitalize("rick o'shea") => Rick O'Shea correctly than worry about possessives.
@cwisniew ?
If the 's ends the word, it shouldn't be capitalized.
It's more than just the 's.
List: 's, 'll, 't, 'd, 've, 're
Example: [capitalize("i'll do it. no you won't. like you'd know. i've seen you.")]
Result: I'Ll Do It. No You Won'T. Like You'D Know. I'Ve Seen You.
Wow, that's going to be tough to solve, especially considering that the locale is a factor.
I seem to recall that the String class allows a locale to be specified for things like a case-insensitive equals function... Perhaps there's something similar for case conversion?
Edit: Nope, no such luck. Or at least, I didn't see anything appropriate in the String or Locale classes, but I didn't search the web for it.
True. In French you have "C'est la vie" which definitely should not be capitalized to "C'Est La Vie" like it is currently.
Maybe capitalize should have an extra parameter, to specify how the capitalization should be done?
The alternative is to change capitalize so that only the first letter of the word is capitalized. This would mean O'Brian and O'Shea do not have their second letter capitalized if they weren't capitalized before. There is a workaround however: just always use the capitalized version of these names in your campaign - [capitalize("O'Brian")] will returns O'Brian as it should. These names should always have their first two letters capitalized anyway, so this shouldn't be much of an issue.
I think the 's, 'll, 't, 'd, 've, 're being capitalized when they shouldn't is much more problematic - there is no workaround for it, and these apostrophes are frequent for spell names and the like (think Leomund鈥橲 Tiny Hut or Mordenkainen'S Magnificent Mansion).
I'd tend to agree with Merudo that the downsides of treating ' as a word boundary here outweigh the somewhat incidental gain of capitalizing "O'Brien". The function is intended (or at least, is described as intended) to capitalize the first letter of each word, so it doing any kind of internal capitalization seems inappropriate.
For what it's worth, that's the approach taken by the Apache Commons library's WordUtils.captialize(), and ICU4J's UCharacter.toTitleCase() methods.
Unless the code changed since it was added back in October it is using common-language WordUtils.capitalize().
Unless the code changed since it was added back in October it is using common-language WordUtils.capitalize().
It is using Regex:
private String capitalize(String str) {
Pattern pattern = Pattern.compile("(\\p{IsAlphabetic}+)");
Matcher matcher = pattern.matcher(str);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String word = matcher.group();
matcher.appendReplacement(result, Character.toTitleCase(word.charAt(0)) + word.substring(1));
}
matcher.appendTail(result);
return result.toString();
}
Had to go back to the discussion last October. Craig was going to use it but didn't. From the discussion it was desired that symbols and numbers were seen as word breaks which coincidentally is exactly what the documentation says.
Feel free to add a parameter that switches to using WordUtils.capitalize().
Wiki page for capitalize() updated to reflect changes coming in 1.8
(though, sidenote: if anyone can come up with a more succinct name for the new treatNumbersSymbolsAsBoundaries parameter, please feel free to replace it in those docs!)
Tested. New parameter provides an alternative way to get capitalization wrong.
[r: capitalize("o'shea thinks it's a sin")]
[r: capitalize("o'shea thinks it's a sin",1)]
produces O'Shea Thinks It'S A Sin
[r: capitalize("o'shea thinks it's a sin",0)]
produces O'shea Thinks It's A Sin
@Phergus if that second option doesn't produce a capital Sin, we've got problems - but I'm assuming it's just a typo in your comment.
Yup. lol
Pasting out of MT chat into issues is a nuisance and I was too lazy to do it first in NP++ and then into the issue.