- add docstrings for palette methods
[PyX/mjg.git] / www / pt2html.py
blob584c78e0063c61d610edf9c22615d2e753177287
1 #!/usr/bin/env python
3 import sys, os, os.path, cgi, StringIO, codecs, glob, re
4 import keyword, token, tokenize
5 import xml.dom.minidom
6 from zope.pagetemplate.pagetemplatefile import PageTemplateFile
7 import Image
9 sys.path[:0]=[".."]
10 import pyx
12 _KEYWORD = token.NT_OFFSET
14 tokclasses = {token.NUMBER: 'number',
15 token.OP: 'op',
16 token.STRING: 'string',
17 tokenize.COMMENT: 'comment',
18 token.NAME: 'name',
19 _KEYWORD: 'keyword'}
21 class MakeHtml:
23 def fromPython(self, input):
24 input = StringIO.StringIO(input)
25 self.output = StringIO.StringIO()
26 self.col = 0
27 self.tokclass = None
28 self.output.write("<pre id=python>")
29 tokenize.tokenize(input.readline, self.tokeneater)
30 if self.tokclass is not None:
31 self.output.write('</span>')
32 self.output.write("</pre>\n")
33 return self.output.getvalue()
35 def tokeneater(self, toktype, toktext, (srow, scol), (erow, ecol), line):
36 if toktype == token.ERRORTOKEN:
37 raise RuntimeError("ErrorToken occured")
38 if toktype in [token.NEWLINE, tokenize.NL]:
39 self.output.write('\n')
40 self.col = 0
41 else:
42 # map token type to a color group
43 if token.LPAR <= toktype and toktype <= token.OP:
44 toktype = token.OP
45 elif toktype == token.NAME and keyword.iskeyword(toktext):
46 toktype = _KEYWORD
48 # restore whitespace
49 assert scol >= self.col
50 self.output.write(" "*(scol-self.col))
52 try:
53 tokclass = tokclasses[toktype]
54 except KeyError:
55 tokclass = None
56 if self.tokclass is not None and tokclass != self.tokclass:
57 self.output.write('</span>')
58 if tokclass is not None and tokclass != self.tokclass:
59 self.output.write('<span class="%s">' % tokclass)
60 self.output.write(cgi.escape(toktext))
61 self.tokclass = tokclass
63 # calculate new column position
64 self.col = scol + len(toktext)
65 newline = toktext.rfind("\n")
66 if newline != -1:
67 self.col = len(toktext) - newline - 1
69 emptypattern = re.compile(r"\s*$")
70 parpattern = re.compile(r"([ \t]*\n)*(?P<data>(\S[^\n]*\n)+)(([ \t]*\n)+.*)?")
71 parmakeline = re.compile(r"\s*[\r\n]\s*")
72 parmakeinline = re.compile(r"`([^`]*)`")
73 parmakeitalic = re.compile(r"''([^`]*)''")
74 parmakebold = re.compile(r"'''([^`]*)'''")
75 codepattern = re.compile(r"([ \t]*\n)*(?P<data>(([ \t]+[^\n]*)?\n)+)")
76 indentpattern = re.compile(r"([ \t]*\n)*(?P<indent>[ \t]+)")
78 def fromText(self, input):
79 pos = 0
80 output = StringIO.StringIO()
81 while not self.emptypattern.match(input, pos):
82 par = self.parpattern.match(input, pos)
83 if par:
84 pos = par.end("data")
85 par = par.group("data").strip()
86 par = par.replace("__version__", pyx.__version__)
87 par = par.replace("&", "&amp;")
88 par = par.replace("<", "&lt;")
89 par = par.replace(">", "&gt;")
90 par = par.replace("\"", "&quot;")
91 par = self.parmakeline.subn(" ", par)[0]
92 par = self.parmakeinline.subn(r"<code>\1</code>", par)[0]
93 par = self.parmakeitalic.subn(r"<em>\1</em>", par)[0]
94 par = self.parmakebold.subn(r"<strong>\1</strong>", par)[0]
95 output.write("<p>%s</p>\n" % par)
96 else:
97 code = self.codepattern.match(input, pos)
98 if not code:
99 raise RuntimeError("couldn't parse text file")
100 pos = code.end("data")
101 code = code.group("data")
102 indent = self.indentpattern.match(code).group("indent")
103 code = re.subn(r"\s*[\r\n]%s" % indent, "\n", code.strip())[0]
104 output.write("<div class=\"codeindent\">%s</div>\n" % self.fromPython(code + "\n"))
105 return output.getvalue()
107 makehtml = MakeHtml()
110 class example:
112 def __init__(self, basename, dir=None):
113 self.title = basename
114 if dir:
115 name = os.path.join(dir, basename)
116 else:
117 name = basename
118 relname = os.path.join("..", "examples", name)
119 self.code = makehtml.fromPython(codecs.open("%s.py" % relname, encoding="iso-8859-1").read())
120 self.html = "%s.html" % basename
121 self.png = "%s.png" % basename
122 self.width, self.height = Image.open("%s.png" % relname).size
123 self.thumbpng = "%s_thumb.png" % basename
124 self.thumbwidth, self.thumbheight = Image.open("%s_thumb.png" % relname).size
125 self.downloads = []
126 for suffix in ["py", "dat", "jpg", "eps", "pdf"]:
127 try:
128 filesize = "%.1f KB" % (os.path.getsize("%s.%s" % (relname, suffix)) / 1024.0)
129 except OSError:
130 pass
131 else:
132 self.downloads.append({"filename": "%s.%s" % (basename, suffix),
133 "suffixname": ".%s" % suffix,
134 "filesize": filesize,
135 "iconname": "%s.png" % suffix})
136 if os.path.exists("%s.txt" % relname):
137 self.text = makehtml.fromText(codecs.open("%s.txt" % relname, encoding="iso-8859-1").read())
138 else:
139 self.text = None
142 class MyPageTemplateFile(PageTemplateFile):
144 def write(self, text):
145 if isinstance(text, str):
146 text = unicode(text, encoding="iso-8859-1")
147 return PageTemplateFile.write(self, text)
150 def mkrellink(linkname, options):
151 # returns a string containing the relative url for linkname (an absolute url)
152 pagename = options["pagename"]
153 while linkname.find("/") != -1 and pagename.find("/") != -1:
154 linknamefirst, linknameother = linkname.split("/", 1)
155 pagenamefirst, pagenameother = pagename.split("/", 1)
156 if linknamefirst == pagenamefirst:
157 linkname = linknameother
158 pagename = pagenameother
159 else:
160 break
161 for i in pagename.split("/")[:-1]:
162 linkname = "../" + linkname
163 return linkname
165 maintemplate = MyPageTemplateFile("maintemplate.pt")
167 latestnews = 2
168 newsdom = xml.dom.minidom.parse("news.pt")
169 news = "".join(["%s%s" % (dt.toxml(), dd.toxml())
170 for dt, dd in zip(newsdom.getElementsByTagName("dt")[:latestnews],
171 newsdom.getElementsByTagName("dd")[:latestnews])])
173 for ptname in glob.glob("*.pt"):
174 if ptname not in ["maintemplate.pt", "exampleindex.pt", "examples.pt", "example.pt"]:
175 htmlname = "%s.html" % ptname[:-3]
176 template = MyPageTemplateFile(ptname)
177 content = template(pagename=htmlname,
178 maintemplate=maintemplate,
179 examplepages=[],
180 mkrellink=mkrellink,
181 version=pyx.__version__,
182 news=news)
183 codecs.open("build/%s" % htmlname, "w", encoding="iso-8859-1").write(content)
185 exampleindextemplate = MyPageTemplateFile("exampleindex.pt")
186 examplestemplate = MyPageTemplateFile("examples.pt")
187 exampletemplate = MyPageTemplateFile("example.pt")
188 examplepages = [item[:-2]
189 for item in open("../examples/INDEX").readlines()
190 if item[-2] == "/"]
192 prev = None
193 for dirindex, dir in enumerate([None] + examplepages):
194 srcdir = "../examples"
195 destdir = "examples"
196 try:
197 nextdir = examplepages[dirindex] # don't increment due to the None in the list
198 nextdir = os.path.join(destdir, nextdir)
199 except IndexError:
200 nextdir = None
201 if dir:
202 srcdir = os.path.join(srcdir, dir)
203 destdir = os.path.join(destdir, dir)
204 try:
205 abstract = makehtml.fromText(open(os.path.join(srcdir, "README")).read())
206 except IOError:
207 abstract = ""
208 examples = [example(item.strip(), dir)
209 for item in open(os.path.join(srcdir, "INDEX")).readlines()
210 if item[-2] != "/"]
211 htmlname = os.path.join(destdir, "index.html")
212 if dir:
213 template = examplestemplate
214 next = os.path.join(destdir, examples[0].html)
215 else:
216 template = exampleindextemplate
217 next = os.path.join(nextdir, "index.html")
218 content = template(pagename=htmlname,
219 maintemplate=maintemplate,
220 dir=dir,
221 abstract=abstract,
222 examples=examples,
223 examplepages=examplepages,
224 mkrellink=mkrellink,
225 prev=prev,
226 next=next)
227 #print next, htmlname
228 #for line in content.split("\n"):
229 # if line.find("next") != -1:
230 # print line
231 codecs.open("build/%s" % htmlname, "w", encoding="iso-8859-1").write(content)
232 prev = os.path.join(destdir, "index.html")
233 if dir:
234 for exampleindex, aexample in enumerate(examples):
235 try:
236 next = os.path.join(destdir, examples[exampleindex+1].html)
237 except (TypeError, IndexError):
238 if nextdir:
239 next = os.path.join(nextdir, "index.html")
240 else:
241 next = None
242 htmlname = os.path.join(destdir, "%s.html" % aexample.title)
243 content = exampletemplate(pagename=htmlname,
244 maintemplate=maintemplate,
245 dir=dir,
246 abstract=abstract,
247 example=aexample,
248 examplepages=examplepages,
249 mkrellink=mkrellink,
250 prev=prev,
251 next=next)
252 codecs.open("build/%s" % htmlname, "w", encoding="iso-8859-1").write(content)
253 prev = os.path.join(destdir, aexample.html)