At GVR's request.
This commit is contained in:
parent
ff975003cf
commit
d61591813c
|
@ -1,344 +0,0 @@
|
||||||
"""
|
|
||||||
Online help module.
|
|
||||||
|
|
||||||
This module is experimental and could be removed or radically changed
|
|
||||||
at any time.
|
|
||||||
|
|
||||||
It is intended specifically for the standard interpreter command
|
|
||||||
line but is intended to be compatible with and useful for other
|
|
||||||
(e.g. GUI, handheld) environments. Help with those other environments is
|
|
||||||
appreciated.
|
|
||||||
|
|
||||||
Please remember to set PYTHONDOCS to the location of your HTML files:
|
|
||||||
|
|
||||||
e.g.
|
|
||||||
set PYTHONDOCS=c:\python\docs
|
|
||||||
PYTHONDOCS=/python/docs
|
|
||||||
|
|
||||||
The docs directory should have a lib subdirectory with "index.html" in it.
|
|
||||||
If it has *.tex then you have the documentation *source* distribution, not
|
|
||||||
the runtime distribution.
|
|
||||||
|
|
||||||
The module exposes one object: "help". "help" has a repr that does something
|
|
||||||
useful if you just type:
|
|
||||||
|
|
||||||
>>> from onlinehelp import help
|
|
||||||
>>> help
|
|
||||||
|
|
||||||
Of course one day the first line will be done automatically by site.py or
|
|
||||||
something like that. help can be used as a function.
|
|
||||||
|
|
||||||
The function takes the following forms of input:
|
|
||||||
|
|
||||||
help( "string" ) -- built-in topic or global
|
|
||||||
help( <ob> ) -- docstring from object or type
|
|
||||||
help( "doc:filename" ) -- filename from Python documentation
|
|
||||||
|
|
||||||
Type help to get the rest of the instructions.
|
|
||||||
"""
|
|
||||||
import htmllib # todo: add really basic tr/td support
|
|
||||||
import formatter
|
|
||||||
import os, sys
|
|
||||||
import re
|
|
||||||
|
|
||||||
prompt="--more-- (enter for more, q to quit) "
|
|
||||||
|
|
||||||
topics={} # all built-in (non-HTML, non-docstring) topics go in here
|
|
||||||
commands="" # only used at the top level
|
|
||||||
|
|
||||||
def topLevelCommand( name, description, text ):
|
|
||||||
""" this function is just for use at the top-level to make sure that
|
|
||||||
every advertised top-level topic has a description and every
|
|
||||||
description has text. Maybe we can generalize it later."""
|
|
||||||
|
|
||||||
global commands
|
|
||||||
topics[name]=text
|
|
||||||
|
|
||||||
if description[0]=="[":
|
|
||||||
placeholder="(dummy)"
|
|
||||||
elif description[0]=="<":
|
|
||||||
placeholder="link"
|
|
||||||
else:
|
|
||||||
placeholder=""
|
|
||||||
commands=commands+'help( "%s" ) %s - %s\n' % \
|
|
||||||
(name, placeholder, description )
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"intro",
|
|
||||||
"What is Python? Read this first!",
|
|
||||||
"""Welcome to Python, the easy to learn, portable, object oriented
|
|
||||||
programming language.
|
|
||||||
|
|
||||||
[info on how to use help]
|
|
||||||
|
|
||||||
[info on intepreter]"""
|
|
||||||
)
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"keywords",
|
|
||||||
"What are the keywords?",
|
|
||||||
"")
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"syntax",
|
|
||||||
"What is the overall syntax?",
|
|
||||||
"[placeholder]")
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"operators",
|
|
||||||
"What operators are available?",
|
|
||||||
"<doc:ref/operators.html>" )
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"builtins",
|
|
||||||
"What functions, types, etc. are built-in?",
|
|
||||||
"<doc:lib/built-in-funcs.html>")
|
|
||||||
|
|
||||||
topLevelCommand( "modules",
|
|
||||||
"What modules are in the standard library?",
|
|
||||||
"<doc:lib/lib.html>")
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"copyright",
|
|
||||||
"Who owns Python?",
|
|
||||||
"[who knows]")
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"moreinfo",
|
|
||||||
"Where is there more information?",
|
|
||||||
"[placeholder]")
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"changes",
|
|
||||||
"What changed in Python 2.0?",
|
|
||||||
"[placeholder]"
|
|
||||||
)
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"extensions",
|
|
||||||
"What extensions are installed?",
|
|
||||||
"[placeholder]")
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"faq",
|
|
||||||
"What questions are frequently asked?",
|
|
||||||
"[placeholder]")
|
|
||||||
|
|
||||||
topLevelCommand(
|
|
||||||
"ack",
|
|
||||||
"Who has done work on Python lately?",
|
|
||||||
"[placeholder for list of people who contributed patches]")
|
|
||||||
|
|
||||||
|
|
||||||
topics[ "prompt" ]="""<doc:tut/node4.html>"""
|
|
||||||
topics[ "types" ]="""<doc:ref/types.html>"""
|
|
||||||
topics["everything"]= \
|
|
||||||
"""<pre>The help function allows you to read help on Python's various
|
|
||||||
functions, objects, instructions and modules. You have two options:
|
|
||||||
|
|
||||||
1. Use help( obj ) to browse the help attached to some function, module
|
|
||||||
class or other object. e.g. help( dir )
|
|
||||||
|
|
||||||
2. Use help( "somestring" ) to browse help on one of the predefined
|
|
||||||
help topics, unassociated with any particular object:
|
|
||||||
|
|
||||||
%s</pre>""" % commands
|
|
||||||
|
|
||||||
topics[ "keywords" ]=\
|
|
||||||
"""<pre>"if" - Conditional execution
|
|
||||||
"while" - Loop while a condition is true
|
|
||||||
"for" - Loop over a sequence of values (often numbers)
|
|
||||||
"try" - Set up an exception handler
|
|
||||||
"def" - Define a named function
|
|
||||||
"class" - Define a class
|
|
||||||
"assert" - Check that some code is working as you expect it to.
|
|
||||||
"pass" - Do nothing
|
|
||||||
"del" - Delete a data value
|
|
||||||
"print" - Print a value
|
|
||||||
"return" - Return information from a function
|
|
||||||
"raise" - Raise an exception
|
|
||||||
"break" - Terminate a loop
|
|
||||||
"continue" - Skip to the next loop statement
|
|
||||||
"import" - Import a module
|
|
||||||
"global" - Declare a variable global
|
|
||||||
"exec" - Execute some dynamically generated code
|
|
||||||
"lambda" - Define an unnamed function
|
|
||||||
|
|
||||||
For more information, type e.g. help("assert")</pre>"""
|
|
||||||
|
|
||||||
topics[ "if" ]="""<doc:ref/if.html>"""
|
|
||||||
topics[ "while" ]="""<doc:ref/while.html>"""
|
|
||||||
topics[ "for" ]="""<doc:ref/for.html>"""
|
|
||||||
topics[ "try" ]="""<doc:ref/try.html>"""
|
|
||||||
topics[ "def" ]="""<doc:ref/def.html>"""
|
|
||||||
topics[ "class" ]="""<doc:ref/class.html>"""
|
|
||||||
topics[ "assert" ]="""<doc:ref/assert.html>"""
|
|
||||||
topics[ "pass" ]="""<doc:ref/pass.html>"""
|
|
||||||
topics[ "del" ]="""<doc:ref/del.html>"""
|
|
||||||
topics[ "print" ]="""<doc:ref/print.html>"""
|
|
||||||
topics[ "return" ]="""<doc:ref/return.html>"""
|
|
||||||
topics[ "raise" ]="""<doc:ref/raise.html>"""
|
|
||||||
topics[ "break" ]="""<doc:ref/break.html>"""
|
|
||||||
topics[ "continue" ]="""<doc:ref/continue.html>"""
|
|
||||||
topics[ "import" ]="""<doc:ref/import.html>"""
|
|
||||||
topics[ "global" ]="""<doc:ref/global.html>"""
|
|
||||||
topics[ "exec" ]="""<doc:ref/exec.html>"""
|
|
||||||
topics[ "lambda" ]="""<doc:ref/lambda.html>"""
|
|
||||||
|
|
||||||
envir_var="PYTHONDOCS"
|
|
||||||
|
|
||||||
class Help:
|
|
||||||
def __init__( self, out, line_length, docdir=None ):
|
|
||||||
self.out=out
|
|
||||||
self.line_length=line_length
|
|
||||||
self.Parser=htmllib.HTMLParser
|
|
||||||
self.Formatter=formatter.AbstractFormatter
|
|
||||||
self.Pager=Pager
|
|
||||||
self.Writer=formatter.DumbWriter
|
|
||||||
if os.environ.has_key(envir_var):
|
|
||||||
self.docdir=os.environ[envir_var]
|
|
||||||
else:
|
|
||||||
if os.environ.has_key("PYTHONHOME"):
|
|
||||||
pyhome=os.environ["PYTHONHOME"]
|
|
||||||
else:
|
|
||||||
pyhome=os.path.split( sys.executable )[0]
|
|
||||||
self.docdir=os.path.join( pyhome, "doc" )
|
|
||||||
|
|
||||||
testfile=os.path.join(
|
|
||||||
os.path.join( self.docdir, "lib" ), "index.html")
|
|
||||||
|
|
||||||
if not os.path.exists( testfile ):
|
|
||||||
error = \
|
|
||||||
"""Cannot find documentation directory %s.
|
|
||||||
Set the %s environment variable to point to a "doc" directory.
|
|
||||||
It should have a subdirectory "Lib" with a file named "index.html".
|
|
||||||
""" % (self.docdir, envir_var )
|
|
||||||
raise EnvironmentError, error
|
|
||||||
|
|
||||||
def __repr__( self ):
|
|
||||||
self( "everything" )
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def __call__( self, ob, out=None ):
|
|
||||||
try:
|
|
||||||
self.call( ob, out )
|
|
||||||
return 1
|
|
||||||
except (KeyboardInterrupt, EOFError):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def call( self, ob, out ):
|
|
||||||
self.pager=out or self.Pager( self.out, self.line_length )
|
|
||||||
|
|
||||||
if type( ob ) in (type(""),type(u"")):
|
|
||||||
if ob.startswith( "<" ):
|
|
||||||
ob=ob[1:]
|
|
||||||
if ob.endswith( ">" ):
|
|
||||||
ob=ob[:-1]
|
|
||||||
|
|
||||||
self.write( 'Topic: help( "%s" )\n' % ob )
|
|
||||||
|
|
||||||
if ob.startswith("doc:"):
|
|
||||||
path=ob[4:]
|
|
||||||
fullpath=os.path.join( self.docdir, path )
|
|
||||||
data=open( fullpath ).read()
|
|
||||||
index=ob.rfind( "/" )
|
|
||||||
self.writeHTML( ob[:index], data )
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
info=topics[ob]
|
|
||||||
docrlmatch=re.search( "(<doc:[^>]+>)", info.split("\n")[0] )
|
|
||||||
if docrlmatch: # a first-line redirect
|
|
||||||
self( docrlmatch.group(1) )
|
|
||||||
else:
|
|
||||||
self.writeHTML( "", info )
|
|
||||||
except KeyError:
|
|
||||||
glo=__builtins__.__dict__.get( ob, 0 )
|
|
||||||
if glo:
|
|
||||||
self( glo )
|
|
||||||
else:
|
|
||||||
sys.stderr.write( "No such topic "+`ob` )
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
self.write( 'Topic: help( %s )\n' % ob )
|
|
||||||
if hasattr( ob, "__doc__" ):
|
|
||||||
self.writeText(ob.__doc__)
|
|
||||||
else:
|
|
||||||
self.writeText( type( ob ).__doc__ )
|
|
||||||
|
|
||||||
|
|
||||||
def writeHTML( self, base, str ):
|
|
||||||
parser=self.Parser(self.Formatter( self.Writer( self )))
|
|
||||||
parser.feed( str ) # calls self.write automatically
|
|
||||||
for i in range( len( parser.anchorlist) ):
|
|
||||||
self.pager.write( "[%s] %s/%s\n" %(i+1, base,parser.anchorlist[i] ))
|
|
||||||
self.pager.flush()
|
|
||||||
self.out.write( "\n" )
|
|
||||||
|
|
||||||
def writeText( self, str ):
|
|
||||||
self.pager.write( str )
|
|
||||||
self.pager.flush()
|
|
||||||
self.out.write( "\n" )
|
|
||||||
|
|
||||||
def write( self, str ):
|
|
||||||
self.pager.write( str )
|
|
||||||
|
|
||||||
from cStringIO import StringIO
|
|
||||||
|
|
||||||
class Pager:
|
|
||||||
numlines=1
|
|
||||||
|
|
||||||
def __init__(self, out, pagesize=24, linestart="" ):
|
|
||||||
self.out=out
|
|
||||||
self.pagesize=pagesize
|
|
||||||
self.buf=StringIO()
|
|
||||||
self.linestart=linestart
|
|
||||||
|
|
||||||
def close(self ):
|
|
||||||
self.flush()
|
|
||||||
|
|
||||||
def flush(self ):
|
|
||||||
data=self.buf.getvalue().rstrip() # dump trailing ws
|
|
||||||
while data.endswith( "\n|" ): # dump trailing lines
|
|
||||||
data=data[:-2]
|
|
||||||
self.out.write( data )
|
|
||||||
self.buf=StringIO()
|
|
||||||
|
|
||||||
def write(self, str ):
|
|
||||||
lines=str.split( "\n" )
|
|
||||||
self.buf.write( lines[0] )
|
|
||||||
for line in lines[1:]:
|
|
||||||
self.buf.write( "\n| " )
|
|
||||||
self.buf.write( line )
|
|
||||||
if self.numlines and not self.numlines%(self.pagesize):
|
|
||||||
dat=self.buf.getvalue().strip()
|
|
||||||
self.out.write( "| " )
|
|
||||||
self.out.write( dat )
|
|
||||||
self.out.write( "\n" )
|
|
||||||
j=raw_input(prompt)
|
|
||||||
if j and j[0]=="q":
|
|
||||||
raise EOFError
|
|
||||||
self.buf=StringIO()
|
|
||||||
self.numlines=self.numlines+1
|
|
||||||
|
|
||||||
help=Help(sys.stdout,24)
|
|
||||||
|
|
||||||
def test():
|
|
||||||
rc = 1
|
|
||||||
rc = rc and help( "everything" )
|
|
||||||
rc = rc and help( "exec" )
|
|
||||||
rc = rc and help( "doc:lib/unix.html" )
|
|
||||||
rc = rc and help( "doc:lib/module-tty.html" )
|
|
||||||
rc = rc and help( "doc:ref/print.html" )
|
|
||||||
rc = rc and help( "faq" )
|
|
||||||
rc = rc and help( dir )
|
|
||||||
repr( help )
|
|
||||||
|
|
||||||
if __name__=="__main__":
|
|
||||||
if len( sys.argv )!=2:
|
|
||||||
print "Usage: %s <topic> or %s test" % ( sys.argv[0], sys.argv[0] )
|
|
||||||
sys.exit(0)
|
|
||||||
elif sys.argv[1]=="test":
|
|
||||||
test()
|
|
||||||
else:
|
|
||||||
help( sys.argv[1] )
|
|
||||||
|
|
Loading…
Reference in New Issue