""" help.py: Implement the Idle help menu.Contents are subject to revision at any time, without notice.Help => About IDLE: display About Idle dialog<to be moved here from help_about.py>Help => IDLE Help: Display help.html with proper formatting.Doc/library/idle.rst (Sphinx)=> Doc/build/html/library/idle.html(help.copy_strip)=> Lib/idlelib/help.htmlHelpParser - Parse help.html and render to tk Text.HelpText - Display formatted help.html.HelpFrame - Contain text, scrollbar, and table-of-contents.(This will be needed for display in a future tabbed window.)HelpWindow - Display HelpFrame in a standalone window.copy_strip - Copy idle.html to help.html, rstripping each line.show_idlehelp - Create HelpWindow. Called in EditorWindow.help_dialog."""from html.parser import HTMLParserfrom os.path import abspath, dirname, isfile, joinfrom platform import python_versionfrom tkinter import Toplevel, Frame, Text, Menufrom tkinter.ttk import Menubutton, Scrollbarfrom tkinter import font as tkfontfrom idlelib.config import idleConf## About IDLE #### IDLE Help ##class HelpParser(HTMLParser):"""Render help.html into a text widget.The overridden handle_xyz methods handle a subset of html tags.The supplied text should have the needed tag configurations.The behavior for unsupported tags, such as table, is undefined.If the tags generated by Sphinx change, this class, especiallythe 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 intoself.tags = '' # current block level text tags to applyself.chartags = '' # current character level text tagsself.show = False # used so we exclude page navigationself.hdrlink = False # used so we don't show header linksself.level = 0 # indentation levelself.pre = False # displaying preformatted textself.hprefix = '' # prefix such as '25.5' to strip from headingsself.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 tocself.header = '' # text within header tags for tocdef indent(self, amt=1):self.level += amtself.tags = '' if self.level == 0 else 'l'+str(self.level)def handle_starttag(self, tag, attrs):"Handle starttags in help.html."class_ = ''for a, v in attrs:if a == 'class':class_ = vs = ''if tag == 'div' and class_ == 'section':self.show = True # start of main contentelif tag == 'div' and class_ == 'sphinxsidebar':self.show = False # end of main contentelif tag == 'p' and class_ != 'first':s = '\n\n'elif tag == 'span' and class_ == 'pre':self.chartags = 'pre'elif tag == 'span' and class_ == 'versionmodified':self.chartags = 'em'elif tag == 'em':self.chartags = 'em'elif tag in ['ul', 'ol']:if class_.find('simple') != -1:s = '\n'self.simplelist = Trueelse:self.simplelist = Falseself.indent()elif tag == 'dl':if self.level > 0:self.nested_dl = Trueelif 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 lineself.nested_dl = Falseelif tag == 'dd':self.indent()s = '\n'elif tag == 'pre':self.pre = Trueif self.show:self.text.insert('end', '\n\n')self.tags = 'preblock'elif tag == 'a' and class_ == 'headerlink':self.hdrlink = Trueelif tag == 'h1':self.tags = tagelif tag in ['h2', 'h3']:if self.show:self.header = ''self.text.insert('end', '\n\n')self.tags = tagif self.show:self.text.insert('end', s, (self.tags, self.chartags))def handle_endtag(self, tag):"Handle endtags in help.html."if tag in ['h1', 'h2', 'h3']:self.indent(0) # clear tag, reset indentif self.show:indent = (' ' if tag == 'h3' else' ' if tag == 'h2' else'')self.toc.append((indent+self.header, self.text.index('insert')))elif tag in ['span', 'em']:self.chartags = ''elif tag == 'a':self.hdrlink = Falseelif tag == 'pre':self.pre = Falseself.tags = ''elif tag in ['ul', 'dd', 'ol']: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 != '' andd[0:len(self.hprefix)] == self.hprefix):d = d[len(self.hprefix):]self.header += d.strip()self.text.insert('end', d, (self.tags, self.chartags))class HelpText(Text):"Display help.html."def __init__(self, parent, filename):"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 heightText.__init__(self, parent, wrap='word', highlightthickness=0,padx=5, borderwidth=0, width=uwide, height=uhigh)normalfont = self.findfont(['TkDefaultFont', 'arial', 'helvetica'])fixedfont = self.findfont(['TkFixedFont', 'monaco', 'courier'])self['font'] = (normalfont, 12)self.tag_configure('em', font=(normalfont, 12, 'italic'))self.tag_configure('h1', font=(normalfont, 20, 'bold'))self.tag_configure('h2', font=(normalfont, 18, 'bold'))self.tag_configure('h3', font=(normalfont, 15, 'bold'))self.tag_configure('pre', font=(fixedfont, 12), background='#f6f6ff')self.tag_configure('preblock', font=(fixedfont, 10), lmargin1=25,borderwidth=1, relief='solid', background='#eeffcc')self.tag_configure('l1', lmargin1=25, lmargin2=25)self.tag_configure('l2', lmargin1=50, lmargin2=50)self.tag_configure('l3', lmargin1=75, lmargin2=75)self.tag_configure('l4', lmargin1=100, lmargin2=100)self.parser = HelpParser(self)with open(filename, encoding='utf-8') as f:contents = f.read()self.parser.feed(contents)self['state'] = 'disabled'def findfont(self, names):"Return name of first font family derived from names."for name in names:if name.lower() in (x.lower() for x in tkfont.names(root=self)):font = tkfont.Font(name=name, exists=True, root=self)return font.actual()['family']elif name.lower() in (x.lower()for x in tkfont.families(root=self)):return nameclass HelpFrame(Frame):"Display html text, scrollbar, and toc."def __init__(self, parent, filename):Frame.__init__(self, parent)# keep references to widgets for test access.self.text = text = HelpText(self, filename)self['background'] = text['background']self.toc = toc = self.toc_menu(text)self.scroll = scroll = Scrollbar(self, command=text.yview)text['yscrollcommand'] = scroll.setself.rowconfigure(0, weight=1)self.columnconfigure(1, weight=1) # texttoc.grid(row=0, column=0, sticky='nw')text.grid(row=0, column=1, sticky='nsew')scroll.grid(row=0, column=2, sticky='ns')def toc_menu(self, text):"Create table of contents as drop-down menu."toc = Menubutton(self, text='TOC')drop = Menu(toc, tearoff=False)for lbl, dex in text.parser.toc:drop.add_command(label=lbl, command=lambda dex=dex:text.yview(dex))toc['menu'] = dropreturn tocclass HelpWindow(Toplevel):"Display frame with rendered html."def __init__(self, parent, filename, title):Toplevel.__init__(self, parent)self.wm_title(title)self.protocol("WM_DELETE_WINDOW", self.destroy)HelpFrame(self, filename).grid(column=0, row=0, sticky='nsew')self.grid_columnconfigure(0, weight=1)self.grid_rowconfigure(0, weight=1)def copy_strip():"""Copy idle.html to idlelib/help.html, stripping trailing whitespace.Files with trailing whitespace cannot be pushed to the git cpythonrepository. For 3.x (on Windows), help.html is generated, afterediting idle.rst on the master branch, withsphinx-build -bhtml . build/htmlpython_d.exe -c "from idlelib.help import copy_strip; copy_strip()"Check build/html/library/idle.html, the help.html diff, and the textdisplayed by Help => IDLE Help. Add a blurb and create a PR.It can be worthwhile to occasionally generate help.html withouttouching idle.rst. Changes to the master version and to the docbuild system may result in changes that should not changedthe displayed text, but might break HelpParser.As long as master and maintenance versions of idle.rst remain thesame, help.html can be backported. The internal Python versionnumber is not displayed. If maintenance idle.rst diverges fromthe master version, then instead of backporting help.html frommaster, repeat the proceedure above to generate a maintenanceversion."""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:for line in inn:out.write(line.rstrip() + b'\n')print(f'{src} copied to {dst}')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 messagereturnHelpWindow(parent, filename, 'IDLE Help (%s)' % python_version())if __name__ == '__main__':from unittest import mainmain('idlelib.idle_test.test_help', verbosity=2, exit=False)from idlelib.idle_test.htest import runrun(show_idlehelp)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。