My teammate found a bug when using proper() to display a label; a word preceded by a non-alphabetic character will not be converted to proper case.
If the 11th floor is home to the HR department.
We would expect:
Floor 11 (Human Resources)
but instead get:
Floor 11 (human Resources)
To reproduce the issue, I used this expression to check capitalization:
proper( "I am reporting that ""proper() coNverts each [alphabetic] cHaRacter into ProPeR caSe " & "(unless a non-alphabetic character precedes it)""" ),
Where I would expect:
I Am Reporting That "Proper() Converts Each [Alphabetic] Character Into Proper Case (Unless A Non-alphabetic Character Precedes It)
It's returning:
I Am Reporting That "proper() Converts Each [alphabetic] Character Into Proper Case (unless A Non-alphabetic Character Precedes It)
Is proper() working as designed?
Side note: 22.4 documentation reads, "Converts each character in the text into proper case, meaning it will capitalize the first first letter of every word and convert the rest into lowercase. (https://docs.appian.com/suite/help/22.4/fnc_text_proper.html")
Discussion posts and replies are publicly visible
Hello Robin F,
Can you please show us how you are trying to achieve this?
I'm not sure this is a "bug" so much as a constraint, possibly crossed with a lack of specificity in the documention (re: the snippet you copied). I suppose the documentation should be rephrased to something more like, "capatialize the first non-whitespace character, where applicable, of every whole word in the string". I suppose you could argue that the function should specifically exclude non-alphabet characters from its logic, though it seems like that might be expecting too much from a function like this.
I agree that you will get what you get with fn!proper(). However, we can create a more robust rule that removes and replaces certain preceding characters to allow proper() to function more intuitively. This could be optimized, quick and dirty solution to get you going:
a!localVariables( local!data: "I am reporting that ""proper() coNverts each [alphabetic] cHaRacter into ProPeR caSe " & "(unless a non-alphabetic character precedes it)""", local!ignore: {"(",")","""","[","]","-"}, /* preceding characters you want to ignore */ local!removals: a!flatten( a!forEach( items: 1+enumerate(len(local!data)), expression: a!localVariables( local!currentChar: charat(local!data,fv!item), if( contains(local!ignore,local!currentChar), { index: fv!item, char: local!currentChar }, {} ) ) ) ), local!replaced: if( rule!APN_isEmpty(local!removals), local!data, joinarray( a!forEach( items: 1+enumerate(len(local!data)), expression: if( contains(tointeger(local!removals.index),fv!item), " ", charat(local!data,fv!item) ) ) ) ), local!proper: proper(local!replaced), joinarray( a!forEach( items: 1+enumerate(len(local!proper)), expression: a!localVariables( local!replacementIndex: wherecontains(fv!item,tointeger(local!removals.index)), if( rule!APN_isBlank(local!replacementIndex), charat(local!proper,fv!item), property(index(local!removals,local!replacementIndex,{}),"char") ) ) ) ) )