1 #region Copyright © 2001-2003 Jean-Claude Manoli [jc@manoli.net]
3 * This software is provided 'as-is', without any express or implied warranty.
4 * In no event will the author(s) be held liable for any damages arising from
5 * the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not
17 * be misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
26 using System
.Text
.RegularExpressions
;
28 namespace Manoli
.Utils
.CSharpFormat
31 /// Provides a base class for formatting most programming languages.
33 public abstract class CodeFormat
: SourceFormat
36 /// Must be overridden to provide a list of keywords defined in
40 /// Keywords must be separated with spaces.
42 protected abstract string Keywords
48 /// Can be overridden to provide a list of preprocessors defined in
52 /// Preprocessors must be separated with spaces.
54 protected virtual string Preprocessors
60 /// Must be overridden to provide a regular expression string
61 /// to match strings literals.
63 protected abstract string StringRegEx
69 /// Must be overridden to provide a regular expression string
70 /// to match comments.
72 protected abstract string CommentRegEx
78 /// Determines if the language is case sensitive.
80 /// <value><b>true</b> if the language is case sensitive, <b>false</b>
81 /// otherwise. The default is true.</value>
83 /// A case-insensitive language formatter must override this
84 /// property to return false.
86 public virtual bool CaseSensitive
92 protected CodeFormat()
94 //generate the keyword and preprocessor regexes from the keyword lists
96 r
= new Regex(@"\w+|-\w+|#\w+|@@\w+|#(?:\\(?:s|w)(?:\*|\+)?\w+)+|@\\w\*+");
97 string regKeyword
= r
.Replace(Keywords
, @"(?<=^|\W)$0(?=\W)");
98 string regPreproc
= r
.Replace(Preprocessors
, @"(?<=^|\s)$0(?=\s|$)");
100 regKeyword
= r
.Replace(regKeyword
, @"|");
101 regPreproc
= r
.Replace(regPreproc
, @"|");
103 if (regPreproc
.Length
== 0)
105 regPreproc
= "(?!.*)_{37}(?<!.*)"; //use something quite impossible...
108 //build a master regex with capturing groups
109 StringBuilder regAll
= new StringBuilder();
111 regAll
.Append(CommentRegEx
);
112 regAll
.Append(")|(");
113 regAll
.Append(StringRegEx
);
114 if (regPreproc
.Length
> 0)
116 regAll
.Append(")|(");
117 regAll
.Append(regPreproc
);
119 regAll
.Append(")|(");
120 regAll
.Append(regKeyword
);
123 RegexOptions caseInsensitive
= CaseSensitive
? 0 : RegexOptions
.IgnoreCase
;
124 CodeRegex
= new Regex(regAll
.ToString(), RegexOptions
.Singleline
| caseInsensitive
);
128 /// Called to evaluate the HTML fragment corresponding to each
129 /// matching token in the code.
131 /// <param name="match">The <see cref="Match"/> resulting from a
132 /// single regular expression match.</param>
133 /// <returns>A string containing the HTML code fragment.</returns>
134 protected override string MatchEval(Match match
)
136 if(match
.Groups
[1].Success
) //comment
138 StringReader reader
= new StringReader(match
.ToString());
140 StringBuilder sb
= new StringBuilder();
141 while ((line
= reader
.ReadLine()) != null)
147 sb
.Append("<span class=\"rem\">");
149 sb
.Append("</span>");
151 return sb
.ToString();
153 if(match
.Groups
[2].Success
) //string literal
155 return "<span class=\"str\">" + match
.ToString() + "</span>";
157 if(match
.Groups
[3].Success
) //preprocessor keyword
159 return "<span class=\"preproc\">" + match
.ToString() + "</span>";
161 if(match
.Groups
[4].Success
) //keyword
163 return "<span class=\"kwrd\">" + match
.ToString() + "</span>";
165 //System.Diagnostics.Debug.Assert(false, "None of the above!");
166 return ""; //none of the above