6721
Comentário:
|
6932
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.