Mini Kabibi Habibi

Current Path : C:/Users/Public/Documents/DXperience 13.1 Demos/ASP.NET/VB/ChartsWebDemo/App_Code/
Upload File :
Current File : C:/Users/Public/Documents/DXperience 13.1 Demos/ASP.NET/VB/ChartsWebDemo/App_Code/CodeFormatter.vb

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports DevExpress.CodeParser
Imports DevExpress.CodeParser.CSharp
Imports DevExpress.CodeParser.Html
Imports DevExpress.CodeParser.VB
Imports DevExpress.CodeParser.JavaScript
Imports DevExpress.CodeParser.Xml
Imports DevExpress.CodeParser.Css
Imports System.Text

Namespace DevExpress.Web.Demos
	Public NotInheritable Class CodeFormatter
		Private Shared _cssClasses As New Dictionary(Of TokenCategory, TokenCategoryClassProvider)()

		Private Sub New()
		End Sub
		Shared Sub New()
			CssClasses.Add(TokenCategory.Text, New TokenCategoryClassProvider("cr-text", New KeyValuePair(Of TokenLanguage, String)(TokenLanguage.Html, "cr-text-html")))
			CssClasses.Add(TokenCategory.Keyword, New TokenCategoryClassProvider("cr-keyword", New KeyValuePair(Of TokenLanguage, String)(TokenLanguage.Html, "cr-keyword-html"), New KeyValuePair(Of TokenLanguage, String)(TokenLanguage.Css, "cr-keyword-css")))
			CssClasses.Add(TokenCategory.Operator, New TokenCategoryClassProvider("cr-operator"))
			CssClasses.Add(TokenCategory.PreprocessorKeyword, New TokenCategoryClassProvider("cr-preproc", New KeyValuePair(Of TokenLanguage, String)(TokenLanguage.Html, "cr-preproc-html")))
			CssClasses.Add(TokenCategory.String, New TokenCategoryClassProvider("cr-string", New KeyValuePair(Of TokenLanguage, String)(TokenLanguage.Html, "cr-string-html"), New KeyValuePair(Of TokenLanguage, String)(TokenLanguage.Css, "cr-string-css")))
			CssClasses.Add(TokenCategory.Number, New TokenCategoryClassProvider("cr-number"))
			CssClasses.Add(TokenCategory.Identifier, New TokenCategoryClassProvider("cr-identifier"))
			CssClasses.Add(TokenCategory.HtmlServerSideScript, New TokenCategoryClassProvider("cr-htmlserverscript"))
			CssClasses.Add(TokenCategory.HtmlString, New TokenCategoryClassProvider("cr-htmlstring"))
			CssClasses.Add(TokenCategory.Unknown, New TokenCategoryClassProvider("cr-unknown"))
			CssClasses.Add(TokenCategory.Comment, New TokenCategoryClassProvider("cr-comment"))
			CssClasses.Add(TokenCategory.XmlComment, New TokenCategoryClassProvider("cr-xmlcomment"))
			CssClasses.Add(TokenCategory.CssComment, New TokenCategoryClassProvider("cr-csscomment"))
			CssClasses.Add(TokenCategory.CssKeyword, New TokenCategoryClassProvider("cr-csskeyword"))
			CssClasses.Add(TokenCategory.CssPropertyName, New TokenCategoryClassProvider("cr-csspropertyname"))
			CssClasses.Add(TokenCategory.CssPropertyValue, New TokenCategoryClassProvider("cr-csspropertyvalue"))
			CssClasses.Add(TokenCategory.CssSelector, New TokenCategoryClassProvider("cr-cssselector"))
			CssClasses.Add(TokenCategory.CssStringValue, New TokenCategoryClassProvider("cr-cssstringvalue"))
			CssClasses.Add(TokenCategory.HtmlElementName, New TokenCategoryClassProvider("cr-htmlelementname"))
			CssClasses.Add(TokenCategory.HtmlEntity, New TokenCategoryClassProvider("cr-htmlentity"))
			CssClasses.Add(TokenCategory.HtmlOperator, New TokenCategoryClassProvider("cr-htmloperator"))
			CssClasses.Add(TokenCategory.HtmlComment, New TokenCategoryClassProvider("cr-htmlcomment"))
			CssClasses.Add(TokenCategory.HtmlAttributeName, New TokenCategoryClassProvider("cr-htmlattributename"))
			CssClasses.Add(TokenCategory.HtmlAttributeValue, New TokenCategoryClassProvider("cr-htmlattributevalue"))
			CssClasses.Add(TokenCategory.HtmlTagDelimiter, New TokenCategoryClassProvider("cr-htmltagdelimiter"))
		End Sub

		Public Shared ReadOnly Property CssClasses() As Dictionary(Of TokenCategory, TokenCategoryClassProvider)
			Get
				Return _cssClasses
			End Get
		End Property

		Public Shared Function ParseLanguage(ByVal lang As String) As TokenLanguage
			Return CType(System.Enum.Parse(GetType(TokenLanguage), lang, True), TokenLanguage)
		End Function

		Public Shared Function GetLanguageByFileExtension(ByVal extension As String) As TokenLanguage
			Select Case extension.ToLower()
				Case ".cs"
					Return TokenLanguage.CSharp
				Case ".vb"
					Return TokenLanguage.Basic
				Case ".html", ".htm", ".aspx", ".ascx", ".master", ".cshtml"
					Return TokenLanguage.Html
				Case ".js"
					Return TokenLanguage.JavaScript
				Case ".xml"
					Return TokenLanguage.Xml
				Case ".css"
					Return TokenLanguage.Css
				Case Else
					Return TokenLanguage.Unknown
			End Select
		End Function

		Public Shared Function GetFormattedCode(ByVal fileExtension As String, ByVal code As String) As String
			Return GetFormattedCode(GetLanguageByFileExtension(fileExtension), code, False, False)
		End Function
		Public Shared Function GetFormattedCode(ByVal fileExtension As String, ByVal code As String, ByVal isMvc As Boolean, ByVal isRazor As Boolean) As String
			Return GetFormattedCode(GetLanguageByFileExtension(fileExtension), code, isMvc, isRazor)
		End Function
		Public Shared Function GetFormattedCode(ByVal language As TokenLanguage, ByVal code As String) As String
			Return GetFormattedCode(language, code, False, False)
		End Function
		Public Shared Function GetFormattedCode(ByVal language As TokenLanguage, ByVal code As String, ByVal isMvc As Boolean, ByVal isRazor As Boolean) As String
			Dim tokens As TokenCollection = GetTokens(language, code, isMvc, isRazor)
			If tokens IsNot Nothing Then
				Return GetFormattedCode(code, tokens)
			End If
			Return String.Empty
		End Function

		Private Class CodeLine
			Public Indent As Integer
			Public Html As String = ""

			Public ReadOnly Property IsEmpty() As Boolean
				Get
					Return Html.Trim().Length < 1
				End Get
			End Property
		End Class

		Private Shared Function GetFormattedCode(ByVal code As String, ByVal tokens As TokenCollection) As String
			Dim currentLine As New CodeLine()
			Dim lines As New List(Of CodeLine)()
			Dim pos As Integer = 0
			For Each token As CategorizedToken In tokens
				AppendCode(lines, currentLine, code.Substring(pos, token.StartPosition - pos), Nothing)
				AppendCode(lines, currentLine, token.Value, CssClasses(token.Category).GetClassName(token.Language))
				pos = token.EndPosition
			Next token
			AppendCode(lines, currentLine, code.Substring(pos), Nothing)
			lines.Add(currentLine)
			Return MergeCodeLines(lines)
		End Function
		Private Shared Sub AppendCode(ByVal lines As List(Of CodeLine), ByRef currentLine As CodeLine, ByVal code As String, ByVal cssClass As String)
			Dim hasCss As Boolean = Not String.IsNullOrEmpty(cssClass)
			Dim first As Boolean = True
			code = code.Replace(Constants.vbCr, "").Replace(Constants.vbTab, "    ")
			For Each line As String In code.Split(ControlChars.Lf)
				Dim text As String = line
				If (Not first) Then
					lines.Add(currentLine)
					currentLine = New CodeLine()
					text = text.TrimStart()
					currentLine.Indent = line.Length - text.Length
				End If
				If first OrElse text.Trim().Length > 0 Then
					If hasCss Then
						currentLine.Html &= String.Format("<span class=""{0}"">", cssClass)
					End If
					currentLine.Html &= HttpUtility.HtmlEncode(text)
					If hasCss Then
						currentLine.Html &= "</span>"
					End If
				End If
				first = False
			Next line
		End Sub
		Private Shared Function MergeCodeLines(ByVal lines As List(Of CodeLine)) As String
			Dim minIndent As Integer = Integer.MaxValue
			For Each line As CodeLine In lines
				If line.IsEmpty Then
					Continue For
				End If
				If line.Indent < minIndent Then
					minIndent = line.Indent
				End If
			Next line

			Dim result As New StringBuilder()
			Dim emptyLineCount As Integer = 0

			For Each line As CodeLine In lines
				If line.IsEmpty Then
					If result.Length > 0 Then
						emptyLineCount += 1
					End If
					Continue For
				End If
				If emptyLineCount > 0 Then
					Dim i As Integer = 0
					Do While i < emptyLineCount
						result.Append("<br />")
						i += 1
					Loop
					emptyLineCount = 0
				End If
				Dim indent As Integer = line.Indent - minIndent
				For i As Integer = 0 To indent - 1
					result.Append("&nbsp;")
				Next i
				result.Append(line.Html)
				If result.Length > 0 Then
					result.Append("<br />")
				End If
			Next line

			Return result.ToString().Trim()
		End Function

		Private Shared Function GetTokens(ByVal language As TokenLanguage, ByVal code As String, ByVal isMvc As Boolean, ByVal isRazor As Boolean) As TokenCollection
			Select Case language
				Case TokenLanguage.CSharp
					Return CSharpTokensHelper.GetTokens(code)
				Case TokenLanguage.Basic
					Return VBTokensHelper.GetTokens(code)
				Case TokenLanguage.JavaScript
					Return JavaScriptTokensHelper.GetTokens(code)
				Case TokenLanguage.Html
					If (Not isMvc) Then
						Return HtmlTokensHelper.GetTokens(code)
					Else
						If isRazor Then
							Return HtmlTokensHelper.GetTokens(code,LanguageKind.Razor, DotNetLanguageType.CSharp)
						Else
							Return HtmlTokensHelper.GetTokens(code,LanguageKind.Html, DotNetLanguageType.CSharp)
						End If
					End If
				Case TokenLanguage.Xml
					Return New XmlTokensCategoryHelper().GetTokens(code)
				Case TokenLanguage.Css
					Return New CssTokensCategoryHelper().GetTokens(code)
				Case Else
					Return Nothing
			End Select
		End Function
	End Class
	Public Class TokenCategoryClassProvider
		Private className As String
		Private languagesClassNames As New Dictionary(Of TokenLanguage, String)()

		Public Sub New(ByVal className As String)
			Me.New(className, Nothing)
		End Sub
		Public Sub New(ByVal className As String, ParamArray ByVal languagesClassNames() As KeyValuePair(Of TokenLanguage, String))
			Me.className = className
			If languagesClassNames IsNot Nothing Then
				For Each languageClassName As KeyValuePair(Of TokenLanguage, String) In languagesClassNames
					Me.languagesClassNames(languageClassName.Key) = languageClassName.Value
				Next languageClassName
			End If
		End Sub
		Public Function GetClassName(ByVal language As TokenLanguage) As String
			If Me.languagesClassNames.ContainsKey(language) Then
				Return Me.languagesClassNames(language)
			End If
			Return Me.className
		End Function
	End Class
End Namespace