Mini Kabibi Habibi

Current Path : C:/Users/Public/Documents/DXperience 13.1 Demos/ASP.NET/CS/MVCDemos.Razor/Code/
Upload File :
Current File : C:/Users/Public/Documents/DXperience 13.1 Demos/ASP.NET/CS/MVCDemos.Razor/Code/CodeFormatter.cs

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DevExpress.CodeParser;
using DevExpress.CodeParser.CSharp;
using DevExpress.CodeParser.Html;
using DevExpress.CodeParser.VB;
using DevExpress.CodeParser.JavaScript;
using DevExpress.CodeParser.Xml;
using DevExpress.CodeParser.Css;
using System.Text;

namespace DevExpress.Web.Demos {
    public static class CodeFormatter {
        static Dictionary<TokenCategory, TokenCategoryClassProvider> _cssClasses = new Dictionary<TokenCategory, TokenCategoryClassProvider>();

        static CodeFormatter() {
            CssClasses.Add(TokenCategory.Text, new TokenCategoryClassProvider("cr-text", new KeyValuePair<TokenLanguage, string>(TokenLanguage.Html, "cr-text-html")));
            CssClasses.Add(TokenCategory.Keyword, new TokenCategoryClassProvider("cr-keyword", new KeyValuePair<TokenLanguage, string>(TokenLanguage.Html, "cr-keyword-html"), new KeyValuePair<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<TokenLanguage, string>(TokenLanguage.Html, "cr-preproc-html")));
            CssClasses.Add(TokenCategory.String, new TokenCategoryClassProvider("cr-string", new KeyValuePair<TokenLanguage, string>(TokenLanguage.Html, "cr-string-html"), new KeyValuePair<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"));
        }

        public static Dictionary<TokenCategory, TokenCategoryClassProvider> CssClasses {
            get { return _cssClasses; }
        }

        public static TokenLanguage ParseLanguage(string lang) {
            return (TokenLanguage)Enum.Parse(typeof(TokenLanguage), lang, true);
        }

        public static TokenLanguage GetLanguageByFileExtension(string extension) {
            switch(extension.ToLower()) {
                case ".cs":
                    return TokenLanguage.CSharp;
                case ".vb":
                    return TokenLanguage.Basic;
                case ".html":
                case ".htm":
                case ".aspx":
                case ".ascx":
                case ".master":
                case ".cshtml":
                    return TokenLanguage.Html;
                case ".js":
                    return TokenLanguage.JavaScript;
                case ".xml":
                    return TokenLanguage.Xml;
                case ".css":
                    return TokenLanguage.Css;
                default:
                    return TokenLanguage.Unknown;
            }
        }

        public static string GetFormattedCode(string fileExtension, string code) {
            return GetFormattedCode(GetLanguageByFileExtension(fileExtension), code, false, false);
        }
        public static string GetFormattedCode(string fileExtension, string code, bool isMvc, bool isRazor) {
            return GetFormattedCode(GetLanguageByFileExtension(fileExtension), code, isMvc, isRazor);
        }
        public static string GetFormattedCode(TokenLanguage language, string code) {
            return GetFormattedCode(language, code, false, false);
        }
        public static string GetFormattedCode(TokenLanguage language, string code, bool isMvc, bool isRazor) {
            TokenCollection tokens = GetTokens(language, code, isMvc, isRazor);
            if(tokens != null)
                return GetFormattedCode(code, tokens);
            return string.Empty;
        }

        class CodeLine {
            public int Indent;
            public string Html = "";

            public bool IsEmpty { get { return Html.Trim().Length < 1; } }
        }

        static string GetFormattedCode(string code, TokenCollection tokens) {
            CodeLine currentLine = new CodeLine();
            List<CodeLine> lines = new List<CodeLine>();
            int pos = 0;
            foreach(CategorizedToken token in tokens) {
                AppendCode(lines, ref currentLine, code.Substring(pos, token.StartPosition - pos), null);
                AppendCode(lines, ref currentLine, token.Value, CssClasses[token.Category].GetClassName(token.Language));
                pos = token.EndPosition;
            }
            AppendCode(lines, ref currentLine, code.Substring(pos), null);
            lines.Add(currentLine);
            return MergeCodeLines(lines);
        }
        static void AppendCode(List<CodeLine> lines, ref CodeLine currentLine, string code, string cssClass) {
            bool hasCss = !String.IsNullOrEmpty(cssClass);
            bool first = true;
            code = code.Replace("\r", "").Replace("\t", "    ");
            foreach(string line in code.Split('\n')) {
                string text = line;
                if(!first) {
                    lines.Add(currentLine);
                    currentLine = new CodeLine();
                    text = text.TrimStart();
                    currentLine.Indent = line.Length - text.Length;
                }
                if(first || text.Trim().Length > 0) {
                    if(hasCss)
                        currentLine.Html += String.Format("<span class=\"{0}\">", cssClass);
                    currentLine.Html += HttpUtility.HtmlEncode(text);
                    if(hasCss)
                        currentLine.Html += "</span>";
                }
                first = false;
            }
        }
        static string MergeCodeLines(List<CodeLine> lines) {
            int minIndent = int.MaxValue;
            foreach(CodeLine line in lines) {
                if(line.IsEmpty)
                    continue;
                if(line.Indent < minIndent)
                    minIndent = line.Indent;
            }

            StringBuilder result = new StringBuilder();
            int emptyLineCount = 0;

            foreach(CodeLine line in lines) {
                if(line.IsEmpty) {
                    if(result.Length > 0)
                        emptyLineCount++;
                    continue;
                }
                if(emptyLineCount > 0) {
                    for(int i = 0; i < emptyLineCount; i++)
                        result.Append("<br />");
                    emptyLineCount = 0;
                }
                int indent = line.Indent - minIndent;
                for(int i = 0; i < indent; i++)
                    result.Append("&nbsp;");
                result.Append(line.Html);
                if(result.Length > 0)
                    result.Append("<br />");
            }

            return result.ToString().Trim();
        }

        static TokenCollection GetTokens(TokenLanguage language, string code, bool isMvc, bool isRazor) {
            switch(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(!isMvc)
                        return HtmlTokensHelper.GetTokens(code);
                    else
                        return HtmlTokensHelper.GetTokens(code, isRazor ? LanguageKind.Razor : LanguageKind.Html, DotNetLanguageType.CSharp);
                case TokenLanguage.Xml:
                    return new XmlTokensCategoryHelper().GetTokens(code);
                case TokenLanguage.Css:
                    return new CssTokensCategoryHelper().GetTokens(code);
                default:
                    return null;
            }
        }
    }
    public class TokenCategoryClassProvider {
        string className;
        Dictionary<TokenLanguage, string> languagesClassNames = new Dictionary<TokenLanguage, string>();

        public TokenCategoryClassProvider(string className)
            : this(className, null) {
        }
        public TokenCategoryClassProvider(string className, params KeyValuePair<TokenLanguage, string>[] languagesClassNames) {
            this.className = className;
            if(languagesClassNames != null) {
                foreach(KeyValuePair<TokenLanguage, string> languageClassName in languagesClassNames)
                    this.languagesClassNames[languageClassName.Key] = languageClassName.Value;
            }
        }
        public string GetClassName(TokenLanguage language) {
            if(this.languagesClassNames.ContainsKey(language))
                return this.languagesClassNames[language];
            return this.className;
        }
    }
}