def test_extractor(): code = ''' class Foo: def bar: pass def baz: pass ''' parts = {'bar': ['def bar', 'pass']} extractor = Extractor(parts) assert(extractor.extract(code) == code) assert(extractor.extract(code, 'bar') == 'def bar:\n pass')
class Snippetizer: '''Replaces code snippets in a Keynote presentation.''' def __init__(self, keynote_file, out_file, config_file, only = None): '''Takes input and output keynote (.key) files, a configuration file (generated by manually invoking configurize.py). The optional code snippet name restricts the replacement to a single snippet.''' self.keynote_file = keynote_file self.out_file = out_file self.only = only config = {} execfile(config_file, config) self.base = config['base'] self.extractor = Extractor(config['snippets']) self.formatter = KeynoteFormatter(config['styles']) def snippetize(self): '''Performs the snippet replacement.''' with ZipFile(self.keynote_file) as original: with ZipFile(self.out_file, 'w') as updated: for item in original.filelist: if item.filename != 'index.apxl': contents = original.read(item.filename) updated.writestr(item, contents) raw = original.read('index.apxl') doc = minidom.parseString(raw) pattern = '//sf:shape[starts-with(@sf:href,\'http://localhost/\')]' strip = 'http://localhost/' finder = Finder(doc, pattern, strip) template = '''<?xml version="1.0"?> <key:presentation xmlns:sfa="http://developer.apple.com/namespaces/sfa" xmlns:sf="http://developer.apple.com/namespaces/sf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:key="http://developer.apple.com/namespaces/keynote2"> <sf:text-body> %s </sf:text-body> </key:presentation> ''' replacer = Replacer(doc, template) names = self.only and [self.only] or finder.snippets() for name in names: filename, _, part = name.partition('?') path = expanduser(join(self.base, filename)) with open(path) as file: code = self.extractor.extract(file.read(), part) lexer = get_lexer_for_filename(filename, stripall=True) snippet = highlight(code, lexer, self.formatter) parent = '//sf:shape[@sf:href="http://localhost/%s"]//sf:text-storage' % name child = 'sf:text-body' replacer.replace(parent, child, snippet) with ZipFile(self.out_file, 'a') as updated: updated.writestr('index.apxl', doc.toxml().encode('utf-8'))