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%(tagName)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)