Code beautifier

Working on new editor enhancements?
User avatar
Lewis
User
User
Posts: 47
Joined: Fri Nov 25, 2005 1:12 pm

Code beautifier

Post by Lewis »

Can anyone point me to a PureBasic code beautifier (with or without source code)? :wink: Thanks in advance.
DarkDragon
Addict
Addict
Posts: 2345
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

NicTheQuicks SourceOptimizer, but it doesn't work good anymore with PB 3.94(the declares are always at the bottom of the source)

http://forums.purebasic.com/german/arch ... =optimizer
bye,
Daniel
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

here: works with the newest version too.
viewtopic.php?t=17204&highlight=auto+indent

hope that is what you want.
User avatar
Lewis
User
User
Posts: 47
Joined: Fri Nov 25, 2005 1:12 pm

Post by Lewis »

thefool wrote:here: works with the newest version too.
viewtopic.php?t=17204&highlight=auto+indent

hope that is what you want.
Yes, "Indentation" and "Right trim" functionality are important parts of a code beautifier. Many thanks. :D

Any chance of making the source code available (I'd much prefer English versions and even build further on your work)?

Cheers,
Lewis
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

Lewis wrote:
thefool wrote:here: works with the newest version too.
viewtopic.php?t=17204&highlight=auto+indent

hope that is what you want.
Yes, "Indentation" and "Right trim" functionality are important parts of a code beautifier. Many thanks. :D

Any chance of making the source code available (I'd much prefer English versions and even build further on your work)?

Cheers,
Lewis
http://forums.purebasic.com/german/view ... autoindent
http://dostej.pureforge.net/Files/PB%20 ... Source.zip
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
Lewis
User
User
Posts: 47
Joined: Fri Nov 25, 2005 1:12 pm

Post by Lewis »

ts-soft wrote:
Lewis wrote:
thefool wrote:here: works with the newest version too.
viewtopic.php?t=17204&highlight=auto+indent

hope that is what you want.
Yes, "Indentation" and "Right trim" functionality are important parts of a code beautifier. Many thanks. :D

Any chance of making the source code available (I'd much prefer English versions and even build further on your work)?

Cheers,
Lewis
http://forums.purebasic.com/german/view ... autoindent
http://dostej.pureforge.net/Files/PB%20 ... Source.zip
8) Much obliged. Now all I have to do is brush up on my German (no easy task)! :roll:
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

But you can download this:
http://dostej.pureforge.net/Files/PB%20 ... Source.zip
The link included spaces!
The PureBasic-Source have in german the same syntax :wink:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Hurga
Enthusiast
Enthusiast
Posts: 148
Joined: Thu Jul 17, 2003 2:53 pm
Contact:

Post by Hurga »

And some of the comments are in english. I have a little improvement and I ´ll change all comments to english.
I ´ll upload it tomorrow. (I drop the link here, when its done...)
User avatar
Michael Vogel
Addict
Addict
Posts: 2807
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Code beautifier

Post by Michael Vogel »

Lewis wrote:Can anyone point me to a PureBasic code beautifier (with or without source code)? :wink: Thanks in advance.
I think, other programmers have done something like this already, so forgive me.

It's just the kernel, this should be integrated somehow into the IDE. It has also two functions (but these things I needed most for now):
- cleaning the source code from tab and space characters
- doing an auto indent

Michael

Code: Select all

; Define

Global indtxt.s=Chr(9); "   "

Global LeftC.w
Global LeftD.w
Global RightC.w
Global RightD.w
Global RightP.w

#Words=22
Global Dim Word.s(#Words)

For i=1 To #Words
	Read word(i)
Next i

DataSection
	Data.s "; Define"
	Data.s ";{"
	Data.s "Procedure "
	Data.s "Procedure."
	Data.s "DataSection"
	Data.s "If "
	Data.s "Select "
	Data.s "While "
	Data.s "For "
	Data.s "Repeat"
	
	Data.s "Case "	; kurzzeitig ''ausrücken''
	Data.s "ElseIf"	; detto
	
	Data.s "; EndDefine"
	Data.s ";}"
	Data.s "EndProcedure"
	Data.s "xxxxxxxxxxx"
	Data.s "EndDataSection"
	Data.s "EndIf"
	Data.s "EndSelect"
	Data.s "Wend"
	
	Data.s "Next"		; blöd, da kann nach 'Until' noch Text kommen...
	Data.s "Until "	; detto
	
EndDataSection

; EndDefine
Procedure.s RightTrim(s.s)
	l.w=Len(s)
	While l
		l-1
		b.w=PeekB(@s+l)
		If b<>9 And b<>32
			Break
		EndIf
	Wend
	ProcedureReturn Left(s,l+1)
EndProcedure
Procedure.s LeftTrim(s.s)
	l.w=Len(s)
	c.w=0
	While c<l
		b.w=PeekB(@s+c)
		If b<>9 And b<>32 ; Space & Tab
			Break
		EndIf
		c+1
	Wend
	ProcedureReturn Mid(s,c+1,l-c)
EndProcedure
Procedure FindCommas(s.s)
	LeftC=0
	LeftD=0
	RightC=0
	RightD=0
	RightP=1
	l.w=Len(s)
	c.w=0
	While c<l
		b.w=PeekB(@s+c)
		c+1
		Select b
		Case 59		; Semicolon
			RightC=c
			If LeftC=0 : LeftC=c : EndIf
		Case 34	; DoubleQuote
			RightD=c
			If LeftD=0 : LeftD=c : EndIf
		Case 58	; Colon
			RightP=c
		Case 9,32
			If c=RightP+1 : RightP+1 : EndIf
		EndSelect
		
	Wend
EndProcedure
Procedure.s RightCut(s.s,x.w)
	ProcedureReturn RTrim(Left(s,x-1))
EndProcedure
Procedure.s StringS(n, chars.s)
	; Function: returns a string consiting of n concatenated chars
	; LSet("",n,chars) nimmt nur das erste Zeichen!
	Protected s.s=""
	While n>0
		s+chars
		n-1
	Wend
	ProcedureReturn s
EndProcedure

Procedure Doit(mode.w)
	indent.w=0
	
	ReadFile(1,"Test.pb")
	CreateFile(2,"TestX.pb")
	While Not(Eof(1))
		z.s=ReadString(1)
		z=lefttrim(z)
		z=righttrim(z)
		
		If mode
			s.s=z
			FindCommas(s)
			; [1]	if a=0		; remark
			; [2]	if a=''x''	; remark
			; [3]	if a=0		; ''remark''
			; [x]	if a=''x''	; ''remark''
			If LeftC
				If LeftD=0 Or LeftC<LeftD	; [1], [3]
					s=RightCut(s,LeftC)
				ElseIf RightC>RightD		; [2]
					s=RightCut(s,RightC)
				EndIf
			EndIf
			
			afterburner.w=0
			
			For i=1 To #Words
				l.w=Len(word(i))
				Select i
				Case 1 To 12
					p.w=1
				Case 13 To 20
					p.w=Len(s)-l+1
				Case 21,22
					p.w=RightP
				EndSelect
				
				If Mid(s,p,l)=word(i)
					Select i
					Case 1 To 10
						afterburner.w+1
					Case 11,12
						indent-1
						afterburner.w+1
					Case 13 To 22
						If afterburner
							afterburner-1
							Else
							indent-1
						EndIf
						
					EndSelect
					
				EndIf
				
			Next i
			z=strings(indent,indtxt)+z
			;WriteStringN(2,s)
		EndIf
		WriteStringN(2,z)
		indent+afterburner
	Wend
	CloseFile(1)
	CloseFile(2)
EndProcedure

; Doit(0)	trims source code from space and tab characters
; Doit(1)	auto indent the source code

Doit(#True)
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

this one does some reformatting:

http://www.xs4all.nl/~bluez/datatalk/pu ... _codecaddy

(oh, and it allows the use of the line continuation character)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Another option is JaPBe. Even if you don't use it to write the code, you can paste the code into it to get indentation, etc.
@}--`--,-- A rose by any other name ..
Berikco
Administrator
Administrator
Posts: 1326
Joined: Wed Apr 23, 2003 7:57 pm
Location: Belgium
Contact:

Post by Berikco »

Here is one i wrote and posted some time ago.
Must be installed as a tool, and reformats the source quick by hitting a shortcut

Code: Select all

;
; ------------------------------------------------------------
;
;           Source Formatting By Berikco
;
;
; ------------------------------------------------------------
;
; For Purebasic Toolmenu version 3.40 and up
; Will format the source with TABS(Spaces)
; Thanks to PB for his help on the ';' comment finder
;
; --- Toolbox settings ---------------------------------------
;
; Arguments:
; First  argument "%FILE"
; Second argument #Number of spaces for 1 Tab
; Third  argument if 1 extra Select indent
; Example: "%FILE" 2 [1]
;
; Wait Until tool Quits = On
; Reload source after program is finished = On
;
; ------------------------------------------------------------
;
; 
;

DestFileName$ = ProgramParameter()    ; Sourcefile to read
NumSpaces = Val(ProgramParameter())   ; Number of spaces
SelectTab= Val(ProgramParameter())   ; 1= Extra Indent At Select

SourceFileName$ = DestFileName$+"2" ; The backup file *.pb2

#Source=1
#Destination=2

If FileSize(DestFileName$) ; Do nothing if source empty
  
  If FileSize(SourceFileName$) ; If old backupFile exist, delete it
    DeleteFile(SourceFileName$)
  EndIf
  
  If RenameFile(DestFileName$, SourceFileName$) ; Rename source to backup
    
    If OpenFile(#Source,SourceFilename$)        ; Open Source, now with *.pb2 extension
      
      If CreateFile(#Destination,DestFileName$) ; Create new source
        
        While Eof(#source)=false
          
          UseFile(#Source)
          a$=ReadString()
          
          If Eof(#source)=false           ; Check if read is last line in source
            ;                               If this is the case, must not write CRLF
            
            a$=LTrim(a$)                  ;Remove old TABs (spaces in front)
            a$=RTrim(a$)                  ;Remove all spaces at end
            
            Tab+NextTab
            NextTab=0
            in=FindString(a$," ",1)       ; Find PureBasic Keyword
            
            If in>0
              Vgl$=LCase(Left(a$,in-1))          ; Get only Keyword
            Else
              Vgl$=LCase(a$)                     ; Nothing after Keyword, use whole string
            EndIf
            
            ; Check For Keyword that needs formatting
            
            If Left(a$,1)=";"
              ;nope
            ElseIf Vgl$="procedure" Or Vgl$="procedure.b" Or Vgl$="procedure.w" Or Vgl$="procedure.l"  Or Vgl$="procedure.s" Or Vgl$="procedure$" Or Vgl$="datasection" Or Vgl$="enumeration"
              
              Tab=0
              NextTab=1
            ElseIf Vgl$="endprocedure" Or Vgl$="enddatasection" Or Vgl$="endenumeration"
              
              Tab=0
              NextTab=0
              
            ElseIf Vgl$="foreach" Or Vgl$="if" Or Vgl$="with" Or vgl$="select" Or Vgl$="for" Or Vgl$="repeat" Or Vgl$="while" Or Vgl$="structure" Or Vgl$="compilerif" Or Vgl$="opensubmenu"
              
              
              
              b$=a$+";"  ;little trick, add comment to line, only one routine needed to scan
              KeyWord$=""
              
              For r=1 To Len(b$)
                a=Asc(Mid(b$,r,1))
                If a=34
                  q=1-q
                EndIf
                If a=58 And q=0
                  NextTab=0
                  r=Len(b$)
                Else
                  
                EndIf
                If a=59
                  If q=0
                    
                    KeyWord$=LTrim(KeyWord$)        ;Remove spaces in front
                    KeyWord$=LCase(RTrim(KeyWord$)) ;Remove all spaces at end and put lowercase
                    If KeyWord$="endif" Or KeyWord$="endstructure" Or KeyWord$="next" Or KeyWord$="until" Or KeyWord$="Wend" Or KeyWord$="ForEver"
                      If tab>0
                        tab-1
                        
                        
                      EndIf
                      
                    EndIf
                    
                    r=Len(b$)
                  EndIf
                  
                  If Vgl$="select" And SelectTab=1
                    NextTab=2
                  Else
                    NextTab=1
                  EndIf
                EndIf
                keyword$+Chr(a)
                
                
                
              Next
              
              If Vgl$="if"
                ;  Debug "if " + Str(nexttab) + "  " + a$
              EndIf
              
              
            ElseIf Vgl$="endif" Or Vgl$="endstructure" Or Vgl$="endwith" Or Vgl$="return" Or Vgl$="next" Or Vgl$="until" Or Vgl$="wend" Or Vgl$="forever" Or Vgl$="compilerendif"
              Tab-1
              NextTab=0
            ElseIf Vgl$="endselect"
              If SelectTab=1
                Tab-2
              Else
                Tab-1
              EndIf
              NextTab=0
            ElseIf Vgl$="elseif" Or Vgl$="else" Or Vgl$="case" Or Vgl$="compilerelse" Or Vgl$="default"
              Tab-1
              NextTab=1
            Else
              b$=a$+";"  ;little trick, add comment to line, only one routine needed to scan
              KeyWord$=""
              For r=1 To Len(b$)
                a=Asc(Mid(b$,r,1))
                If a=34 : q=1-q : EndIf
                If a=59 And q=0
                  KeyWord$=LTrim(KeyWord$)        ;Remove spaces in front
                  KeyWord$=LCase(RTrim(KeyWord$)) ;Remove all spaces at end and put lowercase
                  If KeyWord$="endif" Or KeyWord$="endstructure" Or KeyWord$="next" Or KeyWord$="until" Or KeyWord$="Wend" Or KeyWord$="ForEver"
                    If tab>0
                      tab-1
                      
                    EndIf
                  EndIf
                EndIf
                keyword$+Chr(a)
                If a=58 And q=0
                  If keyword$=a$
                    Tab=0
                    NextTab=1
                    r=Len(b$)
                  EndIf
                  KeyWord$=""
                EndIf
              Next
            EndIf
            
          
            If tab<0
              tab=0
            EndIf
            Front$=Space(Tab * NumSpaces) ; Create Spaces needed
            a$ = Front$ + a$              ; Put spaces before the line code
            UseFile(#Destination)
            WriteStringN(a$)              ; Write in new source
            
          Else
            UseFile(#Destination)
            WriteString(a$)
          EndIf
        Wend
        
        CloseFile(#source)
        CloseFile(#destination)
        DeleteFile(SourceFileName$)
        
      EndIf
    EndIf
  EndIf
EndIf
End

User avatar
Michael Vogel
Addict
Addict
Posts: 2807
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

AutoIndent, more complex...

Post by Michael Vogel »

Sorry to post that long piece of code, but now it works as wanted...

- works with complete file or selected lines
- uses tab settings from IDE (real tab or space characters)
- is able to remove all heading and trailing space and tab chars also

Michael

Code: Select all

Procedure EditorBug()
EndProcedure

; AutoIndent by Michael Vogel
; -------------
; with pressed shift key:	eliminates tabs and spaces
; without shift key:			indents source code
; no selection:				complete source code is affected
; selection of lines:			only selected lines are changed

; known problems:			when cursor is in line 1, the procedure folds up (editor bug?)

; Define

#Words=41

Global indtxt.s=Chr(9); "   "

Global LeftC.w
Global LeftD.w
Global RightC.w
Global RightD.w
Global RightP.w

Global Dim Word.s(#Words)
Global Dim Border(3)

z.w=0
For i=1 To #Words
	Read Word(i)
	If Word(i)="!" And i<#Words
		Border(z)=i-1

		;Debug Str(z)+": "+Str(i-1)+" = "+word(border(z))
		z+1
		Read Word(i)
	EndIf
Next i
border(z)=#Words


DataSection
	Data.s "; Define"
	Data.s ";{"
	Data.s "Procedure "
	Data.s "Procedure."
	Data.s "ProcedureC"
	Data.s "ProcedureDLL"
	Data.s "DataSection"
	Data.s "If "
	Data.s "Select "
	Data.s "While "
	Data.s "For "
	Data.s "ForEach "
	Data.s "Repeat"
	Data.s "Structure "
	Data.s "Interface "
	Data.s "Enumeration "
	Data.s "CompilerIf "
	Data.s "CompilerSelect "
	Data.s "!"							; border(0)

	Data.s "Case "					; kurzzeitig ''ausrücken''
	Data.s "Else"						; detto
	Data.s "ElseIf"					; detto
	Data.s "Default"
	Data.s "CompilerElse"
	Data.s "CompilerCase"
	Data.s "CompilerDefault"
	Data.s "!"							; border(1)

	Data.s "; EndDefine"
	Data.s ";}"
	Data.s "EndProcedure"
	Data.s "EndDataSection"
	Data.s "EndIf"
	Data.s "EndSelect"
	Data.s "Wend"
	Data.s "ForEver"
	Data.s "EndStructure"
	Data.s "EndInterface"
	Data.s "EndEnumeration"
	;Data.s "CompilerEndIf"		; wird schon bei 'EndIf' entdeckt
	;Data.s "CompilerEndSelect"	; analog oben
	Data.s "!"							; border(2)

	Data.s "Next"						; blöd, da kann nach 'Until' noch Text kommen...
	Data.s "Until "					; detto
	Data.s "!"							; border(3)

EndDataSection
; EndDefine
Procedure.s RightTrim(s.s)
	l.w=Len(s)
	While l
		l-1
		b.w=PeekB(@s+l)
		If b<>9 And b<>32
			Break
		EndIf
	Wend
	ProcedureReturn Left(s,l+1)
EndProcedure
Procedure.s LeftTrim(s.s)
	l.w=Len(s)
	c.w=0
	While c<l
		b.w=PeekB(@s+c)
		If b<>9 And b<>32 ; Space & Tab
			Break
		EndIf
		c+1
	Wend
	ProcedureReturn Mid(s,c+1,l-c)
EndProcedure
Procedure FindCommas(s.s)
	LeftC=0
	LeftD=0
	RightC=0
	RightD=0
	RightP=0
	l.w=Len(s)
	c.w=0
	While c<l
		b.w=PeekB(@s+c)
		c+1
		Select b
		Case 59		; Semicolon
			RightC=c
			If LeftC=0 : LeftC=c : EndIf
		Case 34		; DoubleQuote
			RightD=c
			If LeftD=0 : LeftD=c : EndIf
		Case 58		; Colon
			RightP=c
		Case 9,32
			If c=RightP+1 : RightP+1 : EndIf
		EndSelect

	Wend
EndProcedure
Procedure.s RightCut(s.s,x.w)
	ProcedureReturn RTrim(Left(s,x-1))
EndProcedure
Procedure.s StringS(n, chars.s)
	Protected s.s=""
	While n>0
		s+chars
		n-1
	Wend
	ProcedureReturn s
EndProcedure

; AutoIndent (written by Michael Vogel)
;
; > install the tool using the parameter "%TEMPFILE" %SELECTION
; > use the PureBasic as the working directory (or adapt the OpenPreferences path below)
; > select 'Wait until tool quits' and 'Reload source aftzer tool has quit'

Procedure Init()

	; Dateinamen holen...
	CompilerIf 1
		If CountProgramParameters()<>2
			MessageBox_(0,"'AutoIndent' benötigt die Parameter"+#CR$+"%TEMPFILE und %SELECTION...","Fehler",#MB_ICONERROR| #MB_OK)
			End
		EndIf
		Global OutputFile.s=ProgramParameter()
	CompilerElse
		Global OutputFile.s="Test.pb"
	CompilerEndIf

	Global InputFile.s=OutputFile+"~"
	DeleteFile(InputFile)
	If RenameFile(OutputFile,InputFile)=0
		MessageBox_(0,"'AutoIndent' konnte keine Temporärdatei erstellen","Fehler",#MB_ICONERROR| #MB_OK)
		End
	EndIf

	; Selektion abfragen...
	Global zeile.w=0
	selektion.s=ProgramParameter()
	Global Startzeile.w=Val(StringField(selektion, 1, "x"))
	Global Endzeile.w=Val(StringField(selektion, 3, "x"))
	If startzeile=Endzeile
		startzeile=1
		Endzeile=#MAXSHORT
	EndIf

	; Tabulator-Einstellungen holen...
	OpenPreferences("PureBasic.prefs")
	PreferenceGroup("Global")
	If Val(ReadPreferenceString("RealTab","0"))
		indtxt.s=Chr(9)
	Else
		indtxt.s=Space(Val(ReadPreferenceString("TabLength", "2")))
	EndIf
	ClosePreferences()

EndProcedure
Procedure Doit(mode.w)

	; Doit(0)	auto indent the source code
	; Doit(1)	trims source code from space and tab characters

	init()

	ReadFile(1,InputFile)
	CreateFile(2,OutputFile)

	indent.w=0


	While Not(Eof(1))
		z.s=ReadString(1)
		zeile.w+1
		z=lefttrim(z)
		z=righttrim(z)

		If zeile>=Startzeile And zeile<=Endzeile
			afterburner.w=0

			If (mode=0) And (Len(z)>0)
				s.s=z
				FindCommas(s)
				; [1]	if a=0		; remark
				; [2]	if a=''x''	; remark
				; [3]	if a=0		; ''remark''
				; [x]	if a=''x''	; ''remark''
				If LeftC
					If LeftD=0 Or LeftC<LeftD	; [1], [3]
						s=RightCut(s,LeftC)
				ElseIf RightC>RightD		; [2]
						s=RightCut(s,RightC)
					EndIf
				EndIf

				For i=1 To #Words
					l.w=Len(word(i))
					Select i
					Case 1 To border(1)
						p.w=1
					Case 1 To border(2)
						p.w=Len(s)-l+1
					Case 1 To border(3)
						p.w=RightP+1
					EndSelect

					If Mid(s,p,l)=word(i)

						Select i
						Case 1 To border(0)
							afterburner.w+1

						Case 1 To border(1)
							indent-1
							afterburner.w+1

						Case 1 To border(3)
							If afterburner
								afterburner-1
							Else
								indent-1
							EndIf

						EndSelect
					EndIf

				Next i

				z=strings(indent,indtxt)+z
				;WriteStringN(2,s)

			EndIf ; mode

		EndIf ; Zeilenselektion

		WriteStringN(2,z)
		indent+afterburner
	Wend
	CloseFile(1)
	CloseFile(2)
EndProcedure

Doit(GetKeyState_(#VK_SHIFT) & 128)
Post Reply