Word中使用代码高亮插件

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

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

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

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

Word中使用代码高亮插件_代码高亮

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

Word中使用代码高亮插件_代码高亮_02

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

Word中使用代码高亮插件_word _03

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

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

Word中使用代码高亮插件_word _04

可以选择C#、Java、Xml、Javascript等多种语言。

在word效果如下:

Word中使用代码高亮插件_word _05

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

  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.         privatevoid Ribbon1_Load(object sender, RibbonUIEventArgs e)

  14.         {

  15.  

  16.         }

  17.     }

  18. }

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

  1. <olclass="codeBlock" ...

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

所以我们在博客中,不得设置所有ol的style,幸好博客园的文章都是在一个id为cnblogs_post_body的div下的,所以我在我博客中加了下面的style:

  1. #cnblogs_post_bodyol

  2.  {

  3.      border: 1px dotted #000066;

  4.      line-height: 150%;

  5.      word-break: break-word;

  6.      font-family: Consolas, Verdana !important;

  7.      border-radius: 5px;

  8.      width: 90%;

  9.      background-color: #E3E3FF;

  10.      list-style-position: outside;

  11.      margin-left: 0px;

  12.  }

  13.  #cnblogs_post_bodyolfont

  14.  {

  15.      font-size: 12px !important;

  16.  }

  17.  #cnblogs_post_bodyolli

  18.  {

  19.      background-color: #fff;

  20.      padding-left: 5px;

  21.      border-left: 1px solid #8A8AFF;

  22.      margin-left: 5px !important;

  23.  }

  24.  #cnblogs_post_bodyolli:nth-child(even)

  25.  {

  26.      background-color: #f5f5f5;

  27.  }

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

Word中使用代码高亮插件_word _06

 

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

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

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

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

  1. privatevoid InsertButton_Click(object sender, RibbonControlEventArgs e)

  2. {

  3.     var dialog = new MainForm();

  4.     if (dialog.ShowDialog() == DialogResult.OK)

  5.     {

  6.         dialog.CopyToClipboard();

  7.         Globals.ThisAddIn.Application.Selection.Paste();

  8.     }

  9. }

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

  1.         publicstaticvoid CopyToClipboard(string htmlFragment, string title, Uri sourceUrl)

  2.         {

  3.             if (title == null) title = "From Clipboard";

  4.  

  5.             System.Text.StringBuilder sb = new System.Text.StringBuilder();

  6.  

  7.             string header =

  8.     @"Format:HTML Format

  9. Version:1.0

  10. StartHTML:<<<<<<<1

  11. EndHTML:<<<<<<<2

  12. StartFragment:<<<<<<<3

  13. EndFragment:<<<<<<<4

  14. StartSelection:<<<<<<<3

  15. EndSelection:<<<<<<<3

  16. ";

  17.  

  18.             string pre =

  19.     @"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">

  20. <HTML><HEAD><TITLE>" + title + @"</TITLE></HEAD><BODY><!--StartFragment-->";

  21.  

  22.             string post = @"<!--EndFragment--></BODY></HTML>";

  23.  

  24.             sb.Append(header);

  25.             if (sourceUrl != null)

  26.             {

  27.                 sb.AppendFormat("SourceURL:{0}", sourceUrl);

  28.             }

  29.             var enc = Encoding.UTF8; //中文乱码问题

  30.             int startHTML = enc.GetByteCount(sb.ToString());

  31.  

  32.             sb.Append(pre);

  33.             int fragmentStart = enc.GetByteCount(sb.ToString());

  34.  

  35.             sb.Append(htmlFragment);

  36.             int fragmentEnd = enc.GetByteCount(sb.ToString());

  37.  

  38.             sb.Append(post);

  39.             int endHTML = enc.GetByteCount(sb.ToString());

  40.  

  41.             // Backpatch offsets

  42.             sb.Replace("<<<<<<<1", To8DigitString(startHTML));

  43.             sb.Replace("<<<<<<<2", To8DigitString(endHTML));

  44.             sb.Replace("<<<<<<<3", To8DigitString(fragmentStart));

  45.             sb.Replace("<<<<<<<4", To8DigitString(fragmentEnd));

  46.  

  47.             Clipboard.Clear();

  48.             var dataObj = new DataObject();

  49.             dataObj.SetData(DataFormats.Html, new MemoryStream(enc.GetBytes(sb.ToString())));

  50.             Clipboard.SetDataObject(dataObj, true);

  51.         }

  52.  

  53.         #endregion // Write to Clipboard

  54.     }

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

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

Word中使用代码高亮插件_代码高亮_07

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

  1. privatevoid Test()

  2. {

  3.     var i = 0;

  4.     //do something

  5. }

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

  1. privatestring GetHtml(string content)

  2. {

  3.     _highlighter.Parser = _htmlParser;

  4.     string html = _highlighter.Parse(content);

  5.     _highlighter.Parser = _parser;

  6.     if (html != null)

  7.     {

  8.         html = html.Replace("\t", "");

  9.         //清除首尾空行

  10.         html = Regex.Replace(html, @"(^\s*\n)|(\n\s*$)", "", RegexOptions.Singleline);

  11.  

  12.         //清除掉公共的空格

  13.         MatchCollection matches = Regex.Matches(html, @"^ *(?=\S)", RegexOptions.Multiline);

  14.         int len = matches.OfType<Match>().Select(m => m.Value.Length).Min();

  15.         html = Regex.Replace(html, @"^ {" + len + "}", "", RegexOptions.Multiline);

  16.  

  17.         //把每一行开头的空格变成&nbsp;

  18.         html = Regex.Replace(html, @"^ +(?=\S)",

  19.                              new MatchEvaluator(

  20.                                  m => string.Join("", newstring[m.Length].Select(s => "&nbsp;"))),

  21.                              RegexOptions.Multiline);

  22.     }

  23.     return html;

  24. }

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

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

好文要顶关注我收藏该文联系我Word中使用代码高亮插件_代码高亮_08Word中使用代码高亮插件_代码高亮_09

Word中使用代码高亮插件_代码高亮_10

明年我18
关注 - 4
粉丝 - 59

+加关注

12

0

(请您对文章做出评价)

上一篇:用程序实现HTTP压缩和缓存
下一篇:解决ssh连linux的中文乱码问题

posted on 2012-06-05 19:47 明年我18 阅读(7890) 评论(24)  编辑 <a target=\"_blank\" href="#"  style="border: 0px none rgb(26, 139, 200); color: rgb(26, 139, 200);  font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 13px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: 19.5px; margin: 0px; outline: rgb(26, 139, 200) none 0px; padding: 0px; text-align: right; text-decoration: none