'FORMATTING SOURCE CODE
'======================
=============
class wordman
=============
sys bb 'starting position
sys bc 'starting position of word
sys aa 'ascii code of word
sys le 'length of word
string w 'temp word
method skiplspace(s as string, i as sys)
========================================
sys a
if i>len(s) then exit sub
do
a=asc s,i
select a
case 0 : exit do
case 13 : exit do 'exit at end of a line
case 10 : exit do
case 33 to 255 : exit do 'exit at start of word
end select
i++
end do
end method
method getword(string s, sys*b) as string
=========================================
sys a,c,d
a=0
bb=b
do
c=asc s,b
select c
case 0, 33 to 255 : exit do
end select
b++
end do
bc=b
aa=c
select c
case 34,96 'CAPTURE QUOTES
do
b++
d=asc s,b
if d=0 or d=c then b+=1 : jmp fwd done
end do
end select
do
c=asc s,b
select c
case 0 to 32 : exit do 'white space
case 35,95 : ' # _
case 48 to 57 : 'numbers
case 65 to 90 : 'capitals
case 97 to 122 : 'lower case
case 127 to 255 : 'higher ascii
case else
if b=bc then b+=1 ' self-terminating symbol
exit do
end select
b++
end do
'
done:
'
le=b-bc
if le then return mid s,bc,le
end method
method instrword(sys i,string s,k) as sys
=========================================
do
w=getword s,i
if aa=0 then return 0
if w=k then return bc
end do
end method
method instrwordce(sys i,string s,k) as sys
===========================================
do
w=getword s,i
if aa=0 then return 0
if aa=58 then return i
if w=k then return i
end do
end method
end class 'wordman
============
class buffer
============
'
string br 'buffer string
sys lb 'length of buffer
sys chars 'accum char count
method get() as string
======================
return left br,chars
end method
method append(string s)
=======================
sys a,le
le=len s
a=le+chars
if a>lb
br+=space(8192) 'stretch
lb+=8192
end if
mid (br,chars+1)=s
chars+=le
end method
'
end class
==============
class indenter
==============
has wordman wm 'text word utilities
has buffer buf 'buffer to hold result
'
'SETTINGS
sys instep 'indent step size
sys lmargin 'left margin
'SHARED STATES
sys lcount 'line counter
sys dcount 'indent counter (test)
sys embcmt 'embedded comment flag /* .. */
sys indi 'indent relative
sys indo 'indent accumulator
method spacer(string t,s1,s2,sys n) as sys
==========================================
sys a,b,c,le,i=1
b=wm.instrword i,t,s1
if b=1 'start of word
n*=instep 'create a new indent for the next line
if s2
b=wm.instrword i,t,s2 'block closing on same line
else
b=0
end if
'
if b then 'check for commented out end-blocks
if s2="then" then
b+=4
wm.skiplspace t,b
select asc t,b
case 0,39,59 : indi=n
end select
end if
a=wm.instrword 1,t,"'" : if a>0 and a<b then indi=n
a=wm.instrword 1,t,";" : if a>0 and a<b then indi=n
else
indi=n
end if 's2
if n=0 then indo-=instep : indi=instep 'else elseif case
if indi<0 then indo+=indi : indi=0
if indo<0 then indo=0 'clamp min indentation
'when indi>0 then the indent will be applied to the next line
return 1
end if 's1
end method
method clean(string s) as string
================================
sys a,i,e
string bu=s
e=len bu
do
i++
if i>e then exit do
a=asc bu,i
select a
case 13,10 : 'do not replace
case 0 to 31 : mid bu,i," " 'replace with space
end select
end do
return bu
end method
method indent(string dat)
=========================
'
string cr=chr(13,10)
string tab=chr(9)
sys a,b 'temp
sys ex 'exit flag
sys pu=1 'next line position
string s 'line string
string t 'line string lowercase
string bu 'cleaned dat
'
bu=clean dat
do
if ex then exit do
a=instr pu,bu,cr
if a=0 then ex=1 : a=1+len bu
'
s=mid bu,pu,a-pu 'extract line
pu=a+len(cr) 'skip cr
'
do 'redocmt:
'
s=ltrim rtrim s 'remove previous indents and endspace
t=lcase s 'view lowercase for keyword matching
'
if embcmt
a=instr t,"*/"
if a
embcmt=0
end if
exit do
else
if asc(t)=47
if asc(t,2)=42
b=instr(3,t,"*/")
if b
t=mid(s,b+2)
s=space(lmargin+indo)+left(s,b+1)
buf.append s
s=t
continue do 'look at rest of line again
else
embcmt=1
end if
end if
end if
end if
exit do
end do
'
if spacer(t, "(", ")",1)
elseif spacer(t, "{", "}",1)
elseif spacer(t, "select", "",1)
elseif spacer(t, "sub", "",1)
elseif spacer(t, "function", "",1)
elseif spacer(t, "method", "",1)
elseif spacer(t, "methods", "",1)
elseif spacer(t, "type", "",1)
elseif spacer(t, "class", "",1)
elseif spacer(t, "macro", "",1)
elseif spacer(t, "def", "",1)
elseif spacer(t, "scope", "",1)
elseif spacer(t, "if", "then",1)
elseif spacer(t, "elseif", "",0)
elseif spacer(t, "else", "",0)
elseif spacer(t, "case", "",0)
elseif spacer(t, "for", "next",1)
elseif spacer(t, "do", "",1)
elseif spacer(t, "while", "",1)
elseif spacer(t, "end", "",-1)
elseif spacer(t, "endif", "",-1)
elseif spacer(t, "wend", "",-1)
elseif spacer(t, "next", "",-1)
elseif spacer(t, "endsel", "",-1)
elseif spacer(t, "}", "",-1)
end if
'
if s=""
s=cr
else
s=space(lmargin+indo)+s+cr
's=string(lmargin+indo," ")+s+cr
end if
'
buf.append s
indo+=indi
if indi>0 then dcount+=1
indi=0
lcount+=1
end do
end method
'
end class 'indenter
=====
'main
=====
'
'#recordof indenter
indenter id
id.instep=3 'indent step size
id.lmargin=2 'left margin
'id.indent getfile "in.txt"
id.indent getfile "ind1.o2bas"
putfile "out.bas",id.buf.get
'print "ok " id.buf.chars " bytes " id.lcount " lines " id.dcount " indents"
print id.buf.get