#region Copyright � 2001-2003 Jean-Claude Manoli [jc@manoli.net] /* * This software is provided 'as-is', without any express or implied warranty. * In no event will the author(s) be held liable for any damages arising from * the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. */ #endregion using System; using System.IO; using System.Text; using System.Text.RegularExpressions; namespace CodeFormatter { /// /// Generates color-coded HTML 4.01 from HTML/XML/ASPX source code. /// /// /// /// This implementation assumes that code inside <script> blocks /// is JavaScript, and code inside <% %> blocks is C#. /// /// The default tab width is set to 2 characters in this class. /// public class HtmlFormat : SourceFormat { private CSharpFormat csf; //to format embedded C# code private JavaScriptFormat jsf; //to format client-side JavaScript code private Regex attribRegex; /// public HtmlFormat() { const string regJavaScript = @"(?<=<script(?:\s.*?)?>).+?(?=</script>)"; const string regComment = @"<!--.*?-->"; const string regAspTag = @"<%@.*?%>|<%|%>"; const string regAspCode = @"(?<=<%).*?(?=%>)"; const string regTagDelimiter = @"(?:</?!?\??(?!%)|(? /// Called to evaluate the HTML fragment corresponding to each /// attribute's name/value in the code. /// /// The resulting from a /// single regular expression match. /// A string containing the HTML code fragment. private string AttributeMatchEval(Match match) { if(match.Groups[1].Success) //attribute value return "" + match.ToString() + ""; if(match.Groups[2].Success) //attribute name return "" + match.ToString() + ""; return match.ToString(); } /// /// Called to evaluate the HTML fragment corresponding to each /// matching token in the code. /// /// The resulting from a /// single regular expression match. /// A string containing the HTML code fragment. protected override string MatchEval(Match match) { if(match.Groups[1].Success) //JavaScript code { string s = match.ToString(); return jsf.FormatSubCode(match.ToString()); } if(match.Groups[2].Success) //comment { StringReader reader = new StringReader(match.ToString()); string line; StringBuilder sb = new StringBuilder(); while ((line = reader.ReadLine()) != null) { if(sb.Length > 0) { sb.Append("\n"); } sb.Append(""); sb.Append(line); sb.Append(""); } return sb.ToString(); } if(match.Groups[3].Success) //asp tag { return "" + match.ToString() + ""; } if(match.Groups[4].Success) //asp C# code { return csf.FormatSubCode(match.ToString()); } if(match.Groups[5].Success) //tag delimiter { return "" + match.ToString() + ""; } if(match.Groups[6].Success) //html tagname { return "" + match.ToString() + ""; } if(match.Groups[7].Success) //attributes { return attribRegex.Replace(match.ToString(), new MatchEvaluator(this.AttributeMatchEval)); } if(match.Groups[8].Success) //entity { return "" + match.ToString() + ""; } return match.ToString(); } } }