diff options
Diffstat (limited to 'Lib/idlelib/help.py')
-rw-r--r-- | Lib/idlelib/help.py | 157 |
1 files changed, 71 insertions, 86 deletions
diff --git a/Lib/idlelib/help.py b/Lib/idlelib/help.py index 9f63ea0..3ab4851 100644 --- a/Lib/idlelib/help.py +++ b/Lib/idlelib/help.py @@ -2,9 +2,9 @@ Contents are subject to revision at any time, without notice. -Help => About IDLE: display About Idle dialog +Help => About IDLE: diplay About Idle dialog -<to be moved here from help_about.py> +<to be moved here from aboutDialog.py> Help => IDLE Help: Display help.html with proper formatting. @@ -24,15 +24,16 @@ copy_strip - Copy idle.html to help.html, rstripping each line. show_idlehelp - Create HelpWindow. Called in EditorWindow.help_dialog. """ -from html.parser import HTMLParser -from os.path import abspath, dirname, isfile, join +from HTMLParser import HTMLParser +from os.path import abspath, dirname, isdir, isfile, join from platform import python_version +from Tkinter import Tk, Toplevel, Frame, Text, Scrollbar, Menu, Menubutton +import tkFont as tkfont +from idlelib.configHandler import idleConf -from tkinter import Toplevel, Frame, Text, Menu -from tkinter.ttk import Menubutton, Scrollbar -from tkinter import font as tkfont - -from idlelib.config import idleConf +use_ttk = False # until available to import +if use_ttk: + from tkinter.ttk import Menubutton ## About IDLE ## @@ -49,23 +50,21 @@ class HelpParser(HTMLParser): the handle_starttag and handle_endtags methods, might have to also. """ def __init__(self, text): - HTMLParser.__init__(self, convert_charrefs=True) - 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? - self.hprefix = '' # Heading prefix (like '25.5'?) to remove. - self.nested_dl = False # In a nested <dl>? - self.simplelist = False # In a simple list (no double spacing)? - self.toc = [] # Pair headers with text indexes for toc. - self.header = '' # Text within header tags for toc. - self.prevtag = None # Previous tag info (opener?, tag). + HTMLParser.__init__(self) + 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 # used so we exclude page navigation + self.hdrlink = False # used so we don't show header links + self.level = 0 # indentation level + self.pre = False # displaying preformatted text + self.hprefix = '' # prefix such as '25.5' to strip from headings + self.nested_dl = False # if we're in a nested <dl> + self.simplelist = False # simple list (no double spacing) + self.toc = [] # pair headers with text indexes for toc + self.header = '' # text within header tags for toc def indent(self, amt=1): - "Change indent (+1, 0, -1) and tags." self.level += amt self.tags = '' if self.level == 0 else 'l'+str(self.level) @@ -77,14 +76,11 @@ class HelpParser(HTMLParser): class_ = v s = '' if tag == 'div' and class_ == 'section': - self.show = True # Start main content. + self.show = True # start of main content elif tag == 'div' and class_ == 'sphinxsidebar': - self.show = False # End main content. - elif 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') - s = '\n\n' if lastline and not lastline.isspace() else '\n' + self.show = False # end of main content + elif tag == 'p' and class_ != 'first': + s = '\n\n' elif tag == 'span' and class_ == 'pre': self.chartags = 'pre' elif tag == 'span' and class_ == 'versionmodified': @@ -104,7 +100,7 @@ class HelpParser(HTMLParser): elif tag == 'li': s = '\n* ' if self.simplelist else '\n\n* ' elif tag == 'dt': - s = '\n\n' if not self.nested_dl else '\n' # Avoid extra line. + s = '\n\n' if not self.nested_dl else '\n' # avoid extra line self.nested_dl = False elif tag == 'dd': self.indent() @@ -125,18 +121,13 @@ class HelpParser(HTMLParser): self.tags = tag if self.show: 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 + self.indent(0) # clear tag, reset indent if self.show: - indent = (' ' if tag == 'h3' else - ' ' if tag == 'h2' else - '') - self.toc.append((indent+self.header, self.text.index('insert'))) - self.tags = '' + self.toc.append((self.header, self.text.index('insert'))) elif tag in ['span', 'em']: self.chartags = '' elif tag == 'a': @@ -145,25 +136,24 @@ class HelpParser(HTMLParser): self.pre = False self.tags = '' elif tag in ['ul', 'dd', 'ol']: - self.indent(-1) - self.prevtag = (False, tag) + self.indent(amt=-1) def handle_data(self, data): "Handle date segments in help.html." if self.show and not self.hdrlink: d = data if self.pre else data.replace('\n', ' ') if self.tags == 'h1': - try: - self.hprefix = d[0:d.index(' ')] - except ValueError: - self.hprefix = '' - if self.tags in ['h1', 'h2', 'h3']: - if (self.hprefix != '' and - d[0:len(self.hprefix)] == self.hprefix): - d = d[len(self.hprefix):] - self.header += d.strip() + self.hprefix = d[0:d.index(' ')] + if self.tags in ['h1', 'h2', 'h3'] and self.hprefix != '': + if d[0:len(self.hprefix)] == self.hprefix: + d = d[len(self.hprefix):].strip() + self.header += d self.text.insert('end', d, (self.tags, self.chartags)) + def handle_charref(self, name): + if self.show: + self.text.insert('end', unichr(int(name))) + class HelpText(Text): "Display help.html." @@ -171,7 +161,7 @@ class HelpText(Text): "Configure tags and feed file to parser." uwide = idleConf.GetOption('main', 'EditorWindow', 'width', type='int') uhigh = idleConf.GetOption('main', 'EditorWindow', 'height', type='int') - uhigh = 3 * uhigh // 4 # Lines average 4/3 of editor line height. + uhigh = 3 * uhigh // 4 # lines average 4/3 of editor line height Text.__init__(self, parent, wrap='word', highlightthickness=0, padx=5, borderwidth=0, width=uwide, height=uhigh) @@ -191,8 +181,8 @@ class HelpText(Text): self.tag_configure('l4', lmargin1=100, lmargin2=100) self.parser = HelpParser(self) - with open(filename, encoding='utf-8') as f: - contents = f.read() + with open(filename) as f: + contents = f.read().decode(encoding='utf-8') self.parser.feed(contents) self['state'] = 'disabled' @@ -211,17 +201,15 @@ class HelpFrame(Frame): "Display html text, scrollbar, and toc." def __init__(self, parent, filename): Frame.__init__(self, parent) - self.text = text = HelpText(self, filename) + text = HelpText(self, filename) self['background'] = text['background'] - self.toc = toc = self.toc_menu(text) - self.scroll = scroll = Scrollbar(self, command=text.yview) + scroll = Scrollbar(self, command=text.yview) text['yscrollcommand'] = scroll.set - self.rowconfigure(0, weight=1) - self.columnconfigure(1, weight=1) # Only expand the text widget. - toc.grid(row=0, column=0, sticky='nw') - text.grid(row=0, column=1, sticky='nsew') - scroll.grid(row=0, column=2, sticky='ns') + self.columnconfigure(1, weight=1) # text + self.toc_menu(text).grid(column=0, row=0, sticky='nw') + text.grid(column=1, row=0, sticky='nsew') + scroll.grid(column=2, row=0, sticky='ns') def toc_menu(self, text): "Create table of contents as drop-down menu." @@ -247,46 +235,43 @@ class HelpWindow(Toplevel): def copy_strip(): """Copy idle.html to idlelib/help.html, stripping trailing whitespace. - Files with trailing whitespace cannot be pushed to the git cpython + Files with trailing whitespace cannot be pushed to the hg cpython repository. For 3.x (on Windows), help.html is generated, after - editing idle.rst on the master branch, with + editing idle.rst in the earliest maintenance version, with sphinx-build -bhtml . build/html python_d.exe -c "from idlelib.help import copy_strip; copy_strip()" - Check build/html/library/idle.html, the help.html diff, and the text - displayed by Help => IDLE Help. Add a blurb and create a PR. - - 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 - the displayed text, but might break HelpParser. - - As long as master and maintenance versions of idle.rst remain the - same, help.html can be backported. The internal Python version - number is not displayed. If maintenance idle.rst diverges from - the master version, then instead of backporting help.html from - master, repeat the procedure above to generate a maintenance - version. + After refreshing TortoiseHG workshop to generate a diff, + check both the diff and displayed text. Push the diff along with + the idle.rst change and merge both into default (or an intermediate + maintenance version). + + When the 'earlist' version gets its final maintenance release, + do an update as described above, without editing idle.rst, to + rebase help.html on the next version of idle.rst. Do not worry + about version changes as version is not displayed. Examine other + changes and the result of Help -> IDLE Help. + + If maintenance and default versions of idle.rst diverge, and + merging does not go smoothly, then consider generating + separate help.html files from separate idle.htmls. """ src = join(abspath(dirname(dirname(dirname(__file__)))), - 'Doc', 'build', 'html', 'library', 'idle.html') + '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') as inn,\ + open(dst, 'w') as out: for line in inn: - out.write(line.rstrip() + b'\n') - print(f'{src} copied to {dst}') + out.write(line.rstrip() + '\n') + print('idle.html copied to help.html') def show_idlehelp(parent): "Create HelpWindow; called from Idle Help event handler." filename = join(abspath(dirname(__file__)), 'help.html') if not isfile(filename): - # Try copy_strip, present message. + # try copy_strip, present message return HelpWindow(parent, filename, 'IDLE Help (%s)' % python_version()) if __name__ == '__main__': - from unittest import main - main('idlelib.idle_test.test_help', verbosity=2, exit=False) - from idlelib.idle_test.htest import run run(show_idlehelp) |