diff --git a/Lib/Para.py b/Lib/Para.py
new file mode 100644
index 0000000..6a7057d
--- /dev/null
+++ b/Lib/Para.py
@@ -0,0 +1,408 @@
+# Text formatting abstractions
+
+
+# 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()
