diff --git a/Lib/Para.py b/Lib/Para.py
deleted file mode 100644
index 709b575..0000000
--- a/Lib/Para.py
+++ /dev/null
@@ -1,409 +0,0 @@
-# Text formatting abstractions
-# Note -- this module is obsolete, it's too slow anyway
-
-
-# Oft-used type object
-Int = type(0)
-
-
-# Represent a paragraph.  This is a list of words with associated
-# font and size information, plus indents and justification for the
-# entire paragraph.
-# Once the words have been added to a paragraph, it can be laid out
-# for different line widths.  Once laid out, it can be rendered at
-# different screen locations.  Once rendered, it can be queried
-# for mouse hits, and parts of the text can be highlighted
-class Para:
-	#
-	def __init__(self):
-		self.words = [] # The words
-		self.just = 'l' # Justification: 'l', 'r', 'lr' or 'c'
-		self.indent_left = self.indent_right = self.indent_hang = 0
-		# Final lay-out parameters, may change
-		self.left = self.top = self.right = self.bottom = \
-			self.width = self.height = self.lines = None
-	#
-	# Add a word, computing size information for it.
-	# Words may also be added manually by appending to self.words
-	# Each word should be a 7-tuple:
-	# (font, text, width, space, stretch, ascent, descent)
-	def addword(self, d, font, text, space, stretch):
-		if font <> None:
-			d.setfont(font)
-		width = d.textwidth(text)
-		ascent = d.baseline()
-		descent = d.lineheight() - ascent
-		spw = d.textwidth(' ')
-		space = space * spw
-		stretch = stretch * spw
-		tuple = (font, text, width, space, stretch, ascent, descent)
-		self.words.append(tuple)
-	#
-	# Hooks to begin and end anchors -- insert numbers in the word list!
-	def bgn_anchor(self, id):
-		self.words.append(id)
-	#
-	def end_anchor(self, id):
-		self.words.append(0)
-	#
-	# Return the total length (width) of the text added so far, in pixels
-	def getlength(self):
-		total = 0
-		for word in self.words:
-			if type(word) <> Int:
-				total = total + word[2] + word[3]
-		return total
-	#
-	# Tab to a given position (relative to the current left indent):
-	# remove all stretch, add fixed space up to the new indent.
-	# If the current position is already beying the tab stop,
-	# don't add any new space (but still remove the stretch)
-	def tabto(self, tab):
-		total = 0
-		as, de = 1, 0
-		for i in range(len(self.words)):
-			word = self.words[i]
-			if type(word) == Int: continue
-			(fo, te, wi, sp, st, as, de) = word
-			self.words[i] = (fo, te, wi, sp, 0, as, de)
-			total = total + wi + sp
-		if total < tab:
-			self.words.append((None, '', 0, tab-total, 0, as, de))
-	#
-	# Make a hanging tag: tab to hang, increment indent_left by hang,
-	# and reset indent_hang to -hang
-	def makehangingtag(self, hang):
-		self.tabto(hang)
-		self.indent_left = self.indent_left + hang
-		self.indent_hang = -hang
-	#
-	# Decide where the line breaks will be given some screen width
-	def layout(self, linewidth):
-		self.width = linewidth
-		height = 0
-		self.lines = lines = []
-		avail1 = self.width - self.indent_left - self.indent_right
-		avail = avail1 - self.indent_hang
-		words = self.words
-		i = 0
-		n = len(words)
-		lastfont = None
-		while i < n:
-			firstfont = lastfont
-			charcount = 0
-			width = 0
-			stretch = 0
-			ascent = 0
-			descent = 0
-			lsp = 0
-			j = i
-			while i < n:
-				word = words[i]
-				if type(word) == Int:
-					if word > 0 and width >= avail:
-						break
-					i = i+1
-					continue
-				fo, te, wi, sp, st, as, de = word
-				if width + wi > avail and width > 0 and wi > 0:
-					break
-				if fo <> None:
-					lastfont = fo
-					if width == 0:
-						firstfont = fo
-				charcount = charcount + len(te) + (sp > 0)
-				width = width + wi + sp
-				lsp = sp
-				stretch = stretch + st
-				lst = st
-				ascent = max(ascent, as)
-				descent = max(descent, de)
-				i = i+1
-			while i > j and type(words[i-1]) == Int and \
-				words[i-1] > 0: i = i-1
-			width = width - lsp
-			if i < n:
-				stretch = stretch - lst
-			else:
-				stretch = 0
-			tuple = i-j, firstfont, charcount, width, stretch, \
-				ascent, descent
-			lines.append(tuple)
-			height = height + ascent + descent
-			avail = avail1
-		self.height = height
-	#
-	# Call a function for all words in a line
-	def visit(self, wordfunc, anchorfunc):
-		avail1 = self.width - self.indent_left - self.indent_right
-		avail = avail1 - self.indent_hang
-		v = self.top
-		i = 0
-		for tuple in self.lines:
-			wordcount, firstfont, charcount, width, stretch, \
-				ascent, descent = tuple
-			h = self.left + self.indent_left
-			if i == 0: h = h + self.indent_hang
-			extra = 0
-			if self.just == 'r': h = h + avail - width
-			elif self.just == 'c': h = h + (avail - width) / 2
-			elif self.just == 'lr' and stretch > 0:
-				extra = avail - width
-			v2 = v + ascent + descent
-			for j in range(i, i+wordcount):
-				word = self.words[j]
-				if type(word) == Int:
-					ok = anchorfunc(self, tuple, word, \
-							h, v)
-					if ok <> None: return ok
-					continue
-				fo, te, wi, sp, st, as, de = word
-				if extra > 0 and stretch > 0:
-					ex = extra * st / stretch
-					extra = extra - ex
-					stretch = stretch - st
-				else:
-					ex = 0
-				h2 = h + wi + sp + ex
-				ok = wordfunc(self, tuple, word, h, v, \
-					h2, v2, (j==i), (j==i+wordcount-1))
-				if ok <> None: return ok
-				h = h2
-			v = v2
-			i = i + wordcount
-			avail = avail1
-	#
-	# Render a paragraph in "drawing object" d, using the rectangle
-	# given by (left, top, right) with an unspecified bottom.
-	# Return the computed bottom of the text.
-	def render(self, d, left, top, right):
-		if self.width <> right-left:
-			self.layout(right-left)
-		self.left = left
-		self.top = top
-		self.right = right
-		self.bottom = self.top + self.height
-		self.anchorid = 0
-		try:
-			self.d = d
-			self.visit(self.__class__._renderword, \
-				   self.__class__._renderanchor)
-		finally:
-			self.d = None
-		return self.bottom
-	#
-	def _renderword(self, tuple, word, h, v, h2, v2, isfirst, islast):
-		if word[0] <> None: self.d.setfont(word[0])
-		baseline = v + tuple[5]
-		self.d.text((h, baseline - word[5]), word[1])
-		if self.anchorid > 0:
-			self.d.line((h, baseline+2), (h2, baseline+2))
-	#
-	def _renderanchor(self, tuple, word, h, v):
-		self.anchorid = word
-	#
-	# Return which anchor(s) was hit by the mouse
-	def hitcheck(self, mouseh, mousev):
-		self.mouseh = mouseh
-		self.mousev = mousev
-		self.anchorid = 0
-		self.hits = []
-		self.visit(self.__class__._hitcheckword, \
-			   self.__class__._hitcheckanchor)
-		return self.hits
-	#
-	def _hitcheckword(self, tuple, word, h, v, h2, v2, isfirst, islast):
-		if self.anchorid > 0 and h <= self.mouseh <= h2 and \
-			v <= self.mousev <= v2:
-			self.hits.append(self.anchorid)
-	#
-	def _hitcheckanchor(self, tuple, word, h, v):
-		self.anchorid = word
-	#
-	# Return whether the given anchor id is present
-	def hasanchor(self, id):
-		return id in self.words or -id in self.words
-	#
-	# Extract the raw text from the word list, substituting one space
-	# for non-empty inter-word space, and terminating with '\n'
-	def extract(self):
-		text = ''
-		for w in self.words:
-			if type(w) <> Int:
-				word = w[1]
-				if w[3]: word = word + ' '
-				text = text + word
-		return text + '\n'
-	#
-	# Return which character position was hit by the mouse, as
-	# an offset in the entire text as returned by extract().
-	# Return None if the mouse was not in this paragraph
-	def whereis(self, d, mouseh, mousev):
-		if mousev < self.top or mousev > self.bottom:
-			return None
-		self.mouseh = mouseh
-		self.mousev = mousev
-		self.lastfont = None
-		self.charcount = 0
-		try:
-			self.d = d
-			return self.visit(self.__class__._whereisword, \
-					  self.__class__._whereisanchor)
-		finally:
-			self.d = None
-	#
-	def _whereisword(self, tuple, word, h1, v1, h2, v2, isfirst, islast):
-		fo, te, wi, sp, st, as, de = word
-		if fo <> None: self.lastfont = fo
-		h = h1
-		if isfirst: h1 = 0
-		if islast: h2 = 999999
-		if not (v1 <= self.mousev <= v2 and h1 <= self.mouseh <= h2):
-			self.charcount = self.charcount + len(te) + (sp > 0)
-			return
-		if self.lastfont <> None:
-			self.d.setfont(self.lastfont)
-		cc = 0
-		for c in te:
-			cw = self.d.textwidth(c)
-			if self.mouseh <= h + cw/2:
-				return self.charcount + cc
-			cc = cc+1
-			h = h+cw
-		self.charcount = self.charcount + cc
-		if self.mouseh <= (h+h2) / 2:
-			return self.charcount
-		else:
-			return self.charcount + 1
-	#
-	def _whereisanchor(self, tuple, word, h, v):
-		pass
-	#
-	# Return screen position corresponding to position in paragraph.
-	# Return tuple (h, vtop, vbaseline, vbottom).
-	# This is more or less the inverse of whereis()
-	def screenpos(self, d, pos):
-		if pos < 0:
-			ascent, descent = self.lines[0][5:7]
-			return self.left, self.top, self.top + ascent, \
-				self.top + ascent + descent
-		self.pos = pos
-		self.lastfont = None
-		try:
-			self.d = d
-			ok = self.visit(self.__class__._screenposword, \
-					self.__class__._screenposanchor)
-		finally:
-			self.d = None
-		if ok == None:
-			ascent, descent = self.lines[-1][5:7]
-			ok = self.right, self.bottom - ascent - descent, \
-				self.bottom - descent, self.bottom
-		return ok
-	#
-	def _screenposword(self, tuple, word, h1, v1, h2, v2, isfirst, islast):
-		fo, te, wi, sp, st, as, de = word
-		if fo <> None: self.lastfont = fo
-		cc = len(te) + (sp > 0)
-		if self.pos > cc:
-			self.pos = self.pos - cc
-			return
-		if self.pos < cc:
-			self.d.setfont(self.lastfont)
-			h = h1 + self.d.textwidth(te[:self.pos])
-		else:
-			h = h2
-		ascent, descent = tuple[5:7]
-		return h, v1, v1+ascent, v2
-	#
-	def _screenposanchor(self, tuple, word, h, v):
-		pass
-	#
-	# Invert the stretch of text between pos1 and pos2.
-	# If pos1 is None, the beginning is implied;
-	# if pos2 is None, the end is implied.
-	# Undoes its own effect when called again with the same arguments
-	def invert(self, d, pos1, pos2):
-		if pos1 == None:
-			pos1 = self.left, self.top, self.top, self.top
-		else:
-			pos1 = self.screenpos(d, pos1)
-		if pos2 == None:
-			pos2 = self.right, self.bottom,self.bottom,self.bottom
-		else:
-			pos2 = self.screenpos(d, pos2)
-		h1, top1, baseline1, bottom1 = pos1
-		h2, top2, baseline2, bottom2 = pos2
-		if bottom1 <= top2:
-			d.invert((h1, top1), (self.right, bottom1))
-			h1 = self.left
-			if bottom1 < top2:
-				d.invert((h1, bottom1), (self.right, top2))
-			top1, bottom1 = top2, bottom2
-		d.invert((h1, top1), (h2, bottom2))
-
-
-# Test class Para
-# XXX This was last used on the Mac, hence the weird fonts...
-def test():
-	import stdwin
-	from stdwinevents import *
-	words = 'The', 'quick', 'brown', 'fox', 'jumps', 'over', \
-		'the', 'lazy', 'dog.'
-	paralist = []
-	for just in 'l', 'r', 'lr', 'c':
-		p = Para()
-		p.just = just
-		p.addword(stdwin, ('New York', 'p', 12), words[0], 1, 1)
-		for word in words[1:-1]:
-			p.addword(stdwin, None, word, 1, 1)
-		p.addword(stdwin, None, words[-1], 2, 4)
-		p.addword(stdwin, ('New York', 'b', 18), 'Bye!', 0, 0)
-		p.addword(stdwin, ('New York', 'p', 10), 'Bye!', 0, 0)
-		paralist.append(p)
-	window = stdwin.open('Para.test()')
-	start = stop = selpara = None
-	while 1:
-		etype, win, detail = stdwin.getevent()
-		if etype == WE_CLOSE:
-			break
-		if etype == WE_SIZE:
-			window.change((0, 0), (1000, 1000))
-		if etype == WE_DRAW:
-			width, height = window.getwinsize()
-			d = None
-			try:
-				d = window.begindrawing()
-				d.cliprect(detail)
-				d.erase(detail)
-				v = 0
-				for p in paralist:
-					v = p.render(d, 0, v, width)
-					if p == selpara and \
-					   start <> None and stop <> None:
-						p.invert(d, start, stop)
-			finally:
-				if d: d.close()
-		if etype == WE_MOUSE_DOWN:
-			if selpara and start <> None and stop <> None:
-				d = window.begindrawing()
-				selpara.invert(d, start, stop)
-				d.close()
-			start = stop = selpara = None
-			mouseh, mousev = detail[0]
-			for p in paralist:
-				start = p.whereis(stdwin, mouseh, mousev)
-				if start <> None:
-					selpara = p
-					break
-		if etype == WE_MOUSE_UP and start <> None and selpara:
-			mouseh, mousev = detail[0]
-			stop = selpara.whereis(stdwin, mouseh, mousev)
-			if stop == None: start = selpara = None
-			else:
-				if start > stop:
-					start, stop = stop, start
-				d = window.begindrawing()
-				selpara.invert(d, start, stop)
-				d.close()
-	window.close()
diff --git a/Lib/addpack.py b/Lib/addpack.py
deleted file mode 100644
index 3d09236..0000000
--- a/Lib/addpack.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# This module provides standard support for "packages".
-#
-# The idea is that large groups of related modules can be placed in
-# their own subdirectory, which can be added to the Python search path
-# in a relatively easy way.
-#
-# The current version takes a package name and searches the Python
-# search path for a directory by that name, and if found adds it to
-# the module search path (sys.path).  It maintains a list of packages
-# that have already been added so adding the same package many times
-# is OK.
-#
-# It is intended to be used in a fairly stylized manner: each module
-# that wants to use a particular package, say 'Foo', is supposed to
-# contain the following code:
-#
-#   from addpack import addpack
-#   addpack('Foo')
-#   <import modules from package Foo>
-#
-# Additional arguments, when present, provide additional places where
-# to look for the package before trying sys.path (these may be either
-# strings or lists/tuples of strings).  Also, if the package name is a
-# full pathname, first the last component is tried in the usual way,
-# then the full pathname is tried last.  If the package name is a
-# *relative* pathname (UNIX: contains a slash but doesn't start with
-# one), then nothing special is done.  The packages "/foo/bar/bletch"
-# and "bletch" are considered the same, but unrelated to "bar/bletch".
-#
-# If the algorithm finds more than one suitable subdirectory, all are
-# added to the search path -- this makes it possible to override part
-# of a package.  The same path will not be added more than once.
-#
-# If no directory is found, ImportError is raised.
-
-_packs = {}				# {pack: [pathname, ...], ...}
-
-def addpack(pack, *locations):
-	import os
-	if os.path.isabs(pack):
-		base = os.path.basename(pack)
-	else:
-		base = pack
-	if _packs.has_key(base):
-		return
-	import sys
-	path = []
-	for loc in _flatten(locations) + sys.path:
-		fn = os.path.join(loc, base)
-		if fn not in path and os.path.isdir(fn):
-			path.append(fn)
-	if pack != base and pack not in path and os.path.isdir(pack):
-		path.append(pack)
-	if not path: raise ImportError, 'package ' + pack + ' not found'
-	_packs[base] = path
-	for fn in path:
-		if fn not in sys.path:
-			sys.path.append(fn)
-
-def _flatten(locations):
-	locs = []
-	for loc in locations:
-		if type(loc) == type(''):
-			locs.append(loc)
-		else:
-			locs = locs + _flatten(loc)
-	return locs
diff --git a/Lib/fmt.py b/Lib/fmt.py
deleted file mode 100644
index 3f146cb..0000000
--- a/Lib/fmt.py
+++ /dev/null
@@ -1,623 +0,0 @@
-# Text formatting abstractions
-# Note -- this module is obsolete, it's too slow anyway
-
-
-import string
-import Para
-
-
-# A formatter back-end object has one method that is called by the formatter:
-# addpara(p), where p is a paragraph object.  For example:
-
-
-# Formatter back-end to do nothing at all with the paragraphs
-class NullBackEnd:
-	#
-	def __init__(self):
-		pass
-	#
-	def addpara(self, p):
-		pass
-	#
-	def bgn_anchor(self, id):
-		pass
-	#
-	def end_anchor(self, id):
-		pass
-
-
-# Formatter back-end to collect the paragraphs in a list
-class SavingBackEnd(NullBackEnd):
-	#
-	def __init__(self):
-		self.paralist = []
-	#
-	def addpara(self, p):
-		self.paralist.append(p)
-	#
-	def hitcheck(self, h, v):
-		hits = []
-		for p in self.paralist:
-			if p.top <= v <= p.bottom:
-				for id in p.hitcheck(h, v):
-					if id not in hits:
-						hits.append(id)
-		return hits
-	#
-	def extract(self):
-		text = ''
-		for p in self.paralist:
-			text = text + (p.extract())
-		return text
-	#
-	def extractpart(self, long1, long2):
-		if long1 > long2: long1, long2 = long2, long1
-		para1, pos1 = long1
-		para2, pos2 = long2
-		text = ''
-		while para1 < para2:
-			ptext = self.paralist[para1].extract()
-			text = text + ptext[pos1:]
-			pos1 = 0
-			para1 = para1 + 1
-		ptext = self.paralist[para2].extract()
-		return text + ptext[pos1:pos2]
-	#
-	def whereis(self, d, h, v):
-		total = 0
-		for i in range(len(self.paralist)):
-			p = self.paralist[i]
-			result = p.whereis(d, h, v)
-			if result <> None:
-				return i, result
-		return None
-	#
-	def roundtowords(self, long1, long2):
-		i, offset = long1
-		text = self.paralist[i].extract()
-		while offset > 0 and text[offset-1] <> ' ': offset = offset-1
-		long1 = i, offset
-		#
-		i, offset = long2
-		text = self.paralist[i].extract()
-		n = len(text)
-		while offset < n-1 and text[offset] <> ' ': offset = offset+1
-		long2 = i, offset
-		#
-		return long1, long2
-	#
-	def roundtoparagraphs(self, long1, long2):
-		long1 = long1[0], 0
-		long2 = long2[0], len(self.paralist[long2[0]].extract())
-		return long1, long2
-
-
-# Formatter back-end to send the text directly to the drawing object
-class WritingBackEnd(NullBackEnd):
-	#
-	def __init__(self, d, width):
-		self.d = d
-		self.width = width
-		self.lineno = 0
-	#
-	def addpara(self, p):
-		self.lineno = p.render(self.d, 0, self.lineno, self.width)
-
-
-# A formatter receives a stream of formatting instructions and assembles
-# these into a stream of paragraphs on to a back-end.  The assembly is
-# parametrized by a text measurement object, which must match the output
-# operations of the back-end.  The back-end is responsible for splitting
-# paragraphs up in lines of a given maximum width.  (This is done because
-# in a windowing environment, when the window size changes, there is no
-# need to redo the assembly into paragraphs, but the splitting into lines
-# must be done taking the new window size into account.)
-
-
-# Formatter base class.  Initialize it with a text measurement object,
-# which is used for text measurements, and a back-end object,
-# which receives the completed paragraphs.  The formatting methods are:
-# setfont(font)
-# setleftindent(nspaces)
-# setjust(type) where type is 'l', 'c', 'r', or 'lr'
-# flush()
-# vspace(nlines)
-# needvspace(nlines)
-# addword(word, nspaces)
-class BaseFormatter:
-	#
-	def __init__(self, d, b):
-		# Drawing object used for text measurements
-		self.d = d
-		#
-		# BackEnd object receiving completed paragraphs
-		self.b = b
-		#
-		# Parameters of the formatting model
-		self.leftindent = 0
-		self.just = 'l'
-		self.font = None
-		self.blanklines = 0
-		#
-		# Parameters derived from the current font
-		self.space = d.textwidth(' ')
-		self.line = d.lineheight()
-		self.ascent = d.baseline()
-		self.descent = self.line - self.ascent
-		#
-		# Parameter derived from the default font
-		self.n_space = self.space
-		#
-		# Current paragraph being built
-		self.para = None
-		self.nospace = 1
-		#
-		# Font to set on the next word
-		self.nextfont = None
-	#
-	def newpara(self):
-		return Para.Para()
-	#
-	def setfont(self, font):
-		if font == None: return
-		self.font = self.nextfont = font
-		d = self.d
-		d.setfont(font)
-		self.space = d.textwidth(' ')
-		self.line = d.lineheight()
-		self.ascent = d.baseline()
-		self.descent = self.line - self.ascent
-	#
-	def setleftindent(self, nspaces):
-		self.leftindent = int(self.n_space * nspaces)
-		if self.para:
-			hang = self.leftindent - self.para.indent_left
-			if hang > 0 and self.para.getlength() <= hang:
-				self.para.makehangingtag(hang)
-				self.nospace = 1
-			else:
-				self.flush()
-	#
-	def setrightindent(self, nspaces):
-		self.rightindent = int(self.n_space * nspaces)
-		if self.para:
-			self.para.indent_right = self.rightindent
-			self.flush()
-	#
-	def setjust(self, just):
-		self.just = just
-		if self.para:
-			self.para.just = self.just
-	#
-	def flush(self):
-		if self.para:
-			self.b.addpara(self.para)
-			self.para = None
-			if self.font <> None:
-				self.d.setfont(self.font)
-		self.nospace = 1
-	#
-	def vspace(self, nlines):
-		self.flush()
-		if nlines > 0:
-			self.para = self.newpara()
-			tuple = None, '', 0, 0, 0, int(nlines*self.line), 0
-			self.para.words.append(tuple)
-			self.flush()
-			self.blanklines = self.blanklines + nlines
-	#
-	def needvspace(self, nlines):
-		self.flush() # Just to be sure
-		if nlines > self.blanklines:
-			self.vspace(nlines - self.blanklines)
-	#
-	def addword(self, text, space):
-		if self.nospace and not text:
-			return
-		self.nospace = 0
-		self.blanklines = 0
-		if not self.para:
-			self.para = self.newpara()
-			self.para.indent_left = self.leftindent
-			self.para.just = self.just
-			self.nextfont = self.font
-		space = int(space * self.space)
-		self.para.words.append(self.nextfont, text, \
-			self.d.textwidth(text), space, space, \
-			self.ascent, self.descent)
-		self.nextfont = None
-	#
-	def bgn_anchor(self, id):
-		if not self.para:
-			self.nospace = 0
-			self.addword('', 0)
-		self.para.bgn_anchor(id)
-	#
-	def end_anchor(self, id):
-		if not self.para:
-			self.nospace = 0
-			self.addword('', 0)
-		self.para.end_anchor(id)
-
-
-# Measuring object for measuring text as viewed on a tty
-class NullMeasurer:
-	#
-	def __init__(self):
-		pass
-	#
-	def setfont(self, font):
-		pass
-	#
-	def textwidth(self, text):
-		return len(text)
-	#
-	def lineheight(self):
-		return 1
-	#
-	def baseline(self):
-		return 0
-
-
-# Drawing object for writing plain ASCII text to a file
-class FileWriter:
-	#
-	def __init__(self, fp):
-		self.fp = fp
-		self.lineno, self.colno = 0, 0
-	#
-	def setfont(self, font):
-		pass
-	#
-	def text(self, (h, v), str):
-		if not str: return
-		if '\n' in str:
-			raise ValueError, 'can\'t write \\n'
-		while self.lineno < v:
-			self.fp.write('\n')
-			self.colno, self.lineno = 0, self.lineno + 1
-		while self.lineno > v:
-			# XXX This should never happen...
-			self.fp.write('\033[A') # ANSI up arrow
-			self.lineno = self.lineno - 1
-		if self.colno < h:
-			self.fp.write(' ' * (h - self.colno))
-		elif self.colno > h:
-			self.fp.write('\b' * (self.colno - h))
-		self.colno = h
-		self.fp.write(str)
-		self.colno = h + len(str)
-
-
-# Formatting class to do nothing at all with the data
-class NullFormatter(BaseFormatter):
-	#
-	def __init__(self):
-		d = NullMeasurer()
-		b = NullBackEnd()
-		BaseFormatter.__init__(self, d, b)
-
-
-# Formatting class to write directly to a file
-class WritingFormatter(BaseFormatter):
-	#
-	def __init__(self, fp, width):
-		dm = NullMeasurer()
-		dw = FileWriter(fp)
-		b = WritingBackEnd(dw, width)
-		BaseFormatter.__init__(self, dm, b)
-		self.blanklines = 1
-	#
-	# Suppress multiple blank lines
-	def needvspace(self, nlines):
-		BaseFormatter.needvspace(self, min(1, nlines))
-
-
-# A "FunnyFormatter" writes ASCII text with a twist: *bold words*,
-# _italic text_ and _underlined words_, and `quoted text'.
-# It assumes that the fonts are 'r', 'i', 'b', 'u', 'q': (roman,
-# italic, bold, underline, quote).
-# Moreover, if the font is in upper case, the text is converted to
-# UPPER CASE.
-class FunnyFormatter(WritingFormatter):
-	#
-	def flush(self):
-		if self.para: finalize(self.para)
-		WritingFormatter.flush(self)
-
-
-# Surrounds *bold words* and _italic text_ in a paragraph with
-# appropriate markers, fixing the size (assuming these characters'
-# width is 1).
-openchar = \
-    {'b':'*', 'i':'_', 'u':'_', 'q':'`', 'B':'*', 'I':'_', 'U':'_', 'Q':'`'}
-closechar = \
-    {'b':'*', 'i':'_', 'u':'_', 'q':'\'', 'B':'*', 'I':'_', 'U':'_', 'Q':'\''}
-def finalize(para):
-	oldfont = curfont = 'r'
-	para.words.append(('r', '', 0, 0, 0, 0)) # temporary, deleted at end
-	for i in range(len(para.words)):
-		fo, te, wi = para.words[i][:3]
-		if fo <> None: curfont = fo
-		if curfont <> oldfont:
-			if closechar.has_key(oldfont):
-				c = closechar[oldfont]
-				j = i-1
-				while j > 0 and para.words[j][1] == '': j = j-1
-				fo1, te1, wi1 = para.words[j][:3]
-				te1 = te1 + c
-				wi1 = wi1 + len(c)
-				para.words[j] = (fo1, te1, wi1) + \
-					para.words[j][3:]
-			if openchar.has_key(curfont) and te:
-				c = openchar[curfont]
-				te = c + te
-				wi = len(c) + wi
-				para.words[i] = (fo, te, wi) + \
-					para.words[i][3:]
-			if te: oldfont = curfont
-			else: oldfont = 'r'
-		if curfont in string.uppercase:
-			te = string.upper(te)
-			para.words[i] = (fo, te, wi) + para.words[i][3:]
-	del para.words[-1]
-
-
-# Formatter back-end to draw the text in a window.
-# This has an option to draw while the paragraphs are being added,
-# to minimize the delay before the user sees anything.
-# This manages the entire "document" of the window.
-class StdwinBackEnd(SavingBackEnd):
-	#
-	def __init__(self, window, drawnow):
-		self.window = window
-		self.drawnow = drawnow
-		self.width = window.getwinsize()[0]
-		self.selection = None
-		self.height = 0
-		window.setorigin(0, 0)
-		window.setdocsize(0, 0)
-		self.d = window.begindrawing()
-		SavingBackEnd.__init__(self)
-	#
-	def finish(self):
-		self.d.close()
-		self.d = None
-		self.window.setdocsize(0, self.height)
-	#
-	def addpara(self, p):
-		self.paralist.append(p)
-		if self.drawnow:
-			self.height = \
-				p.render(self.d, 0, self.height, self.width)
-		else:
-			p.layout(self.width)
-			p.left = 0
-			p.top = self.height
-			p.right = self.width
-			p.bottom = self.height + p.height
-			self.height = p.bottom
-	#
-	def resize(self):
-		self.window.change((0, 0), (self.width, self.height))
-		self.width = self.window.getwinsize()[0]
-		self.height = 0
-		for p in self.paralist:
-			p.layout(self.width)
-			p.left = 0
-			p.top = self.height
-			p.right = self.width
-			p.bottom = self.height + p.height
-			self.height = p.bottom
-		self.window.change((0, 0), (self.width, self.height))
-		self.window.setdocsize(0, self.height)
-	#
-	def redraw(self, area):
-		d = self.window.begindrawing()
-		(left, top), (right, bottom) = area
-		d.erase(area)
-		d.cliprect(area)
-		for p in self.paralist:
-			if top < p.bottom and p.top < bottom:
-				v = p.render(d, p.left, p.top, p.right)
-		if self.selection:
-			self.invert(d, self.selection)
-		d.close()
-	#
-	def setselection(self, new):
-		if new:
-			long1, long2 = new
-			pos1 = long1[:3]
-			pos2 = long2[:3]
-			new = pos1, pos2
-		if new <> self.selection:
-			d = self.window.begindrawing()
-			if self.selection:
-				self.invert(d, self.selection)
-			if new:
-				self.invert(d, new)
-			d.close()
-			self.selection = new
-	#
-	def getselection(self):
-		return self.selection
-	#
-	def extractselection(self):
-		if self.selection:
-			a, b = self.selection
-			return self.extractpart(a, b)
-		else:
-			return None
-	#
-	def invert(self, d, region):
-		long1, long2 = region
-		if long1 > long2: long1, long2 = long2, long1
-		para1, pos1 = long1
-		para2, pos2 = long2
-		while para1 < para2:
-			self.paralist[para1].invert(d, pos1, None)
-			pos1 = None
-			para1 = para1 + 1
-		self.paralist[para2].invert(d, pos1, pos2)
-	#
-	def search(self, prog):
-		import re, string
-		if type(prog) == type(''):
-			prog = re.compile(string.lower(prog))
-		if self.selection:
-			iold = self.selection[0][0]
-		else:
-			iold = -1
-		hit = None
-		for i in range(len(self.paralist)):
-			if i == iold or i < iold and hit:
-				continue
-			p = self.paralist[i]
-			text = string.lower(p.extract())
-			match = prog.search(text)
-			if match:
-				a, b = match.group(0)
-				long1 = i, a
-				long2 = i, b
-				hit = long1, long2
-				if i > iold:
-					break
-		if hit:
-			self.setselection(hit)
-			i = hit[0][0]
-			p = self.paralist[i]
-			self.window.show((p.left, p.top), (p.right, p.bottom))
-			return 1
-		else:
-			return 0
-	#
-	def showanchor(self, id):
-		for i in range(len(self.paralist)):
-			p = self.paralist[i]
-			if p.hasanchor(id):
-				long1 = i, 0
-				long2 = i, len(p.extract())
-				hit = long1, long2
-				self.setselection(hit)
-				self.window.show( \
-					(p.left, p.top), (p.right, p.bottom))
-				break
-
-
-# GL extensions
-
-class GLFontCache:
-	#
-	def __init__(self):
-		self.reset()
-		self.setfont('')
-	#
-	def reset(self):
-		self.fontkey = None
-		self.fonthandle = None
-		self.fontinfo = None
-		self.fontcache = {}
-	#
-	def close(self):
-		self.reset()
-	#
-	def setfont(self, fontkey):
-		if fontkey == '':
-			fontkey = 'Times-Roman 12'
-		elif ' ' not in fontkey:
-			fontkey = fontkey + ' 12'
-		if fontkey == self.fontkey:
-			return
-		if self.fontcache.has_key(fontkey):
-			handle = self.fontcache[fontkey]
-		else:
-			import string
-			i = string.index(fontkey, ' ')
-			name, sizestr = fontkey[:i], fontkey[i:]
-			size = eval(sizestr)
-			key1 = name + ' 1'
-			key = name + ' ' + `size`
-			# NB key may differ from fontkey!
-			if self.fontcache.has_key(key):
-				handle = self.fontcache[key]
-			else:
-				if self.fontcache.has_key(key1):
-					handle = self.fontcache[key1]
-				else:
-					import fm
-					handle = fm.findfont(name)
-					self.fontcache[key1] = handle
-				handle = handle.scalefont(size)
-				self.fontcache[fontkey] = \
-					self.fontcache[key] = handle
-		self.fontkey = fontkey
-		if self.fonthandle <> handle:
-			self.fonthandle = handle
-			self.fontinfo = handle.getfontinfo()
-			handle.setfont()
-
-
-class GLMeasurer(GLFontCache):
-	#
-	def textwidth(self, text):
-		return self.fonthandle.getstrwidth(text)
-	#
-	def baseline(self):
-		return self.fontinfo[6] - self.fontinfo[3]
-	#
-	def lineheight(self):
-		return self.fontinfo[6]
-
-
-class GLWriter(GLFontCache):
-	#
-	# NOTES:
-	# (1) Use gl.ortho2 to use X pixel coordinates!
-	#
-	def text(self, (h, v), text):
-		import gl, fm
-		gl.cmov2i(h, v + self.fontinfo[6] - self.fontinfo[3])
-		fm.prstr(text)
-	#
-	def setfont(self, fontkey):
-		oldhandle = self.fonthandle
-		GLFontCache.setfont(fontkey)
-		if self.fonthandle <> oldhandle:
-			handle.setfont()
-
-
-class GLMeasurerWriter(GLMeasurer, GLWriter):
-	pass
-
-
-class GLBackEnd(SavingBackEnd):
-	#
-	def __init__(self, wid):
-		import gl
-		gl.winset(wid)
-		self.wid = wid
-		self.width = gl.getsize()[1]
-		self.height = 0
-		self.d = GLMeasurerWriter()
-		SavingBackEnd.__init__(self)
-	#
-	def finish(self):
-		pass
-	#
-	def addpara(self, p):
-		self.paralist.append(p)
-		self.height = p.render(self.d, 0, self.height, self.width)
-	#
-	def redraw(self):
-		import gl
-		gl.winset(self.wid)
-		width = gl.getsize()[1]
-		if width <> self.width:
-			setdocsize = 1
-			self.width = width
-			for p in self.paralist:
-				p.top = p.bottom = None
-		d = self.d
-		v = 0
-		for p in self.paralist:
-			v = p.render(d, 0, v, width)
diff --git a/Lib/newdir.py b/Lib/newdir.py
deleted file mode 100644
index 937c49e..0000000
--- a/Lib/newdir.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# New dir() function
-
-
-# This should be the new dir(), except that it should still list
-# the current local name space by default
-
-def listattrs(x):
-	try:
-		dictkeys = x.__dict__.keys()
-	except (AttributeError, TypeError):
-		dictkeys = []
-	#
-	try:
-		methods = x.__methods__
-	except (AttributeError, TypeError):
-		methods = []
-	#
-	try:
-		members = x.__members__
-	except (AttributeError, TypeError):
-		members = []
-	#
-	try:
-		the_class = x.__class__
-	except (AttributeError, TypeError):
-		the_class = None
-	#
-	try:
-		bases = x.__bases__
-	except (AttributeError, TypeError):
-		bases = ()
-	#
-	total = dictkeys + methods + members
-	if the_class:
-		# It's a class instace; add the class's attributes
-		# that are functions (methods)...
-		class_attrs = listattrs(the_class)
-		class_methods = []
-		for name in class_attrs:
-			if is_function(getattr(the_class, name)):
-				class_methods.append(name)
-		total = total + class_methods
-	elif bases:
-		# It's a derived class; add the base class attributes
-		for base in bases:
-			base_attrs = listattrs(base)
-			total = total + base_attrs
-	total.sort()
-	return total
-	i = 0
-	while i+1 < len(total):
-		if total[i] == total[i+1]:
-			del total[i+1]
-		else:
-			i = i+1
-	return total
-
-
-# Helper to recognize functions
-
-def is_function(x):
-	return type(x) == type(is_function)
-
-
-# Approximation of builtin dir(); but note that this lists the user's
-# variables by default, not the current local name space.
-
-def dir(x = None):
-	if x is not None:
-		return listattrs(x)
-	else:
-		import __main__
-		return listattrs(__main__)
