mirror of https://github.com/python/cpython
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