introduce workaround for a strange behaviour of pdfTeX
[PyX/mjg.git] / www / pt2html.py
blob31268c00d2232e99be1d4f74c7e78cc18b10b76d
1 #!/usr/bin/env python
3 import sys, os, os.path, cgi, StringIO, codecs, glob
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 py2html:
23 def __init__(self, input, output):
24 self.output = output
25 self.col = 0
26 self.tokclass = None
27 self.output.write("<pre id=python>")
28 tokenize.tokenize(input.readline, self.tokeneater)
29 if self.tokclass is not None:
30 self.output.write('</span>')
31 self.output.write("</pre>\n")
33 def tokeneater(self, toktype, toktext, (srow, scol), (erow, ecol), line):
34 if toktype == token.ERRORTOKEN:
35 raise RuntimeError("ErrorToken occured")
36 if toktype in [token.NEWLINE, tokenize.NL]:
37 self.output.write('\n')
38 self.col = 0
39 else:
40 # map token type to a color group
41 if token.LPAR <= toktype and toktype <= token.OP:
42 toktype = token.OP
43 elif toktype == token.NAME and keyword.iskeyword(toktext):
44 toktype = _KEYWORD
46 # restore whitespace
47 assert scol >= self.col
48 self.output.write(" "*(scol-self.col))
50 try:
51 tokclass = tokclasses[toktype]
52 except KeyError:
53 tokclass = None
54 if self.tokclass is not None and tokclass != self.tokclass:
55 self.output.write('</span>')
56 if tokclass is not None and tokclass != self.tokclass:
57 self.output.write('<span class="%s">' % tokclass)
58 self.output.write(cgi.escape(toktext))
59 self.tokclass = tokclass
61 # calculate new column position
62 self.col = scol + len(toktext)
63 newline = toktext.rfind("\n")
64 if newline != -1:
65 self.col = len(toktext) - newline - 1
68 class example:
70 def __init__(self, basename, dir=None):
71 self.title = basename
72 if dir:
73 name = os.path.join(dir, basename)
74 else:
75 name = basename
76 relname = os.path.join("..", "examples", name)
77 htmlbuffer = StringIO.StringIO()
78 py2html(codecs.open("%s.py" % relname, encoding="iso-8859-1"), htmlbuffer)
79 self.code = htmlbuffer.getvalue()
80 self.png = "%s.png" % basename
81 self.width, self.height = Image.open("%s.png" % relname).size
82 self.downloads = []
83 for suffix in ["py", "dat", "jpg", "eps", "pdf"]:
84 try:
85 filesize = "%.1f KB" % (os.path.getsize("%s.%s" % (relname, suffix)) / 1024.0)
86 except OSError:
87 pass
88 else:
89 self.downloads.append({"filename": "%s.%s" % (basename, suffix),
90 "suffixname": ".%s" % suffix,
91 "filesize": filesize,
92 "iconname": "%s.png" % suffix})
95 class MyPageTemplateFile(PageTemplateFile):
97 def write(self, text):
98 if isinstance(text, str):
99 text = unicode(text, encoding="iso-8859-1")
100 return PageTemplateFile.write(self, text)
103 def mkrellink(linkname, options):
104 # returns a string containing the relative url for linkname (an absolute url)
105 pagename = options["pagename"]
106 while linkname.find("/") != -1 and pagename.find("/") != -1:
107 linknamefirst, linknameother = linkname.split("/", 1)
108 pagenamefirst, pagenameother = pagename.split("/", 1)
109 if linknamefirst == pagenamefirst:
110 linkname = linknameother
111 pagename = pagenameother
112 else:
113 break
114 for i in pagename.split("/")[:-1]:
115 linkname = "../" + linkname
116 return linkname
118 maintemplate = MyPageTemplateFile("maintemplate.pt")
120 latestnews = 2
121 newsdom = xml.dom.minidom.parse("news.pt")
122 news = "".join(["%s%s" % (dt.toxml(), dd.toxml())
123 for dt, dd in zip(newsdom.getElementsByTagName("dt")[:latestnews],
124 newsdom.getElementsByTagName("dd")[:latestnews])])
126 for ptname in glob.glob("*.pt"):
127 if ptname in ["maintemplate.pt", "examples.pt"]:
128 continue
129 htmlname = "%s.html" % ptname[:-3]
130 template = MyPageTemplateFile(ptname)
131 content = template(pagename=htmlname,
132 maintemplate=maintemplate,
133 examplepages=[],
134 mkrellink=mkrellink,
135 version=pyx.__version__,
136 news=news)
137 codecs.open("build/%s" % htmlname, "w", encoding="iso-8859-1").write(content)
139 examplestemplate = MyPageTemplateFile("examples.pt")
140 examplepages = [item[:-2]
141 for item in open("../examples/INDEX").readlines()
142 if item[-2] == "/"]
144 for dir in [None] + examplepages:
145 srcdir = "../examples"
146 destdir = "examples"
147 if dir:
148 srcdir = os.path.join(srcdir, dir)
149 destdir = os.path.join(destdir, dir)
150 try:
151 abstract = open(os.path.join(srcdir, "README")).read()
152 except IOError:
153 abstract = ""
154 abstract = abstract.replace("__version__", pyx.__version__).replace("\PyX{}", "PyX").replace("\TeX{}", "TeX").replace("\LaTeX{}", "LaTeX").replace("\n\n", "<br><br>")
155 examples = [example(item.strip(), dir)
156 for item in open(os.path.join(srcdir, "INDEX")).readlines()
157 if item[-2] != "/"]
158 htmlname = os.path.join(destdir, "index.html")
159 content = examplestemplate(pagename=htmlname,
160 maintemplate=maintemplate,
161 abstract=abstract,
162 examples=examples,
163 examplepages=examplepages,
164 mkrellink=mkrellink)
165 codecs.open("build/%s" % htmlname, "w", encoding="iso-8859-1").write(content)