# Browser for "Info files" as used by the Emacs documentation system.
#
# Now you can read Info files even if you can't spare the memory, time or
# disk space to run Emacs.  (I have used this extensively on a Macintosh
# with 1 Megabyte main memory and a 20 Meg harddisk.)
#
# You can give this to someone with great fear of complex computer
# systems, as long as they can use a mouse.
#
# Another reason to use this is to encourage the use of Info for on-line
# documentation of software that is not related to Emacs or GNU.
# (In particular, I plan to redo the Python and STDWIN documentation
# in texinfo.)


# NB: this is not a self-executing script.  You must startup Python,
# import ibrowse, and call ibrowse.main().  On UNIX, the script 'ib'
# runs the browser.


# Configuration:
#
# - The pathname of the directory (or directories) containing
#   the standard Info files should be set by editing the
#   value assigned to INFOPATH in module ifile.py.
#
# - The default font should be set by editing the value of FONT
#   in this module (ibrowse.py).
#
# - For fastest I/O, you may look at BLOCKSIZE and a few other
#   constants in ifile.py.


# This is a fairly large Python program, split in the following modules:
#
# ibrowse.py	Main program and user interface.
#		This is the only module that imports stdwin.
#
# ifile.py	This module knows about the format of Info files.
#		It is imported by all of the others.
#
# itags.py	This module knows how to read prebuilt tag tables,
#		including indirect ones used by large texinfo files.
#
# icache.py	Caches tag tables and visited nodes.


# XXX There should really be a different tutorial, as the user interface
# XXX differs considerably from Emacs...


import sys
import regexp
import stdwin
from stdwinevents import *
import string
from ifile import NoSuchFile, NoSuchNode
import icache


# Default font.
# This should be an acceptable argument for stdwin.setfont();
# on the Mac, this can be a pair (fontname, pointsize), while
# under X11 it should be a standard X11 font name.
# For best results, use a constant width font like Courier;
# many Info files contain tabs that don't align with other text
# unless all characters have the same width.
#
#FONT = ('Monaco', 9)		# Mac
FONT = '-schumacher-clean-medium-r-normal--14-140-75-75-c-70-iso8859-1'	# X11


# Try not to destroy the list of windows when reload() is used.
# This is useful during debugging, and harmless in production...
#
try:
	dummy = windows
	del dummy
except NameError:
	windows = []


# Default main function -- start at the '(dir)' node.
#
def main():
	start('(dir)')


# Start at an arbitrary node.
# The default file is 'ibrowse'.
#
def start(ref):
	stdwin.setdefscrollbars(0, 1)
	stdwin.setfont(FONT)
	stdwin.setdefwinsize(76*stdwin.textwidth('x'), 22*stdwin.lineheight())
	makewindow('ibrowse', ref)
	mainloop()


# Open a new browser window.
# Arguments specify the default file and a node reference
# (if the node reference specifies a file, the default file is ignored).
#
def makewindow(file, ref):
	win = stdwin.open('Info file Browser, by Guido van Rossum')
	win.mainmenu = makemainmenu(win)
	win.navimenu = makenavimenu(win)
	win.textobj = win.textcreate((0, 0), win.getwinsize())
	win.file = file
	win.node = ''
	win.last = []
	win.pat = ''
	win.dispatch = idispatch
	win.nodemenu = None
	win.footmenu = None
	windows.append(win)
	imove(win, ref)

# Create the 'Ibrowse' menu for a new browser window.
#
def makemainmenu(win):
	mp = win.menucreate('Ibrowse')
	mp.callback = []
	additem(mp, 'New window (clone)',	'K', iclone)
	additem(mp, 'Help (tutorial)',		'H', itutor)
	additem(mp, 'Command summary',		'?', isummary)
	additem(mp, 'Close this window',	'W', iclose)
	additem(mp, '', '', None)
	additem(mp, 'Copy to clipboard',	'C', icopy)
	additem(mp, '', '', None)
	additem(mp, 'Search regexp...',		'S', isearch)
	additem(mp, '', '', None)
	additem(mp, 'Reset node cache',		'',  iresetnodecache)
	additem(mp, 'Reset entire cache',	'',  iresetcache)
	additem(mp, '', '', None)
	additem(mp, 'Quit',			'Q', iquit)
	return mp

# Create the 'Navigation' menu for a new browser window.
#
def makenavimenu(win):
	mp = win.menucreate('Navigation')
	mp.callback = []
	additem(mp, 'Menu item...',		'M', imenu)
	additem(mp, 'Follow reference...',	'F', ifollow)
	additem(mp, 'Go to node...',		'G', igoto)
	additem(mp, '', '', None)
	additem(mp, 'Next node in tree',	'N', inext)
	additem(mp, 'Previous node in tree',	'P', iprev)
	additem(mp, 'Up in tree',		'U', iup)
	additem(mp, 'Last visited node',	'L', ilast)
	additem(mp, 'Top of tree',		'T', itop)
	additem(mp, 'Directory node',		'D', idir)
	return mp

# Add an item to a menu, and a function to its list of callbacks.
# (Specifying all in one call is the only way to keep the menu
# and the list of callbacks in synchrony.)
#
def additem(mp, text, shortcut, function):
	if shortcut:
		mp.additem(text, shortcut)
	else:
		mp.additem(text)
	mp.callback.append(function)


# Stdwin event processing main loop.
# Return when there are no windows left.
# Note that windows not in the windows list don't get their events.
#
def mainloop():
	while windows:
		event = stdwin.getevent()
		if event[1] in windows:
			try:
				event[1].dispatch(event)
			except KeyboardInterrupt:
				# The user can type Control-C (or whatever)
				# to leave the browser without closing
				# the window.  Mainly useful for
				# debugging.
				break
			except:
				# During debugging, it was annoying if
				# every mistake in a callback caused the
				# whole browser to crash, hence this
				# handler.  In a production version
				# it may be better to disable this.
				#
				msg = sys.exc_type
				if sys.exc_value:
					val = sys.exc_value
					if type(val) <> type(''):
						val = `val`
					msg = msg + ': ' + val
				msg = 'Oops, an exception occurred: ' + msg
				event = None
				stdwin.message(msg)
		event = None


# Handle one event.  The window is taken from the event's window item.
# This function is placed as a method (named 'dispatch') on the window,
# so the main loop will be able to handle windows of a different kind
# as well, as long as they are all placed in the list of windows.
#
def idispatch(event):
	type, win, detail = event
	if type == WE_CHAR:
		if not keybindings.has_key(detail):
			detail = string.lower(detail)
		if keybindings.has_key(detail):
			keybindings[detail](win)
			return
		if detail in '0123456789':
			i = eval(detail) - 1
			if i < 0: i = len(win.menu) + i
			if 0 <= i < len(win.menu):
				topic, ref = win.menu[i]
				imove(win, ref)
				return
		stdwin.fleep()
		return
	if type == WE_COMMAND:
		if detail == WC_LEFT:
			iprev(win)
		elif detail == WC_RIGHT:
			inext(win)
		elif detail == WC_UP:
			iup(win)
		elif detail == WC_DOWN:
			idown(win)
		elif detail == WC_BACKSPACE:
			ibackward(win)
		elif detail == WC_RETURN:
			idown(win)
		else:
			stdwin.fleep()
		return
	if type == WE_MENU:
		mp, item = detail
		if mp == None:
			pass # A THINK C console menu was selected
		elif mp in (win.mainmenu, win.navimenu):
			mp.callback[item](win)
		elif mp == win.nodemenu:
			topic, ref = win.menu[item]
			imove(win, ref)
		elif mp == win.footmenu:
			topic, ref = win.footnotes[item]
			imove(win, ref)
		return
	if type == WE_SIZE:
		win.textobj.move((0, 0), win.getwinsize())
		(left, top), (right, bottom) = win.textobj.getrect()
		win.setdocsize(0, bottom)
		return
	if type == WE_CLOSE:
		iclose(win)
		return
	if not win.textobj.event(event):
		pass


# Paging callbacks

def ibeginning(win):
	win.setorigin(0, 0)
	win.textobj.setfocus(0, 0) # To restart searches

def iforward(win):
	lh = stdwin.lineheight() # XXX Should really use the window's...
	h, v = win.getorigin()
	docwidth, docheight = win.getdocsize()
	width, height = win.getwinsize()
	if v + height >= docheight:
		stdwin.fleep()
		return
	increment = max(lh, ((height - 2*lh) / lh) * lh)
	v = v + increment
	win.setorigin(h, v)

def ibackward(win):
	lh = stdwin.lineheight() # XXX Should really use the window's...
	h, v = win.getorigin()
	if v <= 0:
		stdwin.fleep()
		return
	width, height = win.getwinsize()
	increment = max(lh, ((height - 2*lh) / lh) * lh)
	v = max(0, v - increment)
	win.setorigin(h, v)


# Ibrowse menu callbacks

def iclone(win):
	stdwin.setdefwinsize(win.getwinsize())
	makewindow(win.file, win.node)

def itutor(win):
	# The course looks best at 76x22...
	stdwin.setdefwinsize(76*stdwin.textwidth('x'), 22*stdwin.lineheight())
	makewindow('ibrowse', 'Help')

def isummary(win):
	stdwin.setdefwinsize(76*stdwin.textwidth('x'), 22*stdwin.lineheight())
	makewindow('ibrowse', 'Summary')

def iclose(win):
	#
	# Remove the window from the windows list so the mainloop
	# will notice if all windows are gone.
	# Delete the textobj since it constitutes a circular reference
	# to the window which would prevent it from being closed.
	# (Deletion is done by assigning None to avoid crashes
	# when closing a half-initialized window.)
	#
	if win in windows:
		windows.remove(win)
	win.textobj = None

def icopy(win):
	focustext = win.textobj.getfocustext()
	if not focustext:
		stdwin.fleep()
	else:
		stdwin.rotatecutbuffers(1)
		stdwin.setcutbuffer(0, focustext)
		# XXX Should also set the primary selection...

def isearch(win):
	try:
		pat = stdwin.askstr('Search pattern:', win.pat)
	except KeyboardInterrupt:
		return
	if not pat:
		pat = win.pat
		if not pat:
			stdwin.message('No previous pattern')
			return
	try:
		cpat = regexp.compile(pat)
	except regexp.error, msg:
		stdwin.message('Bad pattern: ' + msg)
		return
	win.pat = pat
	f1, f2 = win.textobj.getfocus()
	text = win.text
	match = cpat.match(text, f2)
	if not match:
		stdwin.fleep()
		return
	a, b = match[0]
	win.textobj.setfocus(a, b)


def iresetnodecache(win):
	icache.resetnodecache()

def iresetcache(win):
	icache.resetcache()

def iquit(win):
	for win in windows[:]:
		iclose(win)


# Navigation menu callbacks

def imenu(win):
	ichoice(win, 'Menu item (abbreviated):', win.menu, whichmenuitem(win))

def ifollow(win):
	ichoice(win, 'Follow reference named (abbreviated):', \
		win.footnotes, whichfootnote(win))

def igoto(win):
	try:
		choice = stdwin.askstr('Go to node (full name):', '')
	except KeyboardInterrupt:
		return
	if not choice:
		stdwin.message('Sorry, Go to has no default')
		return
	imove(win, choice)

def inext(win):
	prev, next, up = win.header
	if next:
		imove(win, next)
	else:
		stdwin.fleep()

def iprev(win):
	prev, next, up = win.header
	if prev:
		imove(win, prev)
	else:
		stdwin.fleep()

def iup(win):
	prev, next, up = win.header
	if up:
		imove(win, up)
	else:
		stdwin.fleep()

def ilast(win):
	if not win.last:
		stdwin.fleep()
	else:
		i = len(win.last)-1
		lastnode, lastfocus = win.last[i]
		imove(win, lastnode)
		if len(win.last) > i+1:
			# The move succeeded -- restore the focus
			win.textobj.setfocus(lastfocus)
		# Delete the stack top even if the move failed,
		# else the whole stack would remain unreachable
		del win.last[i:] # Delete the entry pushed by imove as well!

def itop(win):
	imove(win, '')

def idir(win):
	imove(win, '(dir)')


# Special and generic callbacks

def idown(win):
	if win.menu:
		default = whichmenuitem(win)
		for topic, ref in win.menu:
			if default == topic:
				break
		else:
			topic, ref = win.menu[0]
		imove(win, ref)
	else:
		inext(win)

def ichoice(win, prompt, list, default):
	if not list:
		stdwin.fleep()
		return
	if not default:
		topic, ref = list[0]
		default = topic
	try:
		choice = stdwin.askstr(prompt, default)
	except KeyboardInterrupt:
		return
	if not choice:
		return
	choice = string.lower(choice)
	n = len(choice)
	for topic, ref in list:
		topic = string.lower(topic)
		if topic[:n] == choice:
			imove(win, ref)
			return
	stdwin.message('Sorry, no topic matches ' + `choice`)


# Follow a reference, in the same window.
#
def imove(win, ref):
	savetitle = win.gettitle()
	win.settitle('Looking for ' + ref + '...')
	#
	try:
		file, node, header, menu, footnotes, text = \
			icache.get_node(win.file, ref)
	except NoSuchFile, file:
		win.settitle(savetitle)
		stdwin.message(\
		'Sorry, I can\'t find a file named ' + `file` + '.')
		return
	except NoSuchNode, node:
		win.settitle(savetitle)
		stdwin.message(\
		'Sorry, I can\'t find a node named ' + `node` + '.')
		return
	#
	win.settitle('Found (' + file + ')' + node + '...')
	#
	if win.file and win.node:
		lastnode = '(' + win.file + ')' + win.node
		win.last.append(lastnode, win.textobj.getfocus())
	win.file = file
	win.node = node
	win.header = header
	win.menu = menu
	win.footnotes = footnotes
	win.text = text
	#
	win.setorigin(0, 0) # Scroll to the beginnning
	win.textobj.settext(text)
	win.textobj.setfocus(0, 0)
	(left, top), (right, bottom) = win.textobj.getrect()
	win.setdocsize(0, bottom)
	#
	if win.footmenu: win.footmenu.close()
	if win.nodemenu: win.nodemenu.close()
	win.footmenu = None
	win.nodemenu = None
	#
	win.menu = menu
	if menu:
		win.nodemenu = win.menucreate('Menu')
		digit = 1
		for topic, ref in menu:
			if digit < 10:
				win.nodemenu.additem(topic, `digit`)
			else:
				win.nodemenu.additem(topic)
			digit = digit + 1
	#
	win.footnotes = footnotes
	if footnotes:
		win.footmenu = win.menucreate('Footnotes')
		for topic, ref in footnotes:
			win.footmenu.additem(topic)
	#
	win.settitle('(' + win.file + ')' + win.node)


# Find menu item at focus
#
findmenu = regexp.compile('^\* [mM]enu:').match
findmenuitem = regexp.compile( \
	'^\* ([^:]+):[ \t]*(:|\([^\t]*\)[^\t,\n.]*|[^:(][^\t,\n.]*)').match
#
def whichmenuitem(win):
	if not win.menu:
		return ''
	match = findmenu(win.text)
	if not match:
		return ''
	a, b = match[0]
	i = b
	f1, f2 = win.textobj.getfocus()
	lastmatch = ''
	while i < len(win.text):
		match = findmenuitem(win.text, i)
		if not match:
			break
		(a, b), (a1, b1), (a2, b2) = match
		if a > f1:
			break
		lastmatch = win.text[a1:b1]
		i = b
	return lastmatch


# Find footnote at focus
#
findfootnote = \
	regexp.compile('\*[nN]ote ([^:]+):[ \t]*(:|[^:][^\t,\n.]*)').match
#
def whichfootnote(win):
	if not win.footnotes:
		return ''
	i = 0
	f1, f2 = win.textobj.getfocus()
	lastmatch = ''
	while i < len(win.text):
		match = findfootnote(win.text, i)
		if not match:
			break
		(a, b), (a1, b1), (a2, b2) = match
		if a > f1:
			break
		lastmatch = win.text[a1:b1]
		i = b
	return lastmatch


# Now all the "methods" are defined, we can initialize the table
# of key bindings.
#
keybindings = {}

# Window commands

keybindings['k'] = iclone
keybindings['h'] = itutor
keybindings['?'] = isummary
keybindings['w'] = iclose

keybindings['c'] = icopy

keybindings['s'] = isearch

keybindings['q'] = iquit

# Navigation commands

keybindings['m'] = imenu
keybindings['f'] = ifollow
keybindings['g'] = igoto

keybindings['n'] = inext
keybindings['p'] = iprev
keybindings['u'] = iup
keybindings['l'] = ilast
keybindings['d'] = idir
keybindings['t'] = itop

# Paging commands

keybindings['b'] = ibeginning
keybindings['.'] = ibeginning
keybindings[' '] = iforward
