1 import sys
, os
, os
.path
, cgi
, StringIO
, codecs
, glob
, re
, warnings
2 import keyword
, token
, tokenize
4 from zope
.pagetemplate
.pagetemplate
import PageTemplate
10 def PageTemplateFile(filename
):
12 pt
.write(codecs
.open(filename
, "r", encoding
="utf-8").read())
15 _KEYWORD
= token
.NT_OFFSET
17 tokclasses
= {token
.NUMBER
: 'number',
19 token
.STRING
: 'string',
20 tokenize
.COMMENT
: 'comment',
26 def fromPython(self
, input):
27 input = StringIO
.StringIO(input)
28 self
.output
= StringIO
.StringIO()
31 self
.output
.write("<pre id=python>")
32 tokenize
.tokenize(input.readline
, self
.tokeneater
)
33 if self
.tokclass
is not None:
34 self
.output
.write('</span>')
35 self
.output
.write("</pre>\n")
36 return self
.output
.getvalue()
38 def tokeneater(self
, toktype
, toktext
, (srow
, scol
), (erow
, ecol
), line
):
39 if toktype
== token
.ERRORTOKEN
:
40 raise RuntimeError("ErrorToken occured")
41 if toktype
in [token
.NEWLINE
, tokenize
.NL
]:
42 self
.output
.write('\n')
45 # map token type to a color group
46 if token
.LPAR
<= toktype
and toktype
<= token
.OP
:
48 elif toktype
== token
.NAME
and keyword
.iskeyword(toktext
):
52 assert scol
>= self
.col
53 self
.output
.write(" "*(scol
-self
.col
))
56 tokclass
= tokclasses
[toktype
]
59 if self
.tokclass
is not None and tokclass
!= self
.tokclass
:
60 self
.output
.write('</span>')
61 if tokclass
is not None and tokclass
!= self
.tokclass
:
62 self
.output
.write('<span class="%s">' % tokclass
)
63 self
.output
.write(cgi
.escape(toktext
))
64 self
.tokclass
= tokclass
66 # calculate new column position
67 self
.col
= scol
+ len(toktext
)
68 newline
= toktext
.rfind("\n")
70 self
.col
= len(toktext
) - newline
- 1
72 emptypattern
= re
.compile(r
"\s*$")
73 parpattern
= re
.compile(r
"([ \t]*\n)*(?P<data>(\S[^\n]*\n)+)(([ \t]*\n)+.*)?")
74 parmakeline
= re
.compile(r
"\s*[\r\n]\s*")
75 parmakeinline
= re
.compile(r
"`(.*?)`")
76 parmakebold
= re
.compile(r
"'''(.*?)'''")
77 parmakeitalic
= re
.compile(r
"''(.*?)''")
78 parmakeref
= re
.compile(r
"\[([^]]*)\s([^\s]*)\]")
79 codepattern
= re
.compile(r
"([ \t]*\n)*(?P<data>(([ \t]+[^\n]*)?\n)+)")
80 indentpattern
= re
.compile(r
"([ \t]*\n)*(?P<indent>[ \t]+)")
82 def fromText(self
, input, bend
=""):
85 output
= StringIO
.StringIO()
86 while not self
.emptypattern
.match(input, pos
):
87 par
= self
.parpattern
.match(input, pos
)
90 par
= par
.group("data").strip()
91 par
= par
.replace("__version__", pyx
.__version
__)
92 par
= par
.replace("&", "&")
93 par
= par
.replace("<", "<")
94 par
= par
.replace(">", ">")
95 par
= par
.replace("\"", """)
96 par
= self
.parmakeline
.subn(" ", par
)[0]
97 par
= self
.parmakeinline
.subn(r
"<code>\1</code>", par
)[0]
98 par
= self
.parmakebold
.subn(r
"<strong>\1</strong>", par
)[0]
99 par
= self
.parmakeitalic
.subn(r
"<em>\1</em>", par
)[0]
100 par
= self
.parmakeref
.subn(r
'<a href="\2">\1</a>', par
)[0]
105 while par
.startswith("!"):
107 warnings
.warn("ignore bend sign")
111 output
.write("%s<p>%s</p>\n" % (bend
*bends
, par
))
113 code
= self
.codepattern
.match(input, pos
)
115 raise RuntimeError("couldn't parse text file")
116 pos
= code
.end("data")
117 code
= code
.group("data")
118 indent
= self
.indentpattern
.match(code
).group("indent")
119 code
= re
.subn(r
"\s*[\r\n]%s" % indent
, "\n", code
.strip())[0]
120 if len(indent
.expandtabs()) >= 4:
121 code
= self
.fromPython(code
+ "\n")
123 code
= "<pre>%s</pre>" % code
124 output
.write("<div class=\"codeindent\">%s</div>\n" % code
)
125 text
= output
.getvalue()
126 shorttext
= text
.split("...")[0]
127 text
= text
.replace("...", "", 1)
128 return title
, shorttext
, text
130 makehtml
= MakeHtml()
135 def __init__(self
, basesrcdir
, dir, basename
):
136 self
.basename
= basename
138 name
= os
.path
.join(dir, basename
)
141 relname
= os
.path
.join(basesrcdir
, name
)
142 self
.filename
= "%s.py" % name
143 self
.code
= makehtml
.fromPython(codecs
.open("%s.py" % relname
, encoding
="utf-8").read())
144 self
.html
= "%s.html" % basename
145 self
.png
= "%s.png" % basename
146 self
.width
, self
.height
= Image
.open("%s.png" % relname
).size
147 self
.thumbpng
= "%s_thumb.png" % basename
148 self
.thumbwidth
, self
.thumbheight
= Image
.open("%s_thumb.png" % relname
).size
150 for suffix
in ["py", "dat", "jpg", "eps", "pdf"]:
152 filesize
= "%.1f KB" % (os
.path
.getsize("%s.%s" % (relname
, suffix
)) / 1024.0)
156 self
.downloads
.append({"filename": "%s.%s" % (basename
, suffix
),
157 "suffixname": ".%s" % suffix
,
158 "filesize": filesize
,
159 "iconname": "%s.png" % suffix
})
160 if os
.path
.exists("%s.txt" % relname
):
161 self
.title
, self
.shorttext
, self
.text
= makehtml
.fromText(codecs
.open("%s.txt" % relname
, encoding
="utf-8").read(), bend
="<div class=\"examplebend\"><img src=\"../../bend.png\" width=22 height=31></div>\n")
163 self
.title
= basename
164 self
.shorttext
= self
.text
= None
167 def mkrellink(linkname
, options
):
168 # returns a string containing the relative url for linkname (an absolute url)
169 pagename
= options
["pagename"]
170 while linkname
.find("/") != -1 and pagename
.find("/") != -1:
171 linknamefirst
, linknameother
= linkname
.split("/", 1)
172 pagenamefirst
, pagenameother
= pagename
.split("/", 1)
173 if linknamefirst
== pagenamefirst
:
174 linkname
= linknameother
175 pagename
= pagenameother
178 for i
in pagename
.split("/")[:-1]:
179 linkname
= "../" + linkname
182 maintemplate
= PageTemplateFile("maintemplate.pt")
185 newsdom
= xml
.dom
.minidom
.parse("news.pt")
186 news
= "".join(["%s%s" % (dt
.toxml(), dd
.toxml())
187 for dt
, dd
in zip(newsdom
.getElementsByTagName("dt")[:latestnews
],
188 newsdom
.getElementsByTagName("dd")[:latestnews
])])
190 for ptname
in glob
.glob("*.pt"):
191 if ptname
not in ["maintemplate.pt", "exampleindex.pt", "examples.pt", "example.pt"]:
192 htmlname
= "%s.html" % ptname
[:-3]
193 template
= PageTemplateFile(ptname
)
194 content
= template(pagename
=htmlname
,
195 maintemplate
=maintemplate
,
198 version
=pyx
.__version
__,
200 codecs
.open("build/%s" % htmlname
, "w", encoding
="utf-8").write(content
)
203 def processexamples(basedir
):
204 exampleindextemplate
= PageTemplateFile("exampleindex.pt")
205 examplestemplate
= PageTemplateFile("examples.pt")
206 exampletemplate
= PageTemplateFile("example.pt")
210 for dir in open(os
.path
.join("..", basedir
, "INDEX")).readlines():
212 if dir.endswith("/"):
213 exampledirs
.append(dir)
214 dir = dir.rstrip("/")
216 title
= open(os
.path
.join("..", basedir
, dir, "README")).readline().strip()
219 examplepages
.append({"dir": dir, "title": title
})
222 for dirindex
, dir in enumerate(exampledirs
):
224 srcdir
= os
.path
.join("..", basedir
, dir)
225 destdir
= os
.path
.join(basedir
, dir)
226 bend
= "<div class=\"examplebend\"><img src=\"../../bend.png\" width=22 height=31></div>\n"
228 srcdir
= os
.path
.join("..", basedir
)
230 bend
= "<div class=\"examplebend\"><img src=\"../bend.png\" width=22 height=31></div>\n"
232 nextdir
= exampledirs
[dirindex
+ 1]
233 nextdir
= os
.path
.join(basedir
, nextdir
)
237 title
, shorttext
, text
= makehtml
.fromText(open(os
.path
.join(srcdir
, "README")).read(), bend
=bend
)
241 examples
= [example(os
.path
.join("..", basedir
), dir, item
.strip())
242 for item
in open(os
.path
.join(srcdir
, "INDEX")).readlines()
244 htmlname
= os
.path
.join(destdir
, "index.html")
246 template
= examplestemplate
247 next
= os
.path
.join(destdir
, examples
[0].html
)
249 template
= exampleindextemplate
250 next
= os
.path
.join(nextdir
, "index.html")
251 content
= template(pagename
=htmlname
,
252 maintemplate
=maintemplate
,
258 subpages
=examplepages
,
262 codecs
.open("build/%s" % htmlname
, "w", encoding
="utf-8").write(content
)
263 prev
= os
.path
.join(destdir
, "index.html")
265 for exampleindex
, aexample
in enumerate(examples
):
267 next
= os
.path
.join(destdir
, examples
[exampleindex
+1].html
)
268 except (TypeError, IndexError):
270 next
= os
.path
.join(nextdir
, "index.html")
273 htmlname
= os
.path
.join(destdir
, "%s.html" % aexample
.basename
)
274 content
= exampletemplate(pagename
=htmlname
,
275 maintemplate
=maintemplate
,
279 subpages
=examplepages
,
283 codecs
.open("build/%s" % htmlname
, "w", encoding
="utf-8").write(content
)
284 prev
= os
.path
.join(destdir
, aexample
.html
)
287 processexamples("examples")
288 processexamples("gallery")