From d85498e2ad16157e2df747434d486d8cd35deaad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Thu, 26 Oct 2023 22:31:10 +0200 Subject: [PATCH] Add 'css' highlighting, fix some bugs, add some enhancements. [GB.HIGHLIGHT] * BUG: Fix embedded highlighting management. * BUG: Correctly handle UTF-8 text everywhere now. * NEW: Some little syntax changes in definition file. * NEW: Add '@include' command for including inside a definition file another file. * NEW: TextHighlighter.ToHTML() takes embedded highlighting into account using automatic background colors. * NEW: Add 'c', 'cpluscplus' and 'webpage' highlighting. --- .../gb.highlight/.src/CCommandBetween.class | 4 +- comp/src/gb.highlight/.src/CCommandFrom.class | 14 +-- .../src/gb.highlight/.src/CCommandMatch.class | 16 ++-- comp/src/gb.highlight/.src/CCommandWord.class | 7 +- comp/src/gb.highlight/.src/CState.class | 23 +++-- comp/src/gb.highlight/.src/Main.module | 13 +-- .../gb.highlight/.src/TextHighlighter.class | 89 ++++++++++++++----- .../.src/_TextHighlighter_Gambas.class | 81 ++++++++++++++--- .../custom/CustomHighlighter.class | 64 ++++++++++--- comp/src/gb.highlight/highlight/c.highlight | 32 +++++++ .../highlight/cplusplus.highlight | 37 ++++++++ comp/src/gb.highlight/highlight/css.highlight | 2 + .../src/gb.highlight/highlight/html.highlight | 14 +-- .../highlight/javascript.highlight | 4 +- .../gb.highlight/highlight/webpage.highlight | 31 +++++++ .../gb.highlight/highlight/webpage.include | 6 ++ .../highlight/webpage_css.highlight | 65 ++++++++++++++ .../highlight/webpage_javascript.highlight | 44 +++++++++ 18 files changed, 459 insertions(+), 87 deletions(-) create mode 100644 comp/src/gb.highlight/highlight/c.highlight create mode 100644 comp/src/gb.highlight/highlight/cplusplus.highlight create mode 100644 comp/src/gb.highlight/highlight/webpage.highlight create mode 100644 comp/src/gb.highlight/highlight/webpage.include create mode 100644 comp/src/gb.highlight/highlight/webpage_css.highlight create mode 100644 comp/src/gb.highlight/highlight/webpage_javascript.highlight diff --git a/comp/src/gb.highlight/.src/CCommandBetween.class b/comp/src/gb.highlight/.src/CCommandBetween.class index 982a8b080..5955e21bb 100644 --- a/comp/src/gb.highlight/.src/CCommandBetween.class +++ b/comp/src/gb.highlight/.src/CCommandBetween.class @@ -20,13 +20,13 @@ Public Sub Compile(hState As CState) CState.IfStartWith($sFrom, hState.GetNextLabel()) - hState.Forward(Len($sFrom)) + hState.Forward(String.Len($sFrom)) hState.PrintLabel(hState.GetLabel() & "_LOOP") CState.Print("If $bEof Then Return") CState.IfStartWith($sTo) - hState.Forward(Len($sTo)) + hState.Forward(String.Len($sTo)) hState.Continue() CState.Print("Endif") diff --git a/comp/src/gb.highlight/.src/CCommandFrom.class b/comp/src/gb.highlight/.src/CCommandFrom.class index 0c249ea60..eeb583255 100644 --- a/comp/src/gb.highlight/.src/CCommandFrom.class +++ b/comp/src/gb.highlight/.src/CCommandFrom.class @@ -12,7 +12,7 @@ Public Sub SetArgs(aArgs As String[]) If aArgs.Count >= 3 And If aArgs[1] = "to" Then $sFrom = aArgs[0] $sTo = aArgs[2] - If aArgs.Count = 5 And If aArgs[3] = "include" Then + If aArgs.Count = 5 And If aArgs[3] = "with" Then $sInclude = aArgs[4] $iInclude = CState.AddInclude($sInclude) Else If aArgs.Count <> 3 Then @@ -33,22 +33,26 @@ Public Sub Compile(hState As CState) If $sInclude Then - hState.Forward(Len($sFrom)) + CState.Print("Imbricate(" & CStr($iInclude) & ")") + hState.Forward(String.Len($sFrom)) + CState.Print("Imbricate(0)") hState.PrintLabel(hState.GetLabel() & "_LOOP") CState.Print("If $bEof Then Return") CState.Print("If Include(" & CStr($iInclude) & ", " & Quote($sInclude) & ", False, " & Quote($sTo) & ", aState) Then Return") - hState.Forward(Len($sTo)) + CState.Print("Imbricate(" & CStr($iInclude) & ")") + hState.Forward(String.Len($sTo)) + CState.Print("Imbricate(0)") hState.Continue() Else - hState.Forward(Len($sFrom)) + hState.Forward(String.Len($sFrom)) hState.PrintLabel(hState.GetLabel() & "_LOOP") CState.Print("If $bEof Then Return") CState.IfStartWith($sTo) - hState.Forward(Len($sTo)) + hState.Forward(String.Len($sTo)) hState.Continue() CState.Print("Endif") diff --git a/comp/src/gb.highlight/.src/CCommandMatch.class b/comp/src/gb.highlight/.src/CCommandMatch.class index e7a32d0d9..4fac638df 100644 --- a/comp/src/gb.highlight/.src/CCommandMatch.class +++ b/comp/src/gb.highlight/.src/CCommandMatch.class @@ -12,7 +12,7 @@ Public Sub SetArgs(aArgs As String[]) If aArgs.Count >= 3 And If aArgs[1] = "to" Then $sFrom = aArgs[0] $sTo = aArgs[2] - If aArgs.Count = 5 And If aArgs[3] = "include" Then + If aArgs.Count = 5 And If aArgs[3] = "with" Then $sInclude = aArgs[4] $iInclude = CState.AddInclude($sInclude) Else If aArgs.Count <> 3 Then @@ -32,7 +32,7 @@ Public Sub Compile(hState As CState) CState.Print("sWord = Match(" & Quote($sFrom) & ")") CState.Print("If Not sWord Then Goto " & hState.GetNextLabel()) - hState.Forward("Len(sWord)") + hState.Forward("String.Len(sWord)") hState.CompileChildren() hState.Continue() @@ -41,26 +41,30 @@ Public Sub Compile(hState As CState) CState.Print("sWord = Match(" & Quote($sFrom) & ")") CState.Print("If Not sWord Then Goto " & hState.GetNextLabel()) - hState.Forward("Len(sWord)") + CState.Print("Imbricate(" & CStr($iInclude) & ")") + hState.Forward("String.Len(sWord)") + CState.Print("Imbricate(0)") hState.PrintLabel(hState.GetLabel() & "_LOOP") CState.Print("If $bEof Then Return") CState.Print("If Include(" & CStr($iInclude) & ", " & Quote($sInclude) & ", True, " & Quote($sTo) & ", aState) Then Return") - hState.Forward("Len(Match(" & Quote($sTo) & "))") + CState.Print("Imbricate(" & CStr($iInclude) & ")") + hState.Forward("String.Len(Match(" & Quote($sTo) & "))") + CState.Print("Imbricate(0)") hState.Continue() Else CState.Print("sWord = Match(" & Quote($sFrom) & ")") CState.Print("If Not sWord Then Goto " & hState.GetNextLabel()) - hState.Forward("Len(sWord)") + hState.Forward("String.Len(sWord)") hState.PrintLabel(hState.GetLabel() & "_LOOP") CState.Print("If $bEof Then Return") CState.Print("sWord = Match(" & Quote($sTo) & ")") CState.Print("If sWord Then") - hState.Forward("Len(sWord)") + hState.Forward("String.Len(sWord)") hState.Continue() CState.Print("Endif") diff --git a/comp/src/gb.highlight/.src/CCommandWord.class b/comp/src/gb.highlight/.src/CCommandWord.class index b67682116..72699634f 100644 --- a/comp/src/gb.highlight/.src/CCommandWord.class +++ b/comp/src/gb.highlight/.src/CCommandWord.class @@ -20,10 +20,7 @@ Public Sub SetArgs(aArgs As String[]) Else - $aWords = New String[] - For I = 0 To $aWords.Max - $aWords.Add(aArgs[I]) - Next + $aWords = aArgs.Copy() Endif @@ -63,7 +60,7 @@ Public Sub Compile(hState As CState) CState.Print("sWord = GetWord()") CState.Print("If Not sWord Or If Not " & $sWords & ".Exist(sWord) Then Goto " & hState.GetNextLabel()) - hState.Forward("Len(sWord)") + hState.Forward("String.Len(sWord)") hState.Continue() End diff --git a/comp/src/gb.highlight/.src/CState.class b/comp/src/gb.highlight/.src/CState.class index 1bf2cf828..95727937e 100644 --- a/comp/src/gb.highlight/.src/CState.class +++ b/comp/src/gb.highlight/.src/CState.class @@ -12,7 +12,7 @@ Static Private $aStateName As New String[] Static Private $aLabel As New String[] Static Private $cTitle As New Collection -Static Private $aInclude As New String[] +Static Private $cInclude As New Collection Static Private $cSubst As New Collection @@ -35,7 +35,6 @@ Static Public Sub Init(sPath As String) $aStateName.Clear $aLabel.Clear $cTitle.Clear - $aInclude.Clear Keywords.Clear End @@ -160,16 +159,16 @@ End Static Public Sub IfStartWith(sStr As String, Optional sLabel As String) If sLabel Then - Print("If Mid$($sText, $iPos, " & CStr(Len(sStr)) & ") <> " & Quote(sStr) & " Then Goto " & sLabel) + Print("If String.Mid$($sText, $iPos, " & CStr(String.Len(sStr)) & ") <> " & Quote(sStr) & " Then Goto " & sLabel) Else - Print("If Mid$($sText, $iPos, " & CStr(Len(sStr)) & ") = " & Quote(sStr) & " Then") + Print("If String.Mid$($sText, $iPos, " & CStr(String.Len(sStr)) & ") = " & Quote(sStr) & " Then") Endif End Static Public Sub Peek(sLen As String) As String - Return "Mid$($sText, $iPos, " & sLen & ")" + Return "String.Mid$($sText, $iPos, " & sLen & ")" End @@ -286,12 +285,12 @@ Public Sub Compile(Optional sContinue As String) Print("If $sTextLimit Then") Print("If $bMatchLimit Then") Print("If Match($sTextLimit) Then") - Print("aState.Remove(0)") + 'Print("aState.Remove(0)") Print("Return") Print("Endif") Print("Else") Print("If $sTextLimit And If Mid$($sText, $iPos) Begins $sTextLimit Then") - Print("aState.Remove(0)") + 'Print("aState.Remove(0)") Print("Return") Print("Endif") Print("Endif") @@ -395,8 +394,14 @@ Static Public Sub GetKeywords() As String End Static Public Sub AddInclude(sInclude As String) As Integer + + Dim iInclude As Integer - $aInclude.Add(sInclude) - Return $aInclude.Count + Try iInclude = $cInclude[sInclude] + If Error Then + iInclude = $cInclude.Count + 1 + $cInclude[sInclude] = iInclude + Endif + Return iInclude End diff --git a/comp/src/gb.highlight/.src/Main.module b/comp/src/gb.highlight/.src/Main.module index 84bbcc0a7..9d97fa5c5 100644 --- a/comp/src/gb.highlight/.src/Main.module +++ b/comp/src/gb.highlight/.src/Main.module @@ -2,16 +2,9 @@ Public Sub Main() - Dim hJS As TextHighlighter - Dim hCSS As TextHighlighter - Dim hHTML As TextHighlighter - - hJS = TextHighlighter.FromFile("./highlight/javascript.highlight") - hCSS = TextHighlighter.FromFile("./highlight/css.highlight") - hHTML = TextHighlighter.FromFile("./highlight/html.highlight") - 'File.Save("~/test.html", hTextHighlighter.ToHTML(File.Load("custom/selectr.js"))) - 'File.Save("~/test.html", hCSS.ToHTML(File.Load("test/style.css"))) - File.Save("~/test.html", hHTML.ToHTML(File.Load("test/page.html"))) + TextHighlighter.CanRewrite = False + 'File.Save("~/test.html", TextHighlighter["webpage"].ToHTML(File.Load("~/gambas/git/master/comp/src/gb.form.editor/test.html"))) + File.Save("~/test.html", TextHighlighter["cplusplus"].ToHTML(File.Load("~/gambas/git/master/gb.qt5/src/CWidget.cpp"))) End diff --git a/comp/src/gb.highlight/.src/TextHighlighter.class b/comp/src/gb.highlight/.src/TextHighlighter.class index 2db06a26b..6acff0a7f 100644 --- a/comp/src/gb.highlight/.src/TextHighlighter.class +++ b/comp/src/gb.highlight/.src/TextHighlighter.class @@ -3,20 +3,26 @@ Export Create Static -Static Public TextAfter As String Static Public CanRewrite As Boolean +Public TextAfter As String +Public TextLengthBefore As Integer +Public Rewrite As Boolean + +Property Read Name As String Property Read Keywords As String[] Static Public Sub _get(Name As String) As TextHighlighter - Try Return Class.Load("_TextHighlighter_" & Name).AutoCreate() + Name = LCase(Name) + Try Return Classes["_TextHighlighter_" & Name].AutoCreate() Return FromFile("./highlight" &/ Name & ".highlight") End Static Public Sub _Create(Name As String) As TextHighlighter + _get(Name) Return Object.New("_TextHighlighter_" & Name) End @@ -34,7 +40,7 @@ Static Public Sub FromFile(Path As String, Optional Name As String) As TextHighl Catch - Error.Raise("Cannot load highlighter '" & Name & "': " & Error.Text) + Error.Raise("Cannot load highlighter '" & Name & "': " & Error.Where & ": " & Error.Text) End @@ -44,15 +50,17 @@ End Public Sub Run(Text As String, State As Byte[]) As Byte[] - If Not Text Then Return New Byte[] If State.Count = 0 Then State.Add(0) + If Not Text Then + If CanRewrite Then Me.TextAfter = "" + Return New Byte[] + Endif Return Me._Analyze(Text, State) End Static Private Sub CreateCustomHighlighter(sHighlight As String, sPath As String) - Dim hFile As File Dim iLine As Integer Dim sLine As String @@ -68,6 +76,9 @@ Static Private Sub CreateCustomHighlighter(sHighlight As String, sPath As String Dim sDir As String Dim sProject As String Dim iPos As Integer + Dim aLines As String[] + Dim aInclude As String[] + Dim I As Integer sDir = File.Dir(Temp$()) &/ "gb.highlight." & sHighlight Mkdir sDir @@ -81,14 +92,16 @@ Static Private Sub CreateCustomHighlighter(sHighlight As String, sPath As String hOutput = Open sOutput For Create Output To hOutput - hFile = Open sPath For Input + aLines = Split(File.Load(sPath), "\n") Print File.Load("custom/CustomHighlighter.class") iCurrentIndent = 0 + iLine = 0 - For Each sLine In hFile.Lines + While iLine < aLines.Count + sLine = aLines[iLine] Inc iLine sLine = RTrim(sLine) @@ -100,6 +113,17 @@ Static Private Sub CreateCustomHighlighter(sHighlight As String, sPath As String If sLine Begins "#" Then Continue + If sLine Begins "@include " Then + sLine = Trim(Mid$(sLine, 9)) + If Not sLine Then Error.Raise("Syntax error") + aInclude = Split(File.Load(File.Dir(sPath) &/ sLine), "\n") + For I = 0 To aInclude.Max + aInclude[I] = Space$(iIndent) & aInclude[I] + Next + aLines.Insert(aInclude, iLine) + Continue + Endif + If sLine Begins "$(" Then sLine = Mid$(sLine, 3) iPos = InStr(sLine, ")=") @@ -148,7 +172,7 @@ Static Private Sub CreateCustomHighlighter(sHighlight As String, sPath As String Endif - Next + Wend iLine = 0 @@ -185,7 +209,7 @@ Static Private Sub CreateCustomHighlighter(sHighlight As String, sPath As String Output To Default hOutput.Close - Print File.Load(sOutput) + 'Print File.Load(sOutput) sProject = File.Load("custom/project.template") sProject = Replace(sProject, "$(startup)", "_TextHighlighter_" & sHighlight) @@ -197,16 +221,26 @@ Static Private Sub CreateCustomHighlighter(sHighlight As String, sPath As String Component.Load(sDir &/ "gb.highlight." & sHighlight & ".gambas") -Catch - - If iLine Then - Error.Raise(Error.Text & " at line " & CStr(iLine)) - Else - Error.Propagate() - Endif +' Catch +' +' If iLine Then +' Error.Raise(Error.Text & " at line " & CStr(iLine)) +' Else +' Error.Propagate() +' Endif End +Private Sub GetIncludeColor(iInclude As Integer) As Integer + + Dim iHue As Integer + + iHue = [60, 0, 210, 120, 30, 270][iInclude Mod 6] + Return Color.HSV(iHue, 32, 255) + +End + + Public Sub ToHTML(Text As String, Optional Theme As TextHighlighterTheme) As String Dim aResult As New String[] @@ -229,6 +263,8 @@ Public Sub ToHTML(Text As String, Optional Theme As TextHighlighterTheme) As Str Dim aState As Byte[] Dim iLevel As Integer Dim iBg As Integer + Dim aInclude As New Byte[] + Dim iInclude As Byte If Not Theme Then Theme = New TextHighlighterTheme @@ -245,8 +281,6 @@ Public Sub ToHTML(Text As String, Optional Theme As TextHighlighterTheme) As Str sLine = aText[Y] & "\n" aHighlight = Me.Run(sLine, aState) - 'If TextHighlighter.TextAfter Then sLine = TextHighlighter.TextAfter - sLineHtml = "" P = 1 @@ -257,11 +291,14 @@ Public Sub ToHTML(Text As String, Optional Theme As TextHighlighterTheme) As Str If iLen = 0 Then If iState Then + aInclude.Push(iInclude) + iInclude = iState Inc iLevel Else + iInclude = aInclude.Pop() Dec iLevel Endif - iBg = Color.HSV(-1, 0, 255 - 16 * iLevel * iLevel) + iBg = GetIncludeColor(iInclude) 'Color.HSV(-1, 0, 255 - 8 * (iLevel * (iLevel + 1))) Continue Endif @@ -269,6 +306,7 @@ Public Sub ToHTML(Text As String, Optional Theme As TextHighlighterTheme) As Str If Error Then hStyle = aStyles[0] sHtml = Replace(Html(String.Mid$(sLine, P, iLen)), " ", " ") + sHtml = Replace(sHtml, "\t", "  ") P += iLen If hStyle.Bold Then sHtml = "" & sHtml & "" @@ -322,7 +360,7 @@ Static Public Sub _Add(aHighlight As Byte[], iState As Byte, iCount As Integer) Dim iMax As Integer iMax = aHighlight.Max - If aHighlight.Count And If aHighlight[iMax - 1] = iState Then + If aHighlight.Count And If aHighlight[iMax - 1] = iState And If aHighlight[iMax] Then If aHighlight[iMax] <= (255 - iCount) Then aHighlight[iMax] += iCount Return @@ -344,3 +382,14 @@ Static Public Sub _Add(aHighlight As Byte[], iState As Byte, iCount As Integer) Endif End + +Private Function Name_Read() As String + + Dim sClass As String + Dim iPos As Integer + + sClass = Object.Type(Me) + iPos = RInStr(sClass, "_") + Try Return LCase(Mid$(sClass, iPos + 1)) + +End diff --git a/comp/src/gb.highlight/.src/_TextHighlighter_Gambas.class b/comp/src/gb.highlight/.src/_TextHighlighter_Gambas.class index cec0adce8..f8e096844 100644 --- a/comp/src/gb.highlight/.src/_TextHighlighter_Gambas.class +++ b/comp/src/gb.highlight/.src/_TextHighlighter_Gambas.class @@ -1,8 +1,8 @@ ' Gambas class file +Export Inherits TextHighlighter -'Public Const Name As String = "gambas" 'Public Const FullName As String = "Gambas" 'Public Const _Styles As String = "Keyword,Function,Operator,Symbol,Number,String,Breakpoint,Current,Datatype,Preprocessor,Escape,Label,Constant" @@ -59,20 +59,48 @@ Private Sub IsProc() As Boolean End -Public Sub _Analyze(Text As String, (State) As Byte[], Optional (MatchLimit) As Boolean, (Limit) As String, ByRef (Pos) As Integer) As Byte[] +Public Sub _Analyze(Text As String, (State) As Byte[], Optional (MatchLimit) As Boolean, Limit As String, ByRef Pos As Integer) As Byte[] Dim aHighlight As New Byte[] - Dim iState As Short - Dim iTag As Short Dim iPos As Integer Dim I As Integer Dim iLen As Integer + Dim sSym As String + Dim bRewrite As Boolean + Dim sTextAfter As String + Dim iLenText As Integer + Dim iLenBefore As Integer ' Gambas syntax implies that: ' - A line always starts at normal state. ' - 'Text' must be a whole line of code. + ' - 'MatchLimit' must be False + ' - 'Limit' can only be '%>' - Highlight.Analyze(Text, TextHighlighter.CanRewrite) + bRewrite = TextHighlighter.CanRewrite + + Text = String.Mid$(Text, Pos) + iLenText = String.Len(Text) + iLenBefore = iLenText + + If Limit And If bRewrite Then + + Highlight.Analyze(Text, False) + + For I = 0 To Highlight.Symbols.Max + sSym = Highlight.Symbols[I] + iPos = Highlight.Positions[I] + If sSym Begins Limit Then + iLenBefore = iPos + Break + Endif + iPos += String.Len(sSym) + Next + + Endif + + Highlight.Analyze(Text, bRewrite) + If bRewrite Then sTextAfter = Highlight.TextAfter 'TextHighlighter.Limit = IsProc() 'TextHighlighter.Comment = Left(LTrim(Text)) = "'" @@ -80,22 +108,55 @@ Public Sub _Analyze(Text As String, (State) As Byte[], Optional (MatchLimit) As iPos = 0 For I = 0 To Highlight.Symbols.Max + sSym = Highlight.Symbols[I] + If Limit And If sSym Begins Limit Then + If I = 0 Then + iPos = Highlight.Positions[0] + If iPos Then TextHighlighter._Add(aHighlight, 0, iPos) + Endif + ' iPos = 0 + ' Else + ' iPos = Highlight.Positions[I - 1] + String.Len(Highlight.Symbols[I - 1]) + ' Endif + If bRewrite Then + sTextAfter = String.Left(sTextAfter, iPos) + iLenText = iPos + Else + iLenText = Highlight.Positions[I] + Endif + Break + Endif + If iPos < Highlight.Positions[I] Then TextHighlighter._Add(aHighlight, 0, Highlight.Positions[I] - iPos) iPos = Highlight.Positions[I] Endif - iLen = String.Len(Highlight.Symbols[I]) - TextHighlighter._Add($cState[Highlight.Types[I]], iLen) + iLen = String.Len(sSym) + TextHighlighter._Add(aHighlight, $cState[Highlight.Types[I]], iLen) iPos += iLen Next - If iPos < String.Len(Highlight.TextAfter) Then - TextHighlighter._Add(0, String.Len(Highlight.TextAfter) - iPos) + If bRewrite Then + iLen = String.Len(sTextAfter) + Else + iLen = iLenText Endif - If TextHighlighter.CanRewrite Then TextHighlighter.TextAfter = Highlight.TextAfter + If iPos < iLen Then + TextHighlighter._Add(aHighlight, 0, iLen - iPos) + iPos = iLen + Endif + + If bRewrite Then + Me.TextAfter = sTextAfter + Me.TextLengthBefore = iLenBefore + Endif + + If Limit Then Pos += iLen + + Return aHighlight End diff --git a/comp/src/gb.highlight/custom/CustomHighlighter.class b/comp/src/gb.highlight/custom/CustomHighlighter.class index 5c0dde25a..555a8d28b 100644 --- a/comp/src/gb.highlight/custom/CustomHighlighter.class +++ b/comp/src/gb.highlight/custom/CustomHighlighter.class @@ -11,8 +11,10 @@ Static Private $sWordRegExp As String Static Private $cRegExp As New Collection Private $sText As String +Private $iLen As Integer Private $iPos As Integer Private $bEof As Boolean +Private $bTextAfter As Boolean Private $bMatchLimit As Boolean Private $sTextLimit As String @@ -22,24 +24,33 @@ Private $aHighlight As Byte[] Private Sub Init(sText As String) $sText = sText + $iLen = String.Len($sText) $iPos = 1 $bEof = False $aHighlight = New Byte[] + $bTextAfter = False If Not $hWordRegExp Then - $sWordRegExp = "[A-Za-z][A-Za-z0-9]*" + $sWordRegExp = "[A-Za-z_][A-Za-z0-9_]*" $hWordRegExp = New RegExp $hWordRegExp.Compile("^" & $sWordRegExp & "(.*)") Endif End +Private Sub Imbricate(iType As Byte) + + $aHighlight.Add(iType) + $aHighlight.Add(0) + +End + Private Sub Forward(iState As Byte, Optional N As Integer = 1) If $bEof Then Error.Raise("End of file") TextHighlighter._Add($aHighlight, iState, N) $iPos += N - $bEof = $iPos > Len($sText) + $bEof = $iPos > $iLen End @@ -48,10 +59,10 @@ Private Sub IgnoreSpaces() As Boolean Dim P As Integer P = $iPos - If Not IsSpace(Mid$($sText, P, 1)) Then Return $bEof + If Not IsSpace(String.Mid$($sText, P, 1)) Then Return $bEof Inc P - While IsSpace(Mid$($sText, P, 1)) + While IsSpace(String.Mid$($sText, P, 1)) If $bEof Then Break Inc P Wend @@ -64,9 +75,9 @@ End Private Sub GetWord() As String If $bEof Then Return - $hWordRegExp.Exec(Mid$($sText, $iPos)) + $hWordRegExp.Exec(String.Mid$($sText, $iPos)) If $hWordRegExp.Count < 1 Then Return - Return Mid$($sText, $iPos, $hWordRegExp[1].Offset) + Return Left(String.Mid$($sText, $iPos), $hWordRegExp[1].Offset) End @@ -83,10 +94,14 @@ Private Sub Match(sPattern As String) As String $cRegExp[sPattern] = hRegExp Endif - If $iPos > Len($sText) Then Return - hRegExp.Exec(Mid$($sText, $iPos)) + If $iPos > $iLen Then Return + hRegExp.Exec(String.Mid$($sText, $iPos)) If hRegExp.Count < 1 Then Return - Return Mid$($sText, $iPos, hRegExp[hRegExp.Count].Offset) + Return Left(String.Mid$($sText, $iPos), hRegExp[hRegExp.Count].Offset) + +Catch + + Stop End @@ -95,6 +110,9 @@ Private Sub Include(iHighlight As Byte, sHighlight As String, bMatch As Boolean, Dim iSave As Byte Dim aHighlight As Byte[] Dim nState As Integer + Dim hHighlight As TextHighlighter + Dim iLenAfter As Integer + Dim iPosBefore As Integer 'Stop @@ -109,9 +127,23 @@ Private Sub Include(iHighlight As Byte, sHighlight As String, bMatch As Boolean, $aHighlight.Add(0) Endif - aHighlight = TextHighlighter._Create(sHighlight)._Analyze($sText, aState, bMatch, sLimit, ByRef $iPos) + hHighlight = TextHighlighter._Create(sHighlight) + hHighlight.TextAfter = "" + iPosBefore = $iPos + + aHighlight = hHighlight._Analyze($sText, aState, bMatch, sLimit, ByRef $iPos) + $aHighlight.Insert(aHighlight) - $bEof = $iPos > Len($sText) + + If TextHighlighter.CanRewrite Then + iLenAfter = String.Len(hHighlight.TextAfter) + $sText = String.Left($sText, iPosBefore - 1) & hHighlight.TextAfter & String.Mid$($sText, $iPos + hHighlight.TextLengthBefore - iLenAfter) + Me.TextAfter = $sText + Me.TextLengthBefore = $iLen + $iLen = String.Len($sText) + Endif + + $bEof = $iPos > $iLen aState.Add(iSave, 0) @@ -120,6 +152,7 @@ Private Sub Include(iHighlight As Byte, sHighlight As String, bMatch As Boolean, ' We left the imbricated state $aHighlight.Add(0) $aHighlight.Add(0) + aState.Pop() End @@ -129,6 +162,7 @@ Public Sub _Analyze(Text As String, State As Byte[], Optional MatchLimit As Bool If iPos Then $iPos = iPos $bMatchLimit = MatchLimit $sTextLimit = Limit + Try Compile(State) If Error And If Not $bEof Then Error Error.Where; ": "; Error.Text @@ -137,6 +171,14 @@ Public Sub _Analyze(Text As String, State As Byte[], Optional MatchLimit As Bool If $sTextLimit Then iPos = $iPos + If TextHighlighter.CanRewrite Then + If $sTextLimit Then + Me.TextAfter = String.Left(Me.TextAfter, iPos) + Else + Me.TextAfter = $sText + Endif + Endif + Return $aHighlight End diff --git a/comp/src/gb.highlight/highlight/c.highlight b/comp/src/gb.highlight/highlight/c.highlight new file mode 100644 index 000000000..16d88fa56 --- /dev/null +++ b/comp/src/gb.highlight/highlight/c.highlight @@ -0,0 +1,32 @@ +documentation: + from /** to */ +comment: + from /* to */ + #match #if\s0 to \*/ + from // +preprocessor: + match # to \n + preprocessor.escape{Preprocessor}: + match \\\n +string: + from " to " + from ' to ' + escape: + match \\[fnrtv0'"\\] + match \\c[A-Za-z] + match \\x[0-9a-fA-F]{2} + match \\u[0-9a-fA-F]{4} + match \\u{[0-9a-fA-F]+} +number: + match [+-]?[0-9]*(\.[0-9]+)?([Ee][+-]?[0-9]+)? + match 0x[0-9a-fA-F]* +keyword: + word asm auto break case const continue default do else enum extern for goto if inline register return sizeof static struct switch typedef union volatile while +constant: + keyword FALSE NULL TRUE +datatype: + keyword void signed unsigned char short int long float double int64_t uint64_t int32_t uint32_t int16_t uint16_t int8_t uint8_t uchar ushort uint ulong intptr_t uintptr_t wchar_t +operator: + symbol { } . >= + << ! = >>= ; == - >> ~ += ( , != * && -= &= ) < % & || *= |= [ > ++ | ? %= ^= -- ^ : <<= ] <= / /= +identifier: + match [A-Za-z_$][A-Za-z_$0-9]* \ No newline at end of file diff --git a/comp/src/gb.highlight/highlight/cplusplus.highlight b/comp/src/gb.highlight/highlight/cplusplus.highlight new file mode 100644 index 000000000..17bb21566 --- /dev/null +++ b/comp/src/gb.highlight/highlight/cplusplus.highlight @@ -0,0 +1,37 @@ +documentation: + from /** to */ +comment: + from /* to */ + from // +preprocessor: + match # to \n + preprocessor.escape{Preprocessor}: + match \\\n +string: + from " to " + from ' to ' + escape: + match \\[fnrtv0'"\\] + match \\c[A-Za-z] + match \\x[0-9a-fA-F]{2} + match \\u[0-9a-fA-F]{4} + match \\u{[0-9a-fA-F]+} +number: + match [+-]?[0-9]+(\.[0-9]+)?([Ee][+-]?[0-9]+)? + match 0x[0-9a-fA-F]+ +casting{Datatype}: + match [a-z]*?_cast[<].*?[>] +keyword: + word alignof asm auto break case catch class const continue default delete do else enum explicit export extern for friend goto if inline mutable namespace new noexcept operator private protected public register return sizeof static struct switch template this throw try typedef typeid typename union using virtual volatile while +constant: + keyword false null true FALSE NULL TRUE +datatype: + keyword void signed unsigned char short int long float double int64_t uint64_t int32_t uint32_t int16_t uint16_t int8_t uint8_t uchar ushort uint ulong intptr_t uintptr_t wchar_t +operator.mul{Function}: + match \*\s +operator: + symbol { } . ; ( , ) [ :: ] -> ? : <=> ->* .* * +operator.action{Function}: + symbol = >= + << ! >>= == - >> ~ += != && -= &= < % & || *= |= > ++ | %= ^= -- ^ <<= <= / /= +identifier: + match [A-Za-z_$][A-Za-z_$0-9]* \ No newline at end of file diff --git a/comp/src/gb.highlight/highlight/css.highlight b/comp/src/gb.highlight/highlight/css.highlight index 6260f9c3f..379cc8f78 100644 --- a/comp/src/gb.highlight/highlight/css.highlight +++ b/comp/src/gb.highlight/highlight/css.highlight @@ -16,6 +16,8 @@ documentation: from /** to */ comment: from /* to */ +atrule{Preprocessor}: + match @$(IDENT) class{Datatype}: match \.$(IDENT) pseudoclass{Preprocessor}: diff --git a/comp/src/gb.highlight/highlight/html.highlight b/comp/src/gb.highlight/highlight/html.highlight index 69f36932a..7217cdedb 100644 --- a/comp/src/gb.highlight/highlight/html.highlight +++ b/comp/src/gb.highlight/highlight/html.highlight @@ -3,14 +3,14 @@ doctype{Preprocessor}: from comment: from -entity{Operator}: +entity{Function}: match &[A-Za-z]+; match &#[0-9]+; -javascript{Function}: - match to include javascript -css{Function}: - match to include css -markup{Function}: +javascript{Keyword}: + match to with javascript +css{Keyword}: + match to with css +markup{Keyword}: match <$(IDENT) to /?> attribute{Datatype}: match $(IDENT) @@ -24,5 +24,5 @@ markup{Function}: match &#[0-9]+; value.unquoted{String}: match [^"'`=<>\s]+ -markup.close{Function}: +markup.close{Keyword}: match diff --git a/comp/src/gb.highlight/highlight/javascript.highlight b/comp/src/gb.highlight/highlight/javascript.highlight index 596491ece..5a1fae410 100644 --- a/comp/src/gb.highlight/highlight/javascript.highlight +++ b/comp/src/gb.highlight/highlight/javascript.highlight @@ -21,13 +21,13 @@ string.subst{String}: match \\u[0-9a-fA-F]{4} match \\u{[0-9a-fA-F]+} subst{Escape}: - from ${ to } include javascript + from ${ to } with javascript regexp{Datatype}: match /.*?/[a-z]* regexp.escape{Escape}: match \\. number: - match [+-]?[0-9.]+ + match [+-]?[0-9.]+([Ee][+-]?[0-9]+)? match 0x[0-9a-fA-F]* keyword: keyword @javascript.keyword diff --git a/comp/src/gb.highlight/highlight/webpage.highlight b/comp/src/gb.highlight/highlight/webpage.highlight new file mode 100644 index 000000000..166d5fbd0 --- /dev/null +++ b/comp/src/gb.highlight/highlight/webpage.highlight @@ -0,0 +1,31 @@ +$(IDENT)=[a-zA-Z0-9-]+ +doctype{Preprocessor}: + from +comment: + from +@include webpage.include +entity{Function}: + match &[A-Za-z]+; + match &#[0-9]+; +javascript{Keyword}: + match to with webpage_javascript +css{Keyword}: + match to with webpage_css +markup{Keyword}: + match <$(IDENT) to /?> + @include webpage.include + attribute{Datatype}: + match $(IDENT) + equal{Normal}: + symbol = + value{String}: + from " to " + from ' to ' + string.entity{Escape}: + match &[A-Za-z]+; + match &#[0-9]+; + @include webpage.include + value.unquoted{String}: + match [^"'`=<>\s]+ +markup.close{Keyword}: + match diff --git a/comp/src/gb.highlight/highlight/webpage.include b/comp/src/gb.highlight/highlight/webpage.include new file mode 100644 index 000000000..c6519fa63 --- /dev/null +++ b/comp/src/gb.highlight/highlight/webpage.include @@ -0,0 +1,6 @@ +webpage{Preprocessor}: + from << to >> +code{Preprocessor}: + from <% to %> with gambas +code.equal{Preprocessor}: + from <%= to %> with gambas diff --git a/comp/src/gb.highlight/highlight/webpage_css.highlight b/comp/src/gb.highlight/highlight/webpage_css.highlight new file mode 100644 index 000000000..1c6574c70 --- /dev/null +++ b/comp/src/gb.highlight/highlight/webpage_css.highlight @@ -0,0 +1,65 @@ +#num [+-]?([0-9]+|[0-9]*\.[0-9]+)(e[+-]?[0-9]+)? +#string {string1}|{string2} +#string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\" +#string2 \'([^\n\r\f\\']|\\{nl}|{escape})*\' + +$(UNICODE)=\\[0-9a-fA-F]{1,6}(\r\n|[ \n\r\t\f])? +$(ESCAPE)=$(UNICODE)|\\[^\n\r\f0-9a-f] +$(NONASCII)=[^\0-\177] +$(NMSTART)=([_a-zA-Z]|$(NONASCII)|$(ESCAPE)) +$(NMCHAR)=([_a-zA-Z0-9-]|$(NONASCII)|$(ESCAPE)) +$(NAME)=$(NMCHAR)+ +$(IDENT)=[-]?$(NMSTART)$(NMCHAR)* +$(NUMBER)=[+-]?([0-9]+|[0-9]*\.[0-9]+)([eE][+-]?[0-9]+)? + +documentation: + from /** to */ +comment: + from /* to */ +@include webpage.include +atrule{Preprocessor}: + match @$(IDENT) +class{Datatype}: + match \.$(IDENT) +pseudoclass{Preprocessor}: + match ::?$(IDENT) +id{Function}: + match #$(IDENT) +attribute{Keyword}: + match $(IDENT) +type{Keyword}: + from [ to ] + string{Normal}: + from ' to ' +operator: + symbol > , + +block{Operator}: + from { to } + block.documentation{Documentation}: + from /** to */ + block.comment{Comment}: + from /* to */ + @include webpage.include + identifier{Normal}: + match $(IDENT) + property{Operator}: + from : to ; + @include webpage.include + important{Escape}: + match !important + identifier{Keyword}: + match $(IDENT) + symbol % + number: + match $(NUMBER) + string: + from " to " + from ' to ' + string.escape{Escape}: + match $(ESCAPE) + @include webpage.include + color{Constant}: + match #[0-9A-Fa-f]{6} + match #[0-9A-Fa-f]{3} + operator: + symbol ( ) , diff --git a/comp/src/gb.highlight/highlight/webpage_javascript.highlight b/comp/src/gb.highlight/highlight/webpage_javascript.highlight new file mode 100644 index 000000000..f22afac4b --- /dev/null +++ b/comp/src/gb.highlight/highlight/webpage_javascript.highlight @@ -0,0 +1,44 @@ +documentation: + from /** to */ +comment: + from /* to */ + from // +@include webpage.include +string: + from " to " + from ' to ' + escape: + match \\[fnrtv0'"\\] + match \\c[A-Za-z] + match \\x[0-9a-fA-F]{2} + match \\u[0-9a-fA-F]{4} + match \\u{[0-9a-fA-F]+} + @include webpage.include +string.subst{String}: + from ` to ` + escape: + match \\[fnrtv0'"\\] + match \\c[A-Za-z] + match \\x[0-9a-fA-F]{2} + match \\u[0-9a-fA-F]{4} + match \\u{[0-9a-fA-F]+} + subst{Escape}: + from ${ to } with webage_javascript + @include webpage.include +regexp{Datatype}: + match /.*?/[a-z]* + regexp.escape{Escape}: + match \\. +number: + match [+-]?[0-9.]+ + match 0x[0-9a-fA-F]* +keyword: + keyword @javascript.keyword +function: + keyword function +constant: + keyword false null this true undefined NaN Infinity +operator: + symbol { } . >= + << ! = >>= ; == - >> ~ += >>>= ( , != * >>> && -= &= ) < === % & || *= |= [ > !== ++ | ? %= ^= -- ^ : <<= ] <= / /= +identifier: + match [A-Za-z_$][A-Za-z_$0-9]* \ No newline at end of file