mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	 f55aa80b37
			
		
	
	
		f55aa80b37
		
	
	
	
	
		
			
			svn+ssh://svn.python.org/python/branches/py3k ........ r85820 | georg.brandl | 2010-10-24 16:20:22 +0200 (So, 24 Okt 2010) | 1 line Remove usage of exception indexing. ........ r85823 | georg.brandl | 2010-10-24 16:32:45 +0200 (So, 24 Okt 2010) | 1 line Fix style. ........ r85825 | georg.brandl | 2010-10-24 17:16:02 +0200 (So, 24 Okt 2010) | 1 line Add documentation about the default warnings filters. ........ r85840 | georg.brandl | 2010-10-25 19:50:20 +0200 (Mo, 25 Okt 2010) | 1 line #3018: tkinter demo fixes for py3k. ........ r85843 | georg.brandl | 2010-10-26 08:59:23 +0200 (Di, 26 Okt 2010) | 1 line Markup fix. ........ r85844 | georg.brandl | 2010-10-26 12:39:14 +0200 (Di, 26 Okt 2010) | 1 line Work a bit more on tkinter demos. ........ r85845 | georg.brandl | 2010-10-26 12:42:16 +0200 (Di, 26 Okt 2010) | 1 line faqwiz is removed. ........ r85849 | georg.brandl | 2010-10-26 21:31:06 +0200 (Di, 26 Okt 2010) | 1 line #10200: typo. ........ r85850 | georg.brandl | 2010-10-26 21:58:11 +0200 (Di, 26 Okt 2010) | 1 line #10200: typo. ........ r85851 | georg.brandl | 2010-10-26 22:12:37 +0200 (Di, 26 Okt 2010) | 1 line Fix import. ........ r85855 | georg.brandl | 2010-10-27 09:21:54 +0200 (Mi, 27 Okt 2010) | 1 line Encoding fix. ........ r85867 | georg.brandl | 2010-10-27 22:01:51 +0200 (Mi, 27 Okt 2010) | 1 line Add David. ........ r85875 | georg.brandl | 2010-10-28 10:38:30 +0200 (Do, 28 Okt 2010) | 1 line Fix bytes/str issues in get-remote-certificate.py. ........ r85907 | georg.brandl | 2010-10-29 06:54:13 +0200 (Fr, 29 Okt 2010) | 1 line #10222: fix for overzealous AIX compiler. ........ r85908 | georg.brandl | 2010-10-29 07:22:17 +0200 (Fr, 29 Okt 2010) | 1 line send_bytes obviously needs bytes... ........ r85911 | georg.brandl | 2010-10-29 07:36:28 +0200 (Fr, 29 Okt 2010) | 1 line Fix markup error and update false positive entries from "make suspicious". ........ r85914 | georg.brandl | 2010-10-29 08:17:38 +0200 (Fr, 29 Okt 2010) | 1 line (?:...) is a non-capturing, but still grouping construct. ........
		
			
				
	
	
		
			215 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Widget to display a man page
 | |
| 
 | |
| import os
 | |
| import re
 | |
| import sys
 | |
| 
 | |
| from tkinter import *
 | |
| from tkinter.font import Font
 | |
| from tkinter.scrolledtext import ScrolledText
 | |
| 
 | |
| # 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')
 | |
| 
 | |
| 
 | |
| class EditableManPage(ScrolledText):
 | |
|     """Basic Man Page class -- does not disable editing."""
 | |
| 
 | |
|     def __init__(self, master=None, **cnf):
 | |
|         ScrolledText.__init__(self, master, **cnf)
 | |
| 
 | |
|         bold = Font(font=self['font']).copy()
 | |
|         bold.config(weight='bold')
 | |
|         italic = Font(font=self['font']).copy()
 | |
|         italic.config(slant='italic')
 | |
| 
 | |
|         # Define tags for formatting styles
 | |
|         self.tag_config('X', underline=1)
 | |
|         self.tag_config('!', font=bold)
 | |
|         self.tag_config('_', font=italic)
 | |
| 
 | |
|         # Set state to idle
 | |
|         self.fp = None
 | |
|         self.lineno = 0
 | |
| 
 | |
|     def busy(self):
 | |
|         """Test whether we are busy parsing a file."""
 | |
|         return self.fp != None
 | |
| 
 | |
|     def kill(self):
 | |
|         """Ensure we're not busy."""
 | |
|         if self.busy():
 | |
|             self._endparser()
 | |
| 
 | |
|     def asyncparsefile(self, fp):
 | |
|         """Parse a file, in the background."""
 | |
|         self._startparser(fp)
 | |
|         self.tk.createfilehandler(fp, READABLE,
 | |
|                                   self._filehandler)
 | |
| 
 | |
|     parsefile = asyncparsefile   # Alias
 | |
| 
 | |
|     def _filehandler(self, fp, mask):
 | |
|         """I/O handler used by background parsing."""
 | |
|         nextline = self.fp.readline()
 | |
|         if not nextline:
 | |
|             self._endparser()
 | |
|             return
 | |
|         self._parseline(nextline)
 | |
| 
 | |
|     def syncparsefile(self, fp):
 | |
|         """Parse a file, now (cannot be aborted)."""
 | |
|         self._startparser(fp)
 | |
|         while True:
 | |
|             nextline = fp.readline()
 | |
|             if not nextline:
 | |
|                 break
 | |
|             self._parseline(nextline)
 | |
|         self._endparser()
 | |
| 
 | |
|     def _startparser(self, fp):
 | |
|         """Initialize parsing from a particular file -- must not be busy."""
 | |
|         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
 | |
| 
 | |
|     def _endparser(self):
 | |
|         """End parsing -- must be busy, need not be at EOF."""
 | |
|         if not self.busy():
 | |
|             raise RuntimeError('endparser: not busy')
 | |
|         if self.buffer:
 | |
|             self._parseline('')
 | |
|         try:
 | |
|             self.tk.deletefilehandler(self.fp)
 | |
|         except TclError:
 | |
|             pass
 | |
|         self.fp.close()
 | |
|         self.fp = None
 | |
|         del self.ok, self.empty, self.buffer
 | |
| 
 | |
|     def _parseline(self, nextline):
 | |
|         """Parse a single line."""
 | |
|         if not self.buffer:
 | |
|             # Save this line -- we need one line read-ahead
 | |
|             self.buffer = nextline
 | |
|             return
 | |
|         if emptyprog.match(self.buffer):
 | |
|             # Buffered line was empty -- set a flag
 | |
|             self.empty = 1
 | |
|             self.buffer = nextline
 | |
|             return
 | |
|         textline = self.buffer
 | |
|         if ulprog.match(nextline):
 | |
|             # 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):
 | |
|             # 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
 | |
| 
 | |
|     def _insert_prop(self, str, prop = ' '):
 | |
|         """Insert a string at the end, with at most one property (tag)."""
 | |
|         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())
 | |
| 
 | |
| 
 | |
| class ReadonlyManPage(EditableManPage):
 | |
|     """Readonly Man Page class -- disables editing, otherwise the same."""
 | |
| 
 | |
|     def __init__(self, master=None, **cnf):
 | |
|         cnf['state'] = DISABLED
 | |
|         EditableManPage.__init__(self, master, **cnf)
 | |
| 
 | |
| # Alias
 | |
| ManPage = ReadonlyManPage
 | |
| 
 | |
| # usage: ManPage [manpage]; or ManPage [-f] file
 | |
| # -f means that the file is nroff -man output run through ul -i
 | |
| def main():
 | |
|     # XXX This directory may be different on your system
 | |
|     MANDIR = ''
 | |
|     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 -c %s | ul -i' % name, 'r')
 | |
|     manpage.parsefile(fp)
 | |
|     root.mainloop()
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |