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

Você não tem permissão para executar esta ação.

Excluir mensagem

PythonToHtml

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

Volta para CookBook.


PedroWerneck