So that we can do the following:
${str}= | Convert To Titlecase} | abc
Should Be Equal | ${str} | Abc
Cases:
Can be added if someone provides a pull request.
Notice that string.title() converts Bill from the UK to Bill From The Uk which is not what you propose and which I don't like either. This is also the reason Convert To Titlecase was not implemented as part of #1735. Robot has utility function robot.utils.printable_name which handles that case better, but it also collapses spaces so that Bill      from the UK is turned to Bill From The UK. I don't think collapsing spaces is a good idea, especially because it would be inconsistent with other related keywordst, but the utility could be easily enhanced to make that behavior configurable.
Handling convert XML to HTML so that it becomes Convert XML to HTML as you propose is a much bigger problem. Note that title casing words like to would require having a list of such words somewhere. I don't think that's feasible, especially when the keyword should not be tied to English.
I have fix this and would like to create pull request for this. As a first time contributor, I need guidance on how to push code to repository. Can you please guild me
Solution:
Examples:
| ${str1} = | Convert To Titlecase | abc |
| ${str2} = | Convert To Titlecase | i love robot Framework |
| ${str3} = | Convert To Titlecase | i love ROBOT Framework |
| Should Be Equal | ${str1} | Abc |
| Should Be Equal | ${str2} | I Love Robot Framework |
| Should Be Equal | ${str3} | I Love ROBOT Framework |
| ${str4} = | Convert To Titlecase | i love ROBOT Framework |
| Should Be Equal | ${str4} | I Love ROBOT Framework |
Preserve spaces as well.
Awesome! Did you already read contribution guidelines? If you are new to Git/GitHub and pull requests, you probably should read the referenced documents related to them too.
Did you @bbpatel2001 create a PR for this already?
Hi I was thinking of taking this issue up. Is it still needed to be worked on. I have read the whole conversation, and would like to start building a solution, to all of the edge cases.
I have collected all of the tests here, anything missing?
| ${str1} = | Convert To Titlecase | abc |
| ${str2} = | Convert To Titlecase | i love robot Framework |
| ${str3} = | Convert To Titlecase | i love ROBOT Framework |
| ${str4} = | Convert To Titlecase | foo\tbar |
| ${str5} = | Convert To Titlecase | foo\nbar |
| ${str6} = | Convert To Titlecase | fooxa0bar |
| ${str7} = | Convert To Titlecase | äiti åse |
| ${str8} = | Convert To Titlecase | they're from UK |
| ${str9} = | Convert To Titlecase | i love my iPhone |
| ${str10} = | Convert To Titlecase | multiple spaces |
| Should Be Equal | ${str1} | Abc |
| Should Be Equal | ${str2} | I Love Robot Framework |
| Should Be Equal | ${str3} | I Love ROBOT Framework |
| Should Be Equal | ${str4} | Foo\tBar |
| Should Be Equal | ${str5} | Foo\nBar |
| Should Be Equal | ${str6} | Fooxa0Bar |
| Should Be Equal | ${str7} | Äiti Åse |
| Should Be Equal | ${str8} | They're From UK |
| Should Be Equal | ${str9} | I Love My iPhone |
| Should Be Equal | ${str10} | Multiple Spaces |
Still needed, as far as I can tell, still absent from the String Library. I have a need to do convert H3 text to proper case in order to get a match on an Xpath contains, and am now looking at using Split to get the words, then split to Characters, then uppercasing the first element of each array - not pretty.
Yeah, this isn't yet implemented. There was PR #2719 but it had problems that prevented it being merged. As I commented that PR, coming up with an algorithm that handles this seemingly simple problem well is surprisingly complicated. One thing that helps is first creating tests that go through all special cases to make sure the algorithm really works. There were some good tests already in #2719, but at least these should've been added still:
foo\tbar -> Foo\tBar
foo\nbar -> Foo\nBar
foo\xa0bar -> Foo\xa0Bar
äiti åse -> Äiti Åse
they're from UK -> They're From UK
multiple spaces -> Multiple Spaces
There are various solutions for this on Stackoverflow both here and here, but most of them fail some of the above examples. I got a feeling that it's best to handle this using regular expressions either by using re.sub or by splitting from whitespace, but there may be still better solutions than those.
One big problem related to this is that correct title case depends highly on context. For example, in English title casing typically leaves a, to and similar to lower case, but I'd prefer our keywords to be fully generic and title case all words by default. Making the behavior configurable would be nice, though, and we could consider at least these solutions:
Implement different title casing algorithms (one could be just string.title()) and make it possible to select which one to use with an optional argument.
Allow giving a list of words that should not be modified. It could allow usages like | Convert To Title Case | i go to a hotel | preserve=a,to | that would yield I Go to a Hotel.
The latter would probably be easier to implement and also more flexible.
How about what the authors of the titlecase package did, as a start? "The list of "SMALL words" which are not capped comes from the New York Times Manual of Style, plus some others like 'vs' and 'v'."
I don't think that's a good idea for the following two reasons:
One thing to decide when implementing the algorithm is how to handle cases like 3m and -foo-bar- i.e. situation where a string doesn't start with character that has lower and upper case forms. I was a bit surprised how Python's string.title() handles them:
>>> '3m'.title()
'3M'
>>> '-foo-bar-'.title()
'-Foo-Bar-'
At least for me the above behavior is fine, though, but that's one (or two) more special cases to decide and document with explicit tests. One benefit of this behavior would be that it ought to be relatively easy to find words from strings using regexps.
Hey! You are obviously really smart, and thinking seriously about this.
Consider that there is currently NO such option available to Robot
Framework users via the String library.
It seems likely to me that any reasonable approach from here is much better
than nothing. I can't help with the development, but maybe I can help by
pointing out what looks like paralysis by analysis. It seems likely that
English is the best starting language and that the NYT is qualified to
maintain a set of "small words", per the titlecase package. The addition
of the preserve syntax you suggested would be a nice advance.
Hi All,
Thanks for good suggestions by Pekka Klarck and other contributors.
I will again work and try to fix all those suggestions.
Regards
Bharat Patel
On Mon, May 27, 2019 at 9:51 AM Ken Lyle notifications@github.com wrote:
Hey! You are obviously really smart, and thinking seriously about this.
Consider that there is currently NO such option available to Robot
Framework users via the String library.It seems likely to me that any reasonable approach from here is much better
than nothing. I can't help with the development, but maybe I can help by
pointing out what looks like paralysis by analysis. It seems likely that
English is the best starting language and that the NYT is qualified to
maintain a set of "small words", per the titlecase package. The addition
of the preserve syntax you suggested would be a nice advance.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/robotframework/robotframework/issues/2706?email_source=notifications&email_token=AIBN7WZBMZCVSMSRHZTEDEDPXNOUZA5CNFSM4ECECH4KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWIXN7Q#issuecomment-496072446,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AIBN7W3Z6ALLLGKHQ4TSXB3PXNOUZANCNFSM4ECECH4A
.
--
Thanks & Regards
Bharat Patel
In my RF project as a workaround, I had to lowercase an uppercase article title, split the words, and then uppercase the first letter and append it back using substring funcitons, This was in order to pass the refomatted word to an Xpath locator for which I needed the href attribute. Pretty....ugly.
Great if you are interested to continue with this @bbpatel2001! The biggest problem with the old PR was that it contained also unrelated changes. To avoid them, create a dedicated branch for this enhancement and do possible other changes in other branches. If I remember correctly, the PR already had good tests but, as discussed in the comments of the PR and this issue, there are more cases that could still be added. I prototyped a bit with a possible implementation and will include it in a separate comment.
@kenlyle2 I do think seriously cases like this because want to make sure we get details right. I know, based on my own experience, that changing details later is very complicated due to backwards compatibility reasons. That's the reason I rather have no "Convert To Titlecase" keyword in Robot Framework core than have a version that doesn't work well. If someone needs it urgently, it's easy to create a custom library that just calls string.title() or uses some other simple algorithm.
If you need to handle strings in different cases in xpath, you could use upper-case() or lower-case() xpath functions to normalize stings. Or even better, they to use an xpath that doesn't require matching based on text. Best would be adding an id to the element you need to interact but adding an id some of its parent elements might be enough as well.
The following implementation seems to work pretty well and handles cases like -foo-bar-3m-äiti- same way as string.title() (i.e. yields -Foo-Bar-3M-Äiti-) while converting JSON to XML to JSON To XML and not to Json To Xml.
def convert_to_title_case(string):
def match_to_title(match):
word = match.group()
return word[0].upper() + word[1:]
return re.sub('[^\W\d_]+', match_to_title, string, flags=re.UNICODE)
Could still try to find sting.title() source code to make sure we behave same way as it excepts in cases where we explicitly don't want to.
One thing to decide is how to handle cases like iPhone. The above algorithm converts it to IPhone (and string.title() to Iphone) and that feels wrong. We could adjust the algorithm to title case the word only if it is all lower case. That shouldn't require more than changing return word[0].upper() + word[1:] to return word.title() if word.islower() else word.
Earlier discussed support for specifying a list of words that are not converted ought to be pretty easy to implement as well.
Can you please assist
Can you please help
Sorry Guys for delay.
I will work on this PR again.
On Fri, Aug 30, 2019 at 6:00 AM tdee75 notifications@github.com wrote:
Can you please help
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/robotframework/robotframework/issues/2706?email_source=notifications&email_token=AIBN7WZ3KA4VFCP6XPFFPIDQHBS35A5CNFSM4ECECH4KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5QF2XY#issuecomment-526409055,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AIBN7W4KUK6AZOMJ37OTRALQHBS35ANCNFSM4ECECH4A
.
--
Thanks & Regards
Bharat Patel
PR #3308 looks so good that I assign this to RF 3.2.
This keyword was initially implemented in PR #3308 by @bbpatel2001. I enhanced the algorithm (and tests and docs) in feada013daf7f7bb770efca36e928479019f8c29 and added support for excluding certain words in 3ae175987b12b20baf13443920a374f065902508. The resulting title casing algorithm is this:
exclude argument.I'm pretty happy with the results and consider this issue finally done.
Enhanced this a bit still and now optional excludes are regexps.
Most helpful comment
I have fix this and would like to create pull request for this. As a first time contributor, I need guidance on how to push code to repository. Can you please guild me
Solution:
Examples:
| ${str1} = | Convert To Titlecase | abc |
| ${str2} = | Convert To Titlecase | i love robot Framework |
| ${str3} = | Convert To Titlecase | i love ROBOT Framework |
| Should Be Equal | ${str1} | Abc |
| Should Be Equal | ${str2} | I Love Robot Framework |
| Should Be Equal | ${str3} | I Love ROBOT Framework |