I have used the PROPER command and in some instances I do not care for the way it change case. The word OÆNEIL, for example, becomes OÆneil, but I would prefer to see it as OÆNeil. However, I want the word THEYÆRE to remain as TheyÆre.
Other strings, like A.F.L.C.I.O. are changed to A.f.l.c.i.o and the I would prefer to keep them all capitals.
Some sentences look better proper case, but not the short words. Jack And Jill Are Running Up The Hill looks funny. I prefer, Jack and Jill are Running up the Hill.
Using my TRUEPROPER function, you can control how the data is changed. If you like it, you may decide to modify the code so the data items are table driven rather than an array, but overall it works pretty well except you need to adjust the array each time you add / remove a new entry.
Copy the text into a prg. Save it. Run it. You will see the difference between VFP Proper and my TRURPROPER function.
* WRITTEN BY: Jim Osieczonek
* Delta Business Group, LLC
* www.deltabg.com
* First - the VFP Proper Function is applied to the STRING.
* Then modify specific character to make them upper / lower.
* example 1. Upper the character after the apostrophe but only if the character
* before is upper. The first 2 will be changed and the 2nd one left untouched.
MESSAGEBOX(PROPER("o'neil o'conner they're"))
MESSAGEBOX(trueProper("o'neil o'conner they're"))
* example 2. Upper character after the dash
MESSAGEBOX(PROPER("AUTRAIN-ONOTA PULIC SCHOOLS"))
MESSAGEBOX(trueProper("AUTRAIN-ONOTA PULIC SCHOOLS"))
* example 3. Upper characters after the period.
MESSAGEBOX(PROPER("Support the A.F.L.C.I.O"))
MESSAGEBOX(trueproper("Support the A.F.L.C.I.O"))
* example 4. Do not Upper case some words (listed in the array below) that
* we normally would want lower case when they appear in a string.
MESSAGEBOX(PROPER("jack and jill are running up the hill"))
MESSAGEBOX(trueproper("jack and jill are running up the hill"))
* REPLACE table.field with TRUEPROPER(table.field)
*****************************************************************
FUNCTION TrueProper
PARAMETER tcIn
LOCAL lni, lnSpecialCharCount, lnLoc, lcOut, lnj
* how the routine works.
* the variable tcIn gets broken down into smaller and smaller pieces and the
* variable tcOut becomes larger and larger. As we take away from tcIn we add
* to tcOut and at the end of the routines tcOut will the original value of tcIn,
* but it will include Upper cases characters in the determined locations.
tcIn = ALLTRIM(PROPER(tcIn))
lnLen = LEN(tcIn)
lnSpecialCharCount = OCCURS("-",tcIn)
IF lnSpecialCharCount = 0 OR ;
(lnSpecialCharCount = 1 AND LEFT(tcIn,1) = "-") OR ;
(lnSpecialCharCount = 1 AND RIGHT(tcIn,1) = "-")
* either no dash or there is only one and it is at the beginning or end
lcOut = tcIn
ELSE
lcOut = ""
FOR lni = 1 to lnSpecialCharCount
lnLoc = ATC("-",tcIn)
lcOut = lcOut + LEFT(tcIn,lnLoc) + UPPER(SUBSTR(tcIn,lnLoc +1,1))
tcIn = SUBSTR(tcIn,lnLoc+2)
ENDFOR
IF !EMPTY(tcIn)
lcOut = lcOut + tcIn
ENDIF
ENDIF
* Reset tcIn for the next routine
tcIn = lcOut
* UPPER character "prior" to a period, unless it is at the end of a word.
* i.e - Books. would remain Books.
lnLen = LEN(tcIn)
lnSpecialCharCount = OCCURS('.',tcIn)
IF lnSpecialCharCount = 0 OR ;
(lnSpecialCharCount = 1 AND RIGHT(tcIn,1) = ".")
* either no period or there is only one and it is at the end
lcOut = tcIn
ELSE
lcOut = '
FOR lni = 1 to lnSpecialCharCount
lnLoc = ATC('.',tcIn)
IF lnLoc > 0
lcOut = lcOut + LEFT(tcIn,lnLoc)
* includes period from tcIn
IF lnLoc = LEN(tcIn)
* the last char is a period
* and we already included it
tcIn = ""
ENDIF
IF !EMPTY(tcIn)
lcOut = lcOut + UPPER(SUBSTR(tcIn,lnLoc + 1,1))
IF LEN(tcIn) = 1
* only one char and we just concatinated
* it using the UPPER function
tcIn = ""
ELSE
* skip by the period and character we just added
tcIn = SUBSTR(tcIn,lnLoc+2)
ENDIF
ENDIF
ENDIF
ENDFOR
lcOut = lcOut + tcIn
ENDIF
* Reset tcIn for the next routine
tcIn = lcOut
* UPPER the character after an apostrophe if the prior character is a single occurrence.
* O'neil will become O'Neil, but They're will remain They're
* I attempted to use a STRTRAN function, but because we only want to upper the following
* character in certain instances I had to use logic.
lnLen = LEN(tcIn)
lnSpecialCharCount = OCCURS("'",tcIn)
IF lnSpecialCharCount = 0 OR ;
(lnSpecialCharCount = 1 AND LEFT(tcIn,1) = "'") OR ;
(lnSpecialCharCount = 1 AND RIGHT(tcIn,1) = "'")
* either no apostrophe or there is only one and it is at the beginning or end
lcOut = tcIn
ELSE
lcOut = ""
FOR lni = 1 to lnSpecialCharCount
lnLoc = ATC("'",tcIn)
IF lnLoc > 0
IF lnLoc = 1
* at first character
lcOut = lcOut + LEFT(tcIn,1)
tcIn = SUBSTR(tcIn,2)
ELSE
lcOut = lcOut + LEFT(tcIn,lnLoc)
* includes apostrophe from tcIn
IF ISUPPER(SUBSTR(lcOut,LEN(lcOut)-1,1))
* prior character is upper case so make the next tcIn
* character an UPPER character.
tcIn = UPPER(SUBSTR(tcIn,lnLoc+1,1)) +;
SUBSTR(tcIn,lnLoc+2)
ELSE
* skip by the period and character we just added
tcIn = SUBSTR(tcIn,lnLoc+1)
ENDIF
ENDIF
ENDIF
ENDFOR
lcOut = lcOut + tcIn
ENDIF
LOCAL ARRAY laLowerCaseStrings[9]
laLowerCaseStrings[1] = ' Of '
laLowerCaseStrings[2] = ' And '
laLowerCaseStrings[3] = ' The '
laLowerCaseStrings[4] = ' Or '
laLowerCaseStrings[5] = ' For '
laLowerCaseStrings[6] = ' Is '
laLowerCaseStrings[7] = ' At '
laLowerCaseStrings[8] = ' Are '
laLowerCaseStrings[9] = ' Up '
FOR lni = 1 to ALEN(laLowerCaseStrings)
* fix some of the small words ( of ) that we wish to have lower
* there could be multiple items in the same sentence that need
* to be lowered
FOR lnj = 1 to OCCURS(laLowerCaseStrings[lni],lcOut)
lnLoc = AT(laLowerCaseStrings[lni],lcOut)
IF lnLoc > 0
lcOut = LEFT(lcOut,lnLoc -1) + LOWER(laLowerCaseStrings[lni]) +;
SUBSTR(lcOut,lnLoc + LEN(laLowerCaseStrings[lni]))
ENDIF
ENDFOR
ENDFOR
RETURN lcOut