Чистим HTML код, генерируемый Microsoft Word

понедельник, 28 февраля 2011, Александр Краковецкий

Как всем известно, Microsoft Word не смог стать удобным инструментом для блоггеров по причине того, что код, генерируемый Microsoft Word, мягко сказать, ужасный, и пестрит большим количеством ненужных стилей и дополнительного HTML мусора. Но, согласитесь, более удобного способа для написания больших текстов на сегодняшний момент нет. Поэтому в этой статье я расскажу, как можно получить чистый HTML код из Microsoft Word.

Если создать новый Microsoft Word 2010 документ и вставить туда текст "Word Cleanup" и сохранить его как HTML страницу, то получим приблизительно следующее:

<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 14">
<meta name=Originator content="Microsoft Word 14">
<link rel=File-List href="word_files/filelist.xml">
<!--[if gte mso 9]><xml>
 <o:DocumentProperties>
  <o:Author>Marina</o:Author>
 <o:OfficeDocumentSettings>
  <o:AllowPNG/>
 </o:OfficeDocumentSettings>
</xml><![endif]-->
<link rel=themeData href="word_files/themedata.thmx">
<link rel=colorSchemeMapping href="word_files/colorschememapping.xml">
<!--[if gte mso 9]><xml>
 <w:WordDocument>
  </m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
 <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
  DefSemiHidden="true" DefQFormat="false" DefPriority="99"
  LatentStyleCount="267">
  <w:LsdException Locked="false" Priority="0" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Normal"/>
 </w:LatentStyles>
</xml><![endif]-->
<style>
<!--
 /* Font Definitions */
 @font-face
    {font-family:Calibri;
    panose-1:2 15 5 2 2 2 4 3 2 4;
    mso-font-charset:204;
    mso-generic-font-family:swiss;
    mso-font-pitch:variable;
    mso-font-signature:-520092929 1073786111 9 0 415 0;}
 /* Style Definitions */
@page WordSection1
    {size:595.3pt 841.9pt;
    margin:42.5pt 42.5pt 42.5pt 70.85pt;
    mso-header-margin:35.4pt;
    mso-footer-margin:35.4pt;
    mso-paper-source:0;}
div.WordSection1
    {page:WordSection1;}
-->
</style>
<!--[if gte mso 10]>
<style>
 /* Style Definitions */
 table.MsoNormalTable
    {mso-style-name:"Table Normal";
      mso-fareast-language:EN-US;}
</style>
<![endif]--><!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026"/>
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1"/>
 </o:shapelayout></xml><![endif]-->
</head>
<body lang=EN-GB style='tab-interval:36.0pt'>
<div class=WordSection1>
<p class=MsoNormal><span lang=EN-US style='mso-ansi-language:EN-US'>Word
cleanup.<o:p></o:p></span></p>
</div>
</body>
</html>

Я упустил большую часть документа, размер которого составил около 20 KB текста!!! Это просто какая-то феерия!

Документ состоит из мета информации о документе, стилях, а также наличием большого количества тэгов span и дополнительного "мусора".

Давайте все это почистим.

Создадим Windows Forms приложение, которые будет иметь два элемента управления - компонент WebBrowser (в режиме редактирования) и кнопка, по клику которой будем очищать HTML. Вот код самой программы:

using System;
using System.Windows.Forms;
using System.Data.Extracting;

namespace WordCleanUpTool
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void InitWebBrowser()
        {
            string Encoding = "ISO-8859-1";
            HtmlDocument hd;
            mshtml.IHTMLDocument2 axObj;

            webBrowser.DocumentText = "";
            webBrowser.Document.Encoding = Encoding;
            hd = webBrowser.Document;
            axObj = hd.DomDocument as mshtml.IHTMLDocument2;
            axObj.designMode = "On";
            webBrowser.Navigate("about:blank");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ChangeAllowWebBrowserDrop();
            webBrowser.DocumentText = webBrowser.DocumentText.GetCleanedWordHtml();
        }

        void ChangeAllowWebBrowserDrop() 
        { 
            webBrowser.AllowWebBrowserDrop = !webBrowser.AllowWebBrowserDrop; 
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitWebBrowser();
        }
    }
}

Главная функция, которая очищает текст, называется GetCleanedWordHtml(). Она входит в состав Data Extracting SDK.

Вот ее код:

public static string GetCleanedWordHtml(this string html)
{
    // 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);

    html = Regex.Replace(html, @"<style[^>]*?>[\s\S]*?<\/style>", 
       "", RegexOptions.IgnoreCase);

    html = Regex.Replace(html, @"<!--\[if [^>]*?\]>[\s\S]*?<!\[endif\]-->", 
        "", RegexOptions.IgnoreCase);

     return html.TrimSafe();
}

После того, как мы запустим приложение, загрузим наш сохраненный из Word файл и нажмем кнопку "Очистить", то получим такой код:

<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 14">
<meta name=Originator content="Microsoft Word 14">
<link rel=File-List href="word_files/filelist.xml">

<link rel=themeData href="word_files/themedata.thmx">
<link rel=colorSchemeMapping href="word_files/colorschememapping.xml">

</head>
<body >
<div >
<p >Word
cleanup.</p>
</div>
</body>
</html>

Несомненно, намного лучше. Еще еще немного поиграться, то можно довести код до совершенства :)

Кроме того,можно написать небольшое расширение для Microsoft Word, с помощью которого можно очищать ваши статьи перед публикацией в блог. (Хотя рекомендую использовать Live Writer, а такой подход использовать когда у вас есть уже написанный кем-то текст, который нужно опубликовать на веб-сайте.)

Пример использования:

Фрагмент кода, генерируемого программой Word:

После очищения получим следующий результат:

И такой HTML код:

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии