Syntax Highlightning Lösung

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Syntax Highlightning Lösung

Beitrag von Vermilion »

Moin,

da Syntax Highlightning hier im Forum schon oft gesucht, besprochen und nie eine Lösung gefunden wurde (so wie ich mitbekam), habe ich mich mal in den letzten Tagen hingesetzt, und mir einen nützlichen Codeteil aus meinem Archiv zu Nutze gemacht.

Ursprünglich wollte ich mal einen simplen HTML Editor mit Highlightning machen. Sowas wie Notepad mit Highlightning. Werde ich dann auch machen.

Ich habe eine (bei mir) schnelle, gute Lösung für Syntax-Highlightning gefunden. Sie ist noch nicht ganz ausgereift, ich kämpfe derzeit ehrlich gesagt nur noch damit, dass wenn man die Backspace Taste drückt, der Textcursor auch einen weiter nach hinten geht, und nicht zwei Zeichen nach vorne. Finde ich zumindest. Letztendlich wird im Editorgadget wie bei Wordpad einfach automatisch ein Bereich selektiert und dessen Attribute (Format und Schriftfarbe in diesem Fall) geändert.

Hier der Quelltext in PureBasic 4.00:

Code: Alles auswählen

Enumeration
#Editor
EndEnumeration
Structure HighlightWord
Word.s
Color.l
Format.b
EndStructure

Global currentline
Global currentcolumn
Global Length_new.l
Global Length_old.l = Length_new
Global NewList WordsToHighlight.HighlightWord()

Procedure Editor_Select(Gadget, LineStart.l, CharStart.l, LineEnd.l, CharEnd.l)    
  sel.CHARRANGE 
  sel\cpMin = SendMessage_(GadgetID(Gadget), #EM_LINEINDEX, LineStart, 0) + CharStart - 1 
  If LineEnd = -1 
    LineEnd = SendMessage_(GadgetID(Gadget), #EM_GETLINECOUNT, 0, 0)-1 
  EndIf 
  sel\cpMax = SendMessage_(GadgetID(Gadget), #EM_LINEINDEX, LineEnd, 0) 
  If CharEnd = -1 
    sel\cpMax + SendMessage_(GadgetID(Gadget), #EM_LINELENGTH, sel\cpMax, 0) 
  Else 
    sel\cpMax + CharEnd - 1 
  EndIf 
  SendMessage_(GadgetID(Gadget), #EM_EXSETSEL, 0, @sel) 
EndProcedure 

Procedure Editor_Color(Gadget, Color.l) 
  format.CHARFORMAT 
  format\cbSize = SizeOf(CHARFORMAT) 
  format\dwMask = #CFM_COLOR 
  format\crTextColor = Color 
  SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format) 
EndProcedure 

Procedure Editor_Format(Gadget, Flags.l)
  format.CHARFORMAT 
  format\cbSize = SizeOf(CHARFORMAT) 
  format\dwMask = #CFM_ITALIC|#CFM_BOLD|#CFM_STRIKEOUT|#CFM_UNDERLINE 
  format\dwEffects = Flags 
  SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format) ; #CFM_BOLD   #CFM_ITALIC   #CFM_UNDERLINE   #CFM_STRIKEOUT
EndProcedure 

Procedure ExamineEditor()
  SetGadgetFont(#Editor, FontID(0))
  SetGadgetColor(#Editor, #PB_Gadget_FrontColor, RGB(0, 0, 0))
EndProcedure

Procedure ExamineLine(Line)
  
  EditorContent$ = GetGadgetItemText(#Editor, Line, 0)
  Length_new = Len(EditorContent$)
  
  
  
  Editor_Select(#Editor, Line, 1, Line, -1)
  Editor_Format(#Editor, 0)
  Editor_Color(#Editor, RGB(0, 0, 0))
  
  ForEach WordsToHighlight()
      
    Position = FindString(UCase(EditorContent$), WordsToHighlight()\Word, 0)
    
    If Position > 0
        
      Editor_Select(#Editor, Line, Position, Line, Position+Len(WordsToHighlight()\Word))
      Editor_Format(#Editor, WordsToHighlight()\Format)
      Editor_Color(#Editor, WordsToHighlight()\Color)
      
    EndIf
      
  Next
  
  Debug "Lenght_new: "+Str(Length_new)
  Debug "Lenght_old: "+Str(Length_old)
  
  
  If Length_new < Length_old
    Difference = 0
    Length_old = Length_new
  ElseIf Length_new > Length_old
    Difference = 2
    Length_old = Length_new
  Else
    Difference = 0
  EndIf
  
  Debug "Difference: "+Str(Difference)
  
  Editor_Select(#Editor, currentline, currentcolumn+Difference, currentline, currentcolumn+Difference)
  
EndProcedure

Procedure ExamineText()
  Line = 0
  While Line < CountGadgetItems(#Editor)
    ExamineLine(Line)
    Line+1
  Wend
EndProcedure

Procedure Add_String_To_Highlight_List(String$, Color, Format)
  If AddElement(WordsToHighlight())
    WordsToHighlight()\Word = String$
    WordsToHighlight()\Color = Color
    WordsToHighlight()\Format = Format
    ProcedureReturn  1
  Else
    ProcedureReturn  0
  EndIf
EndProcedure

Add_String_To_Highlight_List("<HTML>", RGB(0, 0, 223), #CFM_BOLD)
Add_String_To_Highlight_List("</HTML>", RGB(0, 0, 223), #CFM_BOLD)
Add_String_To_Highlight_List("<B>", RGB(0, 0, 0), #CFM_BOLD)
Add_String_To_Highlight_List("</B>", RGB(0, 0, 0), #CFM_BOLD)
Add_String_To_Highlight_List("<HEAD>", RGB(0, 0, 223), #CFM_BOLD)
Add_String_To_Highlight_List("</HEAD>", RGB(0, 0, 223), #CFM_BOLD)
Add_String_To_Highlight_List("<TITLE>", RGB(191, 0, 0), #CFM_BOLD)
Add_String_To_Highlight_List("</TITLE>", RGB(191, 0, 0), #CFM_BOLD)
Add_String_To_Highlight_List("<BODY>", RGB(0, 0, 223), #CFM_BOLD)
Add_String_To_Highlight_List("<BODY", RGB(0, 0, 223), #CFM_BOLD)
Add_String_To_Highlight_List("</BODY>", RGB(0, 0, 223), #CFM_BOLD)
Add_String_To_Highlight_List("<FONT>", RGB(223, 0, 0), #CFM_BOLD)
Add_String_To_Highlight_List("<FONT", RGB(223, 0, 0), #CFM_BOLD)
Add_String_To_Highlight_List("</FONT>", RGB(223, 0, 0), #CFM_BOLD)
Add_String_To_Highlight_List("<BR>", RGB(191, 191, 191), #CFM_BOLD)
Add_String_To_Highlight_List("nbsp", RGB(191, 191, 191), 0)
Add_String_To_Highlight_List("<HR>", RGB(0, 127, 0), #CFM_BOLD)
Add_String_To_Highlight_List("<HR", RGB(0, 127, 0), #CFM_BOLD)
Add_String_To_Highlight_List("<TABLE>", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("<TABLE", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("</TABLE>", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("<TD>", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("<TD", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("</TD>", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("<TR>", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("<TR", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List("</TR>", RGB(0, 127, 255), #CFM_BOLD)
Add_String_To_Highlight_List(" CLASS=", RGB(127, 127, 127), #CFM_ITALIC)
Add_String_To_Highlight_List(" WIDTH=", RGB(127, 127, 127), #CFM_ITALIC)
Add_String_To_Highlight_List(" HEIGHT=", RGB(127, 127, 127), #CFM_ITALIC)
Add_String_To_Highlight_List(" SIZE=", RGB(127, 127, 127), #CFM_ITALIC)
Add_String_To_Highlight_List(" COLOR=", RGB(127, 127, 127), #CFM_ITALIC)
Add_String_To_Highlight_List(" BGCOLOR=", RGB(127, 127, 127), #CFM_ITALIC)
Add_String_To_Highlight_List(" BORDER=", RGB(127, 127, 127), #CFM_ITALIC)

OpenWindow(0, 0, 0, 1200, 900, "Texthighlightning Editor", #PB_Window_SystemMenu)
  LoadFont(0, "Lucida Console", 10)
  If CreateGadgetList(WindowID(0))
    EditorGadget(#Editor, 0, 0, 1200, 900)
      AddGadgetItem(#Editor, -1, "<HTML>")
      AddGadgetItem(#Editor, -1, "	<HEAD>")
      AddGadgetItem(#Editor, -1, "		<TITLE>Testdokument</TITLE>")
      AddGadgetItem(#Editor, -1, "	</HEAD>")
      AddGadgetItem(#Editor, -1, "	<BODY BGCOLOR=#ffffff>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "	<TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=10 BORDER=0>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "		<TR HEIGHT=100>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "			<TD CLASS=head>Testdokument</TD>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "		</TR>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "		<TR>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "			<TD>")
      AddGadgetItem(#Editor, -1, "			<B>Titel</B><BR>")
      AddGadgetItem(#Editor, -1, "			Text.<BR>")
      AddGadgetItem(#Editor, -1, "			<BR>")
      AddGadgetItem(#Editor, -1, "			<B>Liste</B><BR>")
      AddGadgetItem(#Editor, -1, "				<UL>")
      AddGadgetItem(#Editor, -1, "					<LI>Listeneintrag</LI>")
      AddGadgetItem(#Editor, -1, "				</UL>")
      AddGadgetItem(#Editor, -1, "			</TD>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "		</TR>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "	</TABLE>")
      AddGadgetItem(#Editor, -1, "")
      AddGadgetItem(#Editor, -1, "	</BODY>")
      AddGadgetItem(#Editor, -1, "</HTML>")
      ExamineEditor()
      ExamineText()
  EndIf
Repeat
  EventID = WaitWindowEvent()
  If OldText$ <> GetGadgetText(#Editor)
    ExamineLine(currentline)
    OldText$ = GetGadgetText(#Editor)
  EndIf
  SendMessage_(GadgetID(#Editor), #EM_GETSEL, @charposinalltext.l, 0)
  currentline = SendMessage_(GadgetID(#Editor), #EM_LINEFROMCHAR, -1, 0)
  currentcolumn = charposinalltext.l - SendMessage_(GadgetID(#Editor), #EM_LINEINDEX, -1, 0)
Until EventID = #PB_Event_CloseWindow : End
Was sagt ihr dazu?

Weitere Frage:
Wie kann ich herausfinden, welche Taste gedrückt wurde beim editieren? Dann könnte ich zwischen Entf und Backspace Taste unterscheiden und das mit dem Textcursor-Sprung-Bug beheben.
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

Interessiert sich denn keiner dafür? :cry:
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
PMTheQuick
Beiträge: 630
Registriert: 05.05.2005 19:06

Beitrag von PMTheQuick »

Ich brauchte auch mal so was... Jetzt allerdings nicht mehr! Und trotzdem meine Bewertung:

Code: Bild
Funktionalität: Bild
Gesamtbewertung: Bild-Bild

Und noch: Bild

CODE: Eigentlich gut programmiert, schön eingerückt! TOP!
FUNKTIONALITÄT: Gut, nur ab und zu springt der Cursor an eine andere Position wenn man neuen Text eingibt, und das ist nervig!
GESAMT: Guter Code, mit nen paar kleinen Fehlern! :allright:

Gruss
PMTheQuick ;)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Vermilion hat geschrieben:Interessiert sich denn keiner dafür? :cry:
Hatten wir schon, der Syntax-Highlightner von DarkDragon unterscheidet sich
kaum von Deinem. Für kleinere Sachen brauchbar, aber ansonsten viel zu
langsam.

So wie der Highlightner aufgebaut ist, wirste den auch nicht schneller
bekommen.

Aber für einfachere Sachen ist das schon sehr brauchbar.

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

Danke. <)

Ich dachte DD funktionert anders... :|

Naja, ich werde mal schauen...
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Antworten