Toon posts:

[VB] Syntax Highlighting

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil in VB bijvoorbeeld HTML highlighten, oftewel, alles tussen < en > een andere kleur geven als de rest van de tekst.
Nou had ik zelf al een functietje geschreven die gewoon alle tekens in de RichTextBox selecteert en kijkt welk teken het is, deze functie highlighte alles tussen < en >, en alles tussen " en ", het nadeel was dat dit bij een groter bestand haast 10 seconden duurt.
Nou hoorde ik van iemand op IRC dat je dit ook kunt doen met de eigenschap TextRTF van een RichTextBox, weet iemand misschien hoe dit werkt? Want het is veel sneller hoorde ik.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Kan je XHTML vereisen of wil je ook oudere HTML versies kunnen kleuren?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
Het gaat me eigenlijk meer om het principe, dus hoe je iets tussen twee tekens een andere kleur geeft, als ik dat eenmaal weet kan ik het ook wel op andere dingen toepassen.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
CArNi4: Het gaat me eigenlijk meer om het principe
Hum tja, dat begrijp ik: maar het maakt toch nogal wat verschil. XHTML zit namelijk logisch in elkaar (het is gewoon XML) en hierdoor kan je standaard tools gebruiken om het document te parsen.

Dit kan op verschillende manier: via XSLT, waarbij je de XHTML transformeert naar syntax-gekleurde XHTML of bijvoorbeeld via een XML parser die de inhoud van het document aanreikt via een SAX interfave.

Je hebt in beide gevallen helemaal geen problemen met parsing en je hoeft in feite alleen maar de output te genereren.

Overigens zijn er ook tools die klassieke HTML kunnen parsen en dit naar XML kunnen omzetten, dus zelfs als je HTML wilt accepeteren kan je deze aanpak eventueel nog gebruiken.

Het belangrijke voordeel is dat het kleuren van klassieke HTML niet triviaal is. Je kan niet simpelweg alles tussen < en > gaan kleuren...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Ik heb deze code gebruikt. Werkt snel en makkelijk :). (De maker weet helaas niet hoe hij fatsoenlijk moet coden, wat een zooi :(... maar dat is wel op te schonen)

Verwijderd

Topicstarter
Op zaterdag 13 juli 2002 21:11 schreef KoenM het volgende:
Ik heb deze code gebruikt. Werkt snel en makkelijk :). (De maker weet helaas niet hoe hij fatsoenlijk moet coden, wat een zooi :(... maar dat is wel op te schonen)
Bedankt, ik moet er nog naar kijken maar het is volgens mij wel wat ik zoek.

Verwijderd

Ik was dus die gast van IRC :P
Die code op PSC had hetzelfde principe als die van mij. Deze werkt wat beter (=sneller), maar ik was ook nog niet zo ver :z
Namens Carni4 en mij...bedankt 8-)

  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
ik heb ook recent nog een SQL-editor geschreven in vb met syntax-highlighting.

Ik heb wel een probleem dat mijn tekst wel redelijk zwaar flikkert.

'k Heb dat wel enigzins kunnen minimaliseren door die routine uit te schakelen als de gebruiker een halve seconde niets typt. Er moet toch een andere manier zijn, maar deze heb ik nog niet gevonden ... :(

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


Verwijderd

Topicstarter
Op zondag 14 juli 2002 14:20 schreef -Avalanche- het volgende:
ik heb ook recent nog een SQL-editor geschreven in vb met syntax-highlighting.

Ik heb wel een probleem dat mijn tekst wel redelijk zwaar flikkert.

'k Heb dat wel enigzins kunnen minimaliseren door die routine uit te schakelen als de gebruiker een halve seconde niets typt. Er moet toch een andere manier zijn, maar deze heb ik nog niet gevonden ... :(
Deed je dat ook met TextRTF dan? En zo ja, liet je dan het hele bestand doorlopen? Want dan kun je beter alleen het vorige woord of de vorige zin laten doorlopen.

  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
neen, ik had een functie geschreven die steeds de volledige tekst overliep en op 'keywords' zocht (zoals SELECT) en deze dan in het vet zette.

ik wist niet waarvoor die RTFtext diende

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
nog even een opmerking:

enkel het vorige woord controleren is niet voldoende hoor. Want stel je even het volgende scenario voor:

selectfrom tabel where

ik zet nu een spatie tussen select en from, dan moeten toch de woorden select en from ge-highlighted worden.

dus het lijkt mij noodzakelijk steeds de volledige tekst te overlopen en te controleren.

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


Verwijderd

Nah, je kan toch zoeken (vanaf waar getypt is) naar een spatie ervoor en erna en daartussen de woorden controleren en evt. highlighten. Gaat een stuk sneller dan de hele tekst opnieuw controleren. Ziet er ook leuker uit, als je de selectie-aanpas-methode gebruikt :)

Verwijderd

Topicstarter
Op zaterdag 13 juli 2002 21:11 schreef KoenM het volgende:
Ik heb deze code gebruikt. Werkt snel en makkelijk :). (De maker weet helaas niet hoe hij fatsoenlijk moet coden, wat een zooi :(... maar dat is wel op te schonen)
Ik heb dat project eens bekeken en ik vind het nogal onduidelijk, heeft iemand een link voor me met een duidelijke uitleg over TextRTF?

Verwijderd

Op maandag 15 juli 2002 20:42 schreef CArNi4 het volgende:
Ik heb dat project eens bekeken en ik vind het nogal onduidelijk, heeft iemand een link voor me met een duidelijke uitleg over TextRTF?
Maar werkt het wel? Want daar gaat het natuurlijk om ;).

Anders maak je ff een nieuwe module aan en daar prak je de volgende code in:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
Option Explicit

Private Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long

Dim varColorText, varColorTag, varColorProp, varColorPropVal, varColorComment As OLE_COLOR
Dim regex1 As RegExp, regex2 As RegExp, regex3 As RegExp, regex4 As RegExp ' regex for highlighting
Dim matches As MatchCollection
Dim match As match
Dim cAppendStr As cAppendString
Dim rtfheader As String

Public Function Colorize(rtfTarget As RichTextBox)
'  LockWindowUpdate rtfTarget.hWnd
  Initialize
  rtfTarget.TextRTF = colorhtml(rtfTarget.Text)
 ' LockWindowUpdate False

End Function

Private Function fcnGetRTFColor(ByVal Color As Variant) As String
  '***  this function accepts a VB color (long)
  '***  or a HTML color (string) and
  '***  returns a RTF color table def.
  
  Const sHEX = "0123456789ABCDEF"
  Dim lngRed As Long, lngGreen As Long, lngBlue As Long

  If VarType(Color) = vbLong Then
    lngRed = Color Mod 256&
    lngGreen = (Color Mod 65536) \ 256&
    lngBlue = Color \ 65536
  ElseIf VarType(Color) = vbString Then
    '***  the string should be something like this: #D0D5DF
    '***  strip of the right 6 chars
    Color = Right$(Color, 6)
    
    '***  find the position for each char in sHEX. Position is the value
    lngRed = 16& * (InStr(1, sHEX, Mid$(Color, 1, 1), vbTextCompare) - 1) + _
          1& * (InStr(1, sHEX, Mid$(Color, 2, 1), vbTextCompare) - 1)
    lngGreen = 16& * (InStr(1, sHEX, Mid$(Color, 3, 1), vbTextCompare) - 1) + _
            1& * (InStr(1, sHEX, Mid$(Color, 4, 1), vbTextCompare) - 1)
    lngBlue = 16& * (InStr(1, sHEX, Mid$(Color, 5, 1), vbTextCompare) - 1) + _
           1& * (InStr(1, sHEX, Mid$(Color, 6, 1), vbTextCompare) - 1)
  Else
    '***  this function accepts a VB color (long)
    '***  or a HTML color (string) only.
    Stop
  End If
  
  fcnGetRTFColor = "\red" & CStr(lngRed) & "\green" & CStr(lngGreen) & "\blue" & CStr(lngBlue) & ";"
End Function

Private Function Initialize()
'create regular expresions

'Regx to remove RTF meta characters
  Set regex1 = New VBScript_RegExp_55.RegExp
  regex1.Pattern = "([{}\\])"
  regex1.IgnoreCase = False
  regex1.Global = True
  
' Regx to remove RTF new lines
  Set regex2 = New RegExp
  regex2.Pattern = "(\r)"
  regex2.IgnoreCase = False
  regex2.Global = True
  
' Regx to get text/comments/tags
' This grabs all the text as seperate peices so we can use the very fast
' C append sting module to rebuild the rtf text.
  Set regex3 = New RegExp
  regex3.Pattern = "([^<]*)((<!-[\w\W]*?->)*)((<[^>]*>*)*)"
  regex3.IgnoreCase = False
  regex3.Global = True

' Regx to get properties/value pairs
  Set regex4 = New RegExp
  regex4.Pattern = "(\s\w[\w\d\s:_\-\.]*\s*=\s*)(""[^""]+""|'[^']+'|\d+)"
  regex4.IgnoreCase = False
  regex4.Global = True
Dim colortbl As String
' define fonts/ colors and create rtf header
varColorText = vbBlack
varColorTag = &HC00000
varColorProp = &HC000C0
varColorPropVal = &HC000&
varColorComment = &H808080

Dim rtfcolor(4) As String
rtfcolor(0) = fcnGetRTFColor(varColorText)
rtfcolor(1) = fcnGetRTFColor(varColorTag)
rtfcolor(2) = fcnGetRTFColor(varColorProp)
rtfcolor(3) = fcnGetRTFColor(varColorPropVal)
rtfcolor(4) = fcnGetRTFColor(varColorComment)
colortbl = Join(rtfcolor, "")

'add font header
rtfheader = "{\rtf1\ansi\ansicpg1252\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fswiss MS Sans Serif;}}" & vbCrLf
'add color header
rtfheader = rtfheader & "{\colortbl" & colortbl & "}" & vbCrLf
'add end header
'rtfheader = rtfheader & "\deflang1033\pard"
End Function

Private Function colorhtml(htmltext As String) As String
'lets time it
Set cAppendStr = New cAppendString
cAppendStr.Append rtfheader
'Escape Meta RTF chars using Regular expression
htmltext = regex1.Replace(htmltext, "\$1")
htmltext = regex2.Replace(htmltext, "\par \r")
' color text using regular expressions
  Set matches = regex3.Execute(htmltext)    ' Execute search.
  For Each match In matches     ' Iterate Matches collection.
    cAppendStr.Append "\plain\f2\fs17\cf0 " & match.SubMatches(0) & "\plain\f2\fs17\cf4 " & match.SubMatches(1) & "\plain\f2\fs17\cf1"
    cAppendStr.Append regex4.Replace(match.SubMatches(3), "\plain\f2\fs17\cf2 $1\plain\f2\fs17\cf3 $2\plain\f2\fs17\cf1 ")
  Next
'add footer
cAppendStr.Append "}"
colorhtml = cAppendStr.Value
cAppendStr.Clear
End Function

Als je nu de functie Colorize(...) aanroept met je rtf box, dan ben je klaar :). Sim-pel ;)

PS Ik gok dat de lay-out hier niet zo goed tegen kan >:)

  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Op maandag 15 juli 2002 13:21 schreef KtK het volgende:
Nah, je kan toch zoeken (vanaf waar getypt is) naar een spatie ervoor en erna en daartussen de woorden controleren en evt. highlighten. Gaat een stuk sneller dan de hele tekst opnieuw controleren. Ziet er ook leuker uit, als je de selectie-aanpas-methode gebruikt :)
mjah, ik doe het eigenlijk met een timer die om de 250ms ofzo en functie oproept die dan de volledige tekst onderzoekt.

Die functie zou ik ook steeds kunnen oproepen bij een OnKeyPress() event, maar dan moet ik steeds controleren als ik een spatie, enter, backspace, pijltjes, ... heb ingedrukt en dat leek me een omslachtige manier en ook te instabiel (vooral bij die enter om de vorige lijn en de huidige lijn te kunnen weten)

Misschien mbv die txtRTF dat het vlugger zou kunnen gaan, maar die txtRTF begrijp ik niet :?

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


Verwijderd

Topicstarter
Op maandag 15 juli 2002 21:05 schreef KoenM het volgende:

[..]

Maar werkt het wel? Want daar gaat het natuurlijk om ;).

Anders maak je ff een nieuwe module aan en daar prak je de volgende code in:
code:
1
Die code hierboven dus

Als je nu de functie Colorize(...) aanroept met je rtf box, dan ben je klaar :). Sim-pel ;)

PS Ik gok dat de lay-out hier niet zo goed tegen kan >:)
Ja, maar ik wil ook graag begrijpen wát ik doe, en niet zomaar een codetje overnemen van iemand.

KtK, heb je je eigen versie hiervan al af?
Pagina: 1