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.
This commit is contained in:
parent
75ae8bee70
commit
d85498e2ad
18 changed files with 459 additions and 87 deletions
|
@ -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")
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = "<b>" & sHtml & "</b>"
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
32
comp/src/gb.highlight/highlight/c.highlight
Normal file
32
comp/src/gb.highlight/highlight/c.highlight
Normal file
|
@ -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]*
|
37
comp/src/gb.highlight/highlight/cplusplus.highlight
Normal file
37
comp/src/gb.highlight/highlight/cplusplus.highlight
Normal file
|
@ -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]*
|
|
@ -16,6 +16,8 @@ documentation:
|
|||
from /** to */
|
||||
comment:
|
||||
from /* to */
|
||||
atrule{Preprocessor}:
|
||||
match @$(IDENT)
|
||||
class{Datatype}:
|
||||
match \.$(IDENT)
|
||||
pseudoclass{Preprocessor}:
|
||||
|
|
|
@ -3,14 +3,14 @@ doctype{Preprocessor}:
|
|||
from <!DOCTYPE to >
|
||||
comment:
|
||||
from <!-- to -->
|
||||
entity{Operator}:
|
||||
entity{Function}:
|
||||
match &[A-Za-z]+;
|
||||
match &#[0-9]+;
|
||||
javascript{Function}:
|
||||
match <script(\stype=["']text/javascript['"])?> to </script> include javascript
|
||||
css{Function}:
|
||||
match <style(\stype=["']text/css['"])?> to </style> include css
|
||||
markup{Function}:
|
||||
javascript{Keyword}:
|
||||
match <script.*(type=["']text/javascript['"])?.*> to </script> with javascript
|
||||
css{Keyword}:
|
||||
match <style.*(type=["']text/css['"])?.*> to </style> 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 </$(IDENT)\s*>
|
||||
|
|
|
@ -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
|
||||
|
|
31
comp/src/gb.highlight/highlight/webpage.highlight
Normal file
31
comp/src/gb.highlight/highlight/webpage.highlight
Normal file
|
@ -0,0 +1,31 @@
|
|||
$(IDENT)=[a-zA-Z0-9-]+
|
||||
doctype{Preprocessor}:
|
||||
from <!DOCTYPE to >
|
||||
comment:
|
||||
from <!-- to -->
|
||||
@include webpage.include
|
||||
entity{Function}:
|
||||
match &[A-Za-z]+;
|
||||
match &#[0-9]+;
|
||||
javascript{Keyword}:
|
||||
match <script.*(type=["']text/javascript['"])?.*> to </script> with webpage_javascript
|
||||
css{Keyword}:
|
||||
match <style.*(type=["']text/css['"])?.*> to </style> 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 </$(IDENT)\s*>
|
6
comp/src/gb.highlight/highlight/webpage.include
Normal file
6
comp/src/gb.highlight/highlight/webpage.include
Normal file
|
@ -0,0 +1,6 @@
|
|||
webpage{Preprocessor}:
|
||||
from << to >>
|
||||
code{Preprocessor}:
|
||||
from <% to %> with gambas
|
||||
code.equal{Preprocessor}:
|
||||
from <%= to %> with gambas
|
65
comp/src/gb.highlight/highlight/webpage_css.highlight
Normal file
65
comp/src/gb.highlight/highlight/webpage_css.highlight
Normal file
|
@ -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 ( ) ,
|
44
comp/src/gb.highlight/highlight/webpage_javascript.highlight
Normal file
44
comp/src/gb.highlight/highlight/webpage_javascript.highlight
Normal file
|
@ -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]*
|
Loading…
Reference in a new issue