📄 transforms.cs
字号:
//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
// Copyright (c) Telligent Systems Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data.SqlClient;
using System.Web;
using System.IO;
using System.Web.Caching;
using System.Text.RegularExpressions;
using System.Text;
namespace CommunityServer.Components {
/// <summary>
/// This class is used to take the body of a post message and pre-format it to HTML. Two versions
/// of the post body are stored in the database: raw original post and the transformed pre-formatted
/// post. Pre-transforming the post offers better performance.
/// </summary>
public class Transforms {
#region FormatPost
// *********************************************************************
// FormatPost
//
/// <summary>
/// Main public routine called to perform string transforms.
/// </summary>
///
// ********************************************************************/
public static string FormatPostText (string rawPostBody) {
return FormatPostText (rawPostBody, PostType.HTML, true);
}
public static string FormatPostText (string rawPostBody, PostType postType) {
return FormatPostText (rawPostBody, postType, true);
}
public static string FormatPostText (string rawPostBody, PostType postType, bool allowCustomTransforms) {
string formattedPost = rawPostBody;
// because of the way we receive the post from MSHTML, somethings can already be encoded. This breaks the regex patterns
// so we're unencoding anything that is already encoded so regex patterns work correctly. Later we'll encode everything again.
//SCOTTW: Why? Encoded markup should stay encoded...otherwise it will not render
//formattedPost = HttpUtility.HtmlDecode( formattedPost );
if (allowCustomTransforms ) {
// must do emoteicons first because they are restricted from finding any inside [code][/code] blocks. We have to do
// this before the later steps remove the [code][/code] blocks.
if( CSContext.Current.SiteSettings.EnableEmoticons ) {
formattedPost = EmoticonTransforms(formattedPost);
}
}
// convert any html inside code/pre blocks into encoded html
formattedPost = EncodeCodeBlocks( formattedPost );
// strip the html posts of any offending html tags and encode any that don't meet the criteria.
formattedPost = HtmlScrubber.Clean(formattedPost,false,true);// ScrubHtml( formattedPost, postType );
// convert all html tags to bbcode as the bbcode processor will only allow safe attributes to be included in the ponst.
// formattedPost = HtmlToBBCode( formattedPost );
// Remove any script code
//
// formattedPost = Transforms.StripScriptTags(formattedPost);
// Peform specialized transforms first.
//
// Do BBCode transform, if any
//
formattedPost = BBcodeToHtml(formattedPost);
// Perform HTML Encoding of any tag elements, if not PostType.HTML
//
if (postType != PostType.HTML && postType != PostType.Poll) {
formattedPost = HttpUtility.HtmlEncode(formattedPost);
formattedPost = formattedPost.Replace("\n", Globals.HtmlNewLine);
// Fix to reverse certain items that were HtmlEncoded above
//
formattedPost = UnHtmlEncode(formattedPost);
}
return formattedPost;
}
#endregion
#region CensorPost
/// <summary>
/// Validates if the supplied text would pass the censor test
/// </summary>
public static bool IsValidCensorText(string text)
{
return CensorPost(text) == text;
}
public static string CensorPost( string formattedPost ) {
if(Globals.IsNullorEmpty(formattedPost))
return formattedPost;
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Compiled;
ArrayList censors = CommunityServer.Censors.GetCensors();
foreach( Censor censor in censors ) {
string searchPattern;
// if the string contains any regex patterns, then just use the pattern
if( -1 == censor.Word.IndexOfAny( new char[]{'\\', '[', '^', '*', '{', '.', '#', '?', '+', '$', '|' } ) ) {
searchPattern = String.Format(@"\b{0}\b", censor.Word);
}
else {
searchPattern = censor.Word;
}
formattedPost = Regex.Replace(formattedPost, searchPattern, censor.Replacement, options);
}
return formattedPost;
}
#endregion
#region UnHtmlEncode
// *******************************************************************
// UnHtmlEncode
//
/// <summary>
/// If a post has been HtmlEncoded using the Web.HttpUtility, there are
/// a few characters we don't want encoded. This will allow for the
/// bbcode transforms to properly work. So we must "UnHtmlEncode" these
/// items, back to what they originally were.
/// </summary>
/// <param name="formattedPost">string of post</param>
/// <returns>
/// An Un-HtmlEncoded String of select items.
/// </returns>
// *******************************************************************
public static string UnHtmlEncode(string formattedPost) {
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Compiled;
// "
// TODO: edit the regex match to only replace within a set of brackets [].
//
formattedPost = Regex.Replace(formattedPost, """, "\"", options);
return formattedPost;
}
#endregion
#region BBDecode
// *********************************************************************
// BBDecode
//
/// <summary>
/// Transforms a BBCode encoded string in appropriate HTML
/// </summary>
///
// ********************************************************************/
public static string BBcodeToHtml(string encodedString)
{
// TODO move all this formatting to an external style
//
// Used for normal quoting with a "<pic> <username> wrote:" prefix.
//
string quoteStartHtml = "";
string quoteEndHtml = "</td></tr></table></td></tr></table></BLOCKQUOTE>";
//quoteStartHtml = "<BLOCKQUOTE><table width=\"85%\"><tr><td class=\"txt4\"><img src=\"" + Globals.GetSkinPath() +"/images/icon-quote.gif" + "\"> <strong>$1 wrote:</strong></td></tr><tr><td class=\"quoteTable\"><table width=\"100%\"><tr><td width=\"100%\" valign=\"top\" class=\"txt4\">$3</td></tr></table></td></tr></table></BLOCKQUOTE>";
// Used for when a username is not supplied.
//
string emptyquoteStartHtml = "<BLOCKQUOTE><table width=\"85%\"><tr><td class=\"quoteTable\"><table width=\"100%\"><tr><td width=\"100%\" valign=\"top\" class=\"txt4\">";
string emptyquoteEndHtml = "</td></tr></table></td></tr></table></BLOCKQUOTE>";
//string emptyquoteStartHtml = "<BLOCKQUOTE><table width=\"85%\"><tr><td class=\"quoteTable\"><table width=\"100%\"><tr><td width=\"100%\" valign=\"top\" class=\"txt4\">$2</td></tr></table></td></tr></table></BLOCKQUOTE>";
// When using the Importer, we do not have a skin path. We hardcode it here to
// the default path.
//
if (Globals.GetSkinPath() == "")
quoteStartHtml = "<BLOCKQUOTE><table width=\"85%\"><tr><td class=\"txt4\"><img src=\"themes/default/images/icon-quote.gif" + "\"> <strong>$1 wrote:</strong></td></tr><tr><td class=\"quoteTable\"><table width=\"100%\"><tr><td width=\"100%\" valign=\"top\" class=\"txt4\">";
else
quoteStartHtml = "<BLOCKQUOTE><table width=\"85%\"><tr><td class=\"txt4\"><img src=\"" + Globals.GetSkinPath() +"/images/icon-quote.gif" + "\"> <strong>$1 wrote:</strong></td></tr><tr><td class=\"quoteTable\"><table width=\"100%\"><tr><td width=\"100%\" valign=\"top\" class=\"txt4\">";
string quote = quoteStartHtml + "$3" + quoteEndHtml;
string emptyquote = emptyquoteStartHtml + "$2" + emptyquoteEndHtml;
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline;
// Bold, Italic, Underline
//(
encodedString = Regex.Replace(encodedString, @"\[b(?:\s*)\]((.|\n)*?)\[/b(?:\s*)\]", "<b>$1</b>", options);
encodedString = Regex.Replace(encodedString, @"\[i(?:\s*)\]((.|\n)*?)\[/i(?:\s*)\]", "<i>$1</i>", options);
encodedString = Regex.Replace(encodedString, @"\[u(?:\s*)\]((.|\n)*?)\[/u(?:\s*)\]", "<u>$1</u>", options);
// marquee
encodedString = Regex.Replace(encodedString, @"\[fly(?:\s*)\]((.|\n)*?)\[/fly(?:\s*)\]", "<marquee>$1</marquee>", options);
encodedString = Regex.Replace(encodedString, @"\[marquee(?:\s*)\]((.|\n)*?)\[/marquee(?:\s*)\]", "<marquee>$1</marquee>", options);
// color
encodedString = Regex.Replace(encodedString, @"\[color=""((.|\n)*?)(?:\s*)""\]((.|\n)*?)\[/color(?:\s*)\]", "<font color=\"$1\">$3</font>", options );
encodedString = Regex.Replace(encodedString, @"\[color=((.|\n)*?)(?:\s*)\]((.|\n)*?)\[/color(?:\s*)\]", "<font color=\"$1\">$3</font>", options );
// Left, Right, Center
encodedString = Regex.Replace(encodedString, @"\[left(?:\s*)\]((.|\n)*?)\[/left(?:\s*)]", "<div style=\"text-align:left\">$1</div>", options);
encodedString = Regex.Replace(encodedString, @"\[center(?:\s*)\]((.|\n)*?)\[/center(?:\s*)]", "<div style=\"text-align:center\">$1</div>", options);
encodedString = Regex.Replace(encodedString, @"\[right(?:\s*)\]((.|\n)*?)\[/right(?:\s*)]", "<div style=\"text-align:right\">$1</div>", options);
// Quote
//
encodedString = Regex.Replace(encodedString, "\\[quote(?:\\s*)user=\"((.|\n)*?)\"\\]((.|\n)*?)\\[/quote(\\s*)\\]", quote, options);
encodedString = Regex.Replace(encodedString, "\\[quote(\\s*)\\]((.|\n)*?)\\[/quote(\\s*)\\]", emptyquote, options);
// encodedString = Regex.Replace(encodedString, @"\[quote(?:\s*)user=""((.|\n)*?)""\]", quoteStartHtml, options);
// encodedString = Regex.Replace(encodedString, "\\[/quote(\\s*)\\]", quoteEndHtml, options);
// encodedString = Regex.Replace(encodedString, "\\[quote(\\s*)\\]", emptyquoteStartHtml, options);
// encodedString = Regex.Replace(encodedString, "\\[/quote(\\s*)\\]", emptyquoteEndHtml, options);
// Anchors
//
// encodedString = Regex.Replace(encodedString, "<a href=\"((.|\n)*?)\">((.|\n)*?)</a>", "<a target=\"_blank\" title=\"$1\" href=\"$1\">$3</a>", options);
encodedString = Regex.Replace(encodedString, @"\[url(?:\s*)\]www\.(.*?)\[/url(?:\s*)\]", "<a href=\"http://www.$1\" target=\"_blank\" title=\"$1\">$1</a>", options );
encodedString = Regex.Replace(encodedString, @"\[url(?:\s*)\]((.|\n)*?)\[/url(?:\s*)\]", "<a href=\"$1\" target=\"_blank\" title=\"$1\">$1</a>", options );
encodedString = Regex.Replace(encodedString, @"\[url=""((.|\n)*?)(?:\s*)""\]((.|\n)*?)\[/url(?:\s*)\]", "<a href=\"$1\" target=\"_blank\" title=\"$1\">$3</a>", options );
encodedString = Regex.Replace(encodedString, @"\[url=((.|\n)*?)(?:\s*)\]((.|\n)*?)\[/url(?:\s*)\]", "<a href=\"$1\" target=\"_blank\" title=\"$1\">$3</a>", options );
encodedString = Regex.Replace(encodedString, @"\[link(?:\s*)\]((.|\n)*?)\[/link(?:\s*)\]", "<a href=\"$1\" target=\"_blank\" title=\"$1\">$1</a>", options );
encodedString = Regex.Replace(encodedString, @"\[link=((.|\n)*?)(?:\s*)\]((.|\n)*?)\[/link(?:\s*)\]", "<a href=\"$1\" target=\"_blank\" title=\"$1\">$3</a>", options );
// Image
//
encodedString = Regex.Replace(encodedString, @"\[img(?:\s*)\]((.|\n)*?)\[/img(?:\s*)\]", "<img src=\"$1\" border=\"0\" />", options);
encodedString = Regex.Replace(encodedString, @"\[img=((.|\n)*?)x((.|\n)*?)(?:\s*)\]((.|\n)*?)\[/img(?:\s*)\]", "<img width=\"$1\" height=\"$3\" src=\"$5\" border=\"0\" />", options );
// Flash
//
encodedString = Regex.Replace(encodedString, @"\[flash(?:\s*)\]((.|\n)*?)\[/flash(?:\s*)\]", "<embed src=\"$1\" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" width=\"550\" height=\"400\"></embed>", options);
encodedString = Regex.Replace(encodedString, @"\[flash=((.|\n)*?)x((.|\n)*?)(?:\s*)\]((.|\n)*?)\[/flash(?:\s*)\]", "<embed src=\"$5\" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" width=\"$1\" height=\"$3\"></embed>", options );
encodedString = Regex.Replace(encodedString, @"\[swf(?:\s*)\]((.|\n)*?)\[/swf(?:\s*)\]", "<embed src=\"$1\" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" width=\"550\" height=\"400\"></embed>", options);
encodedString = Regex.Replace(encodedString, @"\[swf=((.|\n)*?)x((.|\n)*?)(?:\s*)\]((.|\n)*?)\[/swf(?:\s*)\]", "<embed src=\"$5\" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" width=\"$1\" height=\"$3\"></embed>", options );
// WMV
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -