Redent is my latest little text based toy to fix up the indents in GLBAsic source code, that go haywire in a web page or a iOs pub ducument.
No rocket science here. But it has been written so that new keywords and rules can be easily added. Why write another indenter if there are so many? Simply because I can, and I love doing it.
The rules (at the end of the code snippit) should be extracted into a rules file in order to be used. Simply extend the rules file without changing any program code to add new keys.
The program runs on a command line, with the source program passed as a parameter. The output file generated is named RedentOut.gbas
The rest should be straight forward enough.
Have fun
// Project: ReDent
// IDE Version: 10.283
// Author: jestermonster@gmail.com (jestermon)
GLOBAL infile$
GLOBAL prtLine = 0;
GLOBAL fdata$, rule$
GLOBAL rcount
GLOBAL filler$ = ""
GLOBAL limits = FALSE
GLOBAL NumSpaces = 4 //Tabs not used here. but simple to add with "fill" subroutines.
DIM code$[0]
DIM cmds$[0]
DIM dent$[0]
DIM linfo$[0]
DIM job$[0]
//Get command line
line$ = GETCOMMANDLINE$()
count = SPLITSTR(line$, cmds$[], " ", TRUE)
//Here we add a test document, if none is specified
IF count < 2
infile$ = "testmy.gbas"
ELSE
infile$ = cmds$[1]
ENDIF
//Load the redents rules file
res0 = OPENFILE(2, "Redent.keys", 1)
WHILE ENDOFFILE(2) <> 1
READLINE 2, rule$
IF LEFT$(rule$,1) <> "#"
DIMPUSH dent$[], rule$
ENDIF
WEND
CLOSEFILE 2
//load the source file for reading
res = OPENFILE(1, infile$, 1)
WHILE ENDOFFILE(1) <> 1
READLINE 1, fdata$
DIMPUSH code$[], fdata$
WEND
CLOSEFILE 1
rcount = LEN(dent$)
//remove ALL leading spaces
count = LEN(code$)
FOR i=0 TO count-1
code$[i] = LTRIM$(code$[i], " \t\r\n\v\f")
NEXT
//go through indent rules
i = -1
WHILE i < count -1
i = i + 1
limits = FALSE
SPLITSTR(code$[i], linfo$[], " ", TRUE)
//only if there is some code in the line. . .
IF LEN(linfo$) > 0
//for each rule
FOR r = 0 TO LEN(dent$) -1
//flatten the rule
SPLITSTR(dent$[r], job$[], " ", TRUE)
IF LEN(job$)> 0
IF job$[0] = linfo$[0]
IF job$[1] = "<<"
GOSUB fillZero
limits = FALSE
ENDIF
IF job$[1] = "<"
GOSUB fillLess
code$[i] = filler$ + code$[i]
limits = TRUE
ENDIF
IF job$[1] = ">"
code$[i] = filler$ + code$[i]
GOSUB fillMore
limits = TRUE
//ignore IF-THEN combos
IF INSTR(code$[i],"IF ") >0 AND INSTR(code$[i],"THEN ") > 0
DEBUG code$[i]
GOSUB fillLess
ENDIF
ENDIF
IF job$[1] = "<>"
GOSUB fillLess
code$[i] = filler$ + code$[i]
GOSUB fillMore
limits = TRUE
ENDIF
IF job$[1] = "<<>"
GOSUB fillZero
code$[i] = filler$ + code$[i]
GOSUB fillMore
limits = TRUE
ENDIF
ENDIF
ENDIF
NEXT
ENDIF
IF limits = FALSE
code$[i] = filler$ + code$[i]
ENDIF
dump(code$[i])
WEND
//Save output
res = OPENFILE(1, "RedentOut.gbas", 0)
FOR i = 0 TO LEN(code$) - 1
WRITELINE 1, code$[i]
NEXT
CLOSEFILE 1
//used only for debug
//SHOWSCREEN
//MOUSEWAIT
SUB fillMore:
FOR n = 1 TO NumSpaces
filler$ = filler$ + " "
NEXT
ENDSUB
SUB fillLess:
filler$ = LEFT$(filler$,LEN(filler$)-NumSpaces)
ENDSUB
SUB fillZero:
filler$ = ""
ENDSUB
//simple console print emulation
FUNCTION dump: msg$
prtLine = prtLine + 20
PRINT msg$, 0, prtLine
ENDFUNCTION
//----------------------------------------------------------------------------------------
// The following text needs to be placed in a file named Redent.keys (with the "//" removed)
// Or if you are in the mood, you can stick the info onto a DATA stack or string array
//----------------------------------------------------------------------------------------
//#=================================================================
//# Redent Rules
//#=================================================================
//#
//# Simply add more BASIC commands that need IN/out dents applied TO them
//#
//# # Comment
//# > Indent all following lines / NOT current line
//# <> Outdent current line, THEN Indent all following lines
//# < Outdent current line
//# << Outdent TO zero
//# <<> Outdent TO zero, THEN indent all following lines
//#
//
//IF >
//ELSE <>
//ELSEIF <>
//ENDIF <
//WHILE >
//WEND <
//FOR >
//NEXT <
//FUNCTION <<>
//ENDFUNCTION <<
//SUB <<>
//ENDSUB <<
//TRY >
//CATCH <>
//FINALLY <
//INLINE >
//ENDINLINE <
//FOREACH >
//GLOBAL <<
//REPEAT >
//UNTIL <
//STARTDATA >
//ENDDATA <
//TYPE >
//ENDTYPE <
Cool, many thanks, I am sure this will be useful at some point! :good:
Talk about good timing; I have a use for exactly this right now.
Thanks.