原文地址: http://guocongbin.iblog.com/post/1964/265367
使用方法:
2)将上面的vba代码拷贝到文档中,步骤:在word2003中,“工具” → “宏” → ”VB编辑器“ → ”Normal工程“ → ”Microsoft Word 对象“ ,双击 ”thisDocument"对象,将上面的代码拷贝到新开的窗口中。
当然你也可以把ccode样式和highlight脚本保存到normal模板中,这样以后你再写代码的时候就可以直接用了,不用自己再辛苦定义这些了。
3)选定代码文本,然后执行highlight脚本: “格式” → “宏” → “宏”, 选择SyntaxHighlight宏,然后执行就可以了。
如果想定制语法高亮,那么修改上面的脚本就是了。
最近我经常在word 里面写东西,发现程序代码拷贝到word 里面就没有了在代码编辑器里面的那种语法高亮的效果,感觉不爽。于是我上网搜了搜,发现目前在word 中实现语法高亮的方法主要是通过安装一个插件。由于我先天的对插件比较反感,所以自己动手,使用word 等office 软件都支持的VBA (Visual BAsic For Application) 写了一个语法高亮的宏。
这个宏的功能比较简单,就是利用得到文档中选中部分的代码,然后分词,判断该词的类别,然后着色。我现在使用的分词方法是VBA 提供的,大部分情况下和我们预期的比较一致。但是在某些情况下,比如连续的分隔符,这种分词方法会和C 语言分析器的分词结果不同的。
这个宏除了可以语法着色,还可以为代码标注行号。(听说侯捷在《word 排版艺术》一书中也有一个为代码添加行号的宏。不知道他的宏和我的宏是否雷同。如有雷同,纯属巧合:)
'
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 "
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 = " ccode "
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
End Sub
Private Sub SetLIneNumber()
Dim lines As Integer
lines = Selection.Paragraphs.Count
Selection.StartOf wdParagraph
For l = 1 To lines
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
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 "
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 = " ccode "
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
End Sub
Private Sub SetLIneNumber()
Dim lines As Integer
lines = Selection.Paragraphs.Count
Selection.StartOf wdParagraph
For l = 1 To lines
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
下面是我给出的使用说明,原文没给出使用说明。
使用方法:
1) 首先为当前文档新定义一个样式,命名为"ccode",专门用来对c代码进行格式化。由于是代码,所以推荐中文使用宋体(注释中),而英文使用等宽字体(courier new)。建立样式的步骤:在word2003中,“格式” → “新样式”
2)将上面的vba代码拷贝到文档中,步骤:在word2003中,“工具” → “宏” → ”VB编辑器“ → ”Normal工程“ → ”Microsoft Word 对象“ ,双击 ”thisDocument"对象,将上面的代码拷贝到新开的窗口中。
当然你也可以把ccode样式和highlight脚本保存到normal模板中,这样以后你再写代码的时候就可以直接用了,不用自己再辛苦定义这些了。
3)选定代码文本,然后执行highlight脚本: “格式” → “宏” → “宏”, 选择SyntaxHighlight宏,然后执行就可以了。
如果想定制语法高亮,那么修改上面的脚本就是了。