ANN: PySourceColor 1.7

Discussion in 'Python' started by M.E.Farmer, Oct 15, 2004.

  1. M.E.Farmer

    M.E.Farmer Guest

    Hello all,
    This version of PySourceColor supports decorators.
    It looks like the syntax is there for a while, so I decided add them
    in.
    They parser code has also been extended to seperate all 12 types of
    string.
    I rewrote the _Null colorscheme to actually be null format.
    Changed the old _Null to _Mono a black and white colorscheme for
    printing.
    Also added a few utility functions.
    If you don't like the builtin colorschemes you should be able to write
    a colorscheme that looks exactly like you want.
    This is something that would be nice to have built into pydoc.
    The links at the top-right of a pydoc page could point to a colorized
    source and a plain text version :)
    This program should run with Python 2.0 -> 2.4.
    The code can be any version.
    Just save to a file and run it.
    It will parse itself into 6 diffrent webpages and show them.
    M.E.Farmer

    ######################################################################
    # PySourceColor
    # A python source to colorized html converter.
    # This does not create w3c valid html, but it works on every
    # browser i've tried so far.(I.E.,Mozilla/Firefox,Opera,wxHTML).
    # After experimenting with diffrent html vs CSS + html
    # I settled on plain old html because it works!
    # Too bad CSS is not supported everywhere yet.
    # Hacked by M.E.Farmer Jr. 2004
    # Python license
    ######################################################################
    # Currently it can seperate and colorize:
    # 12 types of strings
    # 2 comment types
    # numbers
    # operators
    # class / name
    # def / name
    # decorator / name
    # keywords
    # text
    # And can use any combination of 3 styles:
    # bold
    # italic
    # underline
    ######################################################################
    # Recent changes:
    # October 09, 2004:
    # Added support for @decorators.
    # Tested on 2.2 and 2.4
    # Sepetember 25, 2004:
    # Extended string handling:
    # Unicode - single, singletriple, double, double triple
    # Raw - single, singletriple, double, double triple
    # regular - single, singletriple, double, double triple
    #
    ######################################################################

    import keyword, os, sys, traceback
    import cgi, string, cStringIO
    import token, tokenize, glob
    import getopt, webbrowser, time
    __title__ = 'PySourceColor'
    __version__ = "1.7"
    __date__ = '09 October 2004'
    __author__ = "M.E.Farmer Jr."
    __credits__ = '''This was originally submitted /written by
    J├╝rgen Hermann to ASPN python recipes.
    I hacked the parser to give me more control over tokens.
    Python license M.E.Farmer 2004
    '''
    # Testing raw and unicode strings
    # We do nothing with the value just look at colorizing
    _ = (r'raw',r'''raw''',r"raw",r"""raw""")##Raw test
    _ = (u'uni',u'''uni''',u"uni",u"""uni""")##Unicode test

    # Do not edit
    _DOUBLECOMMENT = token.NT_OFFSET + 1
    _CLASS = token.NT_OFFSET + 2
    _DEF = token.NT_OFFSET + 3
    _TEXT = token.NT_OFFSET + 4
    _KEYWORD = token.NT_OFFSET + 5
    _SINGLEQUOTE = token.NT_OFFSET + 6
    _SINGLEQUOTE_R = token.NT_OFFSET + 7
    _SINGLEQUOTE_U = token.NT_OFFSET + 8
    _DOUBLEQUOTE = token.NT_OFFSET + 9
    _DOUBLEQUOTE_R = token.NT_OFFSET + 10
    _DOUBLEQUOTE_U = token.NT_OFFSET + 11
    _TRIPLESINGLEQUOTE = token.NT_OFFSET + 12
    _TRIPLESINGLEQUOTE_R = token.NT_OFFSET + 13
    _TRIPLESINGLEQUOTE_U = token.NT_OFFSET + 14
    _TRIPLEDOUBLEQUOTE = token.NT_OFFSET + 15
    _TRIPLEDOUBLEQUOTE_R = token.NT_OFFSET + 16
    _TRIPLEDOUBLEQUOTE_U = token.NT_OFFSET + 17
    _BACKGROUND = token.NT_OFFSET + 18
    _DECORATOR = token.NT_OFFSET + 19
    _DECORATOR_DEF = token.NT_OFFSET + 20

    ######################################################################
    # Edit colors and styles to taste
    # Create your own scheme, just copy one below , rename and edit.
    # Color is rgb hex and must be specified. #RRGGBB
    # Styles are optional: b=bold, i=italic, u=underline
    # Colorscheme names must start with an underscore: _MyColor
    # Underscore will not be used on command line (--color= Pythonwin)
    ######################################################################
    _Null = {
    token.ERRORTOKEN: '#FF8080',# no edit
    token.STRING: '#000000',# no edit
    _TEXT: '#000000',# no edit
    _DECORATOR_DEF: '#000000',# Decorators
    _DECORATOR: '#000000',# @
    token.NAME: '#000000',# All Text
    token.NUMBER: '#000000',# 0->10
    token.OP: '#000000',# ()<>=!.:;^>%, etc...
    tokenize.COMMENT: '#000000',# There are 2 types of comment
    _DOUBLECOMMENT: '#000000',## Like this
    _CLASS: '#000000',# Class name
    _DEF: '#000000',# Def name
    _KEYWORD: '#000000',# Python keywords
    _SINGLEQUOTE: '#000000',# 'SINGLEQUOTE'
    _SINGLEQUOTE_R: '#000000',# r'SINGLEQUOTE'
    _SINGLEQUOTE_U: '#000000',# u'SINGLEQUOTE'
    _DOUBLEQUOTE: '#000000',# "DOUBLEQUOTE"
    _DOUBLEQUOTE_R: '#000000',# r"DOUBLEQUOTE"
    _DOUBLEQUOTE_U: '#000000',# u"DOUBLEQUOTE"
    _TRIPLESINGLEQUOTE: '#000000',# '''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_R: '#000000',# r'''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_U: '#000000',# u'''TRIPLESINGLEQUOTE'''
    _TRIPLEDOUBLEQUOTE: '#000000',# """TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_R: '#000000',# r"""TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_U: '#000000',# u"""TRIPLEDOUBLEQUOTE"""
    _BACKGROUND: '#FFFFFF',# Page background color
    }

    _Mono = {
    token.ERRORTOKEN: '#FF8080',# no edit
    token.STRING: '#000000',# no edit
    _TEXT: '#000000',# no edit
    _DECORATOR_DEF: 'bu#000000',# Decorators
    _DECORATOR: 'b#000000',# @
    token.NAME: '#000000',# All Text
    token.NUMBER: 'b#000000',# 0->10
    token.OP: 'b#000000',# ()<>=!.:;^>%, etc...
    tokenize.COMMENT: 'i#000000',# There are 2 types of comment
    _DOUBLECOMMENT: '#000000',## Like this
    _CLASS: 'bu#000000',# Class name
    _DEF: 'b#000000',# Def name
    _KEYWORD: 'b#000000',# Python keywords
    _SINGLEQUOTE: '#000000',# 'SINGLEQUOTE'
    _SINGLEQUOTE_R: '#000000',# r'SINGLEQUOTE'
    _SINGLEQUOTE_U: '#000000',# u'SINGLEQUOTE'
    _DOUBLEQUOTE: '#000000',# "DOUBLEQUOTE"
    _DOUBLEQUOTE_R: '#000000',# r"DOUBLEQUOTE"
    _DOUBLEQUOTE_U: '#000000',# u"DOUBLEQUOTE"
    _TRIPLESINGLEQUOTE: '#000000',# '''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_R: '#000000',# r'''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_U: '#000000',# u'''TRIPLESINGLEQUOTE'''
    _TRIPLEDOUBLEQUOTE: 'i#000000',# """TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_R:'i#000000',# r"""TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_U:'i#000000',# u"""TRIPLEDOUBLEQUOTE"""
    _BACKGROUND: '#FFFFFF',# Page background color
    }

    _Dark = {
    token.ERRORTOKEN: '#FF8080',# no edit
    token.STRING: '#FFFFFF',# no edit
    _TEXT: '#000000',# no edit
    _DECORATOR_DEF: 'b#FFBBAA',# Decorators
    _DECORATOR: 'b#CC5511',# @
    token.NAME: '#ffffff',# All Text
    token.NUMBER: '#FF0000',# 0->10
    token.OP: 'b#FAF785',# Operators ()<>=!.:;^>%,
    etc...
    tokenize.COMMENT: 'i#45FCA0',# There are 2 types of comment
    _DOUBLECOMMENT: '#A7C7A9',## Like this
    _CLASS: 'b#B599FD',# Class name
    _DEF: 'b#EBAE5C',# Def name
    _KEYWORD: 'b#8680FF',# Python keywords
    _SINGLEQUOTE: '#F8BAFE',# 'SINGLEQUOTE'
    _SINGLEQUOTE_R: '#F8BAFE',# r'SINGLEQUOTE'
    _SINGLEQUOTE_U: '#F8BAFE',# u'SINGLEQUOTE'
    _DOUBLEQUOTE: '#FF80C0',# "DOUBLEQUOTE"
    _DOUBLEQUOTE_R: '#FF80C0',# r"DOUBLEQUOTE"
    _DOUBLEQUOTE_U: '#FF80C0',# u"DOUBLEQUOTE"
    _TRIPLESINGLEQUOTE: '#FF9595',# '''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_R: '#FF9595',# r'''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_U: '#FF9595',# u'''TRIPLESINGLEQUOTE'''
    _TRIPLEDOUBLEQUOTE: '#B3FFFF',# """TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_R: '#B3FFFF',# r"""TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_U: '#B3FFFF',# u"""TRIPLEDOUBLEQUOTE"""
    _BACKGROUND: '#000000',# Page background color
    }


    _Lite = {
    token.ERRORTOKEN: '#FF8080',# no edit
    token.STRING: '#000000',# no edit
    _TEXT: '#000000',# no edit
    _DECORATOR_DEF: 'b#BB4422',# Decorators
    _DECORATOR: 'b#3333af',# @
    token.NAME: '#000000',# All Text
    token.NUMBER: '#FF2200',# 0->10
    token.OP: 'b#303000',# Operators ()<>=!.:;^>%,
    etc...
    tokenize.COMMENT: '#007F00',# There are 2 types of comment
    _DOUBLECOMMENT: '#606060',## Like this
    _CLASS: '#0000FF',# Class name
    _DEF: 'b#9C7A00',# Def name
    _KEYWORD: 'b#0000AF',# Python keywords
    _SINGLEQUOTE: '#600080',# 'SINGLEQUOTE'
    _SINGLEQUOTE_R: '#600080',# r'SINGLEQUOTE'
    _SINGLEQUOTE_U: '#600080',# u'SINGLEQUOTE'
    _DOUBLEQUOTE: '#A0008A',# "DOUBLEQUOTE"
    _DOUBLEQUOTE_R: '#A0008A',# r"DOUBLEQUOTE"
    _DOUBLEQUOTE_U: '#A0008A',# u"DOUBLEQUOTE"
    _TRIPLESINGLEQUOTE: '#4488BB',# '''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_R: '#4488BB',# r'''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_U: '#4488BB',# u'''TRIPLESINGLEQUOTE'''
    _TRIPLEDOUBLEQUOTE: '#2299BB',# """TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_R: '#2299BB',# r"""TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_U: '#2299BB',# u"""TRIPLEDOUBLEQUOTE"""
    _BACKGROUND: '#FFFFFF',# Page background color
    }

    _Idle = {
    token.ERRORTOKEN: '#FF8080',# no edit
    token.STRING: '#000000',# no edit
    _TEXT: '#000000',# no edit
    _DECORATOR_DEF: '#900090',# Decorators
    _DECORATOR: '#000000',# @
    token.NAME: '#000000',# All Text
    token.NUMBER: '#000000',# 0->10
    token.OP: '#000000',# Operators ()<>=!.:;^>%,
    etc...
    tokenize.COMMENT: '#DD0000',# There are 2 types of comment
    _DOUBLECOMMENT: '#DD0000',## Like this
    _CLASS: '#0000FF',# Class name
    _DEF: '#0000FF',# Def name
    _KEYWORD: '#FF7700',# Python keywords
    _SINGLEQUOTE: '#00AA00',# 'SINGLEQUOTE'
    _SINGLEQUOTE_R: '#00AA00',# r'SINGLEQUOTE'
    _SINGLEQUOTE_U: '#00AA00',# u'SINGLEQUOTE'
    _DOUBLEQUOTE: '#00AA00',# "DOUBLEQUOTE"
    _DOUBLEQUOTE_R: '#00AA00',# r"DOUBLEQUOTE"
    _DOUBLEQUOTE_U: '#00AA00',# u"DOUBLEQUOTE"
    _TRIPLESINGLEQUOTE: '#00AA00',# '''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_R: '#00AA00',# r'''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_U: '#00AA00',# u'''TRIPLESINGLEQUOTE'''
    _TRIPLEDOUBLEQUOTE: '#00AA00',# """TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_R: '#00AA00',# r"""TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_U: '#00AA00',# u"""TRIPLEDOUBLEQUOTE"""
    _BACKGROUND: '#FFFFFF',# Page background color
    }

    _PythonWin = {
    token.ERRORTOKEN: '#FF8080',# no edit
    token.STRING: '#000000',# no edit
    _TEXT: '#000000',# no edit
    _DECORATOR_DEF: 'b#303030',# Decorators
    _DECORATOR: 'b#DD0080',# @
    token.NAME: '#303030',# All Text
    token.NUMBER: '#008080',# 0->10
    token.OP: '#000000',# ()<>=!.:;^>%, etc...
    tokenize.COMMENT: '#007F00',# There are 2 types of comment
    _DOUBLECOMMENT: '#7F7F7F',## Like this
    _CLASS: 'b#0000FF',# Class name
    _DEF: 'b#007F7F',# Def name
    _KEYWORD: 'b#000080',# Python keywords
    _SINGLEQUOTE: '#808000',# 'SINGLEQUOTE'
    _SINGLEQUOTE_R: '#808000',# r'SINGLEQUOTE'
    _SINGLEQUOTE_U: '#808000',# u'SINGLEQUOTE'
    _DOUBLEQUOTE: '#808000',# "DOUBLEQUOTE"
    _DOUBLEQUOTE_R: '#808000',# r"DOUBLEQUOTE"
    _DOUBLEQUOTE_U: '#808000',# u"DOUBLEQUOTE"
    _TRIPLESINGLEQUOTE: '#808000',# '''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_R: '#808000',# r'''TRIPLESINGLEQUOTE'''
    _TRIPLESINGLEQUOTE_U: '#808000',# u'''TRIPLESINGLEQUOTE'''
    _TRIPLEDOUBLEQUOTE: '#808000',# """TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_R: '#808000',# r"""TRIPLEDOUBLEQUOTE"""
    _TRIPLEDOUBLEQUOTE_U: '#808000',# u"""TRIPLEDOUBLEQUOTE"""
    _BACKGROUND: '#FFFFFF',# Page background color
    }
    DefaultColorScheme= _Dark
    ##################################################################################

    def Usage():
    """
    _______________________________________________________________________________
    Example usage:
    # To colorize all .py,.pyw files in cwdir you can also use: . or _
    python PySourceColor.py -i .
    # Using long options w/ =
    python PySourceColor.py --in=c:/myDir/my.py --out=c:/myDir
    --color=Lite --show
    # Using short options w/out =
    python PySourceColor.py -i c:/myDir/ -c Idle
    # Using any mix
    python PySourceColor.py --in _ -o=c:/myDir --show
    -------------------------------------------------------------------------------
    This module is designed to colorize python source code.
    It is a hacked version of MoinMoin python parser recipe.
    -h or --help
    Display this help message.
    -i or --in
    Input file or dir. (Use any of these for the cwdir . , _ ,
    this)
    -o or --out
    Optional, output dir for the colorized source
    default: output dir is input dir.
    -c or --color
    Optional. Null, Dark, Lite, Idle, Pythonwin, create your own!
    default: Dark
    -s or --show
    Optional, Show webpage after creation.
    default: no show
    _______________________________________________________________________________
    """
    print Usage.__doc__

    def Main():
    '''Gathers the command line arguments
    and try to do something reasonable with them.
    '''
    try:
    # try to get command line args
    opts, args = getopt.getopt(sys.argv[1:],
    "hsi:eek::c:", ["help", "show", "input=", "out=",
    "color="])
    except getopt.GetoptError:
    # on error print help information and exit:
    Usage()
    sys.exit(2)
    # init some names
    input = None
    output = None
    scheme = None
    show = 0
    # if we have args then process them
    for o, a in opts:
    if o in ("-h", "--help"):
    Usage()
    sys.exit()
    if o in ("-o", "--out"):
    output = a
    if o in ("-i", "--input"):
    input = a
    if input in('.','_', 'this'):
    input = os.getcwd()
    if o in ("-s", "--show"):
    show = 1
    if o in ("-c", "--color"):
    try:
    #Fix this if you see a weakness
    scheme = eval('_%s'%a)
    except:
    traceback.print_exc()

    if input == None:
    # if there was no input specified then we try to
    # parse ourselves and do it in diffrent flavors.
    fi = sys.argv[0]
    Path2File(fi, '/MyDir/null', _Null, 1)
    Path2File(fi, '/MyDir/mono', _Mono, 1)
    Path2File(fi, '/MyDir/lite', _Lite, 1)
    Path2File(fi, '/MyDir/dark', _Dark, 1)
    Path2File(fi, '/MyDir/idle', _Idle, 1)
    Path2File(fi, '/MyDir/pythonwin', _PythonWin, 1)
    else:
    # if there was at least an input given we can proceed
    Convert(input, output, scheme, show)
    import os

    def Str2Html(sourcestring, title='', form=None, colors=None):
    '''Converts a code(string) to colorized HTML
    and prints to sys.stdout
    form='pre','code',or'snip' for "<pre>yourcode</pre>" only
    colors=_Null,_Mono,_Lite,_Dark,_Idle,or _PythonWin
    example:
    Str2Html("""x, y = os.path.split(myPath)
    if os.path.isdir(y):
    print'No file' """,form='snip',colors=_Lite)
    '''
    Parser(sourcestring, colors, title).format(form)

    def Path2Html(sourcepath, form=None, colors=None):
    '''Converts code(file) to colorized HTML
    and prints to sys.stdout
    form='pre','code',or'snip' for "<pre>yourcode</pre>" only
    colors=_Null,_Mono,_Lite,_Dark,_Idle,or _PythonWin
    '''
    source = open(sourcepath).read()
    Parser(source, colors, sourcepath).format(form)

    def Convert(sourcePath, outdir=None, colors=None, show=0):
    ''' Converts all python source in the given directory to html
    file/s.
    '''
    c=0
    # If it is a filename then Path2File
    if not os.path.isdir(sourcePath):
    if os.path.isfile(sourcePath):
    c+=1
    Path2File(sourcePath, outdir, colors, show)
    # If we pass in a dir we need to walkdir for files.
    # Then we need to colorize them with Path2File
    else:
    fileList = WalkDir(sourcePath)
    if fileList != None:
    for i in fileList:
    c+=1
    Path2File(i, outdir, colors, show)
    print'Completed colorizing %s source files.'% str(c)
    else:
    print"No files to convert in dir."

    def Path2File(sourcePath, outdir=None, colors=None, show=0):
    ''' Converts python source to html file.
    '''
    print" Converting %s into HTML" % sourcePath
    # If no outdir is given we use the sourcePath
    if outdir == None:
    htmlPath = sourcePath + '.html'
    else:
    # If we do give an outdir, and it does
    # not exist , it will be created.
    if not os.path.isdir(outdir):
    os.makedirs(outdir)
    sourceName = os.path.basename(sourcePath)
    htmlPath = os.path.join(outdir,sourceName)+'.html'
    print " Output to %s"%htmlPath
    # Open the text and do the parsing.
    source = open(sourcePath).read()
    Parser(source, colors, sourcePath, open(htmlPath, 'wt')).format()
    if show:
    # load HTML page into the default web browser.
    # slower than os.startfile or os.system, but more universal
    try:
    webbrowser.open_new(htmlPath)
    except:
    traceback.print_exc()
    return htmlPath

    def WalkDir(dir):
    '''Return a list of .py and .pyw files from a given directory.
    This function can be written as a generator Python 2.3, or a
    genexp
    in Python 2.4. But 2.2 and 2.1 would be left out....
    '''
    # Get a list of files that match *.py*
    GLOB_PATTERN = os.path.join(dir, "*.[p][y]*")
    pathlist = glob.glob(GLOB_PATTERN)
    # Now filter out all but py and pyw
    filterlist = [x for x in pathlist
    if x.endswith('.py')
    or x.endswith('.pyw')]
    if filterlist != []:
    # if we have a list send it
    return filterlist
    else:
    return None

    class Parser:
    """ MoinMoin python parser heavily chopped :)
    """
    def __init__(self, raw, colors=None, title='', out=sys.stdout):
    ''' Store the source text & set some flags.
    '''
    if colors == None:
    colors = DefaultColorScheme
    self.raw = string.strip(string.expandtabs(raw))
    self.out = out
    self.title = os.path.basename(title)
    self.ClassFlag = 0
    self.DefFlag = 0
    self.Decorator = 0
    self.colors = colors
    # Name: Date stamp top
    self.header = 0
    # Name: Date stamp bottom
    self.footer = 0

    def format(self, form=None, filler=None):
    ''' Parse and send the colored source.
    '''
    if form in ['snip','pre','code']:
    self.addEnds = 0
    else:
    self.addEnds = 1
    # Store line offsets in self.lines
    self.lines = [0, 0]
    pos = 0

    # Gather lines
    while 1:
    pos = string.find(self.raw, '\n', pos) + 1
    if not pos: break
    self.lines.append(pos)
    self.lines.append(len(self.raw))

    # Wrap text in a filelike object
    self.pos = 0
    text = cStringIO.StringIO(self.raw)

    # Html start
    if self.addEnds:
    self._doPageStart()
    else:
    self._doSnippetStart()

    # Parse the source.
    ## Tokenize calls the __call__
    ## function for each token till done.
    try:
    tokenize.tokenize(text.readline, self)
    except tokenize.TokenError, ex:
    msg = ex[0]
    line = ex[1][0]
    self.out.write("<h3>ERROR: %s</h3>%s\n" % (
    msg, self.raw[self.lines[line]:]))
    traceback.print_exc()

    # Html end
    if self.addEnds:
    self._doPageEnd()
    else:
    self._doSnippetEnd()

    def __call__(self, toktype, toktext, (srow,scol), (erow,ecol),
    line):
    ''' Token handler. Order of evaluation is important do not
    rearrange.
    '''
    style = ''
    # calculate new positions
    oldpos = self.pos
    newpos = self.lines[srow] + scol
    self.pos = newpos + len(toktext)

    # handle newlines
    if toktype in [token.NEWLINE, tokenize.NL]:
    self.out.write('\n')
    return

    # send the original whitespace, if needed
    if newpos > oldpos:
    self.out.write(self.raw[oldpos:newpos])

    # skip indenting tokens
    if toktype in [token.INDENT, token.DEDENT]:
    self.pos = newpos
    return

    if self.ClassFlag or self.DefFlag:
    # maps the color if it was a class or def name
    if self.ClassFlag:
    toktype = _CLASS
    self.ClassFlag = 0
    elif self.DefFlag:
    toktype = _DEF
    self.DefFlag = 0
    else:
    # Sets a flag if it was a class, def
    # next token will be colored.
    if toktext =='class':
    self.ClassFlag = 1
    elif toktext == 'def':
    self.DefFlag = 1
    #The last token was a @ so we must be a deco name
    elif self.Decorator:
    toktype = _DECORATOR_DEF
    # reset the flag
    self.Decorator = 0

    # map token type to a color group
    if token.LPAR <= toktype and toktype <= token.OP:
    # trap decorators py2.4>
    if toktext == '@':
    toktype = _DECORATOR
    #Colorize next token (decorator name)
    self.Decorator = 1
    else:
    toktype = token.OP
    elif toktype == token.NAME and keyword.iskeyword(toktext):
    toktype = _KEYWORD

    # Extended to seperate the diffrent string types..
    # Plus raw and unicode types. (12 string types)
    # Order of evaluation is important do not change.
    if toktype == token.STRING:
    # TRIPLE DOUBLE QUOTE's
    if (toktext[:3].lower() == '"""'):
    toktype = _TRIPLEDOUBLEQUOTE
    elif (toktext[:4].lower() == 'r"""'):
    toktype = _TRIPLEDOUBLEQUOTE_R
    elif (toktext[:4].lower() == 'u"""'):
    toktype = _TRIPLEDOUBLEQUOTE_U
    # DOUBLE QUOTE's
    elif (toktext[:1].lower() == '"'):
    toktype = _DOUBLEQUOTE
    elif (toktext[:2].lower() == 'r"'):
    toktype = _DOUBLEQUOTE_R
    elif (toktext[:2].lower() == 'u"'):
    toktype = _DOUBLEQUOTE_U
    # TRIPLE SINGLE QUOTE's
    elif (toktext[:3].lower() == "'''"):
    toktype = _TRIPLESINGLEQUOTE
    elif (toktext[:4].lower() == "r'''"):
    toktype = _TRIPLESINGLEQUOTE_R
    elif (toktext[:4].lower() == "u'''"):
    toktype = _TRIPLESINGLEQUOTE_U
    # SINGLE QUOTE's
    elif (toktext[:1].lower() == "'"):
    toktype = _SINGLEQUOTE
    elif (toktext[:2].lower() == "r'"):
    toktype = _SINGLEQUOTE_R
    elif (toktext[:2].lower() == "u'"):
    toktype = _SINGLEQUOTE_U

    # Exetended to seperate the diffrent comment types
    elif toktype == tokenize.COMMENT:
    if toktext[:2] == "##":
    toktype = _DOUBLECOMMENT

    # Extended errors to seperate decorators
    elif toktype == token.ERRORTOKEN:
    # trap decorators...<py2.3
    if toktext == '@':
    toktype = _DECORATOR
    self.Decorator = 1
    else:
    # Error tokenizing ..red boxes
    style = ' style="border: solid 1.5pt #FF0000;"'

    # Get the colors from the dictionary for the standard tokens
    color = self.colors.get(toktype, self.colors[_TEXT])
    otherstart = ''
    otherend = ''
    splitpoint = color.find('#')
    tags = color[:splitpoint].lower()
    color = color[splitpoint:]

    # Check for styles and set them if needed.
    if 'b' in tags:#Bold
    otherstart += '<b>'
    otherend += '</b>'
    if 'i' in tags:#Italics
    otherstart += '<i>'
    otherend += '</i>'
    if 'u' in tags:#Underline
    otherstart += '<u>'
    otherend += '</u>'

    # send text
    self.out.write('<font color="%s"%s>%s' % (color, style,
    otherstart))
    self.out.write(cgi.escape(toktext))
    self.out.write('%s</font>'% (otherend,))
    return

    def _doSnippetStart(self):
    self.out.write('<pre><font face="Lucida Console, Courier
    New">\n')

    def _doSnippetEnd(self):
    self.out.write('</pre>\n')

    def _doPageStart(self):
    self.out.write(
    '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2
    Final//EN">\n')
    self.out.write('<html><head><title>%s</title>\n'%
    (self.title))
    self.out.write('<!--This document created by %s %s on:
    %s-->\n'%

    (__title__,__version__,time.ctime()))
    self.out.write('<meta http-equiv="Content-Type" \
    content="text/html;charset=iso-8859-1" />\n')
    # Get background color and check for styles and ignore all but
    b,i,u
    color = self.colors.get(_BACKGROUND, self.colors[_TEXT])
    color = color[color.find('#'):]
    if color[:1] != '#':
    self.out.write('</head><body bgcolor="#000000">\n')
    else:
    self.out.write('</head><body bgcolor="%s">\n'% color)
    # Write a little info at the top.
    if self.header:
    self._doPageHeader()
    self.out.write('<pre><font face="Lucida Console, Courier
    New">\n')

    def _doPageHeader(self):
    color = self.colors.get(token.NAME, self.colors[_TEXT])
    color = color[color.find('#'):]
    self.out.write(' <b><u><font color="%s">%s
    %s</font></u></b>\n'%
    (color, self.title, time.ctime()))
    def _doPageFooter(self):
    color = self.colors.get(token.NAME, self.colors[_TEXT])
    color = color[color.find('#'):]
    self.out.write(' <b><u><font color="%s">%s
    %s</font></u></b>\n'%
    (color, self.title,time.ctime()))
    def _doPageEnd(self):
    self.out.write('</pre>\n')
    # Write a little info at the bottom
    if self.footer:
    self._doPageFooter()
    # Write a little info in the web page source
    self.out.write('<!--This document created by %s ver.%s on:
    %s-->\n'%

    (__title__,__version__,time.ctime()))
    self.out.write('</body></html>\n')

    if __name__ == '__main__':
    Main()
    # End of code
     
    M.E.Farmer, Oct 15, 2004
    #1
    1. Advertising

  2. (M.E.Farmer) wrote in message news:<>...
    > Hello all,
    > This version of PySourceColor supports decorators.
    > It looks like the syntax is there for a while, so I decided add them
    > in.
    > They parser code has also been extended to seperate all 12 types of
    > string.
    > I rewrote the _Null colorscheme to actually be null format.
    > Changed the old _Null to _Mono a black and white colorscheme for
    > printing.
    > Also added a few utility functions.
    > If you don't like the builtin colorschemes you should be able to write
    > a colorscheme that looks exactly like you want.
    > This is something that would be nice to have built into pydoc.
    > The links at the top-right of a pydoc page could point to a colorized
    > source and a plain text version :)
    > This program should run with Python 2.0 -> 2.4.
    > The code can be any version.
    > Just save to a file and run it.
    > It will parse itself into 6 diffrent webpages and show them.


    Hey, this is pretty cool!
    However the long lines where cut in the posted message and I had to fix
    them by hand (those are the rare situations where I would lke Python was
    not an indentation-sensitive language :-(). I also replaced "MyDir"
    with "tmp" which looks as a sensible default, at least on Unices.
    Good work,

    Michele Simionato
     
    Michele Simionato, Oct 15, 2004
    #2
    1. Advertising

  3. I'd love to play with this - but my only NNTP access is via google
    groups, which is mangling line endings.

    Any chance of it being given an http presence ?

    Regards,

    Fuzzy

    [reluctant snip of interesting code....]
     
    Michael Foord, Oct 15, 2004
    #3
  4. M.E.Farmer

    M.E.Farmer Guest

    Sorry :)
    I posted this from Google groups before I went to bed.
    I didn't see the line mangling till today. Argggghhhhhh!
    Thanks for you time and comments !
    I have changed 'MyDir' to 'tmp', good idea.
    I am not near a computer at my day job, so my response will be delayed.
    Here is a link to my webspace 'http://bellsouthpwp.net/m/e/mefjr75/'
    My site is being redesigned...that is just a temporary page.

    HTH,
    M.E.Farmer
     
    M.E.Farmer, Oct 15, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Sampson [MSFT]

    [ANN]: NNTP Server slow downs.

    Mike Sampson [MSFT], Oct 7, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    420
    Mike Sampson [MSFT]
    Oct 7, 2003
  2. Mike Sampson [MSFT]

    [ANN]: NNTP Server slow downs.

    Mike Sampson [MSFT], Dec 6, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    503
    Mike Sampson [MSFT]
    Dec 6, 2003
  3. Richard Grimes [MVP]

    ANN: Free .NET Workshops

    Richard Grimes [MVP], Jul 4, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    506
    Richard Grimes [MVP]
    Jul 4, 2005
  4. Michael Livsey
    Replies:
    3
    Views:
    429
    Michael Livsey
    May 27, 2004
  5. Replies:
    0
    Views:
    268
Loading...

Share This Page