zoukankan      html  css  js  c++  java
  • 【转载】Word中使用代码高亮插件

    Word中使用代码高亮插件

    一年前我写了一个word2010的代码高亮插件,但当时那个版本有一个问题:在用word发布博客的时候,高亮的代码在博客中的格式乱了。今天有空改了一下这个插件,虽然还是有些瑕疵,但至少发布到博客后,格式不会乱了。主要改进是用olli代替了pre,虽然发布到博客后,ol中设置的styleclass依然会被改动,但可以在博客中用css来纠正。

    下载插件和源代码:SyntaxHighlighter4Word.zip

    下面说一下这个插件的用法。

    下载文件后,解压,然后双击binword2010Kong.SyntaxHighlighter.Word2010.vstobinword2007Kong.SyntaxHighlighter.Word2007.vsto,即可完成安装,当然前提是你装了.net framework 4.0。安装成功后的提示如下:

    安装插件后,会在word中多一个功能区(支持word2007word2010):

    点击"设置"按钮,弹出设置界面:

    这里简化了配置,去掉了前一个版本中的一些设置。

    点击"插入代码"按钮,弹出如下界面:

    可以选择C#JavaXmlJavascript等多种语言。

    word效果如下:

    发布到博客后的效果如下:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Windows.Forms;
    6. using Kong.SyntaxHighlighter.Winform;
    7. using Microsoft.Office.Tools.Ribbon;
    8.    
    9. namespace Kong.SyntaxHighlighter.Word
    10. {
    11.     public partial class Ribbon1
    12.     {
    13.         private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
    14.         {
    15.    
    16.         }
    17.     }
    18. }

      我在Word中生成这段代码的时候,用了olli,并且设置了ol以及listyle,这样在word中就可以显示边框以及交替行的颜色,同时给ol设了一个class=codeBlock,妄想在发布到博客后可以通过这个样式名codeBlock来自定义自己喜欢的样式。我在word中生成的代码大概是这个样子:

    19. <ol class="codeBlock" ...

      但是word把这段代码发布到博客后,会去除掉这个class,无语。。。

      所以我们在博客中,不得设置所有olstyle,幸好博客园的文章都是在一个idcnblogs_post_bodydiv下的,所以我在我博客中加了下面的style

    20. #cnblogs_post_body ol
    21.  {
    22.      border1px dotted #000066;
    23.      line-height150%;
    24.      word-breakbreak-word;
    25.      font-familyConsolas, Verdana !important;
    26.      border-radius5px;
    27.      width90%;
    28.      background-color#E3E3FF;
    29.      list-style-positionoutside;
    30.      margin-left0px;
    31.  }
    32.  #cnblogs_post_body ol font
    33.  {
    34.      font-size12px !important;
    35.  }
    36.  #cnblogs_post_body ol li
    37.  {
    38.      background-color#fff;
    39.      padding-left5px;
    40.      border-left1px solid #8A8AFF;
    41.      margin-left5px !important;
    42.  }
    43.  #cnblogs_post_body ol li:nth-child(even)
    44.  {
    45.      background-color#f5f5f5;
    46.  }

      补充一下,这段文本是加在这里的:

         

      插件的使用就介绍到这里,下面简单介绍一下插件的实现。

      如何开发officeadd in,园子里已经有很多文章了,我就不介绍了,因为我自己也不懂。

      如何实现代码高亮?我用的是Wilco.SyntaxHighlighting,有兴趣的同学可以google一下,我提供的下载包里也有它的源码。

      代码高亮后,如何粘帖到word里?原理就是把代码高亮后的文本以html格式复制到剪贴板里,然后调用word的方法去粘帖:

    47. private void InsertButton_Click(object sender, RibbonControlEventArgs e)
    48. {
    49.     var dialog = new MainForm();
    50.     if (dialog.ShowDialog() == DialogResult.OK)
    51.     {
    52.         dialog.CopyToClipboard();
    53.         Globals.ThisAddIn.Application.Selection.Paste();
    54.     }
    55. }

      html格式复制到剪贴板的实现,我是从网上找了一段代码来做的,核心逻辑如下:

    56.         public static void CopyToClipboard(string htmlFragment, string title, Uri sourceUrl)
    57.         {
    58.             if (title == null) title = "From Clipboard";
    59.    
    60.             System.Text.StringBuilder sb = new System.Text.StringBuilder();
    61.    
    62.             string header =
    63.     @"Format:HTML Format
    64. Version:1.0
    65. StartHTML:<<<<<<<1
    66. EndHTML:<<<<<<<2
    67. StartFragment:<<<<<<<3
    68. EndFragment:<<<<<<<4
    69. StartSelection:<<<<<<<3
    70. EndSelection:<<<<<<<3
    71. ";
    72.    
    73.             string pre =
    74.     @"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">
    75. <HTML><HEAD><TITLE>" + title + @"</TITLE></HEAD><BODY><!--StartFragment-->";
    76.    
    77.             string post = @"<!--EndFragment--></BODY></HTML>";
    78.    
    79.             sb.Append(header);
    80.             if (sourceUrl != null)
    81.             {
    82.                 sb.AppendFormat("SourceURL:{0}", sourceUrl);
    83.             }
    84.             var enc = Encoding.UTF8; //中文乱码问题
    85.             int startHTML = enc.GetByteCount(sb.ToString());
    86.    
    87.             sb.Append(pre);
    88.             int fragmentStart = enc.GetByteCount(sb.ToString());
    89.    
    90.             sb.Append(htmlFragment);
    91.             int fragmentEnd = enc.GetByteCount(sb.ToString());
    92.    
    93.             sb.Append(post);
    94.             int endHTML = enc.GetByteCount(sb.ToString());
    95.    
    96.             // Backpatch offsets
    97.             sb.Replace("<<<<<<<1", To8DigitString(startHTML));
    98.             sb.Replace("<<<<<<<2", To8DigitString(endHTML));
    99.             sb.Replace("<<<<<<<3", To8DigitString(fragmentStart));
    100.             sb.Replace("<<<<<<<4", To8DigitString(fragmentEnd));
    101.    
    102.             Clipboard.Clear();
    103.             var dataObj = new DataObject();
    104.             dataObj.SetData(DataFormats.Html, new MemoryStream(enc.GetBytes(sb.ToString())));
    105.             Clipboard.SetDataObject(dataObj, true);
    106.         }
    107.    
    108.         #endregion // Write to Clipboard
    109.     }

      这个类名叫做HtmlFragment,可以在我提供的下载包里找到。

      另外,我这个插件在生成高亮代码时,可以清除掉代码段首尾的空行,也可以清除掉每一行的公共空格,比如下面的代码:

      在插入后会变成这个样子:

    110. private void Test()
    111. {
    112.     var i = 0;
    113.     //do something
    114. }

      我用了几条正则表达式来实现这个功能,代码如下:

    115. private string GetHtml(string content)
    116. {
    117.     _highlighter.Parser = _htmlParser;
    118.     string html = _highlighter.Parse(content);
    119.     _highlighter.Parser = _parser;
    120.     if (html != null)
    121.     {
    122.         html = html.Replace(" ", " ");
    123.         //清除首尾空行
    124.         html = Regex.Replace(html, @"(^s* )|( s*$)", "", RegexOptions.Singleline);
    125.    
    126.         //清除掉公共的空格
    127.         MatchCollection matches = Regex.Matches(html, @"^ *(?=S)", RegexOptions.Multiline);
    128.         int len = matches.OfType<Match>().Select(m => m.Value.Length).Min();
    129.         html = Regex.Replace(html, @"^ {" + len + "}", "", RegexOptions.Multiline);
    130.    
    131.         //把每一行开头的空格变成&nbsp;
    132.         html = Regex.Replace(html, @"^ +(?=S)",
    133.                              new MatchEvaluator(
    134.                                  m => string.Join("", new string[m.Length].Select(s => "&nbsp;"))),
    135.                              RegexOptions.Multiline);
    136.     }
    137.     return html;
    138. }

      有兴趣的同学可以下载源码看一下。

      作者:明年我18 
      出处:http://www.cnblogs.com/default 
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    人月神话读后感2
    大三学习进度13
    大三学习进度16
    大三学习进度14
    大三学习进度11
    大三学习进度15
    人月神话读后感3
    大三学习进度10
    Linux设备树
    clk_enable
  • 原文地址:https://www.cnblogs.com/lihaiyan/p/4274524.html
Copyright © 2011-2022 走看看