| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python3 | 1 #!/usr/bin/env python3 |
| 2 """Generate Python documentation in HTML or text for interactive use. | 2 """Generate Python documentation in HTML or text for interactive use. |
| 3 | 3 |
| 4 In the Python interpreter, do "from pydoc import help" to provide online | 4 In the Python interpreter, do "from pydoc import help" to provide online |
| 5 help. Calling help(thing) on a Python object documents the object. | 5 help. Calling help(thing) on a Python object documents the object. |
| 6 | 6 |
| 7 Or, at the shell command line outside of Python: | 7 Or, at the shell command line outside of Python: |
| 8 | 8 |
| 9 Run "pydoc <name>" to show documentation on something. <name> may be | 9 Run "pydoc <name>" to show documentation on something. <name> may be |
| 10 the name of a function, module, package, or a dotted reference to a | 10 the name of a function, module, package, or a dotted reference to a |
| (...skipping 2453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2464 If the content_type is 'text/css', the _pydoc.css style | 2464 If the content_type is 'text/css', the _pydoc.css style |
| 2465 sheet is read and returned if it exits. | 2465 sheet is read and returned if it exits. |
| 2466 | 2466 |
| 2467 If the content_type is 'text/html', then the result of | 2467 If the content_type is 'text/html', then the result of |
| 2468 get_html_page(url) is returned. | 2468 get_html_page(url) is returned. |
| 2469 """ | 2469 """ |
| 2470 class _HTMLDoc(HTMLDoc): | 2470 class _HTMLDoc(HTMLDoc): |
| 2471 | 2471 |
| 2472 def page(self, title, contents): | 2472 def page(self, title, contents): |
| 2473 """Format an HTML page.""" | 2473 """Format an HTML page.""" |
| 2474 css_path = "pydoc_data/_pydoc.css" | 2474 values = dict(title=title, |
| 2475 css_link = ( | 2475 css_path="pydoc_data/_pydoc.css", |
| 2476 '<link rel="stylesheet" type="text/css" href="%s">' % | 2476 header=html_header(), |
| 2477 css_path) | 2477 content=contents, |
| 2478 return '''\ | 2478 ) |
| 2479 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | 2479 template = \ |
| 2480 <html><head><title>Python: %s</title> | 2480 '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" |
| 2481 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | 2481 "http://www.w3.org/TR/html4/strict.dtd"> |
| 2482 %s</head><body bgcolor="#f0f0f8">%s | 2482 <html> |
| 2483 </body></html>''' % (title, css_link, contents) | 2483 <head> |
| 2484 <title>PyDoc: {title}</title> | |
| 2485 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
| 2486 <link rel="stylesheet" type="text/css" href="{css_path}"> | |
| 2487 </head> | |
| 2488 <body> | |
| 2489 <div id=page> | |
| 2490 {header} | |
| 2491 {content} | |
| 2492 </div> | |
| 2493 </body> | |
| 2494 </html> | |
| 2495 ''' | |
| 2496 return template.format(**values) | |
| 2484 | 2497 |
| 2485 def filelink(self, url, path): | 2498 def filelink(self, url, path): |
| 2486 return '<a href="getfile?key=%s">%s</a>' % (url, path) | 2499 return '<a href="getfile?key=%s">%s</a>' % (url, path) |
| 2487 | 2500 |
| 2488 | 2501 |
| 2502 def _index_section(self, title, items, css_class): | |
| 2503 """Make an index sub-section""" | |
| 2504 items = '</li>\n<li>'.join(items) | |
| 2505 values = dict(title = title, | |
| 2506 items = items, | |
|
ezio.melotti
2011/03/11 23:13:43
The spaces around the = can go.
| |
| 2507 css_class=css_class, | |
| 2508 ) | |
|
ezio.melotti
2011/03/11 23:13:43
The ) should be closed on the previous line.
eric.araujo
2011/03/11 23:35:54
That’s done on purpose by Ron so that any future a
ezio.melotti
2011/03/12 14:35:09
I don't think having one more line is a big deal.
| |
| 2509 template = (' <dt>{title}</dt>' | |
| 2510 ' <dd>' | |
| 2511 ' <ul class="{css_class}">' | |
| 2512 ' <li>{items}</li>' | |
| 2513 ' </ul>' | |
| 2514 ' </dd>' | |
|
ezio.melotti
2011/03/11 23:13:43
It's better to add a \n at the end of the line or
| |
| 2515 ) | |
|
ezio.melotti
2011/03/11 23:13:43
The ) should be closed on the previous line.
| |
| 2516 return template.format(**values) | |
| 2517 | |
| 2518 def index_columns(self, title, items, css_class): | |
| 2519 """Create a index section with columns.""" | |
| 2520 section = html._index_section(title, items, | |
| 2521 css_class="index-columns") | |
|
ezio.melotti
2011/03/11 23:13:43
css_class should be indented under title.
| |
| 2522 template = ('<dl class="{css_class}">' | |
| 2523 ' {section}' | |
| 2524 '</dl>' | |
| 2525 ) | |
|
ezio.melotti
2011/03/11 23:13:43
See previous comments about \n and the ).
| |
| 2526 return template.format(css_class=css_class, section=section) | |
| 2527 | |
| 2528 def index_lines(self, title, items, css_class): | |
| 2529 """Create an index section with line.""" | |
| 2530 section = html._index_section(title, items, | |
| 2531 css_class="index-lines") | |
| 2532 template = ('<dl class="{css_class}">' | |
| 2533 ' {section}' | |
| 2534 '</dl>' | |
| 2535 ) | |
| 2536 return template.format(css_class=css_class, section=section) | |
|
ezio.melotti
2011/03/11 23:13:43
See previous comments.
Also this function is very
| |
| 2537 | |
| 2489 html = _HTMLDoc() | 2538 html = _HTMLDoc() |
| 2490 | 2539 |
| 2491 def html_navbar(): | 2540 def html_header(): |
| 2492 version = "%s [%s, %s]" % (platform.python_version(), | 2541 values = dict(version=platform.python_version(), |
| 2493 platform.python_build()[0], | 2542 build=platform.python_build()[0], |
| 2494 platform.python_compiler()) | 2543 compiler=platform.python_compiler(), |
| 2495 return """ | 2544 platform=platform.platform(terse=True), |
| 2496 <div style='float:left'> | 2545 ) |
| 2497 Python %s<br>%s<br><br> | 2546 template = \ |
| 2498 </div> | 2547 """ |
| 2499 <div style='float:right'> | 2548 <div id="page-header"> |
| 2500 <div style='text-align:center'> | 2549 <h1 id="page-title">PyDoc</h1> |
| 2501 <a href="index.html">Module Index</a> | 2550 <p id="python_version"> |
| 2502 : <a href="topics.html">Topics</a> | 2551 Python {version} - [{build}, {compiler}, {platform}] |
|
ezio.melotti
2011/03/11 23:13:43
</p>
| |
| 2503 : <a href="keywords.html">Keywords</a> | 2552 <ul id="navbar"> |
| 2504 </div> | 2553 <li><form action="get"><div> |
| 2505 <div> | 2554 <input name="key" size="15" type="text"> |
| 2506 <form action="get" style='float:left'> | 2555 <input value="Get" type="submit"> |
| 2507 <input type=text name=key size=15> | 2556 </div></form></li> |
| 2508 <input type=submit value="Get"> | 2557 <li><form action="search"><div> |
| 2509 | 2558 <input name="key" size="15" type="text"> |
| 2510 </form> | 2559 <input value="Search" type="submit"> |
| 2511 <form action="search" style='float:right'> | 2560 </div></form></li> |
| 2512 <input type=text name=key size=15> | 2561 <li> |
| 2513 <input type=submit value="Search"> | 2562 <a href="index.html">modules</a> |
| 2514 </form> | 2563 <a href="keywords.html">keywords</a> |
| 2515 </div> | 2564 <a href="topics.html">topics</a> |
| 2516 </div> | 2565 </li> |
| 2517 <div clear='all'> </div> | 2566 </ul> |
| 2518 """ % (version, platform.platform(terse=True)) | 2567 </div> <!-- end header --> |
| 2519 | 2568 """ |
| 2520 def html_index(): | 2569 return template.format(**values) |
| 2570 | |
| 2571 def html_modules(): | |
| 2521 """Module Index page.""" | 2572 """Module Index page.""" |
| 2522 | 2573 link_list = ['<a href="%s.html">%s</a>' % (name, name) |
| 2523 def bltinlink(name): | 2574 for name in sys.builtin_module_names |
| 2524 return '<a href="%s.html">%s</a>' % (name, name) | 2575 if name != '__main__'] |
| 2525 | 2576 contents = [html.index_columns('Built-in modules', link_list, |
| 2526 heading = html.heading( | 2577 css_class='section modules')] |
| 2527 '<big><big><strong>Index of Modules</strong></big></big>', | 2578 shadowed = set() |
| 2528 '#ffffff', '#7799ee') | |
| 2529 names = [name for name in sys.builtin_module_names | |
| 2530 if name != '__main__'] | |
| 2531 contents = html.multicolumn(names, bltinlink) | |
| 2532 contents = [heading, '<p>' + html.bigsection( | |
| 2533 'Built-in Modules', '#ffffff', '#ee77aa', contents)] | |
| 2534 | |
| 2535 seen = {} | |
| 2536 for dir in sys.path: | 2579 for dir in sys.path: |
| 2537 contents.append(html.index(dir, seen)) | 2580 modules = [] |
| 2538 | 2581 for importer, name, ispkg in pkgutil.iter_modules([dir]): |
| 2539 contents.append( | 2582 if name not in shadowed: |
| 2540 '<p align=right><font color="#909090" face="helvetica,' | 2583 modules.append((name, ispkg)) |
| 2541 'arial"><strong>pydoc</strong> by Ka-Ping Yee' | 2584 shadowed.add(name) |
| 2542 '<ping@lfw.org></font>') | 2585 modules.sort() |
| 2543 return 'Index of Modules', ''.join(contents) | 2586 links = [] |
| 2587 for name, ispkg in modules: | |
| 2588 if ispkg: | |
| 2589 template = ('<span class="package"><a href="{name}.html">' | |
| 2590 '{name}</a> (package)</span>') | |
| 2591 else: | |
| 2592 template = ('<a class="module" href="{name}.html">' | |
| 2593 '{name}</a>') | |
|
ezio.melotti
2011/03/11 23:13:43
I don't like too much the fact that the packages h
eric.araujo
2011/03/11 23:35:54
Why don’t you like it?
ezio.melotti
2011/03/12 14:35:09
Because it's not symmetric, if I want to parse the
| |
| 2594 link = template.format(name=name) | |
| 2595 links.append(link) | |
| 2596 contents.append(html.index_columns(dir, | |
| 2597 links, css_class='section modules')) | |
| 2598 content =''.join(contents) | |
|
ezio.melotti
2011/03/11 23:13:43
Missing space after the =.
| |
| 2599 template = ('<div id="page-content">' | |
| 2600 ' <h2 id="subject">Index of Modules</h2>' | |
| 2601 ' {content}' | |
| 2602 '</div>' | |
| 2603 '<div id="page-footer">' | |
| 2604 ' <p>PyDoc by Ka-Ping Yee<ping@lfw.org>' | |
| 2605 '</div>' | |
| 2606 ) | |
|
ezio.melotti
2011/03/11 23:13:43
\n and ).
There are also other occurrences later.
| |
| 2607 return 'Index of Modules', template.format(content=content) | |
| 2544 | 2608 |
| 2545 def html_search(key): | 2609 def html_search(key): |
| 2546 """Search results page.""" | 2610 """Search results page.""" |
| 2547 # scan for modules | 2611 # scan for modules |
| 2548 search_result = [] | 2612 search_result = [] |
| 2549 | |
| 2550 def callback(path, modname, desc): | 2613 def callback(path, modname, desc): |
| 2551 if modname[-9:] == '.__init__': | 2614 if modname[-9:] == '.__init__': |
| 2552 modname = modname[:-9] + ' (package)' | 2615 modname = modname[:-9] + ' (package)' |
| 2553 search_result.append((modname, desc and '- ' + desc)) | 2616 search_result.append((modname, desc and ' - ' + desc)) |
| 2554 | |
| 2555 with warnings.catch_warnings(): | 2617 with warnings.catch_warnings(): |
| 2556 warnings.filterwarnings('ignore') # ignore problems during import | 2618 warnings.filterwarnings('ignore') # ignore problems during import |
| 2557 ModuleScanner().run(callback, key) | 2619 ModuleScanner().run(callback, key) |
| 2558 | 2620 link_list = ['<a href="%s.html">%s</a>%s' % (name, name, desc) |
| 2559 # format page | 2621 for name, desc in search_result] |
| 2560 def bltinlink(name): | 2622 content = html.index_lines('key = %s' % key, link_list, |
| 2561 return '<a href="%s.html">%s</a>' % (name, name) | 2623 css_class='section modules') |
| 2562 | 2624 template = ('<div id="page-content">' |
| 2563 results = [] | 2625 ' <h2 id="subject">Search Results</h2>' |
| 2564 heading = html.heading( | 2626 ' {content}' |
| 2565 '<big><big><strong>Search Results</strong></big></big>', | 2627 '</div>' |
| 2566 '#ffffff', '#7799ee') | 2628 ) |
| 2567 for name, desc in search_result: | 2629 return 'Search Results', template.format(content=content) |
| 2568 results.append(bltinlink(name) + desc) | |
| 2569 contents = heading + html.bigsection( | |
| 2570 'key = %s' % key, '#ffffff', '#ee77aa', '<br>'.join(results)) | |
| 2571 return 'Search Results', contents | |
| 2572 | 2630 |
| 2573 def html_getfile(path): | 2631 def html_getfile(path): |
| 2574 """Get and display a source file listing safely.""" | 2632 """Get and display a source file listing safely.""" |
| 2575 path = path.replace('%20', ' ') | |
| 2576 with open(path, 'r') as fp: | 2633 with open(path, 'r') as fp: |
| 2577 lines = html.escape(fp.read()) | 2634 lines = html.escape(fp.read()) |
| 2578 body = '<pre>%s</pre>' % lines | 2635 title = 'getfile %s' % path.replace('%20', ' ') |
|
ezio.melotti
2011/03/11 23:13:43
urllib.unquote()?
| |
| 2579 heading = html.heading( | 2636 template = ('<div id="page-content">' |
| 2580 '<big><big><strong>File Listing</strong></big></big>', | 2637 ' <h2 id="subject">File Listing</h2>' |
| 2581 '#ffffff', '#7799ee') | 2638 ' <dl class="section file">' |
| 2582 contents = heading + html.bigsection( | 2639 ' <dt>File: {path}</dt>' |
| 2583 'File: %s' % path, '#ffffff', '#ee77aa', body) | 2640 ' <dd><pre class="python-code"><code' |
| 2584 return 'getfile %s' % path, contents | 2641 ' >{lines}</code></pre>' |
| 2642 ' </dd>' | |
| 2643 ' </dl>' | |
| 2644 '</div>' | |
| 2645 ) | |
| 2646 return title, template.format(path=path, lines=lines) | |
| 2585 | 2647 |
| 2586 def html_topics(): | 2648 def html_topics(): |
| 2587 """Index of topic texts available.""" | 2649 """Index of topic texts available.""" |
| 2588 | 2650 link_list = ['<a href="%s.html">%s</a>' % (name, name) |
| 2589 def bltinlink(name): | 2651 for name in sorted(Helper.topics.keys())] |
| 2590 return '<a href="%s.html">%s</a>' % (name, name) | 2652 content = html.index_columns('Topics', link_list, |
| 2591 | 2653 css_class="section topics") |
| 2592 heading = html.heading( | 2654 template = ('<div id="page-content">' |
| 2593 '<big><big><strong>INDEX</strong></big></big>', | 2655 ' <h2 id="subject">Index</h2>' |
| 2594 '#ffffff', '#7799ee') | 2656 ' {content}' |
| 2595 names = sorted(Helper.topics.keys()) | 2657 '</div>' |
| 2596 | 2658 ) |
| 2597 contents = html.multicolumn(names, bltinlink) | 2659 return 'Topics', template.format(content=content) |
| 2598 contents = heading + html.bigsection( | |
| 2599 'Topics', '#ffffff', '#ee77aa', contents) | |
| 2600 return 'Topics', contents | |
| 2601 | 2660 |
| 2602 def html_keywords(): | 2661 def html_keywords(): |
| 2603 """Index of keywords.""" | 2662 """Index of keywords.""" |
| 2604 heading = html.heading( | 2663 link_list = ['<a href="%s.html">%s</a>' % (name, name) |
| 2605 '<big><big><strong>INDEX</strong></big></big>', | 2664 for name in sorted(Helper.keywords.keys())] |
| 2606 '#ffffff', '#7799ee') | 2665 content = html.index_columns('Keywords', link_list, |
| 2607 names = sorted(Helper.keywords.keys()) | 2666 css_class="section topics") |
| 2608 | 2667 template = ('<div id="page-content">' |
| 2609 def bltinlink(name): | 2668 ' <h2 id="subject">Index</h2>' |
| 2610 return '<a href="%s.html">%s</a>' % (name, name) | 2669 ' {content}' |
| 2611 | 2670 '</div>' |
| 2612 contents = html.multicolumn(names, bltinlink) | 2671 ) |
| 2613 contents = heading + html.bigsection( | 2672 return 'Keywords', template.format(content=content) |
| 2614 'Keywords', '#ffffff', '#ee77aa', contents) | 2673 |
| 2615 return 'Keywords', contents | |
| 2616 | 2674 |
| 2617 def html_topicpage(topic): | 2675 def html_topicpage(topic): |
| 2618 """Topic or keyword help page.""" | 2676 """Topic or keyword help page.""" |
| 2619 buf = io.StringIO() | 2677 buf = io.StringIO() |
| 2620 htmlhelp = Helper(buf, buf) | 2678 htmlhelp = Helper(buf, buf) |
| 2621 contents, xrefs = htmlhelp._gettopic(topic) | 2679 contents, xrefs = htmlhelp._gettopic(topic) |
| 2622 if topic in htmlhelp.keywords: | 2680 if topic in htmlhelp.keywords: |
| 2623 title = 'KEYWORD' | 2681 title = 'Keyword' |
| 2624 else: | 2682 else: |
| 2625 title = 'TOPIC' | 2683 title = 'Topic' |
| 2626 heading = html.heading( | 2684 text = html.markup(contents) |
| 2627 '<big><big><strong>%s</strong></big></big>' % title, | 2685 link_list = ['<a href="%s.html">%s</a>' % (name, name) |
| 2628 '#ffffff', '#7799ee') | 2686 for name in sorted(xrefs.split())] |
| 2629 contents = '<pre>%s</pre>' % contents | 2687 xrefs = html.index_columns('Related help Topics', link_list, |
| 2630 contents = html.bigsection(topic , '#ffffff','#ee77aa', contents) | 2688 css_class="section topics") |
| 2631 xrefs = sorted(xrefs.split()) | 2689 values = dict( |
| 2632 | 2690 title=title, |
| 2633 def bltinlink(name): | 2691 topic=topic, |
| 2634 return '<a href="%s.html">%s</a>' % (name, name) | 2692 text=text, |
| 2635 | 2693 xrefs=xrefs, |
| 2636 xrefs = html.multicolumn(xrefs, bltinlink) | 2694 ) |
|
ezio.melotti
2011/03/11 23:13:43
I use either:
values = dict(foo=bar,
eric.araujo
2011/03/11 23:35:54
I don’t see why you said that: The code uses the s
ezio.melotti
2011/03/12 14:35:09
In the second style the ) is closed under the 'v'
| |
| 2637 xrefs = html.section('Related help topics: ', | 2695 template = ('<div id="page-content">' |
| 2638 '#ffffff', '#ee77aa', xrefs) | 2696 ' <h2 id="subject">{title}</h2>' |
| 2639 return ('%s %s' % (title, topic), | 2697 ' <dl class="section topic">' |
| 2640 ''.join((heading, contents, xrefs))) | 2698 ' <dt>{topic}</dt>' |
| 2641 | 2699 ' <dd><pre class="topic-info">{text}</pre></dd>' |
| 2642 def html_error(url): | 2700 ' </dl>' |
| 2643 heading = html.heading( | 2701 ' {xrefs}' |
| 2644 '<big><big><strong>Error</strong></big></big>', | 2702 '</div>' |
| 2645 '#ffffff', '#ee0000') | 2703 ) |
| 2646 return heading + url | 2704 return '%s %s' % (title, topic), template.format(**values) |
| 2705 | |
| 2706 def html_error(exc, url): | |
| 2707 values = dict( | |
| 2708 title = url, | |
| 2709 exc = repr(exc), | |
| 2710 err = str(exc), | |
|
ezio.melotti
2011/03/11 23:13:43
You can remove the spaces around the =, if you wan
eric.araujo
2011/03/11 23:35:54
This contradicts a previous comment you made :) E
ezio.melotti
2011/03/12 14:35:09
I don't use spaces myself, but it's ok for me if s
| |
| 2711 ) | |
| 2712 template = ('<div id="page-content">' | |
| 2713 ' <h2 id="subject">Error</h2>' | |
| 2714 ' <dl class="section error">' | |
| 2715 ' <dt>{title}</dt>' | |
| 2716 ' <dd>' | |
| 2717 ' <p>{exc}' | |
| 2718 ' <p>{err}' | |
|
ezio.melotti
2011/03/11 23:13:43
It's always better to close the </p>, even if it's
eric.araujo
2011/03/11 23:35:54
I agree, it’s more readable to close elements.
| |
| 2719 ' </dd>' | |
| 2720 ' </dl>' | |
| 2721 '</div>' | |
| 2722 ) | |
| 2723 return "Error - " + url, template.format(**values) | |
| 2647 | 2724 |
| 2648 def get_html_page(url): | 2725 def get_html_page(url): |
| 2649 """Generate an HTML page for url.""" | 2726 """Generate an HTML page for url.""" |
| 2650 if url.endswith('.html'): | 2727 try: |
| 2651 url = url[:-5] | 2728 if url.endswith('.html'): |
| 2652 if url.startswith('/'): | 2729 url = url[:-5] |
| 2653 url = url[1:] | 2730 if url.startswith('/'): |
| 2654 if url.startswith("get?key="): | 2731 url = url[1:] |
| 2655 url = url[8:] | 2732 if url.startswith("get?key="): |
| 2656 title = url | 2733 url = url[8:] |
| 2657 contents = '' | 2734 if url in ("", ".", "index"): |
| 2658 if url in ("", ".", "index"): | 2735 title, content = html_modules() |
| 2659 title, contents = html_index() | 2736 elif url == "topics": |
| 2660 elif url == "topics": | 2737 title, content = html_topics() |
| 2661 title, contents = html_topics() | 2738 elif url == "keywords": |
| 2662 elif url == "keywords": | 2739 title, content = html_keywords() |
| 2663 title, contents = html_keywords() | 2740 elif url.startswith("search?key="): |
| 2664 elif url.startswith("search?key="): | 2741 title, content = html_search(url[11:]) |
| 2665 title, contents = html_search(url[11:]) | 2742 elif url.startswith("getfile?key="): |
| 2666 elif url.startswith("getfile?key="): | 2743 path = url[12:] |
| 2667 url = url[12:] | 2744 title, content = html_getfile(path) |
| 2668 try: | 2745 elif url in Helper.keywords or url in Helper.topics: |
| 2669 title, contents = html_getfile(url) | 2746 title, content = html_topicpage(url) |
| 2670 except IOError: | 2747 else: |
| 2671 contents = html_error('could not read file %r' % url) | |
| 2672 title = 'Read Error' | |
| 2673 else: | |
| 2674 obj = None | |
| 2675 try: | |
| 2676 obj = locate(url, forceload=1) | 2748 obj = locate(url, forceload=1) |
| 2677 except ErrorDuringImport as value: | 2749 if obj is None and url != "None": |
| 2678 contents = html.escape(str(value)) | 2750 raise ValueError('could not find "%s"' % url) |
| 2679 if obj: | |
| 2680 title = describe(obj) | 2751 title = describe(obj) |
| 2681 contents = html.document(obj, url) | 2752 content = ('<div id="page-content">%s</div>' % |
| 2682 elif url in Helper.keywords or url in Helper.topics: | 2753 html.document(obj, url)) |
| 2683 title, contents = html_topicpage(url) | 2754 except Exception as exc: |
| 2684 else: | 2755 title, content = html_error(exc, url) |
| 2685 contents = html_error( | 2756 return html.page(title, content) |
| 2686 'no Python documentation found for %r' % url) | |
| 2687 title = 'Error' | |
| 2688 return html.page(title, html_navbar() + contents) | |
| 2689 | 2757 |
| 2690 if url.startswith('/'): | 2758 if url.startswith('/'): |
| 2691 url = url[1:] | 2759 url = url[1:] |
| 2692 if content_type == 'text/css': | 2760 if content_type == 'text/css': |
| 2693 path_here = os.path.dirname(os.path.realpath(__file__)) | 2761 path_here = os.path.dirname(os.path.realpath(__file__)) |
| 2694 try: | 2762 with open(os.path.join(path_here, url)) as fp: |
| 2695 with open(os.path.join(path_here, url)) as fp: | 2763 return ''.join(fp.readlines()) |
| 2696 return ''.join(fp.readlines()) | |
| 2697 except IOError: | |
| 2698 return 'Error: can not open css file %r' % url | |
| 2699 elif content_type == 'text/html': | 2764 elif content_type == 'text/html': |
| 2700 return get_html_page(url) | 2765 return get_html_page(url) |
| 2701 return 'Error: unknown content type %r' % content_type | 2766 raise ValueError('unknown content type: (%r, %r)' % (content_type, url)) |
| 2702 | 2767 |
| 2703 | 2768 |
| 2704 def browse(port=0, *, open_browser=True): | 2769 def browse(port=0, *, open_browser=True): |
| 2705 """Start the enhanced pydoc Web server and open a Web browser. | 2770 """Start the enhanced pydoc Web server and open a Web browser. |
| 2706 | 2771 |
| 2707 Use port '0' to start the server on an arbitrary port. | 2772 Use port '0' to start the server on an arbitrary port. |
| 2708 Set open_browser to False to suppress opening a browser. | 2773 Set open_browser to False to suppress opening a browser. |
| 2709 """ | 2774 """ |
| 2710 import webbrowser | 2775 import webbrowser |
| 2711 serverthread = _start_server(_url_handler, port) | 2776 serverthread = _start_server(_url_handler, port) |
| 2712 if serverthread.error: | 2777 if serverthread.error: |
| 2713 print(serverthread.error) | 2778 print(serverthread.error) |
| 2714 return | 2779 return |
| 2715 if serverthread.serving: | 2780 if serverthread.serving: |
| 2716 server_help_msg = 'Server commands: [b]rowser, [q]uit' | 2781 server_help_msg = 'Server commands: [b]rowser, [q]uit' |
| 2717 if open_browser: | 2782 if open_browser: |
| 2718 webbrowser.open(serverthread.url) | 2783 webbrowser.open(serverthread.url) |
| 2719 try: | 2784 try: |
| 2720 print('Server ready at', serverthread.url) | 2785 print('Server ready at', serverthread.url) |
| 2721 print(server_help_msg) | 2786 print(server_help_msg) |
| 2722 while serverthread.serving: | 2787 while serverthread.serving: |
| 2788 if serverthread.error: | |
| 2789 print(serverthread.error) | |
| 2723 cmd = input('server> ') | 2790 cmd = input('server> ') |
| 2724 cmd = cmd.lower() | 2791 cmd = cmd.lower() |
| 2725 if cmd == 'q': | 2792 if cmd == 'q': |
| 2726 break | 2793 break |
| 2727 elif cmd == 'b': | 2794 elif cmd == 'b': |
| 2728 webbrowser.open(serverthread.url) | 2795 webbrowser.open(serverthread.url) |
| 2729 else: | 2796 else: |
| 2730 print(server_help_msg) | 2797 print(server_help_msg) |
| 2731 except (KeyboardInterrupt, EOFError): | 2798 except (KeyboardInterrupt, EOFError): |
| 2732 print() | 2799 print() |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2828 Deprecated. | 2895 Deprecated. |
| 2829 | 2896 |
| 2830 {cmd} -w <name> ... | 2897 {cmd} -w <name> ... |
| 2831 Write out the HTML documentation for a module to a file in the current | 2898 Write out the HTML documentation for a module to a file in the current |
| 2832 directory. If <name> contains a '{sep}', it is treated as a filename; if | 2899 directory. If <name> contains a '{sep}', it is treated as a filename; if |
| 2833 it names a directory, documentation is written for all the contents. | 2900 it names a directory, documentation is written for all the contents. |
| 2834 """.format(cmd=cmd, sep=os.sep)) | 2901 """.format(cmd=cmd, sep=os.sep)) |
| 2835 | 2902 |
| 2836 if __name__ == '__main__': | 2903 if __name__ == '__main__': |
| 2837 cli() | 2904 cli() |
| OLD | NEW |