示例#1
0
 def apply(self):
     doc = self.document
     i = len(doc) - 1
     refsect = copyright = None
     while i >= 0 and isinstance(doc[i], nodes.section):
         title_words = doc[i][0].astext().lower().split()
         if 'references' in title_words:
             refsect = doc[i]
             break
         elif 'copyright' in title_words:
             copyright = i
         i -= 1
     if not refsect:
         refsect = nodes.section()
         refsect += nodes.title('', 'References')
         doc.set_id(refsect)
         if copyright:
             # Put the new "References" section before "Copyright":
             doc.insert(copyright, refsect)
         else:
             # Put the new "References" section at end of doc:
             doc.append(refsect)
     pending = nodes.pending(references.TargetNotes)
     refsect.append(pending)
     self.document.note_pending(pending, 0)
     pending = nodes.pending(misc.CallBack,
                             details={'callback': self.cleanup_callback})
     refsect.append(pending)
     self.document.note_pending(pending, 1)
示例#2
0
    def run (self, transform, extraclasses = None):
        """
        extra_classes: classes set on container element
        """

        document = self.state_machine.document
        extraclasses = extraclasses or []
        
        self.options['directive_name'] = self.name
        extraclasses.append (self.name) # contents, loa, lof, lot, footnotes

        container = nodes.container ()
        container['classes'] += self.options.get ('class', [])
        if 'depth' in self.options:
            container['toc_depth'] = self.options['depth']

        pending = nodes.pending (transform, self.options)
        document.note_pending (pending)
        container += pending

        pending = nodes.pending (parts.EmptySectionRemover)
        document.note_pending (pending)

        entries = []

        if 'local' in self.options:
            container['classes'] += ['local']
            container['classes'] += map (lambda x: 'local-' + x, extraclasses)
            entries = [container]
        elif self.arguments:
            container['classes'] += extraclasses

            section = nodes.section ()
            title_text = self.arguments[0]
            text_nodes, dummy_messages = self.state.inline_text (title_text,
                                                          self.lineno)
            title = nodes.title (title_text, '', *text_nodes)
            title['toc_entry'] = None # default for generated sections is: no toc entry
            section += title
            section += pending
            section += container
            document.note_implicit_target (section)
            entries = [section]
        else:
            container['classes'] += extraclasses
            entries = [pending, container]

        return entries
示例#3
0
 def run(self):
     # TODO: error checking
     meta_name, meta_value = self.arguments
     # create new pending node, which will:
     #  - hold metadata
     #  - reference transform class which is concerned with this node
     pending = nodes.pending(self.transform_class)
     # add content into pending node
     pending.details['meta_name'] = meta_name
     pending.details['meta_value'] = meta_value
     # check if there is already some metadata pending node in the
     # document tree
     # TODO: this is not very smart/effective, fix it later
     meta_pending_registered = False
     for node in self.state_machine.document.traverse(nodes.pending):
         if 'meta_name' in node.details:
             meta_pending_registered = True
             break
     # since transformation will process all pending nodes
     # at once, we register only 1st test metadata pending node, and
     # this also means that the result generated by pylatest transform
     # will be located in the place of this first test step directive
     if not meta_pending_registered:
         # without this, transformer wouldn't know about this pending node
         self.state_machine.document.note_pending(pending)
     # and finally return the pending node as the only result
     return [pending]
 def run(self):
     aafig_options = dict()
     image_attrs = dict()
     own_options_keys = self.own_option_spec.keys() + ['scale']
     for (k, v) in self.options.items():
         if k in own_options_keys:
             # convert flags to booleans
             if v is None:
                 v = True
             # convert percentage to float
             if k == 'scale':
                 v = float(v) / 100
             aafig_options[k] = v
             del self.options[k]
     self.arguments = ['']
     (image_node,) = directives.images.Image.run(self)
     if isinstance(image_node, nodes.system_message):
         return [image_node]
     text = '\n'.join(self.content)
     pending_node = nodes.pending(AafigTransform, rawsource=text)
     pending_node.details.update(dict(
         image_node = image_node,
         aafigure_options = aafig_options,
     ))
     self.state_machine.document.note_pending(pending_node)
     return [pending_node]
示例#5
0
 def run (self):
     self.options['char'] = self.arguments[0]
     if len (self.arguments) >= 2:
         self.options['span'] = self.arguments[1]
     pending = nodes.pending (parts.DropCapTransform, self.options) 
     self.state_machine.document.note_pending (pending)
     return [pending]
示例#6
0
def class_directive(name, arguments, options, content, lineno,
                       content_offset, block_text, state, state_machine):
    """
    Set a "class" attribute on the directive content or the next element.
    When applied to the next element, a "pending" element is inserted, and a
    transform does the work later.
    """
    try:
        class_value = directives.class_option(arguments[0])
    except ValueError:
        error = state_machine.reporter.error(
            'Invalid class attribute value for "%s" directive: "%s".'
            % (name, arguments[0]),
            nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
    node_list = []
    if content:
        container = nodes.Element()
        state.nested_parse(content, content_offset, container)
        for node in container:
            node['classes'].extend(class_value)
        node_list.extend(container.children)
    else:
        pending = nodes.pending(misc.ClassAttribute,
                                {'class': class_value, 'directive': name},
                                block_text)
        state_machine.document.note_pending(pending)
        node_list.append(pending)
    return node_list
示例#7
0
 def run(self):
     if not (self.state_machine.match_titles or isinstance(self.state_machine.node, nodes.sidebar)):
         raise self.error('The "%s" directive may not be used within ' "topics or body elements." % self.name)
     document = self.state_machine.document
     language = languages.get_language(document.settings.language_code)
     if self.arguments:
         title_text = self.arguments[0]
         text_nodes, messages = self.state.inline_text(title_text, self.lineno)
         title = nodes.title(title_text, "", *text_nodes)
     else:
         messages = []
         if self.options.has_key("local"):
             title = None
         else:
             title = nodes.title("", language.labels["contents"])
     topic = nodes.topic(classes=["contents"])
     topic["classes"] += self.options.get("class", [])
     if self.options.has_key("local"):
         topic["classes"].append("local")
     if title:
         name = title.astext()
         topic += title
     else:
         name = language.labels["contents"]
     name = nodes.fully_normalize_name(name)
     if not document.has_name(name):
         topic["names"].append(name)
     document.note_implicit_target(topic)
     pending = nodes.pending(parts.Contents, rawsource=self.block_text)
     pending.details.update(self.options)
     document.note_pending(pending)
     topic += pending
     return [topic] + messages
示例#8
0
文件: references.py 项目: garinh/cs
def target_notes(name, arguments, options, content, lineno,
                 content_offset, block_text, state, state_machine):
    """Target footnote generation."""
    pending = nodes.pending(references.TargetNotes)
    state_machine.document.note_pending(pending)
    nodelist = [pending]
    return nodelist
示例#9
0
 def parsemeta(self, match):
     name = self.parse_field_marker(match)
     indented, indent, line_offset, blank_finish = \
           self.state_machine.get_first_known_indented(match.end())
     node = self.meta()
     pending = nodes.pending(components.Filter,
                             {'component': 'writer',
                              'format': 'html',
                              'nodes': [node]})
     node['content'] = ' '.join(indented)
     if not indented:
         line = self.state_machine.line
         msg = self.reporter.info(
               'No content for meta tag "%s".' % name,
               nodes.literal_block(line, line),
               line=self.state_machine.abs_line_number())
         return msg, blank_finish
     tokens = name.split()
     try:
         attname, val = utils.extract_name_value(tokens[0])[0]
         node[attname.lower()] = val
     except utils.NameValueError:
         node['name'] = tokens[0]
     for token in tokens[1:]:
         try:
             attname, val = utils.extract_name_value(token)[0]
             node[attname.lower()] = val
         except utils.NameValueError, detail:
             line = self.state_machine.line
             msg = self.reporter.error(
                   'Error parsing meta tag attribute "%s": %s.'
                   % (token, detail), nodes.literal_block(line, line),
                   line=self.state_machine.abs_line_number())
             return msg, blank_finish
示例#10
0
文件: parts.py 项目: crystalspace/CS
def sectnum(name, arguments, options, content, lineno,
            content_offset, block_text, state, state_machine):
    """Automatic section numbering."""
    pending = nodes.pending(parts.SectNum)
    pending.details.update(options)
    state_machine.document.note_pending(pending)
    return [pending]
示例#11
0
    def run(self):

        node_list = []
        if not self.content:
            pending = nodes.pending(RemoveNext, {"directive": self.name}, self.block_text)
            self.state_machine.document.note_pending(pending)
            node_list.append(pending)
        return node_list
示例#12
0
 def run(self):
     tmp = self.options["prefix"]
     tmp += " "
     self.options["prefix"] = tmp
     pending = nodes.pending(parts.SectNum)
     pending.details.update(self.options)
     self.state_machine.document.note_pending(pending)
     return [pending]
示例#13
0
 def apply(self):
     language = languages.get_language(self.document.settings.language_code)
     name = language.labels['contents']
     title = nodes.title('', name)
     topic = nodes.topic('', title, classes=['contents'])
     name = nodes.fully_normalize_name(name)
     if not self.document.has_name(name):
         topic['names'].append(name)
     self.document.note_implicit_target(topic)
     pending = nodes.pending(parts.Contents)
     topic += pending
     self.document.insert(1, topic)
     self.document.note_pending(pending)
示例#14
0
def contents(name, arguments, options, content, lineno,
             content_offset, block_text, state, state_machine):
    """Table of contents."""
    if arguments:
        title_text = arguments[0]
        text_nodes, messages = state.inline_text(title_text, lineno)
        title = nodes.title(title_text, '', *text_nodes)
    else:
        messages = []
        title = None
    pending = nodes.pending(parts.Contents, {'title': title}, block_text)
    pending.details.update(options)
    state_machine.document.note_pending(pending)
    return [pending] + messages
示例#15
0
def contents(name, arguments, options, content, lineno, content_offset,
             block_text, state, state_machine):
    """
    Table of contents.

    The table of contents is generated in two passes: initial parse and
    transform.  During the initial parse, a 'pending' element is generated
    which acts as a placeholder, storing the TOC title and any options
    internally.  At a later stage in the processing, the 'pending' element is
    replaced by a 'topic' element, a title and the table of contents proper.
    """
    if not (state_machine.match_titles
            or isinstance(state_machine.node, nodes.sidebar)):
        error = state_machine.reporter.error(
            'The "%s" directive may not be used within topics '
            'or body elements.' % name,
            nodes.literal_block(block_text, block_text),
            line=lineno)
        return [error]
    document = state_machine.document
    language = languages.get_language(document.settings.language_code)
    if arguments:
        title_text = arguments[0]
        text_nodes, messages = state.inline_text(title_text, lineno)
        title = nodes.title(title_text, '', *text_nodes)
    else:
        messages = []
        if options.has_key('local'):
            title = None
        else:
            title = nodes.title('', language.labels['contents'])
    topic = nodes.topic(classes=['contents'])
    topic['classes'] += options.get('class', [])
    if options.has_key('local'):
        topic['classes'].append('local')
    if title:
        name = title.astext()
        topic += title
    else:
        name = language.labels['contents']
    name = nodes.fully_normalize_name(name)
    if not document.has_name(name):
        topic['names'].append(name)
    document.note_implicit_target(topic)
    pending = nodes.pending(parts.Contents, rawsource=block_text)
    pending.details.update(options)
    document.note_pending(pending)
    topic += pending
    return [topic] + messages
示例#16
0
    def run (self):
        if self.arguments:
            self.options['selector'] = self.arguments[0]
        if 'language' in self.options:
            self.options['class'].extend (['language-' + x for x in self.options['language']])
            del self.options['language']

        pending = nodes.pending (parts.StyleTransform, self.options) 
        self.state_machine.document.note_pending (pending)

        if self.content:
            # parse content into pending node
            self.state.nested_parse (self.content, self.content_offset, pending)

        return [pending]
示例#17
0
 def apply(self):
     language = languages.get_language(
         self.document.settings.language_code, self.document.reporter
     )
     name = language.labels["contents"]
     title = nodes.title("", name)
     topic = nodes.topic("", title, classes=["contents"])
     name = nodes.fully_normalize_name(name)
     if not self.document.has_name(name):
         topic["names"].append(name)
     self.document.note_implicit_target(topic)
     pending = nodes.pending(parts.Contents)
     topic += pending
     self.document.insert(1, topic)
     self.document.note_pending(pending)
示例#18
0
文件: __init__.py 项目: bradh/sira
    def __call__(self, typ, rawtext, text, lineno, inliner, options={},\
                  content=[]):
        """
    When a ``cite`` role is encountered, we replace it with a
    ``docutils.nodes.pending`` node that uses a ``CitationTrasform`` for
    generating the proper citation reference representation during the
    resolve_xref phase.
    """
        rnodes = super(CitationXRefRole,
                       self).__call__(typ, rawtext, text, lineno, inliner,
                                      options, content)
        rootnode = rnodes[0][0]

        env = inliner.document.settings.env
        citations = env.domains['cite'].citations

        # Get the config at this point in the document
        config = {}
        for opt in ['style', 'brackets', 'separator', 'sort', 'sort_compress']:
            config[opt] = env.temp_data.get(
                "cite_%s" % opt,
                env.domaindata['cite']['conf'].get(opt, DEFAULT_CONF[opt]))

        if typ == "cite:text":
            # A ``text`` citation is unique because it doesn't reference a cite-key
            keys = []
            pre, post = text, ''
        else:
            keys, pre, post = parse_keys(text)
            for key in keys:
                if citations.get(key) is None:
                    env.warn(env.docname,
                             "cite-key `%s` not found in bibtex file" % key,
                             lineno)
                    continue
                env.domaindata['cite']['keys'].add(key)

        data = {
            'keys': keys,
            'pre': pre,
            'post': post,
            'typ': typ,
            'global_keys': env.domaindata['cite']['keys'],
            'config': config
        }

        rootnode += nodes.pending(CitationTransform, data)
        return [rootnode], []
示例#19
0
文件: parts.py 项目: crystalspace/CS
def contents(name, arguments, options, content, lineno,
             content_offset, block_text, state, state_machine):
    """
    Table of contents.

    The table of contents is generated in two passes: initial parse and
    transform.  During the initial parse, a 'pending' element is generated
    which acts as a placeholder, storing the TOC title and any options
    internally.  At a later stage in the processing, the 'pending' element is
    replaced by a 'topic' element, a title and the table of contents proper.
    """
    if not (state_machine.match_titles
            or isinstance(state_machine.node, nodes.sidebar)):
        error = state_machine.reporter.error(
              'The "%s" directive may not be used within topics '
              'or body elements.' % name,
              nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
    document = state_machine.document
    language = languages.get_language(document.settings.language_code)
    if arguments:
        title_text = arguments[0]
        text_nodes, messages = state.inline_text(title_text, lineno)
        title = nodes.title(title_text, '', *text_nodes)
    else:
        messages = []
        if options.has_key('local'):
            title = None
        else:
            title = nodes.title('', language.labels['contents'])
    topic = nodes.topic(classes=['contents'])
    topic['classes'] += options.get('class', [])
    if options.has_key('local'):
        topic['classes'].append('local')
    if title:
        name = title.astext()
        topic += title
    else:
        name = language.labels['contents']
    name = nodes.fully_normalize_name(name)
    if not document.has_name(name):
        topic['names'].append(name)
    document.note_implicit_target(topic)
    pending = nodes.pending(parts.Contents, rawsource=block_text)
    pending.details.update(options)
    document.note_pending(pending)
    topic += pending
    return [topic] + messages
示例#20
0
    def run(self):
        if self.arguments:
            self.options['selector'] = self.arguments[0]
        if 'language' in self.options:
            self.options['class'].extend(
                ['language-' + x for x in self.options['language']])
            del self.options['language']

        pending = nodes.pending(parts.StyleTransform, self.options)
        self.state_machine.document.note_pending(pending)

        if self.content:
            # parse content into pending node
            self.state.nested_parse(self.content, self.content_offset, pending)

        return [pending]
示例#21
0
def class_directive(name, arguments, options, content, lineno,
                       content_offset, block_text, state, state_machine):
    """"""
    class_value = nodes.make_id(arguments[0])
    if class_value:
        pending = nodes.pending(misc.ClassAttribute,
                                {'class': class_value, 'directive': name},
                                block_text)
        state_machine.document.note_pending(pending)
        return [pending]
    else:
        error = state_machine.reporter.error(
            'Invalid class attribute value for "%s" directive: %s'
            % (name, arguments[0]),
            nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
示例#22
0
    def run(self):
        # css class is the same as the directive name
        classes = [self.name]
        if self.arguments:
            try:
                classes.extend(directives.class_option(self.arguments[0]))
            except ValueError:
                raise self.error(
                    'Invalid class attribute value for "%s" directive: "%s".' % (self.name, self.arguments[0])
                )

        pending = nodes.pending(
            BlockLines, {"directive": self.name, "class": classes, "allpage": self.allpage}, self.block_text
        )
        self.state_machine.document.note_pending(pending)
        return [pending]
示例#23
0
    def result_nodes(
            self, document: nodes.document, env: BuildEnvironment,
            node: nodes.Element, is_ref: bool
    ) -> Tuple[List[nodes.Node], List[nodes.system_message]]:
        """
        When a ``cite`` role is encountered, we replace it with a
        ``docutils.nodes.pending`` node that uses a ``CitationTransform`` for
        generating the proper citation reference representation during the
        resolve_xref phase.
        """
        domain = cast(CitationDomain, env.get_domain('cite'))

        # Get the config at this point in the document
        config = {}
        for opt in ['style', 'brackets', 'separator', 'sort', 'sort_compress']:
            config[opt] = env.temp_data.get(
                "cite_%s" % opt,
                env.domaindata['cite']['conf'].get(opt, DEFAULT_CONF[opt]))

        if self.name == "cite:text":
            # A ``text`` citation is unique because it doesn't reference a
            # cite-key
            keys = []
            pre, post = self.text, ''
        else:
            keys, pre, post = parse_keys(self.text)
            for key in keys:
                if domain.citations.get(key) is None:
                    logger.warning("cite-key `%s` not found in bibtex file" %
                                   key,
                                   location=(env.docname, self.lineno))
                    continue
                env.domaindata['cite']['keys'][key] = None
                env.domaindata['cite']['keys'] = sort_references(
                    env.domaindata['cite']['keys'], domain.citations)

        data = {
            'keys': keys,
            'pre': pre,
            'post': post,
            'typ': self.name,
            'global_keys': env.domaindata['cite']['keys'],
            'config': config
        }

        node += nodes.pending(CitationTransform, data)
        return [node], []
示例#24
0
def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine):
    """
    Set a "class" attribute on the next element.
    A "pending" element is inserted, and a transform does the work later.
    """
    try:
        class_value = directives.class_option(arguments[0])
    except ValueError:
        error = state_machine.reporter.error(
            'Invalid class attribute value for "%s" directive: "%s".' % (name, arguments[0]),
            nodes.literal_block(block_text, block_text),
            line=lineno,
        )
        return [error]
    pending = nodes.pending(misc.ClassAttribute, {"class": class_value, "directive": name}, block_text)
    state_machine.document.note_pending(pending)
    return [pending]
示例#25
0
def class_directive(name, arguments, options, content, lineno, content_offset,
                    block_text, state, state_machine):
    """"""
    class_value = nodes.make_id(arguments[0])
    if class_value:
        pending = nodes.pending(misc.ClassAttribute, {
            'class': class_value,
            'directive': name
        }, block_text)
        state_machine.document.note_pending(pending)
        return [pending]
    else:
        error = state_machine.reporter.error(
            'Invalid class attribute value for "%s" directive: %s' %
            (name, arguments[0]),
            nodes.literal_block(block_text, block_text),
            line=lineno)
        return [error]
    def run(self):
        node = addnodes.only()
        node.document = self.state.document
        set_source_info(self, node)
        node['expr'] = 'iguide'

        class_value = ['iguide', self.arguments[0]]
            
        pending = nodes.pending(misc.ClassAttribute,
                                {'class': class_value, 
                                 'directive': self.name},
                                self.block_text)
        self.state_machine.document.note_pending(pending)
        node += pending

        self.state.nested_parse(self.content, self.content_offset, node,
                                match_titles=1)
        return [node]
示例#27
0
 def parsemeta(self, match):
     name = self.parse_field_marker(match)
     name = utils.unescape(utils.escape2null(name))
     (
         indented,
         indent,
         line_offset,
         blank_finish,
     ) = self.state_machine.get_first_known_indented(match.end())
     node = self.meta()
     pending = nodes.pending(
         components.Filter,
         {
             "component": "writer",
             "format": "html",
             "nodes": [node]
         },
     )
     node["content"] = utils.unescape(utils.escape2null(" ".join(indented)))
     if not indented:
         line = self.state_machine.line
         msg = self.reporter.info('No content for meta tag "%s".' % name,
                                  nodes.literal_block(line, line))
         return msg, blank_finish
     tokens = name.split()
     try:
         attname, val = utils.extract_name_value(tokens[0])[0]
         node[attname.lower()] = val
     except utils.NameValueError:
         node["name"] = tokens[0]
     for token in tokens[1:]:
         try:
             attname, val = utils.extract_name_value(token)[0]
             node[attname.lower()] = val
         except utils.NameValueError as detail:
             line = self.state_machine.line
             msg = self.reporter.error(
                 'Error parsing meta tag attribute "%s": %s.' %
                 (token, detail),
                 nodes.literal_block(line, line),
             )
             return msg, blank_finish
     self.document.note_pending(pending)
     return pending, blank_finish
示例#28
0
    def run(self):
        if not Initialized:
            # FIXME: Better way to handle one-time initialization?
            init(self.state.document.settings, self.state.document.reporter)

        os.chdir(BTestBase)

        self.assert_has_content()
        document = self.state_machine.document

        tag = self.arguments[0]

        if not tag in Tests:
            import sys
            test = Test()
            test.tag = tag
            test.path = os.path.join(BTestTests, tag + ".btest")
            test.parts = 0
            Tests[tag] = test

        test = Tests[tag]
        test.parts += 1
        part = test.parts

        # Save the test.

        if part == 1:
            file = test.path
        else:
            file = test.path + "#%d" % part

        out = open(file, "w")
        for line in self.content:
            out.write("%s\n" % line)

        out.close()

        details = (test, part)
        pending = nodes.pending(BTestTransform,
                                details,
                                rawsource=self.block_text)
        document.note_pending(pending)

        return [pending]
示例#29
0
文件: misc.py 项目: srid/debris
 def run(self):
     try:
         class_value = directives.class_option(self.arguments[0])
     except ValueError:
         raise self.error('Invalid class attribute value for "%s" directive: "%s".' % (self.name, self.arguments[0]))
     node_list = []
     if self.content:
         container = nodes.Element()
         self.state.nested_parse(self.content, self.content_offset, container)
         for node in container:
             node["classes"].extend(class_value)
         node_list.extend(container.children)
     else:
         pending = nodes.pending(
             misc.ClassAttribute, {"class": class_value, "directive": self.name}, self.block_text
         )
         self.state_machine.document.note_pending(pending)
         node_list.append(pending)
     return node_list
示例#30
0
 def apply(self):
     try:
         #incompatible API change in docutils
         language = languages.get_language(
             self.document.settings.language_code, None)
     except TypeError:
         language = languages.get_language(
             self.document.settings.language_code)
     name = language.labels['contents']
     title = nodes.title('', name)
     topic = nodes.topic('', title, classes=['contents'])
     name = nodes.fully_normalize_name(name)
     if not self.document.has_name(name):
         topic['names'].append(name)
     self.document.note_implicit_target(topic)
     pending = nodes.pending(parts.Contents)
     topic += pending
     self.document.insert(1, topic)
     self.document.note_pending(pending)
示例#31
0
文件: btest-sphinx.py 项目: bro/btest
    def run(self):
        if not Initialized:
            # FIXME: Better way to handle one-time initialization?
            init(self.state.document.settings, self.state.document.reporter)

        os.chdir(BTestBase)

        self.assert_has_content()
        document = self.state_machine.document

        tag = self.arguments[0]

        if not tag in Tests:
            import sys
            test = Test()
            test.tag = tag
            test.path = os.path.join(BTestTests, tag + ".btest")
            test.parts = 0
            Tests[tag] = test

        test = Tests[tag]
        test.parts += 1
        part = test.parts

        # Save the test.

        if part == 1:
            file = test.path
        else:
            file = test.path + "#%d" % part

        out = open(file, "w")
        for line in self.content:
            out.write("%s\n" % line)

        out.close()

        details = (test, part)
        pending = nodes.pending(BTestTransform, details, rawsource=self.block_text)
        document.note_pending(pending)

        return [pending]
示例#32
0
 def __call__(self, typ, rawtext, text, lineno, inliner, options={}, \
               content=[]):
   """
   When a ``cite`` role is encountered, we replace it with a
   ``docutils.nodes.pending`` node that uses a ``CitationTrasform`` for
   generating the proper citation reference representation during the
   resolve_xref phase.
   """
   rnodes = super(CitationXRefRole, self).__call__(typ, rawtext, text, lineno,
                   inliner, options, content)
   rootnode = rnodes[0][0]
   
   env = inliner.document.settings.env
   citations = env.domains['cite'].citations
   
   # Get the config at this point in the document
   config = {}
   for opt in ['style', 'brackets', 'separator', 'sort', 'sort_compress']:
     config[opt] = env.temp_data.get("cite_%s" % opt, env.domaindata['cite']['conf'].get(opt, DEFAULT_CONF[opt]))
   
   if typ == "cite:text":
     # A ``text`` citation is unique because it doesn't reference a cite-key
     keys = []
     pre, post = text, ''
   else:
     keys, pre, post = parse_keys(text)
     for key in keys:
       if citations.get(key) is None:
         env.warn(env.docname, "cite-key `%s` not found in bibtex file" % key, lineno)
         continue
       env.domaindata['cite']['keys'].add(key)
       env.domaindata['cite']['keys'] = sort_references(env.domaindata['cite']['keys'], citations)
   
   data = {'keys':         keys,
           'pre':          pre,
           'post':         post,
           'typ':          typ,
           'global_keys':  env.domaindata['cite']['keys'],
           'config':       config}
   
   rootnode += nodes.pending(CitationTransform, data)
   return [rootnode], []
示例#33
0
    def apply(self) -> None:
        if not Path(self.document["source"]).match("pep-*"):
            return  # not a PEP file, exit early
        # Create the contents placeholder section
        contents_section = nodes.section("")
        if not self.document.has_name("contents"):
            contents_section["names"].append("contents")
        self.document.note_implicit_target(contents_section)

        # Add a table of contents builder
        pending = nodes.pending(Contents)
        contents_section += pending
        self.document.note_pending(pending)

        # Insert the toc after title and PEP headers
        self.document.children[0].insert(2, contents_section)

        # Add a horizontal rule before contents
        transition = nodes.transition()
        self.document[0].insert(2, transition)
示例#34
0
 def run(self):
     if not (self.state_machine.match_titles
             or isinstance(self.state_machine.node, nodes.sidebar)):
         raise self.error('The "%s" directive may not be used within '
                          'topics or body elements.' % self.name)
     document = self.state_machine.document
     language = languages.get_language(document.settings.language_code,
                                       document.reporter)
     if self.arguments:
         title_text = self.arguments[0]
         text_nodes, messages = self.state.inline_text(
             title_text, self.lineno)
         title = nodes.title(title_text, '', *text_nodes)
     else:
         messages = []
         if 'local' in self.options:
             title = None
         else:
             title = nodes.title('', language.labels['contents'])
     topic = nodes.topic(classes=['contents'])
     topic['classes'] += self.options.get('class', [])
     # the latex2e writer needs source and line for a warning:
     src, srcline = self.state_machine.get_source_and_line()
     topic.source = src
     topic.line = srcline - 1
     if 'local' in self.options:
         topic['classes'].append('local')
     if title:
         name = title.astext()
         topic += title
     else:
         name = language.labels['contents']
     name = nodes.fully_normalize_name(name)
     if not document.has_name(name):
         topic['names'].append(name)
     document.note_implicit_target(topic)
     pending = nodes.pending(parts.Contents, rawsource=self.block_text)
     pending.details.update(self.options)
     document.note_pending(pending)
     topic += pending
     return [topic] + messages
示例#35
0
    def __call__(self, typ, rawtext, text, lineno, inliner, options={}, content=[]):
        """
    When a ``cite`` role is encountered, we replace it with a
    ``docutils.nodes.pending`` node that uses a ``CitationTrasform`` for
    generating the proper citation reference representation during the
    resolve_xref phase.
    """
        rnodes = super(CitationXRefRole, self).__call__(typ, rawtext, text, lineno, inliner, options, content)
        rootnode = rnodes[0][0]

        env = inliner.document.settings.env
        citations = env.domains["cite"].citations

        # Get the config at this point in the document
        config = {}
        for opt in ["style", "brackets", "separator", "sort", "sort_compress"]:
            config[opt] = env.temp_data.get("cite_%s" % opt, env.domaindata["cite"]["conf"].get(opt, DEFAULT_CONF[opt]))

        if typ == "cite:text":
            # A ``text`` citation is unique because it doesn't reference a cite-key
            keys = []
            pre, post = text, ""
        else:
            keys, pre, post = parse_keys(text)
            for key in keys:
                if citations.get(key) is None:
                    env.warn(env.docname, "cite-key `%s` not found in bibtex file" % key, lineno)
                    continue
                env.domaindata["cite"]["keys"].add(key)

        data = {
            "keys": keys,
            "pre": pre,
            "post": post,
            "typ": typ,
            "global_keys": env.domaindata["cite"]["keys"],
            "config": config,
        }

        rootnode += nodes.pending(CitationTransform, data)
        return [rootnode], []
示例#36
0
 def run(self):
     if not (self.state_machine.match_titles
             or isinstance(self.state_machine.node, nodes.sidebar)):
         raise self.error('The "%s" directive may not be used within '
                          'topics or body elements.' % self.name)
     document = self.state_machine.document
     language = languages.get_language(document.settings.language_code,
                                       document.reporter)
     if self.arguments:
         title_text = self.arguments[0]
         text_nodes, messages = self.state.inline_text(title_text,
                                                       self.lineno)
         title = nodes.title(title_text, '', *text_nodes)
     else:
         messages = []
         if 'local' in self.options:
             title = None
         else:
             title = nodes.title('', language.labels['contents'])
     topic = nodes.topic(classes=['contents'])
     topic['classes'] += self.options.get('class', [])
     # the latex2e writer needs source and line for a warning:
     src, srcline = self.state_machine.get_source_and_line()
     topic.source = src
     topic.line = srcline - 1
     if 'local' in self.options:
         topic['classes'].append('local')
     if title:
         name = title.astext()
         topic += title
     else:
         name = language.labels['contents']
     name = nodes.fully_normalize_name(name)
     if not document.has_name(name):
         topic['names'].append(name)
     document.note_implicit_target(topic)
     pending = nodes.pending(parts.Contents, rawsource=self.block_text)
     pending.details.update(self.options)
     document.note_pending(pending)
     topic += pending
     return [topic] + messages
示例#37
0
def index_directive(name, arguments, options, content, lineno,
        content_offset, block_text, state, state_machine):
    #pending = nodes.pending(EffTransformer.Index, {'entries': content})
    #state_machine.document.note_pending(pending)
    #return [pending]
    # XXX
    entries = []
    message_set = []
    for entry in content:
        levels = re_index_levels.split(entry)
        tmp = []
        for level in levels:
            textnodes, messages = state.inline_text(level, lineno)
            entry_level = index_entry_level(level, '', *textnodes)
            tmp.append(entry_level)
            message_set.extend(messages)
        index = index_entry(entry, *tmp)
        entries.append(index)
    pending = nodes.pending(EffTransformer.Index, {'entries': entries})
    state_machine.document.note_pending(pending)
    return [pending] + message_set
示例#38
0
def class_directive(name, arguments, options, content, lineno, content_offset,
                    block_text, state, state_machine):
    """
    Set a "class" attribute on the next element.
    A "pending" element is inserted, and a transform does the work later.
    """
    try:
        class_value = directives.class_option(arguments[0])
    except ValueError:
        error = state_machine.reporter.error(
            'Invalid class attribute value for "%s" directive: "%s".' %
            (name, arguments[0]),
            nodes.literal_block(block_text, block_text),
            line=lineno)
        return [error]
    pending = nodes.pending(misc.ClassAttribute, {
        'class': class_value,
        'directive': name
    }, block_text)
    state_machine.document.note_pending(pending)
    return [pending]
示例#39
0
    def run(self):
        details = {}
        if 'depth' in self.options:
            details['toc_depth'] = self.options['depth']

        container = nodes.container()

        if self.arguments:
            container += nodes.inline('', self.arguments[0])

        self.state.nested_parse(self.content, self.content_offset, container)

        container['classes'] += self.options.get('class', [])
        if container.astext():
            details['content'] = container
        else:
            details['content'] = None  # flag: supress toc entry

        pending = nodes.pending(parts.TocEntryTransform, details)
        self.state_machine.document.note_pending(pending)
        return [pending]
示例#40
0
def index_directive(name, arguments, options, content, lineno, content_offset,
                    block_text, state, state_machine):
    #pending = nodes.pending(EffTransformer.Index, {'entries': content})
    #state_machine.document.note_pending(pending)
    #return [pending]
    # XXX
    entries = []
    message_set = []
    for entry in content:
        levels = re_index_levels.split(entry)
        tmp = []
        for level in levels:
            textnodes, messages = state.inline_text(level, lineno)
            entry_level = index_entry_level(level, '', *textnodes)
            tmp.append(entry_level)
            message_set.extend(messages)
        index = index_entry(entry, *tmp)
        entries.append(index)
    pending = nodes.pending(EffTransformer.Index, {'entries': entries})
    state_machine.document.note_pending(pending)
    return [pending] + message_set
示例#41
0
    def run (self):
        details = {}
        if 'depth' in self.options:
            details['toc_depth'] = self.options['depth']

        container = nodes.container ()
        
        if self.arguments:
            container += nodes.inline ('', self.arguments[0])

        self.state.nested_parse (self.content, self.content_offset,
                                 container)

        container['classes'] += self.options.get ('class', [])
        if container.astext ():
            details['content'] = container
        else:
            details['content'] = None # flag: supress toc entry

        pending = nodes.pending (parts.TocEntryTransform, details) 
        self.state_machine.document.note_pending (pending)
        return [pending]
示例#42
0
 def run(self) -> List[nodes.Node]:
     try:
         rjs_id = self.arguments[0]
     except ValueError:
         raise self.error(
             'Invalid class attribute value for "%s" directive: "%s".' %
             (self.name, self.arguments[0]))
     node_list = []
     if self.content:
         container = nodes.Element()
         self.state.nested_parse(self.content, self.content_offset,
                                 container)
         for node in container:
             node.attributes['revealjs-id'] = rjs_id
         node_list.extend(container.children)
     else:
         pending = nodes.pending(RevealjsIdAttribute, {
             'revealjs-id': rjs_id,
             'directive': self.name
         }, self.block_text)
         self.state_machine.document.note_pending(pending)
         node_list.append(pending)
     return node_list
示例#43
0
 def run(self):
     try:
         class_value = directives.class_option(self.arguments[0])
     except ValueError:
         raise self.error(
             'Invalid class attribute value for "%s" directive: "%s".' %
             (self.name, self.arguments[0]))
     node_list = []
     if self.content:
         container = nodes.Element()
         self.state.nested_parse(self.content, self.content_offset,
                                 container)
         for node in container:
             node['classes'].extend(class_value)
         node_list.extend(container.children)
     else:
         pending = nodes.pending(misc.ClassAttribute, {
             'class': class_value,
             'directive': self.name
         }, self.block_text)
         self.state_machine.document.note_pending(pending)
         node_list.append(pending)
     return node_list
示例#44
0
 def run(self):
     # each pylatest directive in the rst document has mandatory action id
     # (starts from 1), so there is either just one or no pylatest directive
     # with action_id == 1
     # note:
     # action is couple of test step and result with the same action_id
     action_id = int(self.arguments[0])
     # first of all, parse text content of this directive
     # into anonymous node element (can't be used directly in the tree)
     node = nodes.Element()
     # include HACK: link to the referred test case
     # TODO: use a proper referece (nested parse?)
     # TODO: the final solutions is a working include though
     if 'include' in self.options:
         ref_tc, ref_action = str(self.options['include']).split(":", 2)
         text_content = "See {0}, action {1}".format(ref_tc, ref_action)
         node += nodes.paragraph(text=text_content)
     else:
         self.state.nested_parse(self.content, self.content_offset, node)
     # create new pending node, which:
     #  - holds actual data (parsed content of the directive)
     #  - references transform class which is concerned with this node.
     #  - name of the directive (test_step or test_result)
     pending = nodes.pending(self.transform_class)
     # add content into pending node
     pending.details['nodes'] = node
     pending.details['action_id'] = action_id
     pending.details['action_name'] = self.name
     # since pylatest transformation will process all pylatest pending nodes
     # at once, we register only 1st test step pending node, and
     # this also means that the result generated by pylatest transform
     # will be located in the place of this first test step directive
     if action_id == 1 and self.name == "test_step":
         # without this, transformer wouldn't know about this pending node
         self.state_machine.document.note_pending(pending)
     # and finally return the pending node as the only result
     return [pending]
示例#45
0
 def apply(self):
     if not len(self.document):
         # @@@ replace these DataErrors with proper system messages
         raise DataError('Document tree is empty.')
     header = self.document[0]
     if not isinstance(header, nodes.field_list) or \
           'rfc2822' not in header['classes']:
         raise DataError('Document does not begin with an RFC-2822 '
                         'header; it is not a PEP.')
     pep = None
     for field in header:
         if field[0].astext().lower() == 'pep': # should be the first field
             value = field[1].astext()
             try:
                 pep = int(value)
                 cvs_url = self.pep_cvs_url % pep
             except ValueError:
                 pep = value
                 cvs_url = None
                 msg = self.document.reporter.warning(
                     '"PEP" header must contain an integer; "%s" is an '
                     'invalid value.' % pep, base_node=field)
                 msgid = self.document.set_id(msg)
                 prb = nodes.problematic(value, value or '(none)',
                                         refid=msgid)
                 prbid = self.document.set_id(prb)
                 msg.add_backref(prbid)
                 if len(field[1]):
                     field[1][0][:] = [prb]
                 else:
                     field[1] += nodes.paragraph('', '', prb)
             break
     if pep is None:
         raise DataError('Document does not contain an RFC-2822 "PEP" '
                         'header.')
     if pep == 0:
         # Special processing for PEP 0.
         pending = nodes.pending(peps.PEPZero)
         self.document.insert(1, pending)
         self.document.note_pending(pending)
     if len(header) < 2 or header[1][0].astext().lower() != 'title':
         raise DataError('No title!')
     for field in header:
         name = field[0].astext().lower()
         body = field[1]
         if len(body) > 1:
             raise DataError('PEP header field body contains multiple '
                             'elements:\n%s' % field.pformat(level=1))
         elif len(body) == 1:
             if not isinstance(body[0], nodes.paragraph):
                 raise DataError('PEP header field body may only contain '
                                 'a single paragraph:\n%s'
                                 % field.pformat(level=1))
         elif name == 'last-modified':
             date = time.strftime(
                   '%d-%b-%Y',
                   time.localtime(os.stat(self.document['source'])[8]))
             if cvs_url:
                 body += nodes.paragraph(
                     '', '', nodes.reference('', date, refuri=cvs_url))
         else:
             # empty
             continue
         para = body[0]
         if name in ('author', 'bdfl-delegate', 'sponsor'):
             for node in para:
                 if isinstance(node, nodes.reference):
                     node.replace_self(peps.mask_email(node))
         elif name == 'discussions-to':
             for node in para:
                 if isinstance(node, nodes.reference):
                     node.replace_self(peps.mask_email(node, pep))
         elif name in ('replaces', 'superseded-by', 'requires'):
             newbody = []
             space = nodes.Text(' ')
             for refpep in re.split(r',?\s+', body.astext()):
                 pepno = int(refpep)
                 newbody.append(nodes.reference(
                     refpep, refpep,
                     refuri=(self.document.settings.pep_base_url
                             + self.pep_url % pepno)))
                 newbody.append(space)
             para[:] = newbody[:-1] # drop trailing space
         elif name == 'last-modified':
             utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
             if cvs_url:
                 date = para.astext()
                 para[:] = [nodes.reference('', date, refuri=cvs_url)]
         elif name == 'content-type':
             pep_type = para.astext()
             uri = self.document.settings.pep_base_url + self.pep_url % 12
             para[:] = [nodes.reference('', pep_type, refuri=uri)]
         elif name == 'version' and len(body):
             utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
示例#46
0
 def run(self):
     pending = nodes.pending(references.TargetNotes)
     self.add_name(pending)
     pending.details.update(self.options)
     self.state_machine.document.note_pending(pending)
     return [pending]
示例#47
0
 def apply(self):
     pending = nodes.pending(parts.Contents, {'title': None})
     self.document.insert(1, pending)
     self.document.note_pending(pending)
示例#48
0
 def run(self):
     pending = nodes.pending(references.TargetNotes)
     pending.details.update(self.options)
     self.state_machine.document.note_pending(pending)
     nodelist = [pending]
     return nodelist
示例#49
0
    def run(self):
        if len(self.arguments) > 0:
            try:
                class_value = directives.class_option(self.arguments[0])
            except ValueError:
                raise self.error(
                    'Invalid class attribute value for "%s" directive: "%s".' %
                    (self.name, self.arguments[0]))
        else:
            class_value = None

        if 'attributes' in self.options and self.options[
                'attributes'] is not None:
            try:
                attributes = ast.literal_eval(self.options['attributes'])
            except ValueError:
                raise self.error('Could not parse attribute string: "%s"' %
                                 self.options['attributes'])
                attributes = None
        else:
            attributes = None

        if 'slide-attributes' in self.options and self.options[
                'slide-attributes'] is not None:
            try:
                slide_attributes = ast.literal_eval(
                    self.options['slide-attributes'])
            except ValueError:
                raise self.error(
                    'Could not parse slide-attribute string: "%s"' %
                    self.options['slide-attributes'])
                slide_attributes = None
        else:
            slide_attributes = None

        node_list = []
        if self.content:
            container = nodes.Element()
            self.state.nested_parse(self.content, self.content_offset,
                                    container)
            for node in container:
                if class_value is not None:
                    node['classes'].extend(class_value)
                if attributes is not None:
                    if 'attributes' in node:
                        node['attributes'].update(attributes)
                    else:
                        node['attributes'] = attributes
                if slide_attributes is not None:
                    if 'slide-attributes' in node:
                        node['slide-attributes'].update(slide_attributes)
                    else:
                        node['slide-attributes'] = slide_attributes

            node_list.extend(container.children)
        else:
            if 'attributes' in self.options and self.options[
                    'attributes'] is not None:
                try:
                    attributes = ast.literal_eval(self.options['attributes'])
                except ValueError:
                    raise self.error('Could not parse attribute string: "%s"' %
                                     self.options['attributes'])
                    attributes = None
            else:
                attributes = None
            if 'slide-attributes' in self.options and self.options[
                    'slide-attributes'] is not None:
                try:
                    slide_attributes = ast.literal_eval(
                        self.options['slide-attributes'])
                except ValueError:
                    raise self.error(
                        'Could not parse slide-attribute string: "%s"' %
                        self.options['slide-attributes'])
                    slide_attributes = None
            else:
                slide_attributes = None
            pending = nodes.pending(
                ClassAttribute2, {
                    'class': class_value,
                    'directive': self.name,
                    'attributes': attributes,
                    'slide-attributes': slide_attributes
                }, self.block_text)
            self.state_machine.document.note_pending(pending)
            node_list.append(pending)
        return node_list
示例#50
0
 def apply(self):
     if not len(self.document):
         # @@@ replace these DataErrors with proper system messages
         raise DataError("Document tree is empty.")
     header = self.document[0]
     if (
         not isinstance(header, nodes.field_list)
         or "rfc2822" not in header["classes"]
     ):
         raise DataError(
             "Document does not begin with an RFC-2822 " "header; it is not a PEP."
         )
     pep = None
     for field in header:
         if field[0].astext().lower() == "pep":  # should be the first field
             value = field[1].astext()
             try:
                 pep = int(value)
                 cvs_url = self.pep_cvs_url % pep
             except ValueError:
                 pep = value
                 cvs_url = None
                 msg = self.document.reporter.warning(
                     '"PEP" header must contain an integer; "%s" is an '
                     "invalid value." % pep,
                     base_node=field,
                 )
                 msgid = self.document.set_id(msg)
                 prb = nodes.problematic(value, value or "(none)", refid=msgid)
                 prbid = self.document.set_id(prb)
                 msg.add_backref(prbid)
                 if len(field[1]):
                     field[1][0][:] = [prb]
                 else:
                     field[1] += nodes.paragraph("", "", prb)
             break
     if pep is None:
         raise DataError('Document does not contain an RFC-2822 "PEP" ' "header.")
     if pep == 0:
         # Special processing for PEP 0.
         pending = nodes.pending(PEPZero)
         self.document.insert(1, pending)
         self.document.note_pending(pending)
     if len(header) < 2 or header[1][0].astext().lower() != "title":
         raise DataError("No title!")
     for field in header:
         name = field[0].astext().lower()
         body = field[1]
         if len(body) > 1:
             raise DataError(
                 "PEP header field body contains multiple "
                 "elements:\n%s" % field.pformat(level=1)
             )
         elif len(body) == 1:
             if not isinstance(body[0], nodes.paragraph):
                 raise DataError(
                     "PEP header field body may only contain "
                     "a single paragraph:\n%s" % field.pformat(level=1)
                 )
         elif name == "last-modified":
             date = time.strftime(
                 "%d-%b-%Y", time.localtime(os.stat(self.document["source"])[8])
             )
             if cvs_url:
                 body += nodes.paragraph(
                     "", "", nodes.reference("", date, refuri=cvs_url)
                 )
         else:
             # empty
             continue
         para = body[0]
         if name == "author":
             for node in para:
                 if isinstance(node, nodes.reference):
                     node.replace_self(mask_email(node))
         elif name == "discussions-to":
             for node in para:
                 if isinstance(node, nodes.reference):
                     node.replace_self(mask_email(node, pep))
         elif name in ("replaces", "replaced-by", "requires"):
             newbody = []
             space = nodes.Text(" ")
             for refpep in re.split(r",?\s+", body.astext()):
                 pepno = int(refpep)
                 newbody.append(
                     nodes.reference(
                         refpep,
                         refpep,
                         refuri=(
                             self.document.settings.pep_base_url
                             + self.pep_url % pepno
                         ),
                     )
                 )
                 newbody.append(space)
             para[:] = newbody[:-1]  # drop trailing space
         elif name == "last-modified":
             utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
             if cvs_url:
                 date = para.astext()
                 para[:] = [nodes.reference("", date, refuri=cvs_url)]
         elif name == "content-type":
             pep_type = para.astext()
             uri = self.document.settings.pep_base_url + self.pep_url % 12
             para[:] = [nodes.reference("", pep_type, refuri=uri)]
         elif name == "version" and len(body):
             utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
示例#51
0
    def apply(self) -> None:
        if not Path(self.document["source"]).match("pep-*"):
            return  # not a PEP file, exit early

        if not len(self.document):
            raise PEPParsingError("Document tree is empty.")

        header = self.document[0]
        if not isinstance(
                header,
                nodes.field_list) or "rfc2822" not in header["classes"]:
            raise PEPParsingError(
                "Document does not begin with an RFC-2822 header; it is not a PEP."
            )

        # PEP number should be the first field
        pep_field = header[0]
        if pep_field[0].astext().lower() != "pep":
            raise PEPParsingError(
                "Document does not contain an RFC-2822 'PEP' header!")

        # Extract PEP number
        value = pep_field[1].astext()
        try:
            pep_num = int(value)
        except ValueError:
            raise PEPParsingError(
                f"'PEP' header must contain an integer. '{value}' is invalid!")

        # Special processing for PEP 0.
        if pep_num == 0:
            pending = nodes.pending(pep_zero.PEPZero)
            self.document.insert(1, pending)
            self.document.note_pending(pending)

        # If there are less than two headers in the preamble, or if Title is absent
        if len(header) < 2 or header[1][0].astext().lower() != "title":
            raise PEPParsingError("No title!")

        fields_to_remove = []
        for field in header:
            name = field[0].astext().lower()
            body = field[1]
            if len(body) == 0:
                # body is empty
                continue
            elif len(body) > 1:
                msg = f"PEP header field body contains multiple elements:\n{field.pformat(level=1)}"
                raise PEPParsingError(msg)
            elif not isinstance(body[0], nodes.paragraph):  # len(body) == 1
                msg = f"PEP header field body may only contain a single paragraph:\n{field.pformat(level=1)}"
                raise PEPParsingError(msg)

            para = body[0]
            if name in {"author", "bdfl-delegate", "pep-delegate", "sponsor"}:
                # mask emails
                for node in para:
                    if not isinstance(node, nodes.reference):
                        continue
                    node.replace_self(_mask_email(node))
            elif name in {"discussions-to", "resolution", "post-history"}:
                # Prettify mailing list and Discourse links
                for node in para:
                    if (not isinstance(node, nodes.reference)
                            or not node["refuri"]):
                        continue
                    # Have known mailto links link to their main list pages
                    if node["refuri"].lower().startswith("mailto:"):
                        node["refuri"] = _generate_list_url(node["refuri"])
                    parts = node["refuri"].lower().split("/")
                    if len(parts) <= 2 or parts[2] not in LINK_PRETTIFIERS:
                        continue
                    pretty_title = _make_link_pretty(str(node["refuri"]))
                    if name == "post-history":
                        node["reftitle"] = pretty_title
                    else:
                        node[0] = nodes.Text(pretty_title)
            elif name in {"replaces", "superseded-by", "requires"}:
                # replace PEP numbers with normalised list of links to PEPs
                new_body = []
                for pep_str in re.split(r",?\s+", body.astext()):
                    target = self.document.settings.pep_url.format(
                        int(pep_str))
                    new_body += [
                        nodes.reference("", pep_str, refuri=target),
                        nodes.Text(", ")
                    ]
                para[:] = new_body[:-1]  # drop trailing space
            elif name == "topic":
                new_body = []
                for topic_name in body.astext().split(","):
                    if topic_name:
                        target = f"/topic/{topic_name.lower().strip()}/"
                        new_body += [
                            nodes.reference("", topic_name, refuri=target),
                            nodes.Text(", "),
                        ]
                if new_body:
                    para[:] = new_body[:-1]  # Drop trailing space/comma
            elif name in {"last-modified", "content-type", "version"}:
                # Mark unneeded fields
                fields_to_remove.append(field)

            # Remove any trailing commas and whitespace in the headers
            if para and isinstance(para[-1], nodes.Text):
                last_node = para[-1]
                if last_node.astext().strip() == ",":
                    last_node.parent.remove(last_node)
                else:
                    para[-1] = last_node.rstrip().rstrip(",")

        # Remove unneeded fields
        for field in fields_to_remove:
            field.parent.remove(field)
示例#52
0
 def run(self):
     pending = nodes.pending(parts.SectNum)
     pending.details.update(self.options)
     self.state_machine.document.note_pending(pending)
     return [pending]
示例#53
0
    def apply(self):
        self.document.settings.rep_base_url = 'http://ros.org/reps/'

        if not len(self.document):
            # @@@ replace these DataErrors with proper system messages
            raise DataError('Document tree is empty.')
        header = self.document[0]
        if not isinstance(header, nodes.field_list) or \
                'rfc2822' not in header['classes']:
            raise DataError('Document does not begin with an RFC-2822 '
                            'header; it is not a REP.')
        rep = None
        for field in header:
            if field[0].astext().lower() == 'rep':  # should be the first field
                value = field[1].astext()
                try:
                    rep = int(value)
                    repo_url = self.rep_git_url % rep
                except ValueError:
                    rep = value
                    repo_url = None
                    msg = self.document.reporter.warning(
                        '"REP" header must contain an integer; "%s" is an '
                        'invalid value.' % rep,
                        base_node=field)
                    msgid = self.document.set_id(msg)
                    prb = nodes.problematic(value,
                                            value or '(none)',
                                            refid=msgid)
                    prbid = self.document.set_id(prb)
                    msg.add_backref(prbid)
                    if len(field[1]):
                        field[1][0][:] = [prb]
                    else:
                        field[1] += nodes.paragraph('', '', prb)
                break
        if rep is None:
            raise DataError('Document does not contain an RFC-2822 "REP" '
                            'header.')
        if rep == 0:
            # Special processing for REP 0.
            pending = nodes.pending(REPZero)
            self.document.insert(1, pending)
            self.document.note_pending(pending)
        if len(header) < 2 or header[1][0].astext().lower() != 'title':
            raise DataError('No title!')
        for field in header:
            name = field[0].astext().lower()
            body = field[1]
            if len(body) > 1:
                raise DataError('REP header field body contains multiple '
                                'elements:\n%s' % field.pformat(level=1))
            elif len(body) == 1:
                if not isinstance(body[0], nodes.paragraph):
                    raise DataError('REP header field body may only contain '
                                    'a single paragraph:\n%s' %
                                    field.pformat(level=1))
            elif name == 'last-modified':
                date = time.strftime(
                    '%d-%b-%Y',
                    time.localtime(os.stat(self.document['source'])[8]))
                if repo_url:
                    body += nodes.paragraph(
                        '', '', nodes.reference('', date, refuri=repo_url))
            else:
                # empty
                continue
            para = body[0]
            if name == 'author':
                for node in para:
                    if isinstance(node, nodes.reference):
                        node.replace_self(mask_email(node))
            elif name == 'discussions-to':
                for node in para:
                    if isinstance(node, nodes.reference):
                        node.replace_self(mask_email(node, rep))
            elif name in ('replaces', 'replaced-by', 'requires'):
                newbody = []
                space = nodes.Text(' ')
                for refrep in re.split(',?\s+', body.astext()):
                    repno = int(refrep)
                    newbody.append(
                        nodes.reference(
                            refrep,
                            refrep,
                            refuri=(self.document.settings.rep_base_url +
                                    self.rep_url % repno)))
                    newbody.append(space)
                para[:] = newbody[:-1]  # drop trailing space
            elif name == 'last-modified':
                utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
                if repo_url:
                    date = para.astext()
                    para[:] = [nodes.reference('', date, refuri=repo_url)]
            elif name == 'content-type':
                rep_type = para.astext()
                uri = self.document.settings.rep_base_url + self.rep_url % 12
                para[:] = [nodes.reference('', rep_type, refuri=uri)]
            elif name == 'version' and len(body):
                utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
示例#54
0
def fig_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    text = utils.unescape(text)
    node = figref('(?)', '(?)', target=text)
    pending = nodes.pending(FigureReferences)
    inliner.document.note_pending(pending)
    return [node], []
示例#55
0
 def run(self):
     pending = nodes.pending(parts.SectNum)
     pending.details.update(self.options)
     self.state_machine.document.note_pending(pending)
     return [pending]
示例#56
0
    def apply(self) -> None:
        if not Path(self.document["source"]).match("pep-*"):
            return  # not a PEP file, exit early

        if not len(self.document):
            raise PEPParsingError("Document tree is empty.")

        header = self.document[0]
        if not isinstance(
                header,
                nodes.field_list) or "rfc2822" not in header["classes"]:
            raise PEPParsingError(
                "Document does not begin with an RFC-2822 header; it is not a PEP."
            )

        # PEP number should be the first field
        pep_field = header[0]
        if pep_field[0].astext().lower() != "pep":
            raise PEPParsingError(
                "Document does not contain an RFC-2822 'PEP' header!")

        # Extract PEP number
        value = pep_field[1].astext()
        try:
            pep = int(value)
        except ValueError:
            raise PEPParsingError(
                f"'PEP' header must contain an integer. '{value}' is invalid!")

        # Special processing for PEP 0.
        if pep == 0:
            pending = nodes.pending(pep_zero.PEPZero)
            self.document.insert(1, pending)
            self.document.note_pending(pending)

        # If there are less than two headers in the preamble, or if Title is absent
        if len(header) < 2 or header[1][0].astext().lower() != "title":
            raise PEPParsingError("No title!")

        fields_to_remove = []
        for field in header:
            name = field[0].astext().lower()
            body = field[1]
            if len(body) == 0:
                # body is empty
                continue
            elif len(body) > 1:
                msg = f"PEP header field body contains multiple elements:\n{field.pformat(level=1)}"
                raise PEPParsingError(msg)
            elif not isinstance(body[0], nodes.paragraph):  # len(body) == 1
                msg = f"PEP header field body may only contain a single paragraph:\n{field.pformat(level=1)}"
                raise PEPParsingError(msg)

            para = body[0]
            if name in {
                    "author", "bdfl-delegate", "pep-delegate",
                    "discussions-to", "sponsor"
            }:
                # mask emails
                for node in para:
                    if isinstance(node, nodes.reference):
                        pep_num = pep if name == "discussions-to" else None
                        node.replace_self(_mask_email(node, pep_num))
            elif name in {"replaces", "superseded-by", "requires"}:
                # replace PEP numbers with normalised list of links to PEPs
                new_body = []
                for ref_pep in re.split(r",?\s+", body.astext()):
                    new_body += [
                        nodes.reference("",
                                        ref_pep,
                                        refuri=config.pep_url.format(
                                            int(ref_pep)))
                    ]
                    new_body += [nodes.Text(", ")]
                para[:] = new_body[:-1]  # drop trailing space
            elif name in {"last-modified", "content-type", "version"}:
                # Mark unneeded fields
                fields_to_remove.append(field)

        # Remove unneeded fields
        for field in fields_to_remove:
            field.parent.remove(field)
示例#57
0
    def run(self):

        if len(self.arguments) > 0:
            try:
                class_value = directives.class_option(self.arguments[0])
            except ValueError:
                raise self.error(
                    'Invalid class attribute value for "%s" directive: "%s".'
                    % (self.name, self.arguments[0]))
        else:
            class_value = None

        if 'attributes' in self.options and self.options['attributes'] is not None:
            try:
                attributes = []
                for attribute in self.options['attributes'].split("\n"):

                    left, sep, right = attribute.partition('=')
                    if sep == '':
                        a_rest_and_key = left
                        a_val = None
                    else:
                        a_rest_and_key = left
                        a_val = right

                    a_list = a_rest_and_key.split(' ')
                    if len(a_list) == 2:
                        a_restriction = a_list[0]
                        a_key = a_list[1]
                    elif len(a_list) == 1:
                        a_restriction = None
                        a_key = a_list[0]
                    else:
                        raise ValueError("wrong format: "+attribute)

                    attributes += [{'key':a_key, 'val':a_val, 'restriction':a_restriction}]

            except ValueError as e:
                raise self.error(
                    'Could not parse attribute string: "%s" (%s)'
                    % (self.options['attributes'], str(e)))
                attributes = None
        else:
            attributes = None

        node_list = []
        if self.content:
            container = nodes.Element()
            self.state.nested_parse(self.content, self.content_offset,
                                    container)
            for node in container:
                if class_value is not None:
                    node['classes'].extend(class_value)

                if attributes is not None:
                    if 'attributes' in node:
                        node['attributes'].update(attributes)
                    else:
                        node['attributes'] = attributes

            node_list.extend(container.children)
        else:
            pending = nodes.pending(
                ClassAttribute2,
                {'class': class_value, 'directive': self.name, 'attributes': attributes},
                self.block_text)
            self.state_machine.document.note_pending(pending)
            node_list.append(pending)
        return node_list