import re
import keyword
###Following are some crude regexes which I use to tokenise a text object comprising python code
multiline_pat = "(\'\'\'|\"\"\")"+r"(.|\n)*?\1"
singleline_pat = "(\'|\")"+r".*?\1"
kw_pat = r"\b("+"|".join(keyword.kwlist)+r")\b"
number_pat = r"\b\d+\b"
def_pat = r"((?<=def )\w+)|((?<=class )\w+)"
comment_pat = r"#.*(\n|$)"
###Define some colors for each token type
kwcolor = RGB( 255, 0, 0 )
numberColor = RGB( 128, 50, 0)
defColor = RGB(0,0,255)
StrColor = RGB(125,125,0)
CommentColor = RGB(128,128,128)
MultiStrColor = RGB(0,255,0)
def RGB( nRed, nGreen, nBlue ):
"""Return an integer which repsents a color.
The color is specified in RGB notation.
Each of nRed, nGreen and nBlue must be a number from 0 to 255.
"""
return (int( nRed ) & 255) << 16 | (int( nGreen ) & 255) << 8 | (int( nBlue ) & 255)
def HighlightPython():
"""
Main function for highlighting python code in a document. Must be called 'in process'.
"""
ctx = XSCRIPTCONTEXT
doc = ctx.getDocument()
HighlightAll(doc)
def _highlight(pat, data, csr, color):
"""
Does the actual coloring of text
@param pat: a regex to find patterns to highlight
@param data: the source text to use, a string
@param csr: a OOo TextCursor instance
@param color: an integer representing a color. use the RGB() function above to calculate
"""
pos=0
csr.gotoStart(False)
print "pattern:", pat
for match in re.finditer(pat, data):
start, end = match.span()
print "match:", data[start:end]
diff = start-pos
csr.goRight(diff, False)
csr.goRight(end-start,True)
csr.CharColor = color
pos=end
def ColourTextBox(txt):
"""
Highlights a single TextShape item
"""
data = txt.String
csr = txt.createTextCursor()
_highlight(kw_pat, data, csr, kwcolor)
_highlight(number_pat, data, csr, numberColor)
_highlight(def_pat, data, csr, defColor )
_highlight(singleline_pat, data, csr, StrColor)
_highlight(comment_pat, data, csr, CommentColor )
_highlight(multiline_pat, data, csr, MultiStrColor )
def RemoteGetDoc():
"""
Retrieve the document instance when accessing OOo 'out of process', using uno over a socket.
"""
import uno
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext )
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
doc = desktop.getCurrentComponent()
return doc
def HighlightAll(doc):
"""
Apply syntax highlighting to all TextShapes in the document which have the "code"
graphic style applied to them
"""
styles = doc.StyleFamilies.getByName(u"graphics")
code = styles.getByName(u"code")
pages = doc.DrawPages
count = pages.getCount()
for idx in xrange(count):
page = pages.getByIndex(idx)
count = page.getCount()
for item_idx in xrange(count):
item = page.getByIndex(item_idx)
if 'com.sun.star.drawing.TextShape' in item.SupportedServiceNames:
style = item.Style
if style==code:
ColourTextBox(item)
g_exportedScripts = (HighlightPython,)
if __name__=="__main__":
#Script testing is easiest using remote uno over a socket
doc = RemoteGetDoc()
HighlightAll(doc)