MarkdownSharp  1.12
src/Escapes.cs
00001 using System;
00002 using System.Collections.Generic;
00003 using System.Text;
00004 using System.Text.RegularExpressions;
00005 
00006 namespace MarkdownSharp
00007 {
00008     internal static class Escapes
00009     {
00010         private const string _escapeCharacters = @"\`*_{}[]()>#+-.!";
00011         private static readonly KeyValuePair<char, string>[] _escapeTable;
00012         private static readonly Regex _hashFinder;
00013 
00014         static Escapes()
00015         {
00016             _escapeTable = new KeyValuePair<char, string>[_escapeCharacters.Length];
00017             string pattern = "";
00018             for (int i = 0; i < _escapeCharacters.Length; ++i)
00019             {
00020                 char c = _escapeCharacters[i];
00021                 string hash = c.ToString().GetHashCode().ToString();
00022                 _escapeTable[i] = new KeyValuePair<char,string>(c, hash);
00023 
00024                 if (pattern != "") pattern += "|(" + hash + ")";
00025                 else pattern += "(" + hash + ")";
00026             }
00027             _hashFinder = new Regex(pattern, RegexOptions.Compiled | RegexOptions.ExplicitCapture);
00028         }
00029 
00033         public static string get(char c)
00034         {
00035             foreach(var pair in _escapeTable)
00036                 if (pair.Key == c)
00037                     return pair.Value;
00038             throw new IndexOutOfRangeException("The requested character can not be escaped");
00039         }
00040 
00044         private static char getInverse(string s)
00045         {
00046             foreach (var pair in _escapeTable)
00047                 if (pair.Value == s)
00048                     return pair.Key;
00049             throw new IndexOutOfRangeException("The requested hash can not be found");
00050         }
00051 
00055         public static string BackslashEscapes(string text)
00056         {
00057             int len = text.Length, first = 0, i = 0;
00058             var sb = new StringBuilder(len);
00059             while (i < len)
00060             {
00061                 if (text[i] == '\\' && i + 1 < len && Contains(_escapeCharacters, text[i + 1]))
00062                 {
00063                     sb.Append(text, first, i - first);
00064                     sb.Append(get(text[++i]));
00065                     first = ++i;
00066                 }
00067                 else ++i;
00068             }
00069             if (first == 0) return text;
00070             sb.Append(text, first, i - first);
00071             return sb.ToString();
00072         }
00073 
00077         public static string BoldItalic(string text)
00078         {
00079             int len = text.Length, first = 0, i = 0;
00080             var sb = new StringBuilder(len);
00081             while (i < len)
00082             {
00083                 if ('*' == text[i])
00084                 {
00085                     sb.Append(text, first, i - first);
00086                     sb.Append(get('*'));
00087                     first = ++i;
00088                 }
00089                 else if ('_' == text[i])
00090                 {
00091                     sb.Append(text, first, i - first);
00092                     sb.Append(get('_'));
00093                     first = ++i;
00094                 }
00095                 else ++i;
00096             }
00097             if (first == 0) return text;
00098             sb.Append(text, first, i - first);
00099             return sb.ToString();
00100         }
00101 
00105         public static string Escape(string text, string escapes)
00106         {
00107             int len = text.Length, first = 0, i = 0;
00108             var sb = new StringBuilder(len);
00109             while (i < len)
00110             {
00111                 if (Contains(escapes, text[i]))
00112                 {
00113                     sb.Append(text, first, i - first);
00114                     sb.Append(get(text[i]));
00115                     first = ++i;
00116                 }
00117                 else ++i;
00118             }
00119             if (first == 0) return text;
00120             sb.Append(text, first, i - first);
00121             return sb.ToString();
00122         }
00123 
00129         public static string ProblemUrlChars(string url)
00130         {
00131             url = url.Replace("*", "%2A");
00132             url = url.Replace("_", "%5F");
00133             url = url.Replace("'", "%27");
00134             url = url.Replace("(", "%28");
00135             url = url.Replace(")", "%29");
00136             url = url.Replace("[", "%5B");
00137             url = url.Replace("]", "%5D");
00138             if (url.Length > 7 && Contains(url.Substring(7), ':'))
00139             {
00140                 // replace any colons in the body of the URL that are NOT followed by 2 or more numbers
00141                 url = url.Substring(0, 7) + Regex.Replace(url.Substring(7), @":(?!\d{2,})", "%3A");
00142             }
00143 
00144             return url;
00145         }
00146 
00147         private static bool Contains(string s, char c)
00148         {
00149             int len = s.Length;
00150             for (int i = 0; i < len; ++i)
00151                 if (s[i] == c)
00152                     return true;
00153             return false;
00154         }
00155 
00159         public static string Unescape(string text)
00160         {
00161             return _hashFinder.Replace(text, match => getInverse(match.Value).ToString());
00162         }
00163     }
00164 }
 全て クラス ネームスペース 関数 プロパティ