An old one but it still works fine. ;)

A+
jml


*:*********************************************************
*:
*: Procedure file: UL.PRG
*:
*:         System: PROPER Function Replacement
*:         Author: Susan M. Cunningham
*:      Copyright (c) 1991, Susan M. Cunningham
*:
*:  Procs & Fncts: UL()
*:               : CAPNAME()
*:               : SUFFIX()
*:               : PARTNAME()
*:               : CAPAFTER()
*:               : MACNAME()
*:               : ISUPPER()
*:               : WORDS()
*:               : WORDNUM()
*:
*: Documented 10/27/92 at 00:07  FoxDoc  version 2.10d
*:*********************************************************
FUNCTION UL

PARAMETER thename, paramtype
IF PARAMETERS() < 2 OR paramtype < 1 OR paramtype > 4
   paramtype = 0
ENDIF
* paramtype = 1 is used for people's names
* paramtype = 2 is used for trade names
* paramtype = 3 is used for address lines
* paramtype = 4 is used for cities
glUlperiod = .T.
fixname = .F.
fixshop = .F.
fixaddr = .F.
fixcity = .F.
DO CASE
   CASE paramtype = 1
      fixname = .T.
   CASE paramtype = 2
      fixshop = .T.
   CASE paramtype = 3
      fixaddr = .T.
   CASE paramtype = 4
      fixcity = .T.
   OTHERWISE
      fixname = .T.
      fixshop = .T.
      fixaddr = .T.
      fixcity = .T.
ENDCASE

PUBLIC moldname
PRIVATE paramtype,fixname,fixshop,fixaddr,fixcity
PRIVATE i,k,lowname,newname,prd_stat

* Converts names (or addresses) to upper/lower case
* Goes beyond the scope of FoxPro's PROPER() function
* because it takes into account the vagaries of people's
* names, and to some extent, the items commonly found
* in addresses.

* Usage is simply:   newname = UL(name)

* Any problems or suggestions for improvement would be
* sincerely appreciated by the author.


* - - - - - - > The routine uses two public logical
* - - - - - - > variables, glUlmode and glUlperiod.
* - - - - - - > If these public variables have NOT
* - - - - - - > been initialized by the user, they
* - - - - - - > will be initialized by UL.  The
* - - - - - - > default for glUlmode is TRUE and the
* - - - - - - > default for glUlperiod is FALSE.

* - - - - - - > When glUlmode is TRUE, the name will be
* - - - - - - > 'properized'.

* - - - - - - > When glUlmode is FALSE, this routine is
* - - - - - - > ignored and the name returns unchanged.

IF TYPE('glUlmode') <> 'U' AND NOT glUlmode
   RETURN thename
ENDIF

* - - - - - - > When glUlperiod is TRUE, this routine will
* - - - - - - > add a period to common prefixes, suffixes
* - - - - - - > or company or street abbreviations, such as
* - - - - - - > Jr., Sr., Mr., Mrs., Ms., Dr., St., Eqs.,
* - - - - - - > Prof., Capt., Co., Inc., Ave. and Rd.  It
* - - - - - - > will also change PHD to Ph.D.

* - - - - - - > NOTE:  Adding period can LENGTHEN your variable,
* - - - - - - >        so you might want to put some checks into
* - - - - - - >        your code so that you don't lose the latter
* - - - - - - >        part of the passed item to be properized.


* - - - - - - > When glUlperiod is FALSE, this routine will
* - - - - - - > NOT add any periods to these abbreviations

IF TYPE('glUlperiod') = 'U'
   prd_stat = 'U'
   glUlperiod = .F.
ELSE
   prd_stat = ''
ENDIF

* - - - - - - > return null if ALLTRIM of name is empty
IF EMPTY(ALLTRIM(thename))
   RELEASE moldname
   RETURN ''
ENDIF

* - - - - - - > return a single capital if ALLTRIM of
* - - - - - - > name is only 1 character long
IF LEN(ALLTRIM(thename)) = 1
   RELEASE moldname
   RETURN UPPER(ALLTRIM(thename))
ENDIF

* - - - - - - > get the setting of SET EXACT
exact_stat = SET('EXACT')
SET EXACT ON

* - - - - - - > count the number of 'words' in the name
k = WORDS(thename)

* - - - - - - > process each 'word' in the name
* - - - - - - > main work is done by the CAPNAME function
IF k > 1
   newname = ''
   FOR i = 1 TO k
      moldname = WORDNUM(thename,i)

      * - - - - - - > return a single capital if the length
      * - - - - - - > of the 'word' moldname is 1
      IF LEN(moldname) = 1
         IF i = 1
            newname = UPPER(moldname)
         ELSE
            newname = newname+' '+UPPER(moldname)
         ENDIF
         LOOP
      ENDIF

      * - - - - - - > If the word is ALL caps, 'properize'
      * - - - - - - > it.  Otherwise, leave capitalization
      * - - - - - - > as is, because some names have mixed
      * - - - - - - > case, such as LeFevre or DiSantis
      IF ISUPPER(moldname)
         moldname = PROPER(moldname)
      ELSE
      * - - - - - - > guard against a common typing error,
      * - - - - - - > entering JOnes instead of Jones
         IF LEN(moldname) > 1 AND ISUPPER(SUBSTR(moldname,2,1))
            moldname = PROPER(moldname)
         ENDIF
      ENDIF

      * - - - - - - > do not capitalize common articles and
      * - - - - - - > prepositions unless it's the 1st word
      IF i <> 1 AND fixshop                      && for tradenames
         lowname = LOWER(moldname)
         IF lowname=='a'   OR lowname=='an'  OR ;
            lowname=='and' OR lowname=='the' OR ;
            lowname=='of'  OR lowname=='in'  OR ;
            lowname=='by'  OR lowname=='for' OR ;
            lowname=='nor'
            newname = newname+' '+LOWER(moldname)
            LOOP
         ELSE
            newname = newname+' '+CAPNAME(moldname)
         ENDIF
      ELSE
         * - - - - - - > otherwise call the CAPNAME function
         newname = CAPNAME(moldname)
      ENDIF
   ENDFOR
   newname = ALLTRIM(newname)
ELSE
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92
   * - - - - - - > Call the CAPNAME function if the name
   * - - - - - - > contains only one word.
   * - - - - - - > If the word is ALL caps, 'properize'
   * - - - - - - > it.  Otherwise, leave capitalization
   * - - - - - - > as is, because some names have mixed
   * - - - - - - > case, such as LeFevre or DiSantis
   IF ISUPPER(thename)
      thename = PROPER(thename)
   ELSE
   * - - - - - - > guard against a common typing error,
   * - - - - - - > entering JOnes instead of Jones
      IF LEN(thename) > 1 AND ISUPPER(SUBSTR(thename,2,1))
         thename = PROPER(thename)
      ENDIF
   ENDIF
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92
   newname = CAPNAME(thename)
ENDIF

* - - - - - - > restore the setting of EXACT
IF exact_stat = 'ON'
   SET EXACT ON
ELSE
   SET EXACT OFF
ENDIF

* - - - - - - > release global variables if they had
* - - - - - - > not been used by the user
IF prd_stat = 'U'
   RELEASE glUlperiod
ENDIF

* - - - - - - > return the new name
RELEASE moldname
RETURN newname

* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION capname
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETER pname
PRIVATE pname,rname

* this is the main processing routine for the UL function

* - - - - - - > capitalize the first letter of a word
* - - - - - - > NOTE:  if you want to IGNORE any upper case
* - - - - - - >        characters in the original name,
* - - - - - - >        substitute  rname=PROPER(pname)
* - - - - - - >        for the one line of code below
rname = UPPER(LEFT(pname,1))+SUBSTR(pname,2)

DO CASE
   * - - - - - - > capitalize McXXXXXX names properly
CASE LEFT(rname,2) = 'Mc'
   rname = 'Mc' + PROPER(SUBSTR(rname,3))

   * - - - - - - > capitalize words starting with 'MAC'
   * - - - - - - > IF the word is at least 5 characters long
   * - - - - - - > ( won't change Macy, Mack, Macke, etc. )

CASE LEN(rname) >= 5 AND UPPER(LEFT(rname,3)) = 'MAC'
   rname = MACNAME(rname)

   * - - - - - - > capitalize the letter following certain
   * - - - - - - > prefixes only if it was capitalized in
   * - - - - - - > the original name
   * - - - - - - > this WILL NOT work if the original name
   * - - - - - - > was all caps
CASE LEN(rname) >= 4 AND fixname                 && people's names
   DO CASE
   CASE UPPER(LEFT(rname,2)) = 'LA'
      rname = PARTNAME(rname,'La')
   CASE UPPER(LEFT(rname,2)) = 'LE'
      rname = PARTNAME(rname,'Le')
   CASE UPPER(LEFT(rname,2)) = 'DA'
      rname = PARTNAME(rname,'Da')
   CASE UPPER(LEFT(rname,2)) = 'DE'
      rname = PARTNAME(rname,'De')
   CASE UPPER(LEFT(rname,2)) = 'DI'
      rname = PARTNAME(rname,'Di')
   CASE UPPER(LEFT(rname,2)) = 'DU'
      rname = PARTNAME(rname,'Du')
   CASE LEN(rname) >= 5 AND ;
         UPPER(LEFT(rname,3)) = 'DEL'
      rname = PARTNAME(rname,'Del')
   CASE LEN(rname) >= 5 AND ;
         UPPER(LEFT(rname,3)) = 'VAN'
      rname = PARTNAME(rname,'Van')
   ENDCASE
CASE LEN(rname) >= 4
   DO CASE
   CASE LEN(rname) >= 5 AND ;
         UPPER(LEFT(rname,3)) = 'SAN'
      rname = PARTNAME(rname,'San')
   CASE LEN(rname) >= 7 AND ;
         UPPER(LEFT(rname,5)) = 'SANTA'
      rname = PARTNAME(rname,'Santa')
   ENDCASE
ENDCASE

* - - - - - - > capitalize the parts of names which
* - - - - - - > follow the characters / or & or '

IF fixshop                                       && tradenames
   rname = CAPAFTER('/',rname)
ENDIF
IF fixshop                                       && tradenames
   rname = CAPAFTER('&',rname)
ENDIF
IF fixname OR fixshop OR fixaddr
   rname = CAPAFTER("'",rname)
ENDIF

* - - - - - - > capitalize second part of hyphenated names
IF fixname OR fixshop                            && people's names, tradenames
   rname = CAPAFTER('-',rname)
ENDIF

* - - - - - - > capitalize certain suffixes and optionally
* - - - - - - > put periods after the suffixes
rname = SUFFIX(rname)

RETURN (ALLTRIM(rname))




* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION suffix
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETER pname
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92
PRIVATE uname,i,j,x,mixed_name
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92

* this function actually capitalizes more than 'suffixes'
* to names - it capitalizes certain 'pieces' of a name or
* address which need to be treated in a special manner

rname = pname
uname = UPPER(pname)

IF fixname
   IF uname=='II'  OR uname=='III' OR uname=='IV' OR ;
      uname=='BD'  OR uname=='DB'  OR uname=='DD' OR ;
      uname=='JD'  OR uname=='MD'  OR uname=='DO' OR ;
      uname=='DVM' OR uname=='VMD' OR ;
      uname=='DDS'
      rname = UPPER(uname)
   ENDIF
ENDIF
IF fixaddr
   IF uname=='NE' OR uname=='NW' OR ;
      uname=='SE' OR uname=='SW' OR ;
      uname=='RR' OR uname=='PO'
      rname = uname
   ENDIF
ENDIF

* - - - - - - > place periods after commonly
* - - - - - - > abbreviated parts of names or addresses
* - - - - - - > IF the public variable glUlperiod is .T.
IF glUlperiod
   IF fixname AND ;
      (uname=='JR'   OR uname=='SR'  OR ;
       uname=='MR'   OR uname=='MS'  OR ;
       uname=='DR'   OR uname=='MRS' OR ;
       uname=='ST'   OR uname=='ESQ' OR ;
       uname=='PROF' OR uname=='CAPT')
      rname = pname+'.'
   ENDIF
   IF fixshop AND ;
      (UPPER(uname)=='CO'    OR UPPER(uname)=='INC' OR ;
       UPPER(uname)=='LTD')
      rname = PROPER(uname)+'.'
   ENDIF
   IF fixaddr AND ;
      (UPPER(uname)=='AVE' OR ;
       UPPER(uname)=='RD')
      rname = PROPER(uname)+'.'
   ENDIF
   IF fixname AND UPPER(rname) = 'PHD'
      rname = 'Ph.D.'
   ENDIF
ENDIF

* - - - - - - > the following code is useful in addresses so
* - - - - - - > 'Suite 123-J' or 'Apt. 3-B' does not become
* - - - - - - > 'Suite 123-j' or 'Apt. 3-b'
* - - - - - - > and expressions such as 1st, 2nd, 3rd, 4th,
* - - - - - - > etc. come our properly
IF fixaddr AND LEN(rname) > 1
   mixed_name = .F.
   first_etc = .F.
   FOR i = 1 TO LEN(rname)
      IF ISDIGIT(SUBSTR(rname,i,1))
         mixed_name = .T.
         EXIT
      ENDIF
   ENDFOR
   IF mixed_name
      FOR j = i+1 TO LEN(rname)
         IF ISALPHA(SUBSTR(rname,j,1))
            x = UPPER(TRIM(SUBSTR(rname,j)))
            IF x=='ST' OR x=='ND' OR ;
               x=='RD' OR x=='TH'
               first_etc = .T.
               rname = SUBSTR(rname,1,j)+ ;
                  LOWER(SUBSTR(rname,j+1))
               EXIT
            ENDIF
         ENDIF
      ENDFOR
      IF NOT first_etc
         rname = UPPER(rname)
      ENDIF
   ENDIF
ENDIF
RETURN rname




* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION partname
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETER pname,schar
PRIVATE plen,pname,schar,rname

* capitalizes the names of foreign derivation made up of
* a particle plus a name (such as LeFevre or VanBuren)
* only when the non-first letter of the parameter name
* pname is capitalized (so that lefton does not become
* LeFton but leFevre becomes LeFevre)

plen = LEN(schar)
IF ISUPPER(SUBSTR(pname,plen+1,1))
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92
   rname = schar + PROPER(SUBSTR(pname,plen+1))
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92
ELSE
   rname = pname
ENDIF
RETURN rname




* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION capafter
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETER schar,pname
PRIVATE schar,pname,rname,i,spos,skount

* looks for the occurrence of the 'search' character
* character 'schar' in the word 'pname' and capitalizes
* the character following schar.  This is the function
* which converts Jones-smith to Jones-Smith and
* O'brien to O'Brien

rname = pname
skount = OCCURS(schar,pname)
FOR i = 1 TO m.skount
   spos = AT(schar,pname,i)
   IF spos > 0 AND spos < LEN(pname)
      * - - - - - - > make sure we get Joe's, not Joe'S
      IF UPPER(TRIM(SUBSTR(pname,spos+1))) <> 'S'
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92
         rname = LEFT(pname,spos) + ;
            UPPER(SUBSTR(pname,spos+1,1))
         IF LEN(pname) > spos+1
            rname = rname + SUBSTR(pname,spos+2)
         ENDIF
* - - - - - - - - - - - - - - - - - - *  changed 03/06/92
      ENDIF
   ENDIF
ENDFOR
RETURN rname




* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION macname
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETER pname
PRIVATE pname, plen, test, scotch, x

* Users who are curious or who have an inordinant number
* of 'Scotch' or 'Irish' names in their data bases may want
* to add to the specifically coded name fragments herein.

* The author is a mathematician, not a linguist, and does
* not profess to be an authority on surnames of the British Isles

scotch = .F.
plen = LEN(pname)
IF plen >= 8 AND LEFT(pname,7) = 'MACADAM'
   scotch = .T.
ENDIF
IF plen >= 7
   test = UPPER(LEFT(pname,7))
   scotch = INLIST(test,'MACCAFF','MACCARL','MACCLOS', ;
                        'MACCONN','MACCRAC','MACCULL','MACHENR', ;
                        'MACLANE','MACLEAN','MACLEOD','MACLAUG')
ENDIF
IF plen >= 6 AND NOT scotch
   test = UPPER(LEFT(pname,6))
   scotch = INLIST(test,'MACART','MACAFF','MACINT', ;
                        'MACIVE','MACKAY','MACKEN','MACRAE','MACWIL')
ENDIF
IF plen >= 5 AND NOT scotch
   test = UPPER(LEFT(pname,4))
   scotch = INLIST(test,'MACB','MACD','MACF','MACG', ;
                      'MACM','MACN','MACP','MACT','MACV')
ENDIF
IF scotch
   x = PROPER(LEFT(pname,3))+PROPER(SUBSTR(pname,4))
ELSE
   x = pname
ENDIF
RETURN x




* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION isupper
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETER pname
PRIVATE pname
RETURN IIF(pname = UPPER(pname),.T.,.F.)




* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION words
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETERS pname,spacer
PRIVATE pname,spacer

* determines the number of words in pname

DO CASE
CASE PARAMETERS() = 0
   RETURN ''
CASE PARAMETERS() = 1
   spacer = '.,'
ENDCASE
pname = CHRTRAN(pname,spacer,SPACE(LEN(spacer)))
pname = ALLTRIM(pname)
DO WHILE AT('  ',pname) > 0
   pname = STRTRAN(pname,'  ',' ')
ENDDO
RETURN (OCCURS(' ',pname)+1)




* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
FUNCTION wordnum
* - - - - - - - - - - - - - - - - - - - - - - - - - - - *
PARAMETERS pname,n
PRIVATE pname,mname,rname,n,spacer,spos

* determines the nth word of the character string pname

spacer = '.,'
mname = ALLTRIM(CHRTRAN(pname,spacer,'  '))

* - - - - - - > 'squeeze' the name so that only ONE blank
* - - - - - - > appears between the 'words' of a name
DO WHILE AT('  ',mname) > 0
   mname = STRTRAN(mname,'  ',' ')
ENDDO

DO CASE
CASE n > 1
   DO CASE
   CASE AT(' ',mname,n-1) = 0
      rname = ''
   CASE AT(' ',mname,n) = 0
      rname = SUBSTR(mname,AT(' ',mname,n-1)+1)
   OTHERWISE
      spos = AT(' ',mname,n-1)
      rname = SUBSTR(mname,spos,AT(' ',mname,n)+1-spos)
   ENDCASE
CASE n = 1
   IF AT(' ',mname) > 0
      rname = SUBSTR(mname,1,AT(' ',mname)-1)
   ELSE
      rname = mname
   ENDIF
ENDCASE

rname = ALLTRIM(rname)
IF glUlperiod
   IF LEN(rname) = 1 AND ISALPHA(rname)
      rname = rname+'.'
   ENDIF
ENDIF
RETURN rname


On Wed, Mar 14, 2012 at 1:27 PM, Jeff Johnson <[email protected]> wrote:
> Anyone ever do a Proper() that capitalizes names like McDonald?
>
> --
> Jeff

_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: 
http://leafe.com/archives/byMID/profox/CAPqLOBxLUSCVUKVA3WMoiR7EWqP1iaHHfX5cQ6BsiypQ6F3j=g...@mail.gmail.com
** All postings, unless explicitly stated otherwise, are the opinions of the 
author, and do not constitute legal or medical advice. This statement is added 
to the messages for those lawyers who are too stupid to see the obvious.

Reply via email to