PrettifyScp – Code Clean Up
I often end up working on Macro Scheduler code that is hard to read because of a lack of indentation. Sometimes this is simply because the code has been chopped and changed so many times it’s become a bit messy and needs a bit of a clean up. And I’m not pointing fingers here either – some of this code is my own!
Indenting code inside code blocks makes it much easier to read. But cleaning up code and sorting out the indentation manually is tedious. So I wrote a little script to do it!
So here is my first PrettifyScp script. Just run it and browse to the .scp file you want to fix up. Wait a few seconds and it will pop up a message when it’s done.
//tokens to identify start and end of indented code
Let>incTokens=^IF.*|^SRT\>.*|^REPEAT\>.*|^WHILE\>.*|^ELSE|^ELSE>
Let>decTokens=^ENDIF|^END\>.*|^UNTIL\>.*|^ENDWHILE.*|^ELSE|^ELSE>
//tokens to identify blocks to ignore
Let>inIgnores=^DIALOG\>.*|^VBSTART|^/\*.*
Let>outIgnores=^ENDDIALOG\>.*|^VBEND|\*/.*
//set tab chars
Let>tabs={" "}
Let>numTabs=0
Let>inIgnoreSection=0
Let>outText={""}
//ask user for input script file
Input>scp_file,Select script file
If>scp_file<>{""}
//create backup file name
ExtractFilePath>scp_file,path
ExtractFileName>scp_file,scp_name
ExtractFileName>scp_file,scp_name_no_ext,1
Let>backupfile=%path%\%scp_name_no_ext%.BAK
//read in script lines to loop through
ReadFile>scp_file,scp_data
//temporarily remove percent symbols to avoid unwanted variable resolution
StringReplace>scp_data,%,~^PERCENT^~,scp_data
//split to array of lines
Separate>scp_data,CRLF,scp_lines
//if there are lines, loop through them
If>scp_lines_count>0
Let>k=0
Repeat>k
Let>k=k+1
Let>this_line=scp_lines_%k%
//Message>To do: %this_line%
//left trim the line
LTrim>this_line,trimmed_line
//are we going into a section to ignore?
RegEx>inIgnores,trimmed_line,0,matches,pIgnore,0
If>pIgnore>0
Let>inIgnoreSection=1
Endif
If>inIgnoreSection=1
//if we are in a section to ignore, are we coming out of it?
RegEx>outIgnores,trimmed_line,0,matches,pIgnore,0
If>pIgnore>0
Let>inIgnoreSection=0
Endif
Else
//otherwise we are not in an ignore section so see if we need to do anything
//should we unindent?
RegEx>decTokens,trimmed_line,0,matches,dec_nm,0
If>dec_nm=1
Let>numTabs=numTabs-1
//capitalise first letter while we're here
MidStr>trimmed_line,1,1,fChar
Uppercase>fChar,fChar
RegEx>(^.{1}),trimmed_line,0,matches,nm,1,fChar,trimmed_line
Endif
//create the indent chars
Let>indent={""}
If>numTabs>0
Let>t=0
Repeat>t
Let>t=t+1
Let>indent=%indent%%tabs%
Until>t=numTabs
Endif
//insert indent chars to line to output
Let>this_line=%indent%%trimmed_line%
//should we indent further lines?
RegEx>incTokens,trimmed_line,0,matches,inc_nm,0
If>inc_nm=1
Let>numTabs=numTabs+1
//capitalise first letter
MidStr>trimmed_line,1,1,fChar
Uppercase>fChar,fChar
RegEx>(^.{1}),trimmed_line,0,matches,nm,1,fChar,trimed_line
Endif
Endif
//output the new line
Let>outText=%outText%%this_line%
If>k<scp_lines_count
Let>outText=%outText%%CRLF%
Endif
Until>k=scp_lines_count
//swap percent symbols back in ...
StringReplace>outText,~^PERCENT^~,%,outText
//backup the file
DeleteFile>backupfile
CopyFile>scp_file,backupfile
//write output to original file name
DeleteFile>scp_file
Let>WLN_NOCRLF=1
WriteLn>scp_file,res,outText
MessageModal>Done! Backup saved to %backupfile%
Endif
The old script is renamed to a .BAK file so that your original script is backed up. So if there’s something I haven’t thought of in this first stab and something gets messed up, you can’t lose anything, but hopefully you are backing up your code already!
I’m ignoring code inside Dialogs and VBScript blocks as well as comment blocks. Dialogs shouldn’t be messed with and the indentation is handled by the dialog designer. VBScript could be cleaned up but would need a different parser and there are already VBScript code beautifiers out there so you could copy and paste those. So in this version I haven’t touched VBS blocks.
Hope this is useful. Any feedback or suggestions, or if you notice a bug, please post in the comments below.