۱۳۸۷/۰۸/۱۱

حذف تگ‌هاي زايد دريافتي از متون MS-Word


يكي از مشكلاتي كه من هميشه با كاربران عادي دارم بحث انتقال مطالب از Word مايكروسافت به اديتورهاي WYSWING تحت وب است. براي مثال شما سايت پويايي را درست كرده‌ايد كه كاربران مي‌توانند مطالب آنرا ويرايش يا كم و زياد كنند.
اگر مطلب از ابتدا در اين نوع اديتورها تايپ و آماده شود هيچ مشكلي وجود نخواهد داشت چون خروجي اكثر آنها استاندارد است، اما متاسفانه خروجي وب word بسيار مشكل‌زا است (copy/paste معمولي مطالب آن در يك اديتور تحت وب) و خصوصا براي نمايش تايپ فارسي در وب اصلا مناسب نيست. يعني هيچ الزامي وجود ندارد كه اندازه فونت‌ها در متن نهايي نمايش داده شده در وب يكسان باشند يا خطوط در هم فرو نروند و يا عدم تناسب اندازه قلم متن صفحه با قلم استفاده شده در CSS‌ سايت (كه شكل ناهماهنگ و غيرحرفه‌اي را حاصل خواهد كرد) و امثال آن. اينجاست كه كار شما زير سؤال مي‌رود! "اين برنامه درست كار نميكنه! متن من به‌هم ريخته شده و امثال اين"
اين كاربر عادي عموما يك تايپيست است يا يك منشي كه به او گفته شده است شما از امروز موظفيد مطالبي را در اين سايت قرار دهيد. بنابراين اين كاربر حتما از word استفاده خواهد كرد (براي پيش نويس مطالب). همچنين عموما هم مرورگر "سازماني" مورد استفاده، هنوز كه هنوز است همان IE6 است (در اكثر شركت‌ها و خصوصا ادارات) و مهم نيست كه الان آخرين نگارش IE يا فايرفاكس و تمام هياهوهاي مربوطه به كجا ختم شده‌اند. حتما بايد سايت با IE6 هم سازگار باشد. بنابراين از برنامه IE tester غافل نشويد.
و دست آخر شما هم نمي‌توانيد به كاربر عادي ثابت كنيد كه اين خروجي وب word اصلا استاندارد نيست (حتما كار شما است كه مشكل دارد نه شركت معظم مايكروسافت!). يا اينكه به آنها بگوئيد اصلا مجاز نيستيد در وب همانند يك فايل word از چندين نوع قلم مختلف فارسي غيراستاندارد استفاده كنيد چون ممكن است كاربري اين نوع قلم مورد استفاده شما را نداشته باشد و نمايش نهايي به هم ريخته‌تر از آني خواهد بود كه شما فكرش را مي‌كنيد! يا اينكه با استفاده از اين روش حجم نهايي صفحه حداقل 50 كيلو بايت بيشتر خواهد شد (بدليل حجم بالاي تگ‌هاي زايد word) و نبايد كاربران دايال آپ را فراموش كرد.
مدتي در اينباره جستجو كردم و نتيجه حاصل اين بود كه تمامي روش‌ها به يك مورد ختم مي‌شود: حذف تگ‌هاي غيراستاندارد word هنگام دريافت مطلب و پيش از ذخيره سازي آن در ديتابيس
يك سري از اديتورهاي متني تحت وب مانند FCK editor اين قابليت را به صورت خودكار اضافه كرده‌اند و حتي اگر كاربر متني را از word در آنها Paste كند پيغامي را در همين رابطه دريافت خواهد كرد (شكل زير) و البته كاربر مي‌تواند گزينه لغو يا خير را نيز انتخاب كند و دوباره همان وضعيت قبل تكرار خواهد شد. (يا حتي دكمه مخصوص كپي از word را هم به نوار ابزار خود اضافه كرده‌اند)



براي اين منظور تابع زير تهيه شده‌است كه من همواره از آن استفاده مي‌كنم و تا به امروز مشكل پاسخ پس دادن به كاربران عادي را به اين صورت حل كرده‌ام!
اين تابع تمامي تگ‌هاي اضافي و غيراستاندارد word متن دريافتي از يك اديتور WYSWING را حذف مي‌كند و به اين صورت متن نهايي نمايش داده شده در سايت، تابع CSS مورد استفاده در سايت خواهد شد و نه حجم بالايي از تگ‌هاي غيراستاندارد word. (ممكن است كاربر در ابتدا كمي جا بخورد ولي مهم نيست! سايت بايد استاندارد نمايشي خودش را از CSS آن دريافت كند و نه از تگ‌هاي word)

using System.Text.RegularExpressions;
/// <summary>
/// Removes all FONT and SPAN tags, and all Class and Style attributes.
/// Designed to get rid of non-standard Microsoft Word HTML tags.
/// </summary>
public static string CleanMSWordHtml(string html)
{
try
{
// start by completely removing all unwanted tags
html = Regex.Replace(html, @"<[/]?(font|span|xml|del|ins|[ovwxp]:\w )[^>]*?>", "", RegexOptions.IgnoreCase);
// then run another pass over the html (twice), removing unwanted attributes
html = Regex.Replace(html, @"<([^>]*)(?:class|lang|style|size|face|[ovwxp]:\w )=(?:'[^']*'|""[^""]*""|[^\s>] )([^>]*)>", "<$1$2>", RegexOptions.IgnoreCase);
html = Regex.Replace(html, @"<([^>]*)(?:class|lang|style|size|face|[ovwxp]:\w )=(?:'[^']*'|""[^""]*""|[^\s>] )([^>]*)>", "<$1$2>", RegexOptions.IgnoreCase);
return RemoveHTMLComments(html);
}
catch
{
return html;
}
}

public static string RemoveHTMLComments(string html)
{
try
{
Regex _Regex = new Regex("((<!-- )((?!<!-- ).)*( -->))(\r\n)*", RegexOptions.Singleline);
return _Regex.Replace(html, string.Empty);
}
catch
{
return html;
}
}

متد RemoveHTMLComments را عمدا جدا قرار دادم تا مشخص‌تر باشد. پس از تميزكاري اوليه، ممكن است دسته‌گل‌هاي تيم مايكروسافت به صورت كامنت باقي بمانند كه بايد آنها را هم تميز كرد! :)