In July 2010, Chris Hemedinger author of The SAS Dummy blog wrote an article titled 'Hope for ugly programs'.
That article showed that SAS Enterprise Guide had a shortcut of Ctrl-I ("indent this!") to convert ugly code into something much more readable. The below code is my attempt to emulate the behaviour in Base SAS.
/************************************************************************** * Program: codeformatter.sas * Author: Tom Bellmer * Created: 10Oct2014 * Purpose: Make SAS program more readable by placing one statemnt per * line, indent code below PROC and DATA steps and indenting DO * constructs * Usage: %codeformatter( infile = , outfile = c:\temp\beautify.sas ) **************************************************************************/ %macro codeformatter( inputfile =, outputfile = c:\temp\codeout.sas ) ; %if not %sysfunc( fileexist( &inputfile. ) ) %then %do ; %put %str(E)RROR: The input file &inputfile. does not exist. ; %return ; %end ; data _null_ ; length semicolonlocation startposition indent i commentoff 5 sasstatement $8 word $32767 ; retain commentoff 1 ; infile "&inputfile." lrecl = 32767 truncover end = eof ; file "&outputfile." lrecl = 32767 ; do until( eof ) ; input line $32767. ; startposition = 1 ; if find( line, '/*' ) then commentoff = 0 ; do i = 1 to max( count( line, ';' ), 1 ) ; semicolonlocation = find( line, ';', startposition ) + 1 ; if semicolonlocation = 1 then word = line ; else word = substr( line, startposition, ( semicolonlocation - startposition ) ) ; startposition = semicolonlocation ; sasstatement = upcase( compress( scan( word, 1 ), ';' ) ) ; if sasstatement in ( 'LIBNAME', 'GOPTIONS', 'DATA', 'PROC', 'QUIT' , 'RUN', '*', '/*', 'OPTIONS', 'ODS', 'TITLE', 'FOOTNOTE' , 'FILENAME', 'RSUBMIT') then do ; if sasstatement in ( 'PROC', 'DATA' ) then put ; indent = 0 ; end ; else indent = max( 2, indent ) ; if commentoff and ( find( word, 'end ', 'i' ) or find( word, 'end;', 'i' ) ) then indent = indent - 2 ; put +indent word ; if commentoff and ( find( lowcase( word ), 'do ' ) or find( lowcase( word ), 'do;' ) ) then indent + 2 ; end ; if find( line, '*/' ) then commentoff = 1 ; end ; run ; %mend ; /* EOF: codeformatter.sas */
No comments:
Post a Comment