# Widget to display a man page

import re
from Tkinter import *
from Tkinter import _tkinter
from ScrolledText import ScrolledText

# XXX These fonts may have to be changed to match your system
BOLDFONT = '*-Courier-Bold-R-Normal-*-120-*'
ITALICFONT = '*-Courier-Medium-O-Normal-*-120-*'

# XXX Recognizing footers is system dependent
# (This one works for IRIX 5.2 and Solaris 2.2)
footerprog = re.compile(
        '^     Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
emptyprog = re.compile('^[ \t]*\n')
ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')

# Basic Man Page class -- does not disable editing
class EditableManPage(ScrolledText):

    # Initialize instance
    def __init__(self, master=None, **cnf):
        # Initialize base class
        ScrolledText.__init__(self, master, **cnf)

        # Define tags for formatting styles
        self.tag_config('X', underline=1)
        self.tag_config('!', font=BOLDFONT)
        self.tag_config('_', font=ITALICFONT)

        # Set state to idle
        self.fp = None
        self.lineno = 0

    # Test whether we are busy parsing a file
    def busy(self):
        return self.fp != None

    # Ensure we're not busy
    def kill(self):
        if self.busy():
            self._endparser()

    # Parse a file, in the background
    def asyncparsefile(self, fp):
        self._startparser(fp)
        self.tk.createfilehandler(fp, _tkinter.READABLE,
                                  self._filehandler)

    parsefile = asyncparsefile      # Alias

    # I/O handler used by background parsing
    def _filehandler(self, fp, mask):
        nextline = self.fp.readline()
        if not nextline:
            self._endparser()
            return
        self._parseline(nextline)

    # Parse a file, now (cannot be aborted)
    def syncparsefile(self, fp):
        from select import select
        def avail(fp=fp, tout=0.0, select=select):
            return select([fp], [], [], tout)[0]
        height = self.getint(self['height'])
        self._startparser(fp)
        while 1:
            nextline = fp.readline()
            if not nextline:
                break
            self._parseline(nextline)
        self._endparser()

    # Initialize parsing from a particular file -- must not be busy
    def _startparser(self, fp):
        if self.busy():
            raise RuntimeError('startparser: still busy')
        fp.fileno()             # Test for file-ness
        self.fp = fp
        self.lineno = 0
        self.ok = 0
        self.empty = 0
        self.buffer = None
        savestate = self['state']
        self['state'] = NORMAL
        self.delete('1.0', END)
        self['state'] = savestate

    # End parsing -- must be busy, need not be at EOF
    def _endparser(self):
        if not self.busy():
            raise RuntimeError('endparser: not busy')
        if self.buffer:
            self._parseline('')
        try:
            self.tk.deletefilehandler(self.fp)
        except TclError as msg:
            pass
        self.fp.close()
        self.fp = None
        del self.ok, self.empty, self.buffer

    # Parse a single line
    def _parseline(self, nextline):
        if not self.buffer:
            # Save this line -- we need one line read-ahead
            self.buffer = nextline
            return
        if emptyprog.match(self.buffer) >= 0:
            # Buffered line was empty -- set a flag
            self.empty = 1
            self.buffer = nextline
            return
        textline = self.buffer
        if ulprog.match(nextline) >= 0:
            # Next line is properties for buffered line
            propline = nextline
            self.buffer = None
        else:
            # Next line is read-ahead
            propline = None
            self.buffer = nextline
        if not self.ok:
            # First non blank line after footer must be header
            # -- skip that too
            self.ok = 1
            self.empty = 0
            return
        if footerprog.match(textline) >= 0:
            # Footer -- start skipping until next non-blank line
            self.ok = 0
            self.empty = 0
            return
        savestate = self['state']
        self['state'] = NORMAL
        if TkVersion >= 4.0:
            self.mark_set('insert', 'end-1c')
        else:
            self.mark_set('insert', END)
        if self.empty:
            # One or more previous lines were empty
            # -- insert one blank line in the text
            self._insert_prop('\n')
            self.lineno = self.lineno + 1
            self.empty = 0
        if not propline:
            # No properties
            self._insert_prop(textline)
        else:
            # Search for properties
            p = ''
            j = 0
            for i in range(min(len(propline), len(textline))):
                if propline[i] != p:
                    if j < i:
                        self._insert_prop(textline[j:i], p)
                        j = i
                    p = propline[i]
            self._insert_prop(textline[j:])
        self.lineno = self.lineno + 1
        self['state'] = savestate

    # Insert a string at the end, with at most one property (tag)
    def _insert_prop(self, str, prop = ' '):
        here = self.index(AtInsert())
        self.insert(AtInsert(), str)
        if TkVersion <= 4.0:
            tags = self.tag_names(here)
            for tag in tags:
                self.tag_remove(tag, here, AtInsert())
        if prop != ' ':
            self.tag_add(prop, here, AtInsert())

# Readonly Man Page class -- disables editing, otherwise the same
class ReadonlyManPage(EditableManPage):

    # Initialize instance
    def __init__(self, master=None, **cnf):
        cnf['state'] = DISABLED
        EditableManPage.__init__(self, master, **cnf)

# Alias
ManPage = ReadonlyManPage

# Test program.
# usage: ManPage [manpage]; or ManPage [-f] file
# -f means that the file is nroff -man output run through ul -i
def test():
    import os
    import sys
    # XXX This directory may be different on your system
    MANDIR = '/usr/local/man/mann'
    DEFAULTPAGE = 'Tcl'
    formatted = 0
    if sys.argv[1:] and sys.argv[1] == '-f':
        formatted = 1
        del sys.argv[1]
    if sys.argv[1:]:
        name = sys.argv[1]
    else:
        name = DEFAULTPAGE
    if not formatted:
        if name[-2:-1] != '.':
            name = name + '.n'
        name = os.path.join(MANDIR, name)
    root = Tk()
    root.minsize(1, 1)
    manpage = ManPage(root, relief=SUNKEN, borderwidth=2)
    manpage.pack(expand=1, fill=BOTH)
    if formatted:
        fp = open(name, 'r')
    else:
        fp = os.popen('nroff -man %s | ul -i' % name, 'r')
    manpage.parsefile(fp)
    root.mainloop()

# Run the test program when called as a script
if __name__ == '__main__':
    test()
