我们在编写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中的普通文本一起显示,达到了我们的目的。