// Compile with /a /m /w
// Short Code to test the PROPER Function below
LOCAL cString:=SPACE(35),getlist:={}
WHILE .T.
Scroll() ; SetPos(0,0) ; ReadKill(.T.) ; GetList := {}
DispBox( 10, 10, 20, 70, 1 )
DevPos( 10, 28 ) ; DevOut( "[ Blank String to Exit ]" ) 
DevPos( 12, 15 ) ; DevOut( "Enter String: " ) ; SetPos( Row(), Col()+1 ) ; AAdd( GetList, _GET_( cString, "cString",,, ):display() )
ReadModal(GetList) ; GetList := {}
IF EMPTY(cString)
   EXIT
ENDIF    
DevPos( 14, 16 ) ; DevOut( "Converts To:  " + PROPER(cString) )
DevPos( 23, 0 ) ; DevOut( " " )
__Wait( )
ENDDO
Scroll() ; SetPos(0,0) ; ReadKill(.T.) ; GetList := {}
__Quit()


FUNCTION PROPER(cString)
LOCAL n,nLenStr,lFirstLtr:=.T.,cChar

//Trim the String
cString:=LTRIM(RTRIM(cString))

//Get the trimmed length
nLenStr:=LEN(cString)

//Parse each character
FOR n = 1 TO nLenStr

   // Strip out the current character
   cChar:=Substr(cString,n,1)

   IF ISUPPER(cChar) .AND. !lFirstLtr
      // Replace with Lower
      cString:=STUFF(cString,n,1,LOWER(cChar))

   ELSEIF cChar $ ".,;:/\" 
      //Skip over punctuation, add any others you want
      //Don't Reset the First Letter Flag
      lFirstLtr:=.F.

   ELSEIF EMPTY(cChar) 
      //Use spaces as the delimiters, add any others you want
      //Reset the First Letter Flag
      lFirstLtr:=.T.

   ELSEIF lFirstLtr
     // First letters of Proper words fall in here
     // Replace with Upper if not already
     IF ISLOWER(cChar) 
       cString:=STUFF(cString,n,1,UPPER(cChar))
     ENDIF
     lFirstLtr:=.F.

   ELSE
     // It must be lower case, not a first letter, and not punctuation
     // or a space. Do Nothing
	  
   ENDIF

NEXT
RETURN cString
