我们在编写Word文档时,希望也能有CSDN博客中的代码插件的效果,可以插入带有行号和高亮显示的代码,然而这却不太容易做到。要做到这一点,有两种方式,一种是借助Notepad++,将内容导出为HTML格式,然后插入到Word中。这种方式的缺点是不能带行号,这对于想要解释代码来说,非常不方便。还有一种方式,就是我们通过Word中的VBA语言进行编程,来自动对代码段进行高亮显示和添加行号,这种方式可以由我们自己来定制,非常方便。以下代码参考了这篇博文(http://blog.chinaunix.net/uid-20672257-id-3323617.html),在此表示感谢。
在Word2007中要实现代码段的行号和高亮显示,我们首先定义一个新的样式来表示代码行。点击“开始”=》“样式”右下角的箭头,如下图所示:
如上图中红色圆圈处,在随后弹出的窗体中,点击新建样式,如下图所示:
在弹出的样式定义界面中,选择样式定义,如下图所示:
我们将进入段落编辑界面,如下图所示:
这是因为Word缺省的行距太大,我们希望代码紧凑一些,所以缩小了行距。因为要使代码突出显示,我们希望代码有一个柔和的底色,如下图所示:
在随后弹出的边框定义页面中,选择下图中红色圆圈选项:
我们可以将这个样式命名为code1。
至此,我们就定义了一个完整的代码段样式,下面我们就需要通过程序来对关键字、运算符进行高亮显示,并添加行号,我们将使用Word自带的VBA来实现这一功能,我们首先进入宏编辑界面,如下所示:
然后选择创建宏,将下面的代码粘到界面中:
'script to high light code In document Private Function isKeyword(w) As Boolean Dim keys As New Collection With keys .Add " if": .Add "else": .Add "switch": .Add "case": .Add "default": .Add "break" .Add "goto": .Add "return": .Add "for": .Add "while": .Add "do": .Add "continue" .Add "typedef": .Add "sizeof": .Add "NULL": .Add "new": .Add "delete": .Add "throw" .Add "try": .Add "catch": .Add "namespace": .Add "operator": .Add "this": .Add "const_cast" .Add "static_cast": .Add "dynamic_cast": .Add "reinterpret_cast": .Add "true" .Add "false": .Add "null": .Add "using": .Add "typeid": .Add "and": .Add "and_eq" .Add "bitand": .Add "bitor": .Add "compl": .Add "not": .Add "not_eq": .Add "or" .Add "or_eq": .Add "xor": .Add "xor_eq": .Add "import": .Add "print" End With isKeyword = isSpecial(w, keys) End Function Private Function isSpecial(ByVal w As String, ByRef col As Collection) As Boolean For Each i In col If w = i Then isSpecial = True Exit Function End If Next isspeical = False End Function Private Function isOperator(w) As Boolean Dim ops As New Collection With ops .Add "+": .Add "-": .Add "*": .Add "/": .Add "&": .Add "^": .Add ";" .Add "%": .Add "#": .Add "!": .Add ":": .Add ",": .Add "." .Add "||": .Add "&&": .Add "|": .Add "=": .Add "++": .Add "--" .Add "'": .Add """" End With isOperator = isSpecial(w, ops) End Function Private Function isType(ByVal w As String) As Boolean Dim types As New Collection With types .Add "void": .Add "struct": .Add "union": .Add "enum": .Add "char": .Add "short": .Add "int" .Add "long": .Add "double": .Add "float": .Add "signed": .Add "unsigned": .Add "const": .Add "static" .Add "extern": .Add "auto": .Add "register": .Add "volatile": .Add "bool": .Add "class": .Add " private" .Add "protected": .Add "public": .Add "friend": .Add "inlIne": .Add "template": .Add "virtual" .Add "asm": .Add "explicit": .Add "typename" End With isType = isSpecial(w, types) End Function Sub SyntaxHighlight() Dim wordCount As Integer Dim d As Integer ' set the style of selection Selection.Style = "code1" d = 0 wordCount = Selection.Words.Count Selection.StartOf wdWord While d < wordCount d = d + Selection.MoveRight(wdWord, 1, wdExtend) w = Selection.Text If isKeyword(Trim(w)) = True Then Selection.Font.Color = wdColorBlue ElseIf isType(Trim(w)) = True Then Selection.Font.Color = wdColorDarkRed Selection.Font.Bold = True ElseIf isOperator(Trim(w)) = True Then Selection.Font.Color = wdColorBrown ElseIf Trim(w) = "//" Then 'lIne comment Selection.MoveEnd wdLine, 1 commentWords = Selection.Words.Count d = d + commentWords Selection.Font.Color = wdColorGreen Selection.MoveStart wdWord, commentWords ElseIf Trim(w) = "/*" Then 'block comment While Selection.Characters.Last <> "/" Selection.MoveLeft wdCharacter, 1, wdExtend Selection.MoveEndUntil ("*") Selection.MoveRight wdCharacter, 2, wdExtend Wend commentWords = Selection.Words.Count d = d + commentWords Selection.Font.Color = wdColorGreen Selection.MoveStart wdWord, commentWords End If 'move the start of selection to next word Selection.MoveStart wdWord Wend ' prepare For set lIne number Selection.MoveLeft wdWord, wordCount, wdExtend SetLIneNumber 1 End Sub Private Sub SetLIneNumber(ByVal base As Integer) Dim lines As Integer lines = Selection.Paragraphs.Count Selection.StartOf wdParagraph For l = base To lines + base lIneNum = l & " " If l < 10 Then lIneNum = lIneNum & " " End If Selection.Text = lIneNum Selection.Font.Bold = False Selection.Font.Color = wdColorAutomatic p = Selection.MoveDown(wdLine, 1, wdMove) Selection.StartOf wdLine Next l End Sub
上面的代码不太长,而且结构也很简单,大家可以自己去研究一下。与原始代码相比,这里为了高亮显示Python中的import等关键字,所以添加了新的关键字,另外,如果希望开始行号不是从1开始,可以修改SetLIneNumber函数调用中的参数,由1变为希望的值即可。
做好上述设置之后,我们就可以在Word中添加代码段了,添加完成之后,先选中这个代码段,然后点击“开发工具”=》“宏”,在如下界面中点击运行:
最终的效果如下所示:
如上所示,可以看出,我们添加的代码段可以非常好的和Word中的普通文本一起显示,达到了我们的目的。