155 lines
5.5 KiB
C#
155 lines
5.5 KiB
C#
#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.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Nop.Services.Html.CodeFormatter;
|
|
|
|
/// <summary>
|
|
/// Generates color-coded HTML 4.01 from HTML/XML/ASPX source code.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// This implementation assumes that code inside <script> blocks
|
|
/// is JavaScript, and code inside <% %> blocks is C#.</para>
|
|
/// <para>
|
|
/// The default tab width is set to 2 characters in this class.</para>
|
|
/// </remarks>
|
|
public partial class HtmlFormat : SourceFormat
|
|
{
|
|
protected readonly CSharpFormat _csf; //to format embedded C# code
|
|
protected readonly JavaScriptFormat _jsf; //to format client-side JavaScript code
|
|
protected readonly Regex _attributeRegex;
|
|
|
|
/// <summary/>
|
|
public HtmlFormat()
|
|
{
|
|
const string regJavaScript = @"(?<=<script(?:\s.*?)?>).+?(?=</script>)";
|
|
const string regComment = @"<!--.*?-->";
|
|
const string regAspTag = @"<%@.*?%>|<%|%>";
|
|
const string regAspCode = @"(?<=<%).*?(?=%>)";
|
|
const string regTagDelimiter = @"(?:</?!?\??(?!%)|(?<!%)/?>)+";
|
|
const string regTagName = @"(?<=</?!?\??(?!%))[\w\.:-]+(?=.*>)";
|
|
const string regAttributes = @"(?<=<(?!%)/?!?\??[\w:-]+).*?(?=(?<!%)/?>)";
|
|
const string regEntity = @"&\w+;";
|
|
const string regAttributeMatch = @"(=?"".*?""|=?'.*?')|([\w:-]+)";
|
|
|
|
//the regex object will handle all the replacements in one pass
|
|
var regAll = "(" + regJavaScript + ")|(" + regComment + ")|("
|
|
+ regAspTag + ")|(" + regAspCode + ")|("
|
|
+ regTagDelimiter + ")|(" + regTagName + ")|("
|
|
+ regAttributes + ")|(" + regEntity + ")";
|
|
|
|
CodeRegex = new Regex(regAll, RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
|
_attributeRegex = new Regex(regAttributeMatch, RegexOptions.Singleline);
|
|
|
|
_csf = new CSharpFormat();
|
|
_jsf = new JavaScriptFormat();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called to evaluate the HTML fragment corresponding to each
|
|
/// attribute's name/value in the code.
|
|
/// </summary>
|
|
/// <param name="match">The <see cref="Match"/> resulting from a
|
|
/// single regular expression match.</param>
|
|
/// <returns>A string containing the HTML code fragment.</returns>
|
|
protected string AttributeMatchEval(Match match)
|
|
{
|
|
if (match.Groups[1].Success) //attribute value
|
|
return "<span class=\"kwrd\">" + match + "</span>";
|
|
|
|
if (match.Groups[2].Success) //attribute name
|
|
return "<span class=\"attr\">" + match + "</span>";
|
|
|
|
return match.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called to evaluate the HTML fragment corresponding to each
|
|
/// matching token in the code.
|
|
/// </summary>
|
|
/// <param name="match">The <see cref="Match"/> resulting from a
|
|
/// single regular expression match.</param>
|
|
/// <returns>A string containing the HTML code fragment.</returns>
|
|
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
|
|
{
|
|
var reader = new StringReader(match.ToString());
|
|
string line;
|
|
var sb = new StringBuilder();
|
|
while ((line = reader.ReadLine()) != null)
|
|
{
|
|
if (sb.Length > 0)
|
|
{
|
|
sb.Append('\n');
|
|
}
|
|
|
|
sb.Append("<span class=\"rem\">");
|
|
sb.Append(line);
|
|
sb.Append("</span>");
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
if (match.Groups[3].Success) //asp tag
|
|
{
|
|
return "<span class=\"asp\">" + match + "</span>";
|
|
}
|
|
|
|
if (match.Groups[4].Success) //asp C# code
|
|
{
|
|
return _csf.FormatSubCode(match.ToString());
|
|
}
|
|
|
|
if (match.Groups[5].Success) //tag delimiter
|
|
{
|
|
return "<span class=\"kwrd\">" + match + "</span>";
|
|
}
|
|
|
|
if (match.Groups[6].Success) //html tagname
|
|
{
|
|
return "<span class=\"html\">" + match + "</span>";
|
|
}
|
|
|
|
if (match.Groups[7].Success) //attributes
|
|
{
|
|
return _attributeRegex.Replace(match.ToString(), AttributeMatchEval);
|
|
}
|
|
|
|
if (match.Groups[8].Success) //entity
|
|
{
|
|
return "<span class=\"attr\">" + match + "</span>";
|
|
}
|
|
|
|
return match.ToString();
|
|
}
|
|
} |