associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

Diferenças para "PythonToHtml"

Diferenças entre as versões de 3 e 4
Revisão 3e 2004-08-16 02:22:27
Tamanho: 6721
Comentário:
Revisão 4e 2008-09-26 14:05:50
Tamanho: 6932
Editor: localhost
Comentário: converted to 1.6 markup
Nenhuma diferença encontrada!

Python To HTML

Na verdade, isso não é exatamente uma receita. É uma pequena aplicação que imaginei que pudesse ser útil para alguns e não encontrei lugar melhor para colocar.

É um software simples que gera a partir do seu código Python, o código HTML para exibi-lo com coloração de sintaxe. A parte do código para a colorização foi retirada do proprio Moin. A interface para selecionar as cores e arquivos usa Tkinter.

Código

   1 import Tkinter
   2 import tkColorChooser
   3 import tkFileDialog
   4 from Tkconstants import *
   5 
   6 import cgi
   7 import string
   8 import sys
   9 import cStringIO
  10 import keyword
  11 import token
  12 import tokenize
  13 
  14 
  15 _KEYWORD = token.NT_OFFSET + 1
  16 _TEXT    = token.NT_OFFSET + 2
  17 
  18 
  19 class Parser:
  20     """ Send colored python source.
  21     """
  22 
  23     def __init__(self, raw, colors, out = sys.stdout):
  24         """ Store the source text.
  25         """
  26         self.raw = string.strip(string.expandtabs(raw))
  27         self.colors = colors
  28         self.out = out
  29 
  30     def format(self, formatter, form):
  31         """ Parse and send the colored source.
  32         """
  33         # store line offsets in self.lines
  34         self.lines = [0, 0]
  35         pos = 0
  36         while 1:
  37             pos = string.find(self.raw, '\n', pos) + 1
  38             if not pos: break
  39             self.lines.append(pos)
  40         self.lines.append(len(self.raw))
  41 
  42         # parse the source and write it
  43         self.pos = 0
  44         text = cStringIO.StringIO(self.raw)
  45         self.out.write('<pre><font face="Lucida,Courier New">')
  46         try:
  47             tokenize.tokenize(text.readline, self)
  48         except tokenize.TokenError, ex:
  49             msg = ex[0]
  50             line = ex[1][0]
  51             self.out.write("<h3>ERROR: %s</h3>%s\n" % (
  52                 msg, self.raw[self.lines[line]:]))
  53         self.out.write('</font></pre>')
  54 
  55     def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line):
  56         """ Token handler.
  57         """
  58         if 0:
  59             print "type", toktype, token.tok_name[toktype], "text", toktext,
  60             print "start", srow,scol, "end", erow,ecol, "<br>"
  61 
  62         # calculate new positions
  63         oldpos = self.pos
  64         newpos = self.lines[srow] + scol
  65         self.pos = newpos + len(toktext)
  66 
  67         # handle newlines
  68         if toktype in [token.NEWLINE, tokenize.NL]:
  69             self.out.write('\n')
  70             return
  71 
  72         # send the original whitespace, if needed
  73         if newpos > oldpos:
  74             self.out.write(self.raw[oldpos:newpos])
  75 
  76         # skip indenting tokens
  77         if toktype in [token.INDENT, token.DEDENT]:
  78             self.pos = newpos
  79             return
  80 
  81         # map token type to a color group
  82         if token.LPAR <= toktype and toktype <= token.OP:
  83             toktype = token.OP
  84         elif toktype == token.NAME and keyword.iskeyword(toktext):
  85             toktype = _KEYWORD
  86         color = self.colors.get(toktype, self.colors[_TEXT])
  87 
  88         style = ''
  89         if toktype == token.ERRORTOKEN:
  90             style = ' style="border: solid 1.5pt #FF0000;"'
  91 
  92         # send text
  93         self.out.write('<font color="%s"%s>' % (color, style))
  94         self.out.write(cgi.escape(toktext))
  95         self.out.write('</font>')
  96 
  97 
  98 
  99 class MainWindow(Tkinter.Tk):
 100     def __init__(self):
 101         Tkinter.Tk.__init__(self)
 102         self.title("TkColorizer")
 103         self.colors = {"Numbers":"#0080C0",
 104                        "Operators":"#0000C0",
 105                        "Strings":"#004080",
 106                        "Comments":"#008000",
 107                        "Names":"#000000",
 108                        "Errors":"#FF8080",
 109                        "Keywords":"#C00000",
 110                        "Text":"#000000"}
 111         self.build()
 112 
 113     def build(self):
 114         lbody = Tkinter.Frame(self)
 115         for k, v in self.colors.items():
 116             b = Tkinter.Label(lbody, text=k, padx=30, bg=v)
 117             b.pack(expand=1, fill=BOTH)
 118             b.bind("<Button-1>", self.changeColor)
 119             self.setFg(b)
 120         lbody.pack(expand=1, fill=BOTH, side=TOP)
 121 
 122         rbody = Tkinter.Frame(self)
 123         self.input = Tkinter.StringVar()
 124         self.output = Tkinter.StringVar()
 125         Tkinter.Label(rbody, text="Input:").grid(row=0, column=0)
 126         Tkinter.Entry(rbody, textvariable=self.input).grid(row=0, column=1)
 127         Tkinter.Button(rbody, text="...", command=self.askinput,
 128                        bd=1).grid(row=0, column=2)
 129         Tkinter.Label(rbody, text="Output:").grid(row=1, column=0)
 130         Tkinter.Entry(rbody, textvariable=self.output).grid(row=1, column=1)
 131         Tkinter.Button(rbody, text="...", command=self.askoutput,
 132                        bd=1).grid(row=1, column=2)
 133         Tkinter.Button(rbody, text="Generate HTML",
 134                        command=self.done).grid(row=2, column=1)
 135         rbody.pack(expand=1, fill=BOTH, side=BOTTOM)
 136 
 137     def done(self, event=None):
 138         raw = open(self.input.get()).read()
 139         out = open(self.output.get(), "wt")
 140         colors = {token.NUMBER:self.colors['Numbers'],
 141                   token.OP:self.colors['Operators'],
 142                   token.STRING:self.colors['Strings'],
 143                   tokenize.COMMENT:self.colors['Comments'],
 144                   token.NAME:self.colors['Names'],
 145                   token.ERRORTOKEN:self.colors['Errors'],
 146                    _KEYWORD:self.colors['Keywords'],
 147                   _TEXT:self.colors['Text']
 148                   }
 149 
 150         Parser(raw, colors, out).format(None, None)
 151         self.destroy()
 152 
 153     def askinput(self, event=None):
 154         ft = [("Python source file", "*.py"),
 155               ("All files", "*.*")]
 156         file = tkFileDialog.askopenfilename(parent=self, filetypes=ft)
 157         if file:
 158             self.input.set(file)
 159         
 160     def askoutput(self, event=None):
 161         ft = [("HTML file", "*.html"),
 162               ("HTML file", "*.htm"),
 163               ("All files", "*.*")]
 164         file = tkFileDialog.asksaveasfilename(parent=self, filetypes=ft)
 165         if file:
 166             self.output.set(file)
 167         
 168     def setFg(self, button):
 169         bg = eval("0x" + button['bg'][1:])
 170         set = [(bg >> 8*x) % 256 for x in (0, 1, 2)]
 171         if sum(set)/3 < 85:
 172             button['fg'] = "#FFFFFF"
 173         else:
 174             button['fg'] = "#000000"
 175         
 176     def changeColor(self, event=None):
 177         w = event.widget
 178         k = w['text']
 179         c = w['bg']
 180         a, b = tkColorChooser.askcolor(parent=self, initialcolor=c, title=k)
 181         if b is not None:
 182             w['bg'] = b
 183             self.colors[k] = b
 184             self.setFg(w)
 185             
 186         
 187 if __name__ == "__main__":
 188     root = MainWindow()
 189     root.mainloop()

Volta para CookBook.


PedroWerneck