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 */