⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 __init__.py

📁 Requirement =====================================================================================
💻 PY
📖 第 1 页 / 共 4 页
字号:
# Author: David Goodger# Contact: goodger@users.sourceforge.net# Revision: $Revision: 4219 $# Date: $Date: 2005-12-15 15:32:01 +0100 (Thu, 15 Dec 2005) $# Copyright: This module has been placed in the public domain."""Simple HyperText Markup Language document tree Writer.The output conforms to the XHTML version 1.0 Transitional DTD(*almost* strict).  The output contains a minimum of formattinginformation.  The cascading style sheet "html4css1.css" is requiredfor proper viewing with a modern graphical browser."""__docformat__ = 'reStructuredText'import sysimport osimport os.pathimport timeimport refrom types import ListTypetry:    import Image                        # check for the Python Imaging Libraryexcept ImportError:    Image = Noneimport docutilsfrom docutils import frontend, nodes, utils, writers, languagesclass Writer(writers.Writer):    supported = ('html', 'html4css1', 'xhtml')    """Formats this writer supports."""    default_stylesheet = 'html4css1.css'    default_stylesheet_path = utils.relative_path(        os.path.join(os.getcwd(), 'dummy'),        os.path.join(os.path.dirname(__file__), default_stylesheet))    settings_spec = (        'HTML-Specific Options',        None,        (('Specify a stylesheet URL, used verbatim.  Overrides '          '--stylesheet-path.',          ['--stylesheet'],          {'metavar': '<URL>', 'overrides': 'stylesheet_path'}),         ('Specify a stylesheet file, relative to the current working '          'directory.  The path is adjusted relative to the output HTML '          'file.  Overrides --stylesheet.  Default: "%s"'          % default_stylesheet_path,          ['--stylesheet-path'],          {'metavar': '<file>', 'overrides': 'stylesheet',           'default': default_stylesheet_path}),         ('Embed the stylesheet in the output HTML file.  The stylesheet '          'file must be accessible during processing (--stylesheet-path is '          'recommended).  This is the default.',          ['--embed-stylesheet'],          {'default': 1, 'action': 'store_true',           'validator': frontend.validate_boolean}),         ('Link to the stylesheet in the output HTML file.  Default: '          'embed the stylesheet, do not link to it.',          ['--link-stylesheet'],          {'dest': 'embed_stylesheet', 'action': 'store_false',           'validator': frontend.validate_boolean}),         ('Specify the initial header level.  Default is 1 for "<h1>".  '          'Does not affect document title & subtitle (see --no-doc-title).',          ['--initial-header-level'],          {'choices': '1 2 3 4 5 6'.split(), 'default': '1',           'metavar': '<level>'}),         ('Specify the maximum width (in characters) for one-column field '          'names.  Longer field names will span an entire row of the table '          'used to render the field list.  Default is 14 characters.  '          'Use 0 for "no limit".',          ['--field-name-limit'],          {'default': 14, 'metavar': '<level>',           'validator': frontend.validate_nonnegative_int}),         ('Specify the maximum width (in characters) for options in option '          'lists.  Longer options will span an entire row of the table used '          'to render the option list.  Default is 14 characters.  '          'Use 0 for "no limit".',          ['--option-limit'],          {'default': 14, 'metavar': '<level>',           'validator': frontend.validate_nonnegative_int}),         ('Format for footnote references: one of "superscript" or '          '"brackets".  Default is "brackets".',          ['--footnote-references'],          {'choices': ['superscript', 'brackets'], 'default': 'brackets',           'metavar': '<format>',           'overrides': 'trim_footnote_reference_space'}),         ('Format for block quote attributions: one of "dash" (em-dash '          'prefix), "parentheses"/"parens", or "none".  Default is "dash".',          ['--attribution'],          {'choices': ['dash', 'parentheses', 'parens', 'none'],           'default': 'dash', 'metavar': '<format>'}),         ('Remove extra vertical whitespace between items of "simple" bullet '          'lists and enumerated lists.  Default: enabled.',          ['--compact-lists'],          {'default': 1, 'action': 'store_true',           'validator': frontend.validate_boolean}),         ('Disable compact simple bullet and enumerated lists.',          ['--no-compact-lists'],          {'dest': 'compact_lists', 'action': 'store_false'}),         ('Remove extra vertical whitespace between items of simple field '          'lists.  Default: enabled.',          ['--compact-field-lists'],          {'default': 1, 'action': 'store_true',           'validator': frontend.validate_boolean}),         ('Disable compact simple field lists.',          ['--no-compact-field-lists'],          {'dest': 'compact_field_lists', 'action': 'store_false'}),         ('Omit the XML declaration.  Use with caution.',          ['--no-xml-declaration'],          {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false',           'validator': frontend.validate_boolean}),         ('Obfuscate email addresses to confuse harvesters while still '          'keeping email links usable with standards-compliant browsers.',          ['--cloak-email-addresses'],          {'action': 'store_true', 'validator': frontend.validate_boolean}),))    settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'}    relative_path_settings = ('stylesheet_path',)    config_section = 'html4css1 writer'    config_section_dependencies = ('writers',)    def __init__(self):        writers.Writer.__init__(self)        self.translator_class = HTMLTranslator    def translate(self):        self.visitor = visitor = self.translator_class(self.document)        self.document.walkabout(visitor)        self.output = visitor.astext()        for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix',                     'body_pre_docinfo', 'docinfo', 'body', 'fragment',                     'body_suffix'):            setattr(self, attr, getattr(visitor, attr))    def assemble_parts(self):        writers.Writer.assemble_parts(self)        for part in ('title', 'subtitle', 'docinfo', 'body', 'header',                     'footer', 'meta', 'stylesheet', 'fragment',                     'html_prolog', 'html_head', 'html_title', 'html_subtitle',                     'html_body'):            self.parts[part] = ''.join(getattr(self.visitor, part))class HTMLTranslator(nodes.NodeVisitor):    """    This HTML writer has been optimized to produce visually compact    lists (less vertical whitespace).  HTML's mixed content models    allow list items to contain "<li><p>body elements</p></li>" or    "<li>just text</li>" or even "<li>text<p>and body    elements</p>combined</li>", each with different effects.  It would    be best to stick with strict body elements in list items, but they    affect vertical spacing in browsers (although they really    shouldn't).    Here is an outline of the optimization:    - Check for and omit <p> tags in "simple" lists: list items      contain either a single paragraph, a nested simple list, or a      paragraph followed by a nested simple list.  This means that      this list can be compact:          - Item 1.          - Item 2.      But this list cannot be compact:          - Item 1.            This second paragraph forces space between list items.          - Item 2.    - In non-list contexts, omit <p> tags on a paragraph if that      paragraph is the only child of its parent (footnotes & citations      are allowed a label first).    - Regardless of the above, in definitions, table cells, field bodies,      option descriptions, and list items, mark the first child with      'class="first"' and the last child with 'class="last"'.  The stylesheet      sets the margins (top & bottom respectively) to 0 for these elements.    The ``no_compact_lists`` setting (``--no-compact-lists`` command-line    option) disables list whitespace optimization.    """    xml_declaration = '<?xml version="1.0" encoding="%s" ?>\n'    doctype = ('<!DOCTYPE html'               ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'               ' "http://www.w3.org/TR/xhtml1/DTD/'               'xhtml1-transitional.dtd">\n')    head_prefix_template = ('<html xmlns="http://www.w3.org/1999/xhtml"'                            ' xml:lang="%s" lang="%s">\n<head>\n')    content_type = ('<meta http-equiv="Content-Type"'                    ' content="text/html; charset=%s" />\n')    generator = ('<meta name="generator" content="Docutils %s: '                 'http://docutils.sourceforge.net/" />\n')    stylesheet_link = '<link rel="stylesheet" href="%s" type="text/css" />\n'    embedded_stylesheet = '<style type="text/css">\n\n%s\n</style>\n'    named_tags = ['a', 'applet', 'form', 'frame', 'iframe', 'img', 'map']    words_and_spaces = re.compile(r'\S+| +|\n')    def __init__(self, document):        nodes.NodeVisitor.__init__(self, document)        self.settings = settings = document.settings        lcode = settings.language_code        self.language = languages.get_language(lcode)        self.meta = [self.content_type % settings.output_encoding,                     self.generator % docutils.__version__]        self.head_prefix = []        self.html_prolog = []        if settings.xml_declaration:            self.head_prefix.append(self.xml_declaration                                    % settings.output_encoding)            # encoding not interpolated:            self.html_prolog.append(self.xml_declaration)        self.head_prefix.extend([self.doctype,                                 self.head_prefix_template % (lcode, lcode)])        self.html_prolog.append(self.doctype)        self.head = self.meta[:]        stylesheet = utils.get_stylesheet_reference(settings)        self.stylesheet = []        if stylesheet:            if settings.embed_stylesheet:                stylesheet = utils.get_stylesheet_reference(                    settings, os.path.join(os.getcwd(), 'dummy'))                settings.record_dependencies.add(stylesheet)                stylesheet_text = open(stylesheet).read()                self.stylesheet = [self.embedded_stylesheet % stylesheet_text]            else:                self.stylesheet = [self.stylesheet_link                                   % self.encode(stylesheet)]        self.body_prefix = ['</head>\n<body>\n']        # document title, subtitle display        self.body_pre_docinfo = []        # author, date, etc.        self.docinfo = []        self.body = []        self.fragment = []        self.body_suffix = ['</body>\n</html>\n']        self.section_level = 0        self.initial_header_level = int(settings.initial_header_level)        # A heterogenous stack used in conjunction with the tree traversal.        # Make sure that the pops correspond to the pushes:        self.context = []        self.topic_classes = []        self.colspecs = []        self.compact_p = 1        self.compact_simple = None        self.compact_field_list = None        self.in_docinfo = None        self.in_sidebar = None        self.title = []        self.subtitle = []        self.header = []        self.footer = []        self.html_head = [self.content_type] # charset not interpolated        self.html_title = []        self.html_subtitle = []        self.html_body = []        self.in_document_title = 0        self.in_mailto = 0        self.author_in_authors = None    def astext(self):        return ''.join(self.head_prefix + self.head                       + self.stylesheet + self.body_prefix                       + self.body_pre_docinfo + self.docinfo                       + self.body + self.body_suffix)    def encode(self, text):        """Encode special characters in `text` & return."""        # @@@ A codec to do these and all other HTML entities would be nice.        text = text.replace("&", "&amp;")        text = text.replace("<", "&lt;")        text = text.replace('"', "&quot;")        text = text.replace(">", "&gt;")        text = text.replace("@", "&#64;") # may thwart some address harvesters        # Replace the non-breaking space character with the HTML entity:        text = text.replace(u'\u00a0', "&nbsp;")        return text    def cloak_mailto(self, uri):        """Try to hide a mailto: URL from harvesters."""        # Encode "@" using a URL octet reference (see RFC 1738).        # Further cloaking with HTML entities will be done in the        # `attval` function.        return uri.replace('@', '%40')    def cloak_email(self, addr):        """Try to hide the link text of a email link from harversters."""        # Surround at-signs and periods with <span> tags.  ("@" has        # already been encoded to "&#64;" by the `encode` method.)        addr = addr.replace('&#64;', '<span>&#64;</span>')        addr = addr.replace('.', '<span>&#46;</span>')        return addr    def attval(self, text,               whitespace=re.compile('[\n\r\t\v\f]')):        """Cleanse, HTML encode, and return attribute value text."""        encoded = self.encode(whitespace.sub(' ', text))        if self.in_mailto and self.settings.cloak_email_addresses:            # Cloak at-signs ("%40") and periods with HTML entities.            encoded = encoded.replace('%40', '&#37;&#52;&#48;')            encoded = encoded.replace('.', '&#46;')        return encoded    def starttag(self, node, tagname, suffix='\n', empty=0, **attributes):        """        Construct and return a start tag given a node (id & class attributes        are extracted), tag name, and optional attributes.        """        tagname = tagname.lower()        prefix = []        atts = {}        ids = []        for (name, value) in attributes.items():            atts[name.lower()] = value        classes = node.get('classes', [])        if atts.has_key('class'):            classes.append(atts['class'])        if classes:            atts['class'] = ' '.join(classes)        assert not atts.has_key('id')        ids.extend(node.get('ids', []))        if atts.has_key('ids'):            ids.extend(atts['ids'])            del atts['ids']        if ids:            atts['id'] = ids[0]            for id in ids[1:]:                # Add empty "span" elements for additional IDs.  Note                # that we cannot use empty "a" elements because there                # may be targets inside of references, but nested "a"                # elements aren't allowed in XHTML (even if they do                # not all have a "href" attribute).                if empty:                    # Empty tag.  Insert target right in front of element.                    prefix.append('<span id="%s"></span>' % id)                else:                    # Non-empty tag.  Place the auxiliary <span> tag                    # *inside* the element, as the first child.                    suffix += '<span id="%s"></span>' % id        # !!! next 2 lines to be removed in Docutils 0.5:        if atts.has_key('id') and tagname in self.named_tags:            atts['name'] = atts['id']   # for compatibility with old browsers        attlist = atts.items()        attlist.sort()        parts = [tagname]        for name, value in attlist:            # value=None was used for boolean attributes without            # value, but this isn't supported by XHTML.            assert value is not None            if isinstance(value, ListType):                values = [unicode(v) for v in value]                parts.append('%s="%s"' % (name.lower(),                                          self.attval(' '.join(values))))            else:                try:                    uval = unicode(value)                except TypeError:       # for Python 2.1 compatibility:                    uval = unicode(str(value))                parts.append('%s="%s"' % (name.lower(), self.attval(uval)))        if empty:            infix = ' /'        else:            infix = ''        return ''.join(prefix) + '<%s%s>' % (' '.join(parts), infix) + suffix    def emptytag(self, node, tagname, suffix='\n', **attributes):        """Construct and return an XML-compatible empty tag."""        return self.starttag(node, tagname, suffix, empty=1, **attributes)    # !!! to be removed in Docutils 0.5 (change calls to use "starttag"):    def start_tag_with_title(self, node, tagname, **atts):        """ID and NAME attributes will be handled in the title."""        node = {'classes': node.get('classes', [])}        return self.starttag(node, tagname, **atts)    def set_class_on_child(self, node, class_, index=0):        """        Set class `class_` on the visible child no. index of `node`.        Do nothing if node has fewer children than `index`.        """        children = [n for n in node if not isinstance(n, nodes.Invisible)]        try:            child = children[index]        except IndexError:            return        child['classes'].append(class_)    def set_first_last(self, node):

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -