/*
/ Program : capmac.sas
/ Version : 1.0
/ Author : Roland Rashleigh-Berry
/ Date : 30-Jul-2007
/ Purpose : Function-style macro to capitalise the first letter of each
/ word in a macro string.
/ SubMacros : %words %quotelst %lowcase
/ Notes : You can specify words to ignore. Case must match for these.
/ If the string you supply might contain commas or unbalanced
/ quotes then you should use %bquote() around it. See usage.
/ Usage : %let tidy=%capmac(%bquote(A, B AND C'S RESULTS));
/
/===============================================================================
/ PARAMETERS:
/-------name------- -------------------------description------------------------
/ string (pos) Macro string to convert
/ ignore List of strings (separated by spaces) to ignore
/===============================================================================
/ AMENDMENT HISTORY:
/ init --date-- mod-id ----------------------description------------------------
/ rrb 13Feb07 "macro called" message added
/ rrb 30Jul07 Header tidy
/===============================================================================
/ This is public domain software. No guarantee as to suitability or accuracy is
/ given or implied. User uses this code entirely at their own risk.
/=============================================================================*/
%put MACRO CALLED: capmac v1.0;
%macro capmac(string,ignore=);
%local i igquote bit words;
%if %length(&ignore) %then %let igquote=%quotelst(&ignore);
%let words=%words(&string);
%do i=1 %to &words;
%let bit=%qscan(&string,&i,%str( ));
%if %length(&ignore) %then %do;
%if %index(&igquote,"%bquote(&bit)") %then %do;
&bit
%goto done;
%end;
%end;
%let bit=%qlowcase(&bit);
%*- One character word -;
%if %length(&bit) EQ 1 %then %do;
%if &i EQ 1 %then %do;
%qupcase(&bit)
%end;
%else %if "%bquote(&bit)" EQ "a" %then %do;
a
%end;
%else %do;
%qupcase(&bit)
%end;
%end;
%*- Longer than one character word -;
%else %do;
%*- always capitalise the first word -;
%if &i EQ 1 %then %do;
%qupcase(%substr(&bit,1,1))%qsubstr(&bit,2)
%end;
%*- leave join words as lower text if not the last word -;
%else %if %index("an" "and" "as" "at" "but" "by" "for" "in" "is" "it" "of"
"on" "or" "so" "that" "the" "to" "when" "with",
"%bquote(&bit)") and (&i LT &words) %then %do;
&bit
%end;
%*- all other cases -;
%else %do;
%qupcase(%substr(&bit,1,1))%qsubstr(&bit,2)
%end;
%end;
%done:
%end;
%mend;