using System;
using System.Text.RegularExpressions;
namespace yaf
{
///
/// Summary description for BBCode.
///
public class BBCode
{
private BBCode()
{
}
static private int GetNumber( string input )
{
try
{
return int.Parse( input );
}
catch ( FormatException )
{
return -1;
}
}
static private string GetFontSize( int input )
{
switch ( input )
{
case 1:
return "50%";
case 2:
return "70%";
case 3:
return "80%";
case 4:
return "90%";
case 5:
default:
return "100%";
case 6:
return "120%";
case 7:
return "140%";
case 8:
return "160%";
case 9:
return "180%";
}
///return string.Format("{0}pt",input*2);
}
static private RegexOptions m_options = RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline;
static private Regex r_code2 = new Regex( @"\[code=(?[^\]]*)\](?(.*?))\[/code\]", m_options );
static private Regex r_code1 = new Regex( @"\[code\](?(.*?))\[/code\]", m_options );
static private Regex r_size = new Regex( @"\[size=(?([1-9]))\](?(.*?))\[/size\]", m_options );
static private Regex r_bold = new Regex( @"\[B\](?(.*?))\[/B\]", m_options );
static private Regex r_strike = new Regex( @"\[S\](?(.*?))\[/S\]", m_options );
static private Regex r_italic = new Regex( @"\[I\](?(.*?))\[/I\]", m_options );
static private Regex r_underline = new Regex( @"\[U\](?(.*?))\[/U\]", m_options );
static private Regex r_email2 = new Regex( @"\[email=(?[^\]]*)\](?(.*?))\[/email\]", m_options );
static private Regex r_email1 = new Regex( @"\[email[^\]]*\](?(.*?))\[/email\]", m_options );
static private Regex r_url1 = new Regex( @"\[url\](?(http://)|(https://)|(ftp://)|(ftps://))?(?(.*?))\[/url\]", m_options );
static private Regex r_url2 = new Regex( @"\[url=(?(http://)|(https://)|(ftp://)|(ftps://))?(?[^\]]*)\](?(.*?))\[/url\]", m_options );
static private Regex r_font = new Regex( @"\[font=(?([-a-z0-9, ]*))\](?(.*?))\[/font\]", m_options );
static private Regex r_color = new Regex( @"\[color=(?(\#?[-a-z0-9]*))\](?(.*?))\[/color\]", m_options );
static private Regex r_bullet = new Regex( @"\[\*\]", m_options );
static private Regex r_list4 = new Regex( @"\[list=i\](?(.*?))\[/list\]", m_options );
static private Regex r_list3 = new Regex( @"\[list=a\](?(.*?))\[/list\]", m_options );
static private Regex r_list2 = new Regex( @"\[list=1\](?(.*?))\[/list\]", m_options );
static private Regex r_list1 = new Regex( @"\[list\](?(.*?))\[/list\]", m_options );
static private Regex r_center = new Regex( @"\[center\](?(.*?))\[/center\]", m_options );
static private Regex r_left = new Regex( @"\[left\](?(.*?))\[/left\]", m_options );
static private Regex r_right = new Regex( @"\[right\](?(.*?))\[/right\]", m_options );
static private Regex r_quote2 = new Regex( @"\[quote=(?[^\]]*)\](?(.*?))\[/quote\]", m_options );
static private Regex r_quote1 = new Regex( @"\[quote\](?(.*?))\[/quote\]", m_options );
static private Regex r_hr = new Regex( "^[-][-][-][-][-]*[\r]?[\n]", m_options );
static private Regex r_br = new Regex( "[\r]?\n", m_options );
static private Regex r_post = new Regex( @"\[post=(?[^\]]*)\](?(.*?))\[/post\]", m_options );
static private Regex r_topic = new Regex( @"\[topic=(?[^\]]*)\](?(.*?))\[/topic\]", m_options );
static private Regex r_img = new Regex( @"\[img\](?(http://)|(https://)|(ftp://)|(ftps://))?(?(.*?))\[/img\]", m_options );
static private Regex r_yt = new Regex( @"\[yt\](?(.*?))\[/yt\]", m_options );
static public string MakeHtml( yaf.pages.ForumPage basePage, string bbcode, bool DoFormatting, bool HideImages )
{
System.Collections.ArrayList codes = new System.Collections.ArrayList();
const string codeFormat = ".code@{0}.";
string localQuoteStr = basePage.GetText( "COMMON", "BBCODE_QUOTE" );
string localCodeStr = basePage.GetText( "COMMON", "BBCODE_CODE" );
string localQuoteWroteStr = basePage.GetText( "COMMON", "BBCODE_QUOTEWROTE" );
Match m = r_code2.Match( bbcode );
int nCodes = 0;
while ( m.Success )
{
string before_replace = m.Groups [0].Value;
string after_replace = m.Groups ["inner"].Value;
try
{
HighLighter hl = new HighLighter();
hl.ReplaceEnter = true;
after_replace = hl.colorText( after_replace, System.Web.HttpContext.Current.Server.MapPath( Data.ForumRoot + "defs/" ), m.Groups ["language"].Value );
}
catch ( Exception x )
{
if ( basePage.IsAdmin )
basePage.AddLoadMessage( x.Message );
after_replace = FixCode( after_replace );
}
bbcode = bbcode.Replace( before_replace, string.Format( codeFormat, nCodes++ ) );
codes.Add( string.Format( @"", after_replace, localCodeStr ) );
m = r_code2.Match( bbcode );
}
m = r_code1.Match( bbcode );
while ( m.Success )
{
string before_replace = m.Groups [0].Value;
string after_replace = FixCode( m.Groups ["inner"].Value );
bbcode = bbcode.Replace( before_replace, string.Format( codeFormat, nCodes++ ) );
codes.Add( string.Format( @"", after_replace, localCodeStr ) );
m = r_code1.Match( bbcode );
}
m = r_size.Match( bbcode );
while ( m.Success )
{
///Console.WriteLine("{0}",m.Groups["size"]);
int i = GetNumber( m.Groups ["size"].Value );
string tmp;
if ( i < 1 )
tmp = m.Groups ["inner"].Value;
else if ( i > 9 )
tmp = string.Format( "{0}", m.Groups ["inner"].Value, GetFontSize( 9 ) );
else
tmp = string.Format( "{0}", m.Groups ["inner"].Value, GetFontSize( i ) );
bbcode = bbcode.Substring( 0, m.Groups [0].Index ) + tmp + bbcode.Substring( m.Groups [0].Index + m.Groups [0].Length );
m = r_size.Match( bbcode );
}
if ( DoFormatting )
{
NestedReplace( ref bbcode, r_bold, "${inner}" );
NestedReplace( ref bbcode, r_strike, "${inner}" );
NestedReplace( ref bbcode, r_italic, "${inner}" );
NestedReplace( ref bbcode, r_underline, "${inner}" );
// e-mails
NestedReplace( ref bbcode, r_email2, "${inner}", new string [] { "email" } );
NestedReplace( ref bbcode, r_email1, "${inner}" );
// urls
if ( basePage.BoardSettings.BlankLinks )
{
NestedReplace( ref bbcode, r_url2, "${inner}", new string [] { "url", "http" }, new string [] { "", "http://" } );
NestedReplace( ref bbcode, r_url1, "${http}${inner}", new string [] { "http" }, new string [] { "http://" } );
}
else
{
NestedReplace( ref bbcode, r_url2, "${inner}", new string [] { "url", "http" }, new string [] { "", "http://" } );
NestedReplace( ref bbcode, r_url1, "${http}${inner}", new string [] { "http" }, new string [] { "http://" } );
}
// font
NestedReplace( ref bbcode, r_font, "${inner}", new string [] { "font" } );
NestedReplace( ref bbcode, r_color, "${inner}", new string [] { "color" } );
// bullets
bbcode = r_bullet.Replace( bbcode, "" );
NestedReplace( ref bbcode, r_list4, "${inner}
" );
NestedReplace( ref bbcode, r_list3, "${inner}
" );
NestedReplace( ref bbcode, r_list2, "${inner}
" );
NestedReplace( ref bbcode, r_list2, "" );
// alignment
NestedReplace( ref bbcode, r_center, "${inner}
" );
NestedReplace( ref bbcode, r_left, "${inner}
" );
NestedReplace( ref bbcode, r_right, "${inner}
" );
// image
if (HideImages)
{
NestedReplace(ref bbcode, r_img, "");
NestedReplace(ref bbcode, r_yt, "");
}
else
{
NestedReplace(ref bbcode, r_img, "
", new string[] { "http" }, new string[] { "http://" });
NestedReplace(ref bbcode, r_yt, "");
}
//
bbcode = r_hr.Replace( bbcode, "
" );
bbcode = r_br.Replace( bbcode, "
" );
}
bbcode = FormatMsg.iAddSmiles( basePage, bbcode );
string tmpReplaceStr;
tmpReplaceStr = string.Format( @"", localQuoteWroteStr.Replace( "{0}", "${quote}" ), "${inner}" );
while ( r_quote2.IsMatch( bbcode ) )
bbcode = r_quote2.Replace( bbcode, tmpReplaceStr );
tmpReplaceStr = string.Format( @"", localQuoteStr, "${inner}" );
while ( r_quote1.IsMatch( bbcode ) )
bbcode = r_quote1.Replace( bbcode, tmpReplaceStr );
m = r_post.Match( bbcode );
while ( m.Success )
{
string link = Forum.GetLink( Pages.posts, "m={0}#{0}", m.Groups ["post"] );
if ( basePage.BoardSettings.BlankLinks )
bbcode = bbcode.Replace( m.Groups [0].ToString(), string.Format( "{1}", link, m.Groups ["inner"] ) );
else
bbcode = bbcode.Replace( m.Groups [0].ToString(), string.Format( "{1}", link, m.Groups ["inner"] ) );
m = r_post.Match( bbcode );
}
m = r_topic.Match( bbcode );
while ( m.Success )
{
string link = Forum.GetLink( Pages.posts, "t={0}", m.Groups ["topic"] );
if ( basePage.BoardSettings.BlankLinks )
bbcode = bbcode.Replace( m.Groups [0].ToString(), string.Format( "{1}", link, m.Groups ["inner"] ) );
else
bbcode = bbcode.Replace( m.Groups [0].ToString(), string.Format( "{1}", link, m.Groups ["inner"] ) );
m = r_topic.Match( bbcode );
}
while ( nCodes > 0 )
{
bbcode = bbcode.Replace( string.Format( codeFormat, --nCodes ), codes [nCodes].ToString() );
}
return bbcode;
}
static protected void NestedReplace( ref string refText, Regex regexMatch, string strReplace, string [] Variables, string [] VarDefaults )
{
Match m = regexMatch.Match( refText );
while ( m.Success )
{
string tStr = strReplace;
int i = 0;
foreach ( string tVar in Variables )
{
string tValue = m.Groups [tVar].Value;
if ( tValue.Length == 0 )
{
// use default instead
tValue = VarDefaults [i];
}
tStr = tStr.Replace( "${" + tVar + "}", tValue );
i++;
}
tStr = tStr.Replace( "${inner}", m.Groups ["inner"].Value );
refText = refText.Substring( 0, m.Groups [0].Index ) + tStr + refText.Substring( m.Groups [0].Index + m.Groups [0].Length );
m = regexMatch.Match( refText );
}
}
static protected void NestedReplace( ref string refText, Regex regexMatch, string strReplace, string [] Variables )
{
Match m = regexMatch.Match( refText );
while ( m.Success )
{
string tStr = strReplace;
foreach ( string tVar in Variables )
{
tStr = tStr.Replace( "${" + tVar + "}", m.Groups [tVar].Value );
}
tStr = tStr.Replace( "${inner}", m.Groups ["inner"].Value );
refText = refText.Substring( 0, m.Groups [0].Index ) + tStr + refText.Substring( m.Groups [0].Index + m.Groups [0].Length );
m = regexMatch.Match( refText );
}
}
static protected void NestedReplace( ref string refText, Regex regexMatch, string strReplace )
{
Match m = regexMatch.Match( refText );
while ( m.Success )
{
string tStr = strReplace.Replace( "${inner}", m.Groups ["inner"].Value );
refText = refText.Substring( 0, m.Groups [0].Index ) + tStr + refText.Substring( m.Groups [0].Index + m.Groups [0].Length );
m = regexMatch.Match( refText );
}
}
static public string EncodeHTML( string html )
{
return System.Web.HttpContext.Current.Server.HtmlEncode( html );
}
static public string DecodeHTML( string text )
{
return System.Web.HttpContext.Current.Server.HtmlDecode( text );
}
static private string FixCode( string html )
{
html = html.Replace( " ", " " );
html = html.Replace( " ", " " );
html = html.Replace( "\t", " " );
html = html.Replace( "[", "[" );
html = html.Replace( "]", "]" );
html = html.Replace( "<", "<" );
html = html.Replace( ">", ">" );
html = html.Replace( "\r\n", "
" );
return html;
}
}
}