gh-129873: IDLE: Improve help.py's method of parsing HTML (#129859)

In `help.copy_strip`, only copy the text `<section>`.  In `help.HelpParser.handle_starttag` and elsewhere, remove code to skip the no longer present html.  Add a reminder at the top of idle.rst to run copy_strip after changes.
---------

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
Stan Ulbrych 2025-02-09 08:17:35 +00:00 committed by GitHub
parent 0d9c4e260d
commit 6fbf15f98e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 30 additions and 416 deletions

View file

@ -12,6 +12,9 @@ IDLE --- Python editor and shell
single: Python Editor
single: Integrated Development Environment
..
Remember to update Lib/idlelib/help.html with idlelib.help.copy_source() when modifying this file.
--------------
IDLE is Python's Integrated Development and Learning Environment.

View file

@ -19,6 +19,9 @@ Released on 2024-10-07
gh-120104: Fix padding in config and search dialog windows in IDLE.
gh-129873: Simplify displaying the IDLE doc by only copying the text
section of idle.html to idlelib/help.html. Patch by Stan Ulbrych.
gh-120083: Add explicit black IDLE Hovertip foreground color needed for
recent macOS. Fixes Sonoma showing unreadable white on pale yellow.
Patch by John Riggles.

View file

@ -1,231 +1,7 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>IDLE — Python editor and shell &#8212; Python 3.14.0a4 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=aa5eeaf2" />
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
<script src="../_static/documentation_options.js?v=058caec0"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Search within Python 3.14.0a4 documentation"
href="../_static/opensearch.xml"/>
<link rel="author" title="About these documents" href="../about.html" />
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="next" title="Development Tools" href="development.html" />
<link rel="prev" title="tkinter.ttk — Tk themed widgets" href="tkinter.ttk.html" />
<link rel="canonical" href="https://docs.python.org/3/library/idle.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
<script type="text/javascript" src="../_static/search-focus.js"></script>
<script type="text/javascript" src="../_static/themetoggle.js"></script>
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
<meta name="readthedocs-addons-api-version" content="1">
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<nav class="nav-content" role="navigation">
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<span class="nav-items-wrapper">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<span class="version_switcher_placeholder"></span>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
<input type="submit" value="Go"/>
</form>
</span>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<div>
<h3><a href="../contents.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">IDLE — Python editor and shell</a><ul>
<li><a class="reference internal" href="#menus">Menus</a><ul>
<li><a class="reference internal" href="#file-menu-shell-and-editor">File menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#edit-menu-shell-and-editor">Edit menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#format-menu-editor-window-only">Format menu (Editor window only)</a></li>
<li><a class="reference internal" href="#run-menu-editor-window-only">Run menu (Editor window only)</a></li>
<li><a class="reference internal" href="#shell-menu-shell-window-only">Shell menu (Shell window only)</a></li>
<li><a class="reference internal" href="#debug-menu-shell-window-only">Debug menu (Shell window only)</a></li>
<li><a class="reference internal" href="#options-menu-shell-and-editor">Options menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#window-menu-shell-and-editor">Window menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#help-menu-shell-and-editor">Help menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#context-menus">Context menus</a></li>
</ul>
</li>
<li><a class="reference internal" href="#editing-and-navigation">Editing and Navigation</a><ul>
<li><a class="reference internal" href="#editor-windows">Editor windows</a></li>
<li><a class="reference internal" href="#key-bindings">Key bindings</a></li>
<li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li>
<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li>
<li><a class="reference internal" href="#completions">Completions</a></li>
<li><a class="reference internal" href="#calltips">Calltips</a></li>
<li><a class="reference internal" href="#code-context">Code Context</a></li>
<li><a class="reference internal" href="#shell-window">Shell window</a></li>
<li><a class="reference internal" href="#text-colors">Text colors</a></li>
</ul>
</li>
<li><a class="reference internal" href="#startup-and-code-execution">Startup and Code Execution</a><ul>
<li><a class="reference internal" href="#command-line-usage">Command line usage</a></li>
<li><a class="reference internal" href="#startup-failure">Startup failure</a></li>
<li><a class="reference internal" href="#running-user-code">Running user code</a></li>
<li><a class="reference internal" href="#user-output-in-shell">User output in Shell</a></li>
<li><a class="reference internal" href="#developing-tkinter-applications">Developing tkinter applications</a></li>
<li><a class="reference internal" href="#running-without-a-subprocess">Running without a subprocess</a></li>
</ul>
</li>
<li><a class="reference internal" href="#help-and-preferences">Help and Preferences</a><ul>
<li><a class="reference internal" href="#help-sources">Help sources</a></li>
<li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li>
<li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li>
<li><a class="reference internal" href="#extensions">Extensions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#module-idlelib">idlelib — implementation of IDLE application</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="tkinter.ttk.html"
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">tkinter.ttk</span></code> — Tk themed widgets</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="development.html"
title="next chapter">Development Tools</a></p>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">Report a Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/main/Doc/library/idle.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="related" role="navigation" aria-label="Related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="development.html" title="Development Tools"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="tkinter.ttk.html" title="tkinter.ttk — Tk themed widgets"
accesskey="P">previous</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.14.0a4 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="tk.html" accesskey="U">Graphical User Interfaces with Tk</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">IDLE — Python editor and shell</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="idle">
<section id="idle">
<span id="idle-python-editor-and-shell"></span><h1>IDLE — Python editor and shell<a class="headerlink" href="#idle" title="Link to this heading"></a></h1>
<p><strong>Source code:</strong> <a class="extlink-source reference external" href="https://github.com/python/cpython/tree/main/Lib/idlelib/">Lib/idlelib/</a></p>
<hr class="docutils" id="index-0" />
<span class="target" id="index-0"></span><hr class="docutils" />
<p>IDLE is Pythons Integrated Development and Learning Environment.</p>
<p>IDLE has the following features:</p>
<ul class="simple">
@ -1027,168 +803,3 @@ sense that feature changes can be backported (see <span class="target" id="index
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<div>
<h3><a href="../contents.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">IDLE — Python editor and shell</a><ul>
<li><a class="reference internal" href="#menus">Menus</a><ul>
<li><a class="reference internal" href="#file-menu-shell-and-editor">File menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#edit-menu-shell-and-editor">Edit menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#format-menu-editor-window-only">Format menu (Editor window only)</a></li>
<li><a class="reference internal" href="#run-menu-editor-window-only">Run menu (Editor window only)</a></li>
<li><a class="reference internal" href="#shell-menu-shell-window-only">Shell menu (Shell window only)</a></li>
<li><a class="reference internal" href="#debug-menu-shell-window-only">Debug menu (Shell window only)</a></li>
<li><a class="reference internal" href="#options-menu-shell-and-editor">Options menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#window-menu-shell-and-editor">Window menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#help-menu-shell-and-editor">Help menu (Shell and Editor)</a></li>
<li><a class="reference internal" href="#context-menus">Context menus</a></li>
</ul>
</li>
<li><a class="reference internal" href="#editing-and-navigation">Editing and Navigation</a><ul>
<li><a class="reference internal" href="#editor-windows">Editor windows</a></li>
<li><a class="reference internal" href="#key-bindings">Key bindings</a></li>
<li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li>
<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li>
<li><a class="reference internal" href="#completions">Completions</a></li>
<li><a class="reference internal" href="#calltips">Calltips</a></li>
<li><a class="reference internal" href="#code-context">Code Context</a></li>
<li><a class="reference internal" href="#shell-window">Shell window</a></li>
<li><a class="reference internal" href="#text-colors">Text colors</a></li>
</ul>
</li>
<li><a class="reference internal" href="#startup-and-code-execution">Startup and Code Execution</a><ul>
<li><a class="reference internal" href="#command-line-usage">Command line usage</a></li>
<li><a class="reference internal" href="#startup-failure">Startup failure</a></li>
<li><a class="reference internal" href="#running-user-code">Running user code</a></li>
<li><a class="reference internal" href="#user-output-in-shell">User output in Shell</a></li>
<li><a class="reference internal" href="#developing-tkinter-applications">Developing tkinter applications</a></li>
<li><a class="reference internal" href="#running-without-a-subprocess">Running without a subprocess</a></li>
</ul>
</li>
<li><a class="reference internal" href="#help-and-preferences">Help and Preferences</a><ul>
<li><a class="reference internal" href="#help-sources">Help sources</a></li>
<li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li>
<li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li>
<li><a class="reference internal" href="#extensions">Extensions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#module-idlelib">idlelib — implementation of IDLE application</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="tkinter.ttk.html"
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">tkinter.ttk</span></code> — Tk themed widgets</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="development.html"
title="next chapter">Development Tools</a></p>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">Report a Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/main/Doc/library/idle.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</div>
<div id="sidebarbutton" title="Collapse sidebar">
<span>«</span>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="development.html" title="Development Tools"
>next</a> |</li>
<li class="right" >
<a href="tkinter.ttk.html" title="tkinter.ttk — Tk themed widgets"
>previous</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.14.0a4 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="tk.html" >Graphical User Interfaces with Tk</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">IDLE — Python editor and shell</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2001 Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
See <a href="/license.html">History and License</a> for more information.<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
Last updated on Feb 07, 2025 (05:56 UTC).
<a href="/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.1.3.
</div>
</body>
</html>

View file

@ -20,7 +20,7 @@ HelpFrame - Contain text, scrollbar, and table-of-contents.
HelpWindow - Display HelpFrame in a standalone window.
copy_strip - Copy idle.html to help.html, rstripping each line.
copy_strip - Copy the text part of idle.html to help.html while rstripping each line.
show_idlehelp - Create HelpWindow. Called in EditorWindow.help_dialog.
"""
@ -54,7 +54,6 @@ class HelpParser(HTMLParser):
self.text = text # Text widget we're rendering into.
self.tags = '' # Current block level text tags to apply.
self.chartags = '' # Current character level text tags.
self.show = False # Exclude html page navigation.
self.hdrlink = False # Exclude html header links.
self.level = 0 # Track indentation level.
self.pre = False # Displaying preformatted text?
@ -77,11 +76,7 @@ class HelpParser(HTMLParser):
if a == 'class':
class_ = v
s = ''
if tag == 'section' and attrs == [('id', 'idle')]:
self.show = True # Start main content.
elif tag == 'div' and class_ == 'clearer':
self.show = False # End main content.
elif tag == 'p' and self.prevtag and not self.prevtag[0]:
if tag == 'p' and self.prevtag and not self.prevtag[0]:
# Begin a new block for <p> tags after a closed tag.
# Avoid extra lines, e.g. after <pre> tags.
lastline = self.text.get('end-1c linestart', 'end-1c')
@ -112,31 +107,27 @@ class HelpParser(HTMLParser):
s = '\n'
elif tag == 'pre':
self.pre = True
if self.show:
self.text.insert('end', '\n\n')
self.text.insert('end', '\n\n')
self.tags = 'preblock'
elif tag == 'a' and class_ == 'headerlink':
self.hdrlink = True
elif tag == 'h1':
self.tags = tag
elif tag in ['h2', 'h3']:
if self.show:
self.header = ''
self.text.insert('end', '\n\n')
self.header = ''
self.text.insert('end', '\n\n')
self.tags = tag
if self.show:
self.text.insert('end', s, (self.tags, self.chartags))
self.text.insert('end', s, (self.tags, self.chartags))
self.prevtag = (True, tag)
def handle_endtag(self, tag):
"Handle endtags in help.html."
if tag in ['h1', 'h2', 'h3']:
assert self.level == 0
if self.show:
indent = (' ' if tag == 'h3' else
' ' if tag == 'h2' else
'')
self.toc.append((indent+self.header, self.text.index('insert')))
indent = (' ' if tag == 'h3' else
' ' if tag == 'h2' else
'')
self.toc.append((indent+self.header, self.text.index('insert')))
self.tags = ''
elif tag in ['span', 'em']:
self.chartags = ''
@ -151,7 +142,7 @@ class HelpParser(HTMLParser):
def handle_data(self, data):
"Handle date segments in help.html."
if self.show and not self.hdrlink:
if not self.hdrlink:
d = data if self.pre else data.replace('\n', ' ')
if self.tags == 'h1':
try:
@ -253,7 +244,7 @@ class HelpWindow(Toplevel):
def copy_strip(): # pragma: no cover
"""Copy idle.html to idlelib/help.html, stripping trailing whitespace.
"""Copy the text part of idle.html to idlelib/help.html while stripping trailing whitespace.
Files with trailing whitespace cannot be pushed to the git cpython
repository. For 3.x (on Windows), help.html is generated, after
@ -265,7 +256,7 @@ def copy_strip(): # pragma: no cover
It can be worthwhile to occasionally generate help.html without
touching idle.rst. Changes to the master version and to the doc
build system may result in changes that should not changed
build system may result in changes that should not change
the displayed text, but might break HelpParser.
As long as master and maintenance versions of idle.rst remain the
@ -278,10 +269,14 @@ def copy_strip(): # pragma: no cover
src = join(abspath(dirname(dirname(dirname(__file__)))),
'Doc', 'build', 'html', 'library', 'idle.html')
dst = join(abspath(dirname(__file__)), 'help.html')
with open(src, 'rb') as inn,\
open(dst, 'wb') as out:
with open(src, 'r', encoding="utf-8") as inn, open(dst, 'w', encoding="utf-8") as out:
copy = False
for line in inn:
out.write(line.rstrip() + b'\n')
if '<section id="idle">' in line: copy = True
if '<div class="clearer">' in line: break
if copy: out.write(line.strip() + '\n')
print(f'{src} copied to {dst}')

View file

@ -0,0 +1,2 @@
Simplify displaying the IDLE doc by only copying the text section of
idle.html to idlelib/help.html. Patch by Stan Ulbrych.