Skip to content

Instantly share code, notes, and snippets.

@cheery
Created August 12, 2012 21:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cheery/3334706 to your computer and use it in GitHub Desktop.
Save cheery/3334706 to your computer and use it in GitHub Desktop.
Relatively straightforward structural editor's stub (WIP)
import util
@util.make_list
def mkslots(data):
for obj in data:
if isinstance(obj, Template) or obj == None:
yield One(obj)
else:
try:
g = iter(obj)
except TypeError:
raise Exception("%r: unknown document encoding" % obj)
yield Many(g)
class Template(object):
def __init__(self, name, data):
self.name = name
self.slots = mkslots(data)
def __iter__(self):
for slot in self.slots:
yield slot.data
def copy(self):
return Template(self.name, self)
@util.make_list
def unpack(data):
for obj in data:
if isinstance(obj, (unicode, bytes)):
for ch in obj:
yield ch
elif isinstance(obj, Template):
yield obj.copy()
else:
raise Exception("%r: unknown document encoding" % obj)
@util.make_list
def pack(data, duplicate=True):
out = u""
for obj in data:
if isinstance(obj, (unicode, bytes)):
out += obj
elif isinstance(obj, Template):
if len(out) > 0:
yield out
out = u""
if duplicate:
yield obj.copy()
else:
yield obj
else:
raise Exception("%r: unknown document encoding" % obj)
if len(out) > 0:
yield out
class One(object):
def __init__(self, data):
self.data = data
# is this method necessary somewhere?
# def replace(self, data):
# removed = self.data
# self.data = data.copy()
# return removed.copy()
@property
def empty(self):
return self.data == None
class Many(object):
def __init__(self, data):
self.objects = unpack(data)
@property
def data(self):
return pack(self.objects, duplicate=False)
def splice(self, start, stop, data=()):
drop = self.objects[start:stop]
self.objects[start:stop] = unpack(data)
return pack(drop)
def slice(self, start, stop):
return pack(self.objects[start:stop])
@property
def first(self):
return 0
@property
def last(self):
return len(self.objects)
def ref(self, start, stop):
if stop == start + 1:
obj = self.objects[start]
if isinstance(obj, Template):
return obj
else:
return pack(self.objects[start:stop], duplicate=False)
def segments(self):
base = 0
for obj in self.data:
start = base
if isinstance(obj, (bytes, unicode)):
base += len(obj)
else:
base += 1
yield Segment(self, start, base)
def boundaries(self):
base = 0
yield base
for obj in self.data:
if isinstance(obj, (bytes, unicode)):
base += len(obj)
else:
base += 1
yield base
def empty(self):
return len(self.objects) == 0
class Segment(object):
def __init__(self, slot, start, stop):
self.slot = slot
self.start = start
self.stop = stop
@property
def data(self):
return self.slot.ref(self.start, self.stop)
class Factory(object):
def __getattr__(self, name):
def _impl(*args):
return Template(name, args)
return _impl
__all__ = ["Template", "One", "Many", "Segment", "Factory"]
from core import Template, One, Many, Segment, Factory
import json
class TreeEncoder(json.JSONEncoder):
def default(self, obj):
return {
"name": obj.name,
"data": list(obj)
}
def as_tree(dct):
return Template(**dct)
def load(fd):
return json.load(fd, object_hook=as_tree)
def dump(tree, fd):
return json.dump(tree, fd, cls=TreeEncoder)
# a test routine used to produce a file.
if __name__ == "__main__":
a = Factory()
tree = a.root([
"Greetings, this editor is a spinoff from ",
a.link(
["EERP (essential editor research project)"],
["http://github.com/cheery/essence"],
),
".",
])
dump(tree, open('hello.jsontree', 'w'))
from core import Template, One, Many, Segment
def layout(tree, config):
return Stub()
class Stub(object):
def render(self, area):
pass
#!/usr/bin/env python
# empty, load, font, patch9
from ui import eventloop, window, defaultfont, color
from core import Template, One, Many, Segment, Factory
from layouter import layout
import jsontree
import sys, os
phi = 1.61803399
window_width = int(300*phi)
window_height = int(window_width*phi)
red = color(0x20, 0x00, 0x00)
blue = color(0x00, 0x00, 0x90)
a = Factory()
recognised_file_formats = {
".jsontree": jsontree,
}
class Editor(object):
def __init__(self):
self.window = window(window_width, window_height)
self.window.show()
self.window.on('paint', self.paint)
self.window.on('keydown', self.keydown)
self.filename = sys.argv[1]
file_format = os.path.splitext(self.filename)[1]
if not file_format in recognised_file_formats:
raise Exception("unknown file format.")
self.root = recognised_file_formats[file_format].load(open(self.filename, 'r'))
self.layout_config = dict(
font = defaultfont()
)
def keydown(self, key, modifiers, unicode):
#print key, modifiers, unicode
if key == 'escape':
sys.exit(0)
if key == 'space':
self.mode.insert_element(a.space())
if len(unicode) > 0:
self.mode.insert_text(unicode)
def paint(self, screen):
color(0x10, 0x10, 0x10)(screen)
frames = layout(self.root, self.layout_config)
frames.render(screen)
if __name__ == "__main__":
os.environ['SDL_VIDEO_CENTERED'] = '1'
editor = Editor()
eventloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment