Beispiel #1
0
def register_sections_as_label(app, document):
    # type: (Sphinx, nodes.Node) -> None
    labels = app.env.domaindata['std']['labels']
    anonlabels = app.env.domaindata['std']['anonlabels']
    for node in document.traverse(nodes.section):
        if (app.config.autosectionlabel_maxdepth and
                get_node_depth(node) >= app.config.autosectionlabel_maxdepth):
            continue
        labelid = node['ids'][0]
        docname = app.env.docname
        title = cast(nodes.title, node[0])
        ref_name = getattr(title, 'rawsource', title.astext())
        if app.config.autosectionlabel_prefix_document:
            name = nodes.fully_normalize_name(docname + ':' + ref_name)
        else:
            name = nodes.fully_normalize_name(ref_name)
        sectname = clean_astext(title)

        if name in labels:
            logger.warning(__('duplicate label %s, other instance in %s'),
                           name,
                           app.env.doc2path(labels[name][0]),
                           location=node)

        anonlabels[name] = docname, labelid
        labels[name] = docname, labelid, sectname
Beispiel #2
0
    def apply(self):
        settings = self.document.settings
        if not hasattr(settings, 'cc_embed') or not settings.cc_embed:
            return

        logger.debug('Running cc_embed xform')

        subrefname = nodes.fully_normalize_name(
                settings.cc_license_substitution_reference)
        subrefid = nodes.make_id(subrefname)
        subrefpath = nodes.fully_normalize_name(
                settings.cc_license_location)

        subreflist = self.document.traverse(nodes.substitution_reference)
        if subrefname not in subreflist:
            subrefloc = self.find_location(subrefpath)

            # append sub. ref. at location
            subrefnode = nodes.substitution_reference(None, None,
                    refname=subrefname)
            subrefloc.append(subrefnode)
            self.document.note_substitution_ref(subrefnode, subrefname)

        license = self.generate_cc_license()
        # append sub. def. to document
        subdefnode = nodes.substitution_definition(names=subrefname)
        subdefnode.append(license)
        self.document.append(subdefnode)
        self.document.note_substitution_def(subdefnode, subrefname)
def register_sections_as_label(app: Sphinx, document: Node) -> None:
    docname = app.env.docname
    print(docname)

    for pattern in app.config.autosectionlabel_skip_docs:
        if fnmatch(docname, pattern):
            return None

    domain = cast(StandardDomain, app.env.get_domain("std"))
    for node in document.traverse(nodes.section):
        if (app.config.autosectionlabel_maxdepth and
                get_node_depth(node) >= app.config.autosectionlabel_maxdepth):
            continue
        labelid = node["ids"][0]

        title = cast(nodes.title, node[0])
        ref_name = getattr(title, "rawsource", title.astext())
        if app.config.autosectionlabel_prefix_document:
            name = nodes.fully_normalize_name(docname + ":" + ref_name)
        else:
            name = nodes.fully_normalize_name(ref_name)
        sectname = clean_astext(title)

        if name in domain.labels:
            logger.warning(
                __("duplicate label %s, other instance in %s"),
                name,
                app.env.doc2path(domain.labels[name][0]),
                location=node,
                type="autosectionlabel",
                subtype=docname,
            )

        domain.anonlabels[name] = docname, labelid
        domain.labels[name] = docname, labelid, sectname
Beispiel #4
0
def register_sections_as_label(app: Sphinx, document: Node) -> None:
    domain = cast(StandardDomain, app.env.get_domain('std'))
    for node in document.traverse(nodes.section):
        if (app.config.autosectionlabel_maxdepth and
                get_node_depth(node) >= app.config.autosectionlabel_maxdepth):
            continue
        labelid = node['ids'][0]
        docname = app.env.docname
        title = cast(nodes.title, node[0])
        ref_name = getattr(title, 'rawsource', title.astext())
        if app.config.autosectionlabel_prefix_document:
            name = nodes.fully_normalize_name(docname + ':' + ref_name)
        else:
            name = nodes.fully_normalize_name(ref_name)
        sectname = clean_astext(title)

        if name in domain.labels:
            logger.warning(__('duplicate label %s, other instance in %s'),
                           name,
                           app.env.doc2path(domain.labels[name][0]),
                           location=node,
                           type='autosectionlabel',
                           subtype=docname)

        domain.anonlabels[name] = docname, labelid
        domain.labels[name] = docname, labelid, sectname
Beispiel #5
0
def make_module_section(tree,parent_name=None):
    """Return a docutils tree constructed from this Module sub-tree
    """
    module_name = os.path.splitext(tree.filename)[0]
    if parent_name:
        tree_name = "%s.%s"%(parent_name,module_name)
    else:
        tree_name = module_name
    title = "Module %s"%(tree_name)

    # @@@ Same considerations on id/name as above
    section = nodes.section(CLASS="module",id=nodes.make_id(title),
                            name=nodes.fully_normalize_name(title))
    title = nodes.title(text=title)
    section.append(title)

    # Assume that the docstring must be the first child
    if len(tree.children) > 0 and \
       isinstance(tree.children[0],Docstring):
        section.append(make_docstring(tree.children[0]))

    # @@@ Again, I'm looking for classes before anything else
    for child in tree.children:
        if isinstance(child,Class):
            subsection = make_class_section(child,tree_name)
            section.append(subsection)

    return section
Beispiel #6
0
def make_module_section(tree,parent_name=None):
    """Return a docutils tree constructed from this Module sub-tree
    """
    module_name = os.path.splitext(tree.filename)[0]
    if parent_name:
        tree_name = "%s.%s"%(parent_name,module_name)
    else:
        tree_name = module_name
    title = "Module %s"%(tree_name)

    # @@@ Same considerations on id/name as above
    section = nodes.section(CLASS="module",id=nodes.make_id(title),
                            name=nodes.fully_normalize_name(title))
    title = nodes.title(text=title)
    section.append(title)

    # Assume that the docstring must be the first child
    if len(tree.children) > 0 and \
       isinstance(tree.children[0],Docstring):
        section.append(make_docstring(tree.children[0]))

    # @@@ Again, I'm looking for classes before anything else
    for child in tree.children:
        if isinstance(child,Class):
            subsection = make_class_section(child,tree_name)
            section.append(subsection)

    return section
Beispiel #7
0
    def _generate_nodes(self, name, command, parent=None, options={}):
        """Generate the relevant Sphinx nodes.
        Format a `click.Group` or `click.Command`.
        :param name: Name of command, as used on the command line
        :param command: Instance of `click.Group` or `click.Command`
        :param parent: Instance of `click.Context`, or None
        :param show_nested: Whether subcommands should be included in output
        :returns: A list of nested docutil nodes
        """

        # Title
        source_name = name

        section = nodes.section(
            '',
            nodes.title(text=name),
            ids=[nodes.make_id(source_name)],
            names=[nodes.fully_normalize_name(source_name)])

        # Summary

        result = statemachine.ViewList()
        lines = _format_command(name, command, **options)
        for line in lines:
            result.append(line, source_name)
        self.state.nested_parse(result, 0, section)

        return [section]
Beispiel #8
0
    def _generate_nodes(self,
                        name,
                        command,
                        parent=None,
                        show_nested=False,
                        flat_toctree=False,
                        commands=None):
        """Generate the relevant Sphinx nodes.

        Format a `click.Group` or `click.Command`.

        :param name: Name of command, as used on the command line
        :param command: Instance of `click.Group` or `click.Command`
        :param parent: Instance of `click.Context`, or None
        :param show_nested: Whether subcommands should be included in output
        :param flat_toctree: Whether a flat toctree is generated for
            subcommands (instead of a hierarchical one)
        :param commands: Display only listed commands or skip the section if
            empty
        :returns: A list of nested docutil nodes
        """
        ctx = click.Context(command, info_name=name, parent=parent)

        if CLICK_VERSION >= (7, 0) and command.hidden:
            return []

        # Title

        section = nodes.section(
            '',
            nodes.title(text=name),
            ids=[nodes.make_id(ctx.command_path)],
            names=[nodes.fully_normalize_name(ctx.command_path)])

        # Summary

        source_name = ctx.command_path
        result = statemachine.ViewList()

        lines = _format_command(ctx, show_nested, commands)
        for line in lines:
            LOG.debug(line)
            result.append(line, source_name)

        self.state.nested_parse(result, 0, section)

        # Subcommands

        section_list = [section]
        if show_nested:
            commands = _filter_commands(ctx, commands)
            for command in commands:
                new_section = self._generate_nodes(command.name, command, ctx,
                                                   show_nested, flat_toctree)

                if flat_toctree:
                    section_list.extend(new_section)
                else:
                    section.extend(new_section)
        return section_list
Beispiel #9
0
    def build_app_doc(self, module, app):
        """
        Build overall Chalice app documentation.

        Heading comes from app name.
        Body comes from directive content or module docstring.
        """
        # See RSTState.section for regular section creation logic.
        root = App()
        root['names'].append(nodes.fully_normalize_name(app.app_name))
        root += AppName(app.app_name, app.app_name.replace('_', ' ').title())
        self.state.document.note_implicit_target(root, root)
        # Add cross-reference
        self.add_xref('app', app.app_name, root['ids'][0])
        # If content is given use that, otherwise use module docstring.
        if self.content:
            nodeutils.nested_parse_with_titles(self.state, self.content, root)
        else:
            _, content = get_content(module)
            with docutils.switch_source_input(self.state, content):
                # Necessary so that the child nodes get the right source/line
                root.document = self.state.document
                nodeutils.nested_parse_with_titles(self.state, content, root)

        return root
def doctree_resolved(app, doctree, fromdocname):
    env = app.builder.env
    blocks = getattr(env, 'numbered_blocks_by_id', {})
    definition = getattr(env, 'numbered_blocks_definitions', {})
    secnumbers = env.toc_secnumbers

    # Add section number
    for doc in blocks:
        for id, block in blocks[doc].items():
            anchorname = block['anchorname']
            target_doc = block['docname']
            if anchorname not in secnumbers[doc]:
                anchorname = ''
            if 'secnumber' not in block:
                block['secnumber'] = secnumbers[doc][anchorname][0]
            type = block['type']
            if block['count']:
                block['number'] = str(block['secnumber']) + '.' + str(block['count'])
            else:
                block['number'] = False

    # Build labels
    files = doctree.traverse(start_of_file)
    if not files:
        build_labels(app, doctree, fromdocname)
    else:
        for file in files:
            if len(file.traverse(start_of_file)) > 1:   # not a leaf
                continue
            build_labels(app, file, file['docname'], ("document-%s-" % file['docname']))

    # Resolve references
    anonlabels = env.domains['std'].data['anonlabels']
    for ref in doctree.traverse(numbered_block_ref):
        target = nodes.fully_normalize_name(ref['reftarget']).split('+')
        postfix = target[1] if len(target) > 1 else ''
        target = target[0]
        target_doc, id = anonlabels.get(target, ('',False))

        if not id or id not in blocks[target_doc]:
            app.warn('Target block not found: %s' % target)
            label = target
            link = "#%s" % target

        else:
            block = blocks[target_doc][id]
            type = block['type']
            if block['number']:
                label = definition[type]['reference-format'] % block['number'] + postfix
            else:
                label = target
            link = app.builder.get_relative_uri(fromdocname, block['docname'])
            link += '#' if link.find('#') == -1 else '-'
            link += block['id']

        if ref['refexplicit']:
            label = ref.astext()

        html = '<a href="%s">%s</a>' % (link, label)
        ref.replace_self(nodes.raw(html, html, format='html'))
Beispiel #11
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
Beispiel #12
0
    def write_step_definition(self, step):
        assert self.document
        step_text = self.describe_step_definition(step)
        if step_text.startswith("* "):
            step_text = step_text[2:]
        index_id = None
        if self.make_step_index_entries:
            index_id = self.make_step_definition_index_id(step)

        heading = step_text
        step_label = None
        if self.step_heading_prefix:
            heading = self.step_heading_prefix + step_text
        if has_docutils and self.make_step_labels:
            # -- ADD STEP-LABEL (supports: step-refs by name)
            # EXAMPLE: See also :ref:`When my step does "{something}"`.
            step_label = fully_normalize_name(step_text)
            # SKIP-HERE: self.document.write(".. _%s:\n\n" % step_label)
        self.document.write_heading(heading,
                                    level=2,
                                    index_id=index_id,
                                    label=step_label)
        step_definition_doc = self.make_step_definition_doc(step)
        self.document.write("%s\n" % step_definition_doc)
        self.document.write("\n")
Beispiel #13
0
    def run(self):
        language = self.arguments[0]

        indexed_languages = self.options.get('index_as') or language
        index_specs = ['pair: {}; language'.format(l)
                       for l in indexed_languages.splitlines()]

        name = nodes.fully_normalize_name(language)
        target = 'language-{}'.format(name)
        targetnode = nodes.target('', '', ids=[target])
        self.state.document.note_explicit_target(targetnode)

        indexnode = addnodes.index()
        indexnode['entries'] = []
        indexnode['inline'] = False
        set_source_info(self, indexnode)
        for spec in index_specs:
            indexnode['entries'].extend(process_index_entry(spec, target))

        sectionnode = nodes.section()
        sectionnode['names'].append(name)

        title, messages = self.state.inline_text(language, self.lineno)
        titlenode = nodes.title(language, '', *title)

        sectionnode += titlenode
        sectionnode += messages
        self.state.document.note_implicit_target(sectionnode, sectionnode)

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

        return [indexnode, targetnode, sectionnode]
Beispiel #14
0
    def parse_front(self, params):

        prop = {
            m.group('key'): m.group('value')
            for m in re.finditer(reFMKey, params)
        }
        title = prop.get('title')
        permalink = prop.get('permalink')

        # att = {}
        if title:
            # att['title']  = title
            # att['names'] = title.lower()
            # att['ids'] = att['names'].replace(' ', '-')

            title_node = nodes.title(text=title)
            title_node.line = 0

            new_section = nodes.section()
            new_section.line = 0
            new_section.append(title_node)

            self.add_section(new_section, 1)
            name = nodes.fully_normalize_name(title)
            if permalink:
                match = re.search(reFMid, permalink)
                if match:
                    ids = match.group(0)
                    new_section['ids'].append(ids)
                    new_section['names'].append(ids)
            new_section['names'].append(name)
            self.document.note_implicit_target(new_section, new_section)
            self.current_node = new_section
Beispiel #15
0
    def depart_heading(self, mdnode):
        """Finish establishing section

        Wrap up title node, but stick in the section node. Add the section names
        based on all the text nodes added to the title.
        """
        assert isinstance(self.current_node, nodes.title)
        # The title node has a tree of text nodes, use the whole thing to
        # determine the section id and names
        text = self.current_node.astext()
        if self.translate_section_name:
            text = self.translate_section_name(text)
        name = nodes.fully_normalize_name(text)
        section = self.current_node.parent
        section['names'].append(name)

        if mdnode and mdnode.prv and mdnode.prv.last_child and\
                mdnode.prv.last_child.t == 'ald_inline':
            match = reAldTypeID.search(mdnode.prv.last_child.literal)
            if match:
                section['names'].append(match.group(1))
                section['ids'] = [match.group(1)]

        self.document.note_implicit_target(section, section)
        self.current_node = section
Beispiel #16
0
    def visit_reference(self, node):
        """
            Pass links to MoinMoin to get the correct wiki space url. Extract
            the url and pass it on to the html4css1 writer to handle. Inline
            images are also handled by visit_image. Not sure what the "drawing:"
            link scheme is used for, so for now it is handled here.

            Also included here is a hack to allow MoinMoin macros. This routine
            checks for a link which starts with "[[". This link is passed to the
            MoinMoin formatter and the resulting markup is inserted into the
            document in the place of the original link reference.
        """
        moin_link_schemes = ('wiki:', 'attachment:', 'drawing:', '[[',
                             'inline:')

        if 'refuri' in node.attributes:
            target = None
            refuri = node['refuri']

            # MMG: Fix this line
            if [scheme for scheme in moin_link_schemes if
                    refuri.lstrip().startswith(scheme)]:
                # For a macro, We want the actuall text from the user in target,
                # not the fully normalized version that is contained in refuri.
                if refuri.startswith('[['):
                    target = node['name']
                else:
                    target = refuri
            # TODO: Figure out the following two elif's and comment
            # appropriately.
            # The node should have a whitespace normalized name if the docutlis
            # reStructuredText parser would normally fully normalize the name.
            elif ('name' in node.attributes and
                  fully_normalize_name(node['name']) == refuri):
                target = ':%s:' % (node['name'])
            # If its not a uri containing a ':' then its probably destined for
            # wiki space.
            elif ':' not in refuri:
                target = ':%s:' % (refuri)

            if target:
                if target.startswith('inline:'):
                    self.process_inline(node, 'refuri')
                elif target.startswith('[[') and target.endswith(']]'):
                    self.process_wiki_target(target)
                else:
                    # Not a macro or inline so hopefully its a link. Put the target in
                    # brackets so that MoinMoin knows its a link. Extract the
                    # href, if it exists, and let docutils handle it from there.
                    # If there is no href just add whatever MoinMoin returned.
                    node_text = node.astext().replace('\n', ' ')
                    self.process_wiki_text('[%s %s]' % (target, node_text))
                    href = re.search('href="([^"]+)"', self.wiki_text)
                    if href:
                        # dirty hack in order to undo the HTML entity quoting
                        node['refuri'] = href.groups()[0].replace("&amp;", "&")
                    else:
                        self.wiki_text = self.fixup_wiki_formatting(self.wiki_text)
                        self.add_wiki_markup()
        html4css1.HTMLTranslator.visit_reference(self, node)
Beispiel #17
0
    def apply(self):
        if not hasattr(self.document.settings, 'breadcrumb') \
                or not getattr(self.document.settings, 'breadcrumb', None):
            return

        logger.debug('Running breadcrumb xform')

        subrefname = nodes.fully_normalize_name(
            self.document.settings.breadcrumb_substitution_reference)
        subrefid = nodes.make_id(subrefname)

        subreflist = self.document.traverse(nodes.substitution_reference)
        
        if subrefname not in subreflist:
            subloc = self.find_breadcrumb_location()

            # append sub. reference at location
            subrefnode = nodes.substitution_reference(None, subrefname)
            subrefnode['refname'] = subrefname
            subloc.append(subrefnode)
            self.document.note_substitution_ref(subrefnode, subrefname)

        breadcrumb = self.generate_breadcrumb()
        # append sub. definition to document
        subdefnode = nodes.substitution_definition()
        subdefnode.append(breadcrumb)
        subdefnode['names'].append(subrefname)
        self.document.append(subdefnode)
        self.document.note_substitution_def(subdefnode, subrefname) 
Beispiel #18
0
    def run(self):
        language = self.arguments[0]

        indexed_languages = self.options.get('index_as') or language
        index_specs = [
            'pair: {}; language'.format(lang)
            for lang in indexed_languages.splitlines()
        ]

        name = nodes.fully_normalize_name(language)
        target = 'language-{}'.format(name)
        targetnode = nodes.target('', '', ids=[target])
        self.state.document.note_explicit_target(targetnode)

        indexnode = addnodes.index()
        indexnode['entries'] = []
        indexnode['inline'] = False
        set_source_info(self, indexnode)
        for spec in index_specs:
            indexnode['entries'].extend(process_index_entry(spec, target))

        sectionnode = nodes.section()
        sectionnode['names'].append(name)

        title, messages = self.state.inline_text(language, self.lineno)
        titlenode = nodes.title(language, '', *title)

        sectionnode += titlenode
        sectionnode += messages
        self.state.document.note_implicit_target(sectionnode, sectionnode)

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

        return [indexnode, targetnode, sectionnode]
Beispiel #19
0
    def render_heading_open(self, token):
        # Test if we're replacing a section level first

        level = int(token.tag[1])
        if isinstance(self.current_node, nodes.section):
            if self.is_section_level(level, self.current_node):
                self.current_node = self.current_node.parent

        title_node = nodes.title()
        self.add_line_and_source_path(title_node, token)

        new_section = nodes.section()
        self.add_line_and_source_path(new_section, token)
        new_section.append(title_node)

        self.add_section(new_section, level)

        self.current_node = title_node
        self.render_children(token)

        assert isinstance(self.current_node, nodes.title)
        text = self.current_node.astext()
        # if self.translate_section_name:
        #     text = self.translate_section_name(text)
        name = nodes.fully_normalize_name(text)
        section = self.current_node.parent
        section["names"].append(name)
        self.document.note_implicit_target(section, section)
        self.current_node = section
    def run(self):
        env = self.state.document.settings.env
        definitions = env.numbered_blocks_definitions

        (table,) = RSTTable.run(self)
        if isinstance(table, nodes.system_message):
            return [table]

        numbered = self.numbered()
        if not table['ids']:
            id = "%s-%d" % (self.name, env.new_serialno(self.name))
            table['ids'] = [nodes.fully_normalize_name(id)]
            self.add_name(table)

        table['classes'].append('numbered-block')
        table['type'] = self.name
        table['numbered'] = numbered

        title_pos = table.first_child_matching_class(nodes.title)
        if numbered:
            if title_pos == None:
                table.insert(0, nodes.title('', ''))
            else:
                title = table.children[title_pos]
                title.insert(0, nodes.inline('', definitions[self.name]['title-separator'], classes=['separator']))

        return [table]
Beispiel #21
0
def add_labels_to_nodes(app, document):
    labels = app.env.domaindata['std']['labels']
    anonlabels = app.env.domaindata['std']['anonlabels']
    basepath = os.path.join('generated',
                            app.env.config.asdf_schema_standard_prefix)

    for node in document.traverse():
        if isinstance(
                node,
                str) or not (isinstance(node, nodes.Node) and node['ids']):
            continue

        labelid = node['ids'][0]
        docname = app.env.docname
        basename = os.path.relpath(docname, basepath)

        if labelid == normalize_name(basename):
            name = basename
        else:
            name = nodes.fully_normalize_name(basename + ':' + labelid)

        # labelname -> docname, labelid
        anonlabels[name] = docname, labelid
        # labelname -> docname, labelid, sectionname
        labels[name] = docname, labelid, ''
Beispiel #22
0
    def run(self):
        self.assert_has_content()
        document = self.state_machine.document
        text = "\n".join(self.content)
        project = project_node(text)

        name = nodes.fully_normalize_name(self.arguments[0])
        if not document.has_name(name):
            project["names"].append(name)
        document.note_implicit_target(project)

        desc = project_desc(self.arguments[0])
        self.state.nested_parse(self.content, self.content_offset, desc)
        project += desc

        for key, cls in (
            ("code", project_code),
            ("docs", project_docs),
            ("download", project_download),
            ("homepage", project_homepage),
            ("license", project_license),
        ):
            if key in self.options:
                item = cls()
                textnodes, messages = self.state.inline_text(
                    self.options[key], self.content_offset
                )
                item += textnodes
                item += messages
                project += item

        return [project]
Beispiel #23
0
    def run(self):
        if 'align' in self.options:
            if isinstance(self.state, states.SubstitutionDef):
                # Check for align_v_values.
                if self.options['align'] not in self.align_v_values:
                    raise self.error(
                        'Error in "%s" directive: "%s" is not a valid value '
                        'for the "align" option within a substitution '
                        'definition.  Valid values for "align" are: "%s".'
                        % (self.name, self.options['align'],
                           '", "'.join(self.align_v_values)))
            elif self.options['align'] not in self.align_h_values:
                raise self.error(
                    'Error in "%s" directive: "%s" is not a valid value for '
                    'the "align" option.  Valid values for "align" are: "%s".'
                    % (self.name, self.options['align'],
                       '", "'.join(self.align_h_values)))
        messages = []
        reference = directives.uri(self.arguments[0])
        self.options['uri'] = reference
        reference_node = None
        if 'target' in self.options:
            block = states.escape2null(
                self.options['target']).splitlines()
            block = [line for line in block]
            target_type, data = self.state.parse_target(
                block, self.block_text, self.lineno)
            if target_type == 'refuri':
                reference_node = nodes.reference(refuri=data)
            elif target_type == 'refname':
                reference_node = nodes.reference(
                    refname=fully_normalize_name(data),
                    name=whitespace_normalize_name(data))
                reference_node.indirect_reference_name = data
                self.state.document.note_refname(reference_node)
            else:                           # malformed target
                messages.append(data)       # data is a system message
            del self.options['target']


        image_node = nodes.image(self.block_text, **self.options)

        if 'iconmargin' in self.options:
            image_node['classes'].append('iconmargin')

        set_classes(self.options)

        if 'iconmarginheight' in self.options:
            image_node['iconmarginheight'] = \
               int(self.options['iconmarginheight'])

        if 'iconmarginraise' in self.options:
            image_node['iconmarginraise'] = True


        if reference_node:
            reference_node += image_node
            return messages + [reference_node]
        else:
            return messages + [image_node]
Beispiel #24
0
 def make_targetnode(self):
     targetnode = nodes.target(
         '', '', ids=[nodes.make_id(self.arguments[0].strip())])
     name = nodes.fully_normalize_name(self.arguments[0].strip())
     targetnode['names'].append(name)
     self.state_machine.document.note_explicit_target(
         targetnode, targetnode)
     return targetnode
 def _register_ref(self, ref_name: str, ref_title: str, node: Element) -> None:
     doc_name = self.env.docname
     if self.env.config.sphinx_argparse_cli_prefix_document:
         name = fully_normalize_name(f"{doc_name}:{ref_name}")
     else:
         name = fully_normalize_name(ref_name)
     if name in self._std_domain.labels:
         logger.warning(
             __("duplicate label %s, other instance in %s"),
             name,
             self.env.doc2path(self._std_domain.labels[name][0]),
             location=node,
             type="sphinx-argparse-cli",
             subtype=self.env.docname,
         )
     self._std_domain.anonlabels[name] = doc_name, ref_name
     self._std_domain.labels[name] = doc_name, ref_name, ref_title
Beispiel #26
0
 def render_myst_target(self, token):
     text = token.content
     name = nodes.fully_normalize_name(text)
     target = nodes.target(text)
     target["names"].append(name)
     self.add_line_and_source_path(target, token)
     self.document.note_explicit_target(target, self.current_node)
     self.current_node.append(target)
    def run(self):
        oldStdout, sys.stdout = sys.stdout, StringIO()

        tab_width = self.options.get('tab-width', self.state.document.settings.tab_width)
        source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1)

        try:
            code = '\n'.join(self.content)
            exec(code)
            text = sys.stdout.getvalue()
        except Exception:
            return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text = str(sys.exc_info()[1])))]
        finally:
            sys.stdout = oldStdout

        linespec = self.options.get('emphasize-lines')
        if linespec:
            try:
                nlines = len(self.content)
                hl_lines = [x+1 for x in parselinenos(linespec, nlines)]
            except ValueError as err:
                document = self.state.document
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        chevron_code = code.split('\n')
        chevron_code = [c for c in chevron_code if '#hide' not in c]
        chevron_code = '\n'.join([''.join(['>> ', line]) for line in chevron_code])

        if 'dedent' in self.options:
            lines = code.split('\n')
            lines = dedent_lines(lines, self.options['dedent'])
            code = '\n'.join([lines])

        lines = '\n'.join([chevron_code, text])

        literal = nodes.literal_block(lines, lines)
        # literal['language'] = 'python'
        literal['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options
        literal['classes'] += self.options.get('class', [])
        extra_args = literal['highlight_args'] = {}
        if hl_lines is not None:
            extra_args['hl_lines'] = hl_lines
        if 'lineno-start' in self.options:
            extra_args['linenostart'] = self.options['lineno-start']
        set_source_info(self, literal)

        caption = self.options.get('caption')
        if caption:
            self.options.setdefault('name', nodes.fully_normalize_name(caption))
            literal = container_wrapper(self, literal, caption)

        self.add_name(literal)

        return [literal]
Beispiel #28
0
    def create_section(self, title, content, parent_ids):
        ids = parent_ids + '-' + nodes.fully_normalize_name(title)
        section_node = nodes.section(ids=[ids])

        par_node, messages = self.create_paragraph(content)
        title_node = self.create_subtitle(title)
        section_node += title_node
        section_node += par_node
        return section_node, messages
Beispiel #29
0
    def run(self):
        oldStdout, sys.stdout = sys.stdout, StringIO()

        tab_width = self.options.get('tab-width', self.state.document.settings.tab_width)
        source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1)

        try:
            code = '\n'.join(self.content)
            exec(code)
            text = sys.stdout.getvalue()
        except Exception:
            return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text = str(sys.exc_info()[1])))]
        finally:
            sys.stdout = oldStdout

        linespec = self.options.get('emphasize-lines')
        if linespec:
            try:
                nlines = len(self.content)
                hl_lines = [x+1 for x in parselinenos(linespec, nlines)]
            except ValueError as err:
                document = self.state.document
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        chevron_code = code.split('\n')
        chevron_code = [c for c in chevron_code if '#hide' not in c]
        chevron_code = '\n'.join([''.join(['>> ', line]) for line in chevron_code])

        if 'dedent' in self.options:
            lines = code.split('\n')
            lines = dedent_lines(lines, self.options['dedent'])
            code = '\n'.join([lines])

        lines = '\n'.join([chevron_code, text])

        literal = nodes.literal_block(lines, lines)
        # literal['language'] = 'python'
        literal['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options
        literal['classes'] += self.options.get('class', [])
        extra_args = literal['highlight_args'] = {}
        if hl_lines is not None:
            extra_args['hl_lines'] = hl_lines
        if 'lineno-start' in self.options:
            extra_args['linenostart'] = self.options['lineno-start']
        set_source_info(self, literal)

        caption = self.options.get('caption')
        if caption:
            self.options.setdefault('name', nodes.fully_normalize_name(caption))
            literal = container_wrapper(self, literal, caption)

        self.add_name(literal)

        return [literal]
Beispiel #30
0
 def add(self, text):
     ids = make_id(text)
     if ids in self.refs:
         raise ValueError("adding a duplicate reference: {}".format(text))
     else:
         name = fully_normalize_name(text)
         ref = Reference(text=text, ids=ids, names=name)
         self.refs[ids] = ref
         return ref
Beispiel #31
0
 def extract_bibliographic(self, field_list):
     docinfo = nodes.docinfo()
     bibliofields = self.language.bibliographic_fields
     labels = self.language.labels
     topics = {"dedication": None, "abstract": None}
     for field in field_list:
         try:
             name = field[0][0].astext()
             normedname = nodes.fully_normalize_name(name)
             if not (
                 len(field) == 2
                 and normedname in bibliofields
                 and self.check_empty_biblio_field(field, name)
             ):
                 raise TransformError
             canonical = bibliofields[normedname]
             biblioclass = self.biblio_nodes[canonical]
             if issubclass(biblioclass, nodes.TextElement):
                 if not self.check_compound_biblio_field(field, name):
                     raise TransformError
                 utils.clean_rcs_keywords(
                     field[1][0], self.rcs_keyword_substitutions
                 )
                 docinfo.append(biblioclass("", "", *field[1][0]))
             elif issubclass(biblioclass, nodes.authors):
                 self.extract_authors(field, name, docinfo)
             elif issubclass(biblioclass, nodes.topic):
                 if topics[canonical]:
                     field[-1] += self.document.reporter.warning(
                         'There can only be one "%s" field.' % name, base_node=field
                     )
                     raise TransformError
                 title = nodes.title(name, labels[canonical])
                 title[0].rawsource = labels[canonical]
                 topics[canonical] = biblioclass(
                     "", title, classes=[canonical], *field[1].children
                 )
             else:
                 docinfo.append(biblioclass("", *field[1].children))
         except TransformError:
             if len(field[-1]) == 1 and isinstance(field[-1][0], nodes.paragraph):
                 utils.clean_rcs_keywords(
                     field[-1][0], self.rcs_keyword_substitutions
                 )
             # if normedname not in bibliofields:
             classvalue = nodes.make_id(normedname)
             if classvalue:
                 field["classes"].append(classvalue)
             docinfo.append(field)
     nodelist = []
     if len(docinfo) != 0:
         nodelist.append(docinfo)
     for name in ("dedication", "abstract"):
         if topics[name]:
             nodelist.append(topics[name])
     return nodelist
Beispiel #32
0
    def run(self):
        env = self.state.document.settings.env
        definitions = env.numbered_blocks_definitions
        head, tail = definitions[self.name]['wrap-content'].split('%s')
        head = nodes.raw(head, head, format='html')
        tail = nodes.raw(tail, tail, format='html')

        if 'name' in self.options and len(self.options['name'].split('+')) > 1:
            env.app.warn("Invalid '+' in name '%s'" % self.options['name'])

        node = numbered_block(**self.options)
        if 'id' in self.options:
            id = nodes.fully_normalize_name(self.options['id'])
        else:
            id = "%s-%d" % (self.name, env.new_serialno(self.name))

        node['ids'] = [id]
        node['classes'].append('numbered-block')
        node['classes'].append(self.name)
        node['type'] = self.name
        numbered = self.numbered()
        node['numbered'] = numbered

        if not numbered:
            node['classes'].append('nonumber')

        self.add_name(node)
        self.state.nested_parse(self.content, self.content_offset, node)

        # Add title nodes
        messages = []
        if self.arguments or numbered:
            title = numbered_block_title()

            if self.arguments:
                title_text = definitions[
                    self.name]['title-format'] % self.arguments[0]
                title_nodes, messages = self.state.inline_text(title_text, 0)
                for title_node in title_nodes:
                    title.append(title_node)

                if numbered:
                    title.insert(
                        0,
                        nodes.inline('',
                                     definitions[self.name]['title-separator'],
                                     classes=['separator']))

            if definitions[self.name]['title-position'] == 'bottom':
                node.append(title)
            else:
                node.insert(0, title)

        node.insert(0, head)
        node.append(tail)
        return [node] + messages
Beispiel #33
0
 def new_run(self: ClickDirective):
     section_title: str = self.options.get("section-title")
     sections = old_run(self)
     if section_title:
         attrs = sections[0].attributes  # section node attributes
         attrs["ids"] = [nodes.make_id(section_title)]
         attrs["names"] = [nodes.fully_normalize_name(section_title)]
         title = sections[0][0]  # title node
         title.replace_self(nodes.title(text=section_title))
     return sections
Beispiel #34
0
def make_citation(label, text, settings):
    name = fully_normalize_name(label)
    citation = nodes.citation(text)
    citation += nodes.label('', label)
    new_doc = new_document('temp-string', settings)
    parser = Parser()
    parser.parse(text, new_doc)
    citation['names'].append(name)
    citation += new_doc.children
    return citation
    def publish(self):
        Publisher.publish(self)

        # set names and ids attribute to section node
        from docutils import nodes
        for section in self.document.traverse(nodes.section):
            titlenode = section[0]
            name = nodes.fully_normalize_name(titlenode.astext())
            section['names'].append(name)
            self.document.note_implicit_target(section, section)
Beispiel #36
0
def make_citation(label, text, settings):
    name = fully_normalize_name(label)
    citation = nodes.citation(text)
    citation += nodes.label('', label)
    new_doc = new_document('temp-string', settings)
    parser = Parser()
    parser.parse(text, new_doc)
    citation['names'].append(name)
    citation += new_doc.children
    return citation
Beispiel #37
0
def register_sections_as_label(app, document):
    labels = app.env.domaindata['std']['labels']
    anonlabels = app.env.domaindata['std']['anonlabels']
    for node in document.traverse(nodes.section):
        labelid = node['ids'][0]
        docname = app.env.docname
        if app.config.autosectionlabel_prefix_document:
            name = nodes.fully_normalize_name(docname + ':' + node[0].astext())
        else:
            name = nodes.fully_normalize_name(node[0].astext())
        sectname = clean_astext(node[0])

        if name in labels:
            logger.warning('duplicate label %s, ' % name + 'other instance '
                           'in ' + app.env.doc2path(labels[name][0]),
                           location=node)

        anonlabels[name] = docname, labelid
        labels[name] = docname, labelid, sectname
Beispiel #38
0
 def depart_reference(self, node):
   # todo: this is a bit of a hack... if this is an inline reference,
   #       i'm artificially inserting the "TEXT <URI>" output, and
   #       expecting the default handler to wrap it in "`...`_" --
   #       instead, there should be a helper method.
   sibs = list(node.parent)
   idx  = sibs.index(node)
   fmt  = None
   # todo: the ".lower()" is a little disconcerting here... is there
   #       a better way?...
   #       ==> perhaps use `nodes.fully_normalize_name()`
   if idx + 1 < len(sibs) \
       and isinstance(sibs[idx + 1], nodes.target) \
       and node['name'].lower() in sibs[idx + 1]['names'] \
       and sibs[idx + 1].referenced == 1:
     text = self._popOutput().data().strip()
     self._pushOutput()
     self.output.append('{text} <{uri}>'.format(
       text = text,
       uri  = rstEscape(node.get('refuri', node.get('refid', '')))))
   else:
     if 'refuri' in node:
       if plaintexturi_cre.match(node['refuri']):
         text = self._popOutput().data()
         if node['refuri'] in (text, 'mailto:' + text):
           self.output.append(text)
           return
         self._pushOutput()
         self.output.append(text)
         if 'name' in node and nodes.make_id(node['name']) not in self.document.ids:
           if not node.get('anonymous'):
             self.output.append(' <{uri}>'.format(uri=rstEscape(node.get('refuri'))))
           fmt = 'anonymous_reference'
     elif 'refid' in node:
       refid = node['refid']
       if refid in self.document.ids:
         if node.get('anonymous'):
           fmt = 'anonymous_reference'
       else:
         text = self._popOutput().data().strip()
         if text != node.get('name', ''):
           self.document.reporter.warning(
             'implicit reference text does not match reference name... ignoring ref-name')
         if nodes.fully_normalize_name(text) \
             not in self.document.ids[refid].get('names', []):
           self.document.reporter.error(
             'implicit reference text does not match target name... ignoring')
         self._pushOutput()
         self.output.append(text)
     else:
       self.document.reporter.warning(
         'reference with neither ref-uri nor ref-id... ignoring')
       self._pushOutput()
       self.output.append(text)
   return self.default_departure(node, fmt=fmt)
Beispiel #39
0
    def add_name(self, node):
        """Append self.options['name'] to node['names'] if it exists.

        Also normalize the name string and register it as explicit target.
        """
        if 'name' in self.options:
            name = nodes.fully_normalize_name(self.options.pop('name'))
            if 'name' in node:
                del (node['name'])
            node['names'].append(name)
            self.state.document.note_explicit_target(node, node)
Beispiel #40
0
    def add_name(self, node):
        """Append self.options['name'] to node['names'] if it exists.

        Also normalize the name string and register it as explicit target.
        """
        if "name" in self.options:
            name = nodes.fully_normalize_name(self.options.pop("name"))
            if "name" in node:
                del node["name"]
            node["names"].append(name)
            self.renderer.document.note_explicit_target(node, node)
Beispiel #41
0
def register_sections_as_label(app, document):
    # type: (Sphinx, nodes.Node) -> None
    labels = app.env.domaindata['std']['labels']
    anonlabels = app.env.domaindata['std']['anonlabels']
    for node in document.traverse(nodes.section):
        labelid = node['ids'][0]
        docname = app.env.docname
        if app.config.autosectionlabel_prefix_document:
            name = nodes.fully_normalize_name(docname + ':' + node[0].astext())
        else:
            name = nodes.fully_normalize_name(node[0].astext())
        sectname = clean_astext(node[0])

        if name in labels:
            logger.warning('duplicate label %s, ' % name + 'other instance '
                           'in ' + app.env.doc2path(labels[name][0]),
                           location=node)

        anonlabels[name] = docname, labelid
        labels[name] = docname, labelid, sectname
Beispiel #42
0
    def add_name(self, node: nodes.Node, name: str):
        """Append name to node['names'].

        Also normalize the name string and register it as explicit target.
        """
        name = nodes.fully_normalize_name(name)
        if "name" in node:
            del node["name"]
        node["names"].append(name)
        self.document.note_explicit_target(node, node)
        return name
    def add_name(self, node):
        """Append self.options['name'] to node['names'] if it exists.

        Also normalize the name string and register it as explicit target.
        """
        if "name" in self.options:
            name = nodes.fully_normalize_name(self.options.pop("name"))
            if "name" in node:
                del (node["name"])
            node["names"].append(name)
            self.state.document.note_explicit_target(node, node)
Beispiel #44
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)
def register_sections_as_label(app, document):
    # type: (Sphinx, nodes.Node) -> None
    labels = app.env.domaindata['std']['labels']
    anonlabels = app.env.domaindata['std']['anonlabels']
    for node in document.traverse(nodes.section):
        labelid = node['ids'][0]
        docname = app.env.docname
        title = cast(nodes.title, node[0])
        ref_name = getattr(title, 'rawsource', title.astext())
        if app.config.autosectionlabel_prefix_document:
            name = nodes.fully_normalize_name(docname + ':' + ref_name)
        else:
            name = nodes.fully_normalize_name(ref_name)
        sectname = clean_astext(title)

        if name in labels:
            logger.warning(__('duplicate label %s, other instance in %s'),
                           name, app.env.doc2path(labels[name][0]),
                           location=node)

        anonlabels[name] = docname, labelid
        labels[name] = docname, labelid, sectname
Beispiel #46
0
    def depart_heading(self, _):
        """Finish establishing section

        Wrap up title node, but stick in the section node. Add the section names
        based on all the text nodes added to the title.
        """
        assert isinstance(self.current_node, nodes.title)
        # The title node has a tree of text nodes, use the whole thing to
        # determine the section id and names
        name = nodes.fully_normalize_name(self.current_node.astext())
        section = self.current_node.parent
        section['names'].append(name)
        self.document.note_implicit_target(section, section)
        self.current_node = section
Beispiel #47
0
 def extract_bibliographic(self, field_list):
     docinfo = nodes.docinfo()
     bibliofields = self.language.bibliographic_fields
     labels = self.language.labels
     topics = {'dedication': None, 'abstract': None}
     for field in field_list:
         try:
             name = field[0][0].astext()
             normedname = nodes.fully_normalize_name(name)
             if not (len(field) == 2 and normedname in bibliofields
                     and self.check_empty_biblio_field(field, name)):
                 raise TransformError
             canonical = bibliofields[normedname]
             biblioclass = self.biblio_nodes[canonical]
             if issubclass(biblioclass, nodes.TextElement):
                 if not self.check_compound_biblio_field(field, name):
                     raise TransformError
                 utils.clean_rcs_keywords(
                       field[1][0], self.rcs_keyword_substitutions)
                 docinfo.append(biblioclass('', '', *field[1][0]))
             elif issubclass(biblioclass, nodes.authors):
                 self.extract_authors(field, name, docinfo)
             elif issubclass(biblioclass, nodes.topic):
                 if topics[canonical]:
                     field[-1] += self.document.reporter.warning(
                         'There can only be one "%s" field.' % name,
                         base_node=field)
                     raise TransformError
                 title = nodes.title(name, labels[canonical])
                 topics[canonical] = biblioclass(
                     '', title, classes=[canonical], *field[1].children)
             else:
                 docinfo.append(biblioclass('', *field[1].children))
         except TransformError:
             if len(field[-1]) == 1 \
                    and isinstance(field[-1][0], nodes.paragraph):
                 utils.clean_rcs_keywords(
                     field[-1][0], self.rcs_keyword_substitutions)
             if normedname not in bibliofields:
                 classvalue = nodes.make_id(normedname)
                 if classvalue:
                     field['classes'].append(classvalue)
             docinfo.append(field)
     nodelist = []
     if len(docinfo) != 0:
         nodelist.append(docinfo)
     for name in ('dedication', 'abstract'):
         if topics[name]:
             nodelist.append(topics[name])
     return nodelist
Beispiel #48
0
    def _generate_nodes(self,
                        name,
                        command,
                        parent=None,
                        show_nested=False,
                        commands=None):
        """Generate the relevant Sphinx nodes.

        Format a `click.Group` or `click.Command`.

        :param name: Name of command, as used on the command line
        :param command: Instance of `click.Group` or `click.Command`
        :param parent: Instance of `click.Context`, or None
        :param show_nested: Whether subcommands should be included in output
        :param commands: Display only listed commands or skip the section if
            empty
        :returns: A list of nested docutil nodes
        """
        ctx = click.Context(command, info_name=name, parent=parent)

        # Title

        section = nodes.section(
            '',
            nodes.title(text=name),
            ids=[nodes.make_id(ctx.command_path)],
            names=[nodes.fully_normalize_name(ctx.command_path)])

        # Summary

        source_name = ctx.command_path
        result = statemachine.ViewList()

        lines = _format_command(ctx, show_nested, commands)
        for line in lines:
            result.append(line, source_name)

        self.state.nested_parse(result, 0, section)

        # Subcommands

        if show_nested:
            commands = _filter_commands(ctx, commands)
            for command in commands:
                section.extend(
                    self._generate_nodes(command.name, command, ctx,
                                         show_nested))

        return [section]
Beispiel #49
0
    def section(self, block):
        new_section = nodes.section()
        new_section.line = block.start_line
        new_section['level'] = block.level

        title_node = nodes.title()
        title_node.line = block.start_line
        append_inlines(title_node, block.inline_content)
        new_section.append(title_node)
        name = nodes.fully_normalize_name(title_node.astext())
        new_section['names'].append(name)
        self.current_node.document.note_implicit_target(new_section, new_section)

        self.section_handler.add_new_section(new_section, block.level)
        self.current_node = new_section
Beispiel #50
0
def register_sections_as_label(app, document):
    labels = app.env.domaindata['std']['labels']
    anonlabels = app.env.domaindata['std']['anonlabels']
    for node in document.traverse(nodes.section):
        name = nodes.fully_normalize_name(node[0].astext())
        labelid = node['ids'][0]
        docname = app.env.docname
        sectname = clean_astext(node[0])

        if name in labels:
            app.env.warn_node('duplicate label %s, ' % name + 'other instance '
                              'in ' + app.env.doc2path(labels[name][0]), node)

        anonlabels[name] = docname, labelid
        labels[name] = docname, labelid, sectname
Beispiel #51
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
Beispiel #52
0
def make_package_section(tree,parent_name=None):
    """Return a docutils tree constructed from this Package tree
    """
    if parent_name:
        tree_name = "%s.%s"%(parent_name,tree.filename)
    else:
        tree_name = tree.filename
    title = "Package %s"%(tree_name)

    # @@@ Do I really want to normalise (case fold, in particular)
    # the id/name for this section? Python names can legitimately
    # distinguish case, and whilst that's not terribly useful at
    # the file level (since not all OS/filesystems keep such a
    # distinction), it certainly is a valid possibility *within*
    # a file...
    #
    # make_id() produces a name that starts with [a-z] and continues
    # with a-z, 0-9 and hyphen (or something like that).
    #
    # fully_normalize_name() reduces spaces to single spaces (OK),
    # but also lowercases.
    #
    # @@@ Think more on usage here, I guess
    section = nodes.section(CLASS="package",id=nodes.make_id(title),
                            name=nodes.fully_normalize_name(title))
    title = nodes.title(text=title)
    section.append(title)

    # @@@ I'm enforcing an order of modules before non-python files before
    # subpackages here
    #     - do I really care?
    #     - do I want some other way order?
    #     - is this the best way to do it (e.g., I could sort the children
    #       into order first instead)
    for child in tree.children:
        if isinstance(child,Module):
            subsection = make_module_section(child,tree_name)
            section.append(subsection)
    for child in tree.children:
        if isinstance(child,NotPython):
            subsection = make_not_python_section(child,tree_name)
            section.append(subsection)
    for child in tree.children:
        if isinstance(child,Package):
            subsection = make_package_section(child,tree_name)
            section.append(subsection)
    return section
    def _generate_nodes(self, title, command_name, command_class,
                        ignored_opts):
        """Generate the relevant Sphinx nodes.

        This is a little funky. Parts of this use raw docutils nodes while
        other parts use reStructuredText and nested parsing. The reason for
        this is simple: it avoids us having to reinvent the wheel. While raw
        docutils nodes are helpful for the simpler elements of the output,
        they don't provide an easy way to use Sphinx's own directives, such as
        the 'option' directive. Refer to [1] for more information.

        [1] http://www.sphinx-doc.org/en/stable/extdev/markupapi.html

        :param title: Title of command
        :param command_name: Name of command, as used on the command line
        :param command_class: Subclass of :py:class:`cliff.command.Command`
        :param prefix: Prefix to apply before command, if any
        :param ignored_opts: A list of options to exclude from output, if any
        :returns: A list of nested docutil nodes
        """
        command = command_class(None, None)
        parser = command.get_parser(command_name)
        ignored_opts = ignored_opts or []

        # Drop the automatically-added help action
        for action in list(parser._actions):
            for option_string in action.option_strings:
                if option_string in ignored_opts:
                    del parser._actions[parser._actions.index(action)]
                    break

        section = nodes.section(
            '',
            nodes.title(text=title),
            ids=[nodes.make_id(title)],
            names=[nodes.fully_normalize_name(title)])

        source_name = '<{}>'.format(command.__class__.__name__)
        result = statemachine.ViewList()

        for line in _format_parser(parser):
            result.append(line, source_name)

        self.state.nested_parse(result, 0, section)

        return [section]
Beispiel #54
0
    def run(self):
        code = u'\n'.join(self.content)

        linespec = self.options.get('emphasize-lines')
        if linespec:
            try:
                nlines = len(self.content)
                hl_lines = [x+1 for x in parselinenos(linespec, nlines)]
            except ValueError as err:
                document = self.state.document
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        if 'dedent' in self.options:
            lines = code.split('\n')
            lines = dedent_lines(lines, self.options['dedent'])
            code = '\n'.join(lines)

        literal = nodes.literal_block(code, code)
        literal['language'] = self.arguments[0]
        literal['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options
        literal['classes'] += self.options.get('class', [])
        extra_args = literal['highlight_args'] = {}
        if hl_lines is not None:
            extra_args['hl_lines'] = hl_lines
        if 'lineno-start' in self.options:
            extra_args['linenostart'] = self.options['lineno-start']
        set_source_info(self, literal)

        caption = self.options.get('caption')
        if caption:
            self.options.setdefault('name', nodes.fully_normalize_name(caption))
            try:
                literal = container_wrapper(self, literal, caption)
            except ValueError as exc:
                document = self.state.document
                errmsg = _('Invalid caption: %s' % exc[0][0].astext())
                return [document.reporter.warning(errmsg, line=self.lineno)]

        # literal will be note_implicit_target that is linked from caption and numref.
        # when options['name'] is provided, it should be primary ID.
        self.add_name(literal)

        return [literal]
Beispiel #55
0
def image(name, arguments, options, content, lineno,
          content_offset, block_text, state, state_machine):
    if options.has_key('align'):
        # check for align_v values only
        if isinstance(state, states.SubstitutionDef):
            if options['align'] not in align_v_values:
                error = state_machine.reporter.error(
                    'Error in "%s" directive: "%s" is not a valid value for '
                    'the "align" option within a substitution definition.  '
                    'Valid values for "align" are: "%s".'
                    % (name, options['align'], '", "'.join(align_v_values)),
                    nodes.literal_block(block_text, block_text), line=lineno)
                return [error]
        elif options['align'] not in align_h_values:
            error = state_machine.reporter.error(
                'Error in "%s" directive: "%s" is not a valid value for '
                'the "align" option.  Valid values for "align" are: "%s".'
                % (name, options['align'], '", "'.join(align_h_values)),
                nodes.literal_block(block_text, block_text), line=lineno)
            return [error]
    messages = []
    reference = directives.uri(arguments[0])
    options['uri'] = reference
    reference_node = None
    if options.has_key('target'):
        block = states.escape2null(options['target']).splitlines()
        block = [line for line in block]
        target_type, data = state.parse_target(block, block_text, lineno)
        if target_type == 'refuri':
            reference_node = nodes.reference(refuri=data)
        elif target_type == 'refname':
            reference_node = nodes.reference(
                refname=fully_normalize_name(data),
                name=whitespace_normalize_name(data))
            reference_node.indirect_reference_name = data
            state.document.note_refname(reference_node)
        else:                           # malformed target
            messages.append(data)       # data is a system message
        del options['target']
    set_classes(options)
    image_node = nodes.image(block_text, **options)
    if reference_node:
        reference_node += image_node
        return messages + [reference_node]
    else:
        return messages + [image_node]
Beispiel #56
0
def make_not_python_section(tree,parent_name=None):
    """Return a docutils tree constructed from this NotPython (file) sub-tree
    """
    if parent_name:
        tree_name = "%s.%s"%(parent_name,tree.filename)
    else:
        tree_name = tree.filename
    title = "File %s"%(tree_name)

    # @@@ Same considerations on id/name as above
    section = nodes.section(CLASS="file",id=nodes.make_id(title),
                            name=nodes.fully_normalize_name(title))
    title = nodes.title(text=title)
    section.append(title)
    paragraph = nodes.paragraph(text="File ")
    paragraph.append(nodes.literal(text=tree.filename))
    paragraph.append(nodes.Text(" is not a Python module."))
    section.append(paragraph)
    return section
Beispiel #57
0
    def run(self):
        doc = self.state.document
        env = doc.settings.env
        # env.titles doesn't contain the title for env.docname yet
        # and doc.title nor doc['title'] exist yet either
        doctitle = get_title(doc, env)
        
        # needs to be normalized here so that the reference and target agree
        targetid = nodes.fully_normalize_name(self.options['id'])
        titleText = self.options['title']
        # default link text is the title
        reftext = titleText
        # default type is 'text'
        tpe = 'text'
        if 'reftext' in self.options:
            reftext = self.options['reftext']
        if 'type' in self.options:
            tpe = self.options['type']

        # a section+title make the howto have a prominent heading, a link, and entry in a toc
        newsection = make_section(targetid, 'full-howto', doc)
        # title nodes should be the child of a section to work properly
        titlenode = nodes.title(targetid, titleText)
        newsection += titlenode
        # wrap the necessary information for this howto ...
        howto_info = {
            'docname': env.docname,
            'doctitle': doctitle,
            'target': targetid,
            'reftext': reftext,
            'type': tpe,
        }
        if self.content:
            howto_info['content'] = self.content

        # ... and store it in the shared howto list
        if not hasattr(env, 'howto_all_howtos'):
            env.howto_all_howtos = []
        env.howto_all_howtos.append(howto_info)

        # replace the howto directive with the new section, which includes a title/heading
        return [newsection]
Beispiel #58
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
Beispiel #59
0
 def depart_reference(self, node):
   # todo: this is a bit of a hack... if this is an inline reference,
   #       i'm artificially inserting the "TEXT <URI>" output, and
   #       expecting the default handler to wrap it in "`...`_" --
   #       instead, there should be a helper method.
   sibs = list(node.parent)
   idx  = sibs.index(node)
   # todo: the ".lower()" is a little disconcerting here... is there
   #       a better way?...
   if idx + 1 < len(sibs) \
       and isinstance(sibs[idx + 1], nodes.target) \
       and node['name'].lower() in sibs[idx + 1]['names'] \
       and sibs[idx + 1].referenced == 1:
     text = self._popOutput().data().strip()
     self._pushOutput()
     self.output.append('{text} <{uri}>'.format(
       text = text,
       uri  = rstEscape(node.get('refuri', node.get('refid', '')))))
   else:
     if 'refuri' in node:
       if plaintexturi_re.match(node['refuri']):
         text = self._popOutput().data()
         if node['refuri'] in (text, 'mailto:' + text):
           self.output.append(text)
           return
         # doh! something else! revert!...
         # todo: there *must* be a better explanation.
         self._pushOutput()
         self.output.append(text)
     elif 'refid' in node:
       text = self._popOutput().data().strip()
       if text != node.get('name', ''):
         self.document.reporter.warning(
           'implicit reference text does not match reference name... ignoring ref-name')
       if nodes.fully_normalize_name(text) \
           not in self.document.ids[node['refid']].get('names', []):
         self.document.reporter.error(
           'implicit reference text does not match target name... ignoring')
       self._pushOutput()
       self.output.append(text)
   return self.default_departure(node)