0.1.5找回添加 .gitattributes 和 .gitignore。
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
|
||||
namespace Hua.DotNet.Code.Helper.Html;
|
||||
|
||||
public class HtmlHelper
|
||||
{
|
||||
private static readonly Regex paragraphStartRegex = new Regex("<p>", RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex paragraphEndRegex = new Regex("</p>", RegexOptions.IgnoreCase);
|
||||
|
||||
private static string EnsureOnlyAllowedHtml(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
MatchCollection matchCollection = Regex.Matches(text, "<.*?>", RegexOptions.IgnoreCase);
|
||||
for (int num = matchCollection.Count - 1; num >= 0; num--)
|
||||
{
|
||||
if (!IsValidTag(text.Substring(matchCollection[num].Index + 1, matchCollection[num].Length - 1).Trim().ToLower(), "br,hr,b,i,u,a,div,ol,ul,li,blockquote,img,span,p,em,strong,font,pre,h1,h2,h3,h4,h5,h6,address,cite"))
|
||||
{
|
||||
text = text.Remove(matchCollection[num].Index, matchCollection[num].Length);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static bool IsValidTag(string tag, string tags)
|
||||
{
|
||||
string[] array = tags.Split(',');
|
||||
if (tag.IndexOf("javascript") >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (tag.IndexOf("vbscript") >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (tag.IndexOf("onclick") >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
char[] anyOf = new char[4] { ' ', '>', '/', '\t' };
|
||||
int num = tag.IndexOfAny(anyOf, 1);
|
||||
if (num > 0)
|
||||
{
|
||||
tag = tag.Substring(0, num);
|
||||
}
|
||||
if (tag[0] == '/')
|
||||
{
|
||||
tag = tag.Substring(1);
|
||||
}
|
||||
string[] array2 = array;
|
||||
foreach (string text in array2)
|
||||
{
|
||||
if (tag == text)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string FormatText(string text, bool stripTags, bool convertPlainTextToHtml, bool allowHtml, bool allowBBCode, bool resolveLinks, bool addNoFollowTag)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (stripTags)
|
||||
{
|
||||
text = StripTags(text);
|
||||
}
|
||||
text = ((!allowHtml) ? HttpUtility.HtmlEncode(text) : EnsureOnlyAllowedHtml(text));
|
||||
if (convertPlainTextToHtml)
|
||||
{
|
||||
text = ConvertPlainTextToHtml(text);
|
||||
}
|
||||
if (resolveLinks)
|
||||
{
|
||||
text = ResolveLinksHelper.FormatText(text);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
text = $"Text cannot be formatted. Error: {ex.Message}";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string StripTags(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
text = Regex.Replace(text, "(>)(\\r|\\n)*(<)", "><");
|
||||
text = Regex.Replace(text, "(<[^>]*>)([^<]*)", "$2");
|
||||
text = Regex.Replace(text, "(&#x?[0-9]{2,4};|"|&| |<|>|€|©|®|‰|‡|†|‹|›|„|”|“|‚|’|‘|—|–|‏|‎|‍|‌| | | |˜|ˆ|Ÿ|š|Š)", "@");
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string ReplaceAnchorTags(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
text = Regex.Replace(text, "<a\\b[^>]+>([^<]*(?:(?!</a)<[^<]*)*)</a>", "$1", RegexOptions.IgnoreCase);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string ConvertPlainTextToHtml(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
text = text.Replace("\r\n", "<br />");
|
||||
text = text.Replace("\r", "<br />");
|
||||
text = text.Replace("\n", "<br />");
|
||||
text = text.Replace("\t", " ");
|
||||
text = text.Replace(" ", " ");
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string ConvertHtmlToPlainText(string text, bool decode = false, bool replaceAnchorTags = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
if (decode)
|
||||
{
|
||||
text = HttpUtility.HtmlDecode(text);
|
||||
}
|
||||
text = text.Replace("<br>", "\n");
|
||||
text = text.Replace("<br >", "\n");
|
||||
text = text.Replace("<br />", "\n");
|
||||
text = text.Replace(" ", "\t");
|
||||
text = text.Replace(" ", " ");
|
||||
if (replaceAnchorTags)
|
||||
{
|
||||
text = ReplaceAnchorTags(text);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string ConvertPlainTextToParagraph(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
text = paragraphStartRegex.Replace(text, string.Empty);
|
||||
text = paragraphEndRegex.Replace(text, "\n");
|
||||
text = text.Replace("\r\n", "\n").Replace("\r", "\n");
|
||||
text += "\n\n";
|
||||
text = text.Replace("\n\n", "\n");
|
||||
string[] array = text.Split(new char[1] { '\n' });
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string[] array2 = array;
|
||||
foreach (string text2 in array2)
|
||||
{
|
||||
if (text2 != null && text2.Trim().Length > 0)
|
||||
{
|
||||
stringBuilder.AppendFormat("<p>{0}</p>\n", text2);
|
||||
}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Hua.DotNet.Code.Helper.Html;
|
||||
|
||||
public class ResolveLinksHelper
|
||||
{
|
||||
private static readonly Regex regex = new Regex("((http://|https://|www\\.)([A-Z0-9.\\-]{1,})\\.[0-9A-Z?;~&\\(\\)#,=\\-_\\./\\+]{2,})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private const string link = "<a href=\"{0}{1}\" rel=\"nofollow\">{2}</a>";
|
||||
|
||||
private const int MAX_LENGTH = 50;
|
||||
|
||||
private static string ShortenUrl(string url, int max)
|
||||
{
|
||||
if (url.Length <= max)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
int num = url.IndexOf("://");
|
||||
if (num > -1)
|
||||
{
|
||||
url = url.Substring(num + 3);
|
||||
}
|
||||
if (url.Length <= max)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
int num2 = url.IndexOf("/") + 1;
|
||||
int num3 = url.LastIndexOf("/");
|
||||
if (num2 < num3)
|
||||
{
|
||||
url = url.Remove(num2, num3 - num2);
|
||||
url = url.Insert(num2, "...");
|
||||
}
|
||||
if (url.Length <= max)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
int num4 = url.IndexOf("?");
|
||||
if (num4 > -1)
|
||||
{
|
||||
url = url.Substring(0, num4);
|
||||
}
|
||||
if (url.Length <= max)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
int num5 = url.IndexOf("#");
|
||||
if (num5 > -1)
|
||||
{
|
||||
url = url.Substring(0, num5);
|
||||
}
|
||||
if (url.Length <= max)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
num2 = url.LastIndexOf("/") + 1;
|
||||
num3 = url.LastIndexOf(".");
|
||||
if (num3 - num2 > 10)
|
||||
{
|
||||
string text = url.Substring(num2, num3 - num2);
|
||||
int num6 = url.Length - max + 3;
|
||||
if (text.Length > num6)
|
||||
{
|
||||
url = url.Replace(text, "..." + text.Substring(num6));
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
public static string FormatText(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
|
||||
foreach (Match item in regex.Matches(text))
|
||||
{
|
||||
text = (item.Value.Contains("://") ? text.Replace(item.Value, string.Format(invariantCulture, "<a href=\"{0}{1}\" rel=\"nofollow\">{2}</a>", string.Empty, item.Value, ShortenUrl(item.Value, 50))) : text.Replace(item.Value, string.Format(invariantCulture, "<a href=\"{0}{1}\" rel=\"nofollow\">{2}</a>", "http://", item.Value, ShortenUrl(item.Value, 50))));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user