import sys import os import re import imp import cgi #cfg = imp.new_module('cfg') class cfg: pass tagDict = {} class Tag: closes = [] def __init__(self): self._attr = {} self.elements = [] def default(self, value): pass def end(self): raise NotImplementedError def output(self): raise NotImplementedError def get_attrs(self): tmp = [] for key,value in self._attr.iteritems(): tmp.append('%s="%s"' % (key,value)) return ' '.join(tmp) class Presentation(Tag): def __init__(self): Tag.__init__(self) tagStack = [] def pragma_outputFile(self, value): self.outputFile = value def pragma_style(self, value): mod, func = value.split(',') self.styleMod, self.styleFunc = mod, func f, p, d = imp.find_module(mod) mod = imp.load_module(mod, f, p, d) func = getattr(mod, func) cfg.styles = func() def pragma_frame(self, value): cfg.pageFrame = tuple(value.split(',')) def pragma_footer(self, value): cfg.footerFrame = tuple(value.split(',')) def pragma_codeRatio(self, value): cfg.codeRatio = float(value) def output(self): self.setFooters() tmp = [] tmp.append('' % self.get_attrs()) mod, func = self.styleMod, self.styleFunc tmp.append('' % (mod, func)) tmp.append('
') for slide in self.elements: tmp.append(slide.output()) tmp.append('
\n
') return '\n\n'.join(tmp) def setFooters(self): numPages = len(self.elements) pageNo = 0 for slide in self.elements: pageNo += 1 slide.pageNo = pageNo slide.numPages = numPages tagDict['presentation'] = Presentation class Para(Tag): tagName = 'para' styleName = None reCode = re.compile("``([^`]+)``") def __init__(self): Tag.__init__(self) self.codeSize = None def getCodeSize(self): fontSize = cfg.styles[self.styleName].fontSize self.codeSize = round(fontSize * cfg.codeRatio, 1) def parse(self, line): if self.codeSize is None: self.getCodeSize() repl = r'\1' % self.codeSize return self.reCode.sub(repl, line) def default(self, value): value = self.parse(value) self.elements.append(value) def end(self): pass def output(self): outdict = { 'tagName': self.tagName, 'style': 'style="%s"' % self.styleName, 'data': '\n'.join(self.elements) } tmp = '<%(tagName)s %(style)s>%(data)s' % outdict return tmp Para.closes = [Para] class PreFmt(Para): tagName = 'prefmt' styleName = 'Normal' tagDict['prefmt'] = PreFmt class Slide(Tag): def __init__(self): Tag.__init__(self) def pragma_title(self, value): self._attr['title'] = value tmp = Title() tmp.default(value) self.elements.append(tmp) def pragma_head(self, value): self._attr['title'] = value.replace("``", "") tmp = Head() tmp.default(value) self.elements.append(tmp) def end(self): pass def output(self): tmp = [] tmp.append('' % self.get_attrs()) tmp.append(make_frame(cfg.pageFrame)) for tag in self.elements: tmp.append(tag.output()) tmp.append('') tmp.append(make_frame(cfg.footerFrame)) pageNo, numPages = self.pageNo, self.numPages f = '%s' % pageNo tmp.append(f) tmp.append('') tmp.append('') return '\n'.join(tmp) Slide.closes = [Para, Slide] tagDict['slide'] = Slide class Title(Para): styleName = 'title' tmp = Title tagDict[tmp.styleName] = tmp class Head(Para): styleName = 'head' tmp = Head tagDict[tmp.styleName] = tmp class SmallTitle(Para): styleName = 'smalltitle' tmp = SmallTitle tagDict[tmp.styleName] = tmp class Normal(Para): styleName = 'normal' tmp = Normal tagDict[tmp.styleName] = tmp class Bullet(Para): styleName = 'Bullet' # PythonPoint needs cap :-( tagDict['bullet'] = Bullet class Indent(Para): styleName = 'indent' tmp = Indent tagDict[tmp.styleName] = tmp class URL(Para): styleName = 'url' tmp = URL tagDict[tmp.styleName] = tmp class Code(PreFmt): styleName = 'code' def default(self, value): value = cgi.escape(value) PreFmt.default(self, value) def pragma_include(self, value): data = open(value).read() data = cgi.escape(data) self.elements.append(data) tmp = Code tagDict[tmp.styleName] = tmp class Spacer(Para): def output(self): return '' % self.get_attrs() tagDict['spacer'] = Spacer class NumberedList(Para): def default(self, value): self.elements.append(value) def output(self): i = 1 tmp = [] for item in self.elements: s = '%s. %s' % (i, item) tmp.append(s) i += 1 return '\n'.join(tmp) tagDict['numlist'] = NumberedList def make_frame(frame): return '' % frame def dispatch_tag(tag, root): newTag = tagDict[tag]() tagStack = root.tagStack #print tag, newTag.closes for tagType in newTag.closes: currTag = tagStack[-1] #print isinstance(currTag, tagType) if isinstance(currTag, tagType): currTag.end() tagStack.pop() tagStack[-1].elements.append(newTag) tagStack.append(newTag) #print tagStack def dispatch_attrib(line, root): currTag = root.tagStack[-1] key, value = line.split(' ', 1) currTag._attr[key] = value def dispatch_pragma(line, root): currTag = root.tagStack[-1] pragma, value = line.split(' ', 1) meth = getattr(currTag, 'pragma_' + pragma) meth(value) dispatch = { '.': dispatch_tag, '=': dispatch_attrib, '@': dispatch_pragma } def parse(input): root = Presentation() root.tagStack = [root] try: for line in input: line = line.rstrip() if not line: root.tagStack[-1].default(line) continue ch = line[0] if ch in dispatch: # handle continuation lines in interactive mode if line[1] == '.': root.tagStack[-1].default(line) else: dispatch[ch](line[1:], root) else: root.tagStack[-1].default(line) except KeyError: print line raise return root def write(root): f = open(root.outputFile, 'w') f.write(root.output()) # print root.output() def process(input): input = open(input) root = parse(input) write(root) if __name__ == '__main__': input = sys.argv[1] process(input)