Ejemplo n.º 1
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
Ejemplo n.º 2
0
    def _render_service(self, path, service, methods):
        env = self.state.document.settings.env
        service_id = "service-%d" % env.new_serialno('service')
        service_node = nodes.section(ids=[service_id])
        service_node += nodes.title(text='Service at %s' %
                                    service.route_name)
        if service.description is not None:
            service_node += rst2node(_dedent(service.description))

        for method, info in methods.items():
            method_id = '%s-%s' % (service_id, method)
            method_node = nodes.section(ids=[method_id])
            method_node += nodes.title(text=method)

            node = rst2node(_dedent(info['docstring']))
            if node is not None:
                method_node += node

            renderer = info['renderer']
            if renderer == 'simplejson':
                renderer = 'json'

            response = nodes.paragraph()
            response += nodes.strong(text='Response: %s' % renderer)
            method_node += response
            service_node += method_node

        return service_node
Ejemplo n.º 3
0
  def test_ids_generated(self):
    from docutils import utils, nodes
    from docutils.core import publish_from_doctree
    doc = utils.new_document('<program>')
    docsect = nodes.section('')
    docsect['classes'] = ('c1 c2',)
    docsect['ids'] = ('my-test-id',)
    docsect['target-ids'] = ('my-test-id',)
    docsect.append(nodes.title('', '', nodes.Text('Title')))
    docsect.append(nodes.paragraph('', '', nodes.Text('some text.')))
    docsect.append(
      nodes.section(
        '',
        nodes.title('', '', nodes.Text('Sub-Title')),
        nodes.paragraph('', '', nodes.Text('some more text'))))
    doc.append(docsect)
    chk = '''\
.. class:: c1 c2

.. _`my-test-id`:

======
Title
======

some text.

---------
Sub-Title
---------

some more text
'''
    out = publish_from_doctree(doc, writer=rst.Writer())
    self.assertMultiLineEqual(out, chk)
    def depart_Resource(self, node):
        if node['identifier']:
            node.insert(0, nodes.title(text=node['identifier']))
        else:
            node.insert(0, nodes.title(text=node['uri']))

        replace_nodeclass(node, nodes.section)
Ejemplo n.º 5
0
    def formatComponent(self, moduleName, name, X):
        # no class bases available from repository scanner 
        CLASSNAME = self.formatClassStatement(name, X.bases)
        CLASSDOC = self.docString(X.doc)
        INBOXES = self.boxes(name,"Inboxes", X.inboxes)
        OUTBOXES = self.boxes(name,"Outboxes", X.outboxes)
        
        if self.config.includeMethods and len(X.listAllFunctions()):
            METHODS = [ nodes.section('',
                          nodes.title('', 'Methods defined here'),
                          boxright('',
                              nodes.paragraph('', '',
                                  nodes.strong('', nodes.Text("Warning!"))
                              ),
                              nodes.paragraph('', '',
                                  nodes.Text("You should be using the inbox/outbox interface, not these methods (except construction). This documentation is designed as a roadmap as to their functionalilty for maintainers and new component developers.")
                              ),
                          ),
                          * self.formatMethodDocStrings(name,X)
                        )
                      ]
        else:
            METHODS = []

        return \
                nodes.section('',
                * [ nodes.title('', CLASSNAME, ids=["symbol-"+name]) ]
                  + CLASSDOC
                  + [ INBOXES, OUTBOXES ]
                  + METHODS
                  + [ self.formatInheritedMethods(name,X) ]
                )
Ejemplo n.º 6
0
    def _render_service(self, path, service, methods):
        env = self.state.document.settings.env
        service_id = "service-%d" % env.new_serialno('service')
        service_node = nodes.section(ids=[service_id])
        service_node += nodes.title(text='Service at %s' %
                                    service.route_name)

        if service.description is not None:
            service_node += rst2node(_dedent(service.description))

        for method, info in methods.items():
            method_id = '%s-%s' % (service_id, method)
            method_node = nodes.section(ids=[method_id])
            method_node += nodes.title(text=method)

            docstring = info['func'].__doc__ or ""

            if 'validator' in info:
                validators = to_list(info['validator'])
                for validator in validators:
                    if validator.__doc__ is not None:
                        if docstring is not None:
                            docstring += '\n' + validator.__doc__.strip()

            if 'accept' in info:
                accept = info['accept']

                if callable(accept):
                    if accept.__doc__ is not None:
                        docstring += accept.__doc__.strip()
                else:
                    accept = to_list(accept)

                    accept_node = nodes.strong(text='Accepted content types:')
                    node_accept_list = nodes.bullet_list()
                    accept_node += node_accept_list

                    for item in accept:
                        temp = nodes.list_item()
                        temp += nodes.inline(text=item)
                        node_accept_list += temp

                    method_node += accept_node

            node = rst2node(docstring)
            if node is not None:
                method_node += node

            renderer = info['renderer']
            if renderer == 'simplejson':
                renderer = 'json'

            response = nodes.paragraph()

            response += nodes.strong(text='Response: %s' % renderer)
            method_node += response

            service_node += method_node

        return service_node
Ejemplo n.º 7
0
    def render(service, service_id):
        service_node = nodes.section(ids=[service_id])
        title = "%s service" % service.baseRouteName
        service_node += nodes.title(text=title)
        if service.description is not None:
            service_node += create_node(trim(service.description))

        for pattern, route_kw, view_kw, func, schema in service.methods:
            method = route_kw.get('request_method', 'GET')
            method_id = "%s_%s" % (service_id, method)
            method_node = nodes.section(ids=[method_id])
            desc = func.__doc__
            title = None
            if desc:
                # use the first line as title for the endpoint
                sp = desc.split('\n', 1)
                title = sp[0].strip()
                if len(sp) > 1:
                    desc = sp[1].strip()
                else:
                    desc = ''
            if not title:
                title = '%s - %s' % (method, pattern)
            method_node += nodes.title(text=title)
            url = "::\n\n    \n    %s - %s\n\n" % (method, pattern)
            method_node += create_node(url)
            # render description from docstring
            if desc:
                method_node += create_node(trim(desc))

            accept = route_kw.get('accept')
            content_type = route_kw.get('content_type')

            # Render Accept Header documentation
            if accept:
                accept_desc = 'Accept: %s' % accept
                method_node += create_node(accept_desc)
            # Render Content-Type Header documentation
            if content_type:
                content_desc = 'Content-Type: %s' % content_type
                method_node += create_node(content_desc)

            # Render Validator
            if schema:
                schema_id = "%s_%s_%s" % (service_id,
                                          method,
                                          'validator')
                node = nodes.section(ids=[schema_id])
                title = nodes.title(text='Validation Schema')
                node += title
                text = json.dumps(schema, indent=4)
                # indent the text block
                text = '\n    '.join([l for l in text.splitlines()])
                text = '::\n\n    ' + text + '\n\n'
                node += create_node(text)

                method_node += node
            service_node += method_node
        return service_node
Ejemplo n.º 8
0
def print_subcommands(data, nested_content, markDownHelp=False, settings=None):
    """
    Each subcommand is a dictionary with the following keys:

    ['usage', 'action_groups', 'bare_usage', 'name', 'help']

    In essence, this is all tossed in a new section with the title 'name'.
    Apparently there can also be a 'description' entry.
    """

    definitions = map_nested_definitions(nested_content)
    items = []
    if 'children' in data:
        subCommands = nodes.section(ids=["Sub-commands:"])
        subCommands += nodes.title('Sub-commands:', 'Sub-commands:')

        for child in data['children']:
            sec = nodes.section(ids=[child['name']])
            sec += nodes.title(child['name'], child['name'])

            if 'description' in child and child['description']:
                desc = [child['description']]
            elif child['help']:
                desc = [child['help']]
            else:
                desc = ['Undocumented']

            # Handle nested content
            subContent = []
            if child['name'] in definitions:
                classifier, s, subContent = definitions[child['name']]
                if classifier == '@replace':
                    desc = [s]
                elif classifier == '@after':
                    desc.append(s)
                elif classifier == '@before':
                    desc.insert(0, s)

            for element in renderList(desc, markDownHelp):
                sec += element
            sec += nodes.literal_block(text=child['bare_usage'])
            for x in print_action_groups(child, nested_content + subContent, markDownHelp,
                                         settings=settings):
                sec += x

            for x in print_subcommands(child, nested_content + subContent, markDownHelp,
                                       settings=settings):
                sec += x

            if 'epilog' in child and child['epilog']:
                for element in renderList([child['epilog']], markDownHelp):
                    sec += element

            subCommands += sec
        items.append(subCommands)

    return items
Ejemplo n.º 9
0
	def run(self):
		minimal = self.options.get('minimal')
		module = self.arguments[0]
		template_args = {}
		template_args.update(get_authors())
		get_argparser = __import__(str(module), fromlist=[str('get_argparser')]).get_argparser
		parser = get_argparser(AutoManParser)
		if minimal:
			container = nodes.container()
			container += parser.automan_usage(self.options['prog'])
			container += parser.automan_description()
			return [container]
		synopsis_section = nodes.section(
			'',
			nodes.title(text='Synopsis'),
			ids=['synopsis-section'],
		)
		synopsis_section += parser.automan_usage(self.options['prog'])
		description_section = nodes.section(
			'', nodes.title(text='Description'),
			ids=['description-section'],
		)
		description_section += parser.automan_description()
		author_section = nodes.section(
			'', nodes.title(text='Author'),
			nodes.paragraph(
				'',
				nodes.Text('Written by {authors} and contributors. The glyphs in the font patcher are created by {glyphs_author}.'.format(
					**get_authors()
				))
			),
			ids=['author-section']
		)
		issues_url = 'https://github.com/powerline/powerline/issues'
		reporting_bugs_section = nodes.section(
			'', nodes.title(text='Reporting bugs'),
			nodes.paragraph(
				'',
				nodes.Text('Report {prog} bugs to '.format(
					prog=self.options['prog'])),
				nodes.reference(
					issues_url, issues_url,
					refuri=issues_url,
					internal=False,
				),
				nodes.Text('.'),
			),
			ids=['reporting-bugs-section']
		)
		return [synopsis_section, description_section, author_section, reporting_bugs_section]
Ejemplo n.º 10
0
    def build_http_method_section(self, resource, http_method):
        doc = self.get_doc_for_http_method(resource, http_method)
        http_method_func = self.get_http_method_func(resource, http_method)

        # Description text
        returned_nodes = [
            parse_text(self, doc, where='HTTP %s doc' % http_method)
        ]

        # Request Parameters section
        required_fields = getattr(http_method_func, 'required_fields', [])
        optional_fields = getattr(http_method_func, 'optional_fields', [])

        if required_fields or optional_fields:
            all_fields = dict(required_fields)
            all_fields.update(optional_fields)

            fields_section = nodes.section(ids=['%s_params' % http_method])
            returned_nodes.append(fields_section)

            fields_section += nodes.title(text='Request Parameters')

            table = self.build_fields_table(all_fields,
                                            required_fields=required_fields,
                                            show_requirement_labels=True)
            fields_section += table

        # Errors section
        errors = getattr(http_method_func, 'response_errors', [])

        if errors:
            errors_section = nodes.section(ids=['%s_errors' % http_method])
            returned_nodes.append(errors_section)

            errors_section += nodes.title(text='Errors')

            bullet_list = nodes.bullet_list()
            errors_section += bullet_list

            for error in sorted(errors, key=lambda x: x.code):
                item = nodes.list_item()
                bullet_list += item

                paragraph = nodes.paragraph()
                item += paragraph

                paragraph += get_ref_to_error(error)

        return returned_nodes
Ejemplo n.º 11
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
Ejemplo n.º 12
0
Archivo: body.py Proyecto: garinh/cs
def topic(name, arguments, options, content, lineno,
          content_offset, block_text, state, state_machine,
          node_class=nodes.topic):
    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]
    if not content:
        warning = state_machine.reporter.warning(
            'Content block expected for the "%s" directive; none found.'
            % name, nodes.literal_block(block_text, block_text),
            line=lineno)
        return [warning]
    title_text = arguments[0]
    textnodes, messages = state.inline_text(title_text, lineno)
    titles = [nodes.title(title_text, '', *textnodes)]
    # sidebar uses this code
    if options.has_key('subtitle'):
        textnodes, more_messages = state.inline_text(options['subtitle'],
                                                     lineno)
        titles.append(nodes.subtitle(options['subtitle'], '', *textnodes))
        messages.extend(more_messages)
    text = '\n'.join(content)
    node = node_class(text, *(titles + messages))
    node['classes'] += options.get('class', [])
    if text:
        state.nested_parse(content, content_offset, node)
    return [node]
Ejemplo n.º 13
0
 def _section(self, parent, title, id_pattern):
     id = id_pattern % self.resource_type
     section = nodes.section(ids=[id])
     parent.append(section)
     title = nodes.title('', title)
     section.append(title)
     return section
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
def render_cmd(app, node, usage, description):
    title = node.get('title')

    titleid = idregex.sub('-', title).lower()
    section = nodes.section('', ids=[titleid])

    if title:
        section.append(nodes.title(title, title))

    output = "$ {}".format(usage)
    new_node = nodes.literal_block(output, output)
    new_node['language'] = 'text'
    section.append(new_node)

    settings = docutils.frontend.OptionParser(
        components=(docutils.parsers.rst.Parser,)
    ).get_default_values()
    document = docutils.utils.new_document('', settings)
    parser = docutils.parsers.rst.Parser()
    description = inline_literal_regex.sub('``', description)
    description = link_regex.sub(r'`\1 <\2>`_', description)
    description = flag_default_regex.sub(r'\1 (\2)', description)
    parser.parse(description, document)
    for el in document.children:
        section.append(el)

    node.replace_self(section)
Ejemplo n.º 16
0
 def new_subsection(self, level, title, lineno, messages):
     """Append new subsection to document tree. On return, check level."""
     memo = self.memo
     mylevel = memo.section_level
     memo.section_level += 1
     section_node = nodes.section()
     self.parent += section_node
     textnodes, title_messages = self.inline_text(title, lineno)
     titlenode = nodes.title(title, '', *textnodes)
     name = normalize_name(titlenode.astext())
     section_node['names'].append(name)
     section_node += titlenode
     section_node += messages
     section_node += title_messages
     self.document.note_implicit_target(section_node, section_node)
     offset = self.state_machine.line_offset + 1
     absoffset = self.state_machine.abs_line_offset() + 1
     newabsoffset = self.nested_parse(
           self.state_machine.input_lines[offset:], input_offset=absoffset,
           node=section_node, match_titles=1)
     self.goto_line(newabsoffset)
     if memo.section_level <= mylevel: # can't handle next section?
         raise EOFError              # bubble up to supersection
     # reset section_level; next pass will detect it properly
     memo.section_level = mylevel
Ejemplo n.º 17
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]
Ejemplo n.º 18
0
    def visit_admonition(self, node, type=None):
        clss = {
            # ???: 'alert-success',

            'note': 'alert-info',
            'hint': 'alert-info',
            'tip': 'alert-info',
            'seealso': 'alert-go_to',

            'warning': 'alert-warning',
            'attention': 'alert-warning',
            'caution': 'alert-warning',
            'important': 'alert-warning',

            'danger': 'alert-danger',
            'error': 'alert-danger',

            'exercise': 'alert-exercise',
        }
        self.body.append(self.starttag(node, 'div', role='alert', CLASS='alert {}'.format(
            clss.get(type, '')
        )))
        if 'alert-dismissible' in node.get('classes', []):
            self.body.append(
                u'<button type="button" class="close" data-dismiss="alert" aria-label="Close">'
                u'<span aria-hidden="true">&times;</span>'
                u'</button>')
        if type:
            node.insert(0, nodes.title(type, admonitionlabels[type]))
Ejemplo n.º 19
0
    def run(self):
        classes = self.options.get('class', [])
        classes.extend(self.options.get('header_class', '').split(' '))
        self.options['class'] = classes
        set_classes(self.options)

        self.assert_has_content()
        text = '\n'.join(self.content)

        admonition_node = self.node_class(text, **self.options)
        self.add_name(admonition_node)
        if self.node_class is nodes.admonition:
            title_text = self.arguments[0]
            textnodes, messages = self.state.inline_text(title_text,
                                                         self.lineno)
            admonition_node += nodes.title(title_text, '', *textnodes)
            admonition_node += messages
            if not 'classes' in self.options:
                admonition_node['classes'] += [
                    'admonition-' + nodes.make_id(title_text)
                ]

        body = nodes.container(
            classes=self.options.get('body_class', '').split(' ')
        )
        self.state.nested_parse(self.content, self.content_offset, body)
        return [admonition_node, body]
Ejemplo n.º 20
0
    def run(self):
        env = self.state.document.settings.env
        # getting the options
        pkg = self.options['package']
        service_name = self.options.get('service')
        all_services = service_name is None

        # listing the services for the package
        services = self._get_services(pkg)

        if all_services:
            # we want to list all of them
            services_id = "services-%d" % env.new_serialno('services')
            services_node = nodes.section(ids=[services_id])
            services_node += nodes.title(text='Services')

            services_ = [(service.index, path, service, methods) \
                         for (path, service), methods in services.items()]
            services_.sort()

            for _, path, service, methods in services_:
                services_node += self._render_service(path, service, methods)

            return [services_node]
        else:
            # we just want a single service
            #
            # XXX not efficient
            for (path, service), methods in services.items():
                if service.name != service_name:
                    continue
                return [self._render_service(path, service, methods)]
            return []
Ejemplo n.º 21
0
Archivo: html.py Proyecto: LFYG/sphinx
 def visit_admonition(self, node, name=''):
     # type: (nodes.Node, unicode) -> None
     self.body.append(self.starttag(
         node, 'div', CLASS=('admonition ' + name)))
     if name:
         node.insert(0, nodes.title(name, admonitionlabels[name]))
     self.set_first_last(node)
Ejemplo n.º 22
0
Archivo: howto.py Proyecto: 2m/website
def make_title_ref(title_text, link):
    ref = make_reference(' (details)', link)
    t = nodes.Text(title_text)
    # A title can only contain text and inline elements.
    # Therefore, the text and reference elements need to be passed directly
    # as children and not combined in a paragraph or other element.
    return nodes.title('', '', t, ref)
Ejemplo n.º 23
0
    def run(self):

        # largely lifted from the superclass in order to make titles work
        set_classes(self.options)
        # self.assert_has_content()
        text = '\n'.join(self.content)
        admonition_node = self.node_class(text, **self.options)
        self.add_name(admonition_node)

        if self.arguments:
            title_text = self.arguments[0]
            textnodes, messages = self.state.inline_text(title_text,
                                                         self.lineno)
            admonition_node += nodes.title(title_text, '', *textnodes)
            admonition_node += messages
        else:
            # no title, make something up so we have an ID
            title_text = str(hash(' '.join(self.content)))

        if not 'classes' in self.options:
            admonition_node['classes'] += ['admonition-' +
                                           nodes.make_id(title_text)]
        self.state.nested_parse(self.content, self.content_offset,
                                admonition_node)

        return [admonition_node]
Ejemplo n.º 24
0
    def _notes(self, device):
        """Extract and combine notes from a device

        Returns a section, including a title or ``None`` if there are no notes.
        """
        section = nodes.section(ids=[device['name'] + '-notes'],
                                names=[device['name'] + '\\ notes'])
        section += nodes.title(text='Notes')
        result = ViewList()
        has_notes = False
        if 'notes' in device:
            has_notes = True
            for line in device['notes']:
                result.append(line, device['source_file'], device['source_line'])
        if 'mode_info' in device:
            for mode in device['mode_info']:
                if 'notes' in mode:
                    has_notes = True
                    for line in mode['notes']:
                        result.append(line, device['source_file'], device['source_line'])
        if 'cmd_info' in device:
            for cmd in device['cmd_info']:
                if 'notes' in cmd:
                    has_notes = True
                    for line in cmd['notes']:
                        result.append(line, device['source_file'], device['source_line'])

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

        return has_notes and section or None
Ejemplo n.º 25
0
def toctree_directive(dirname, arguments, options, content, lineno,
                      content_offset, block_text, state, state_machine):

    node = nodes.admonition()
    node['classes'] += ['admonition-toctree']
    node += nodes.title('', 'Toctree')

    para = nodes.paragraph('')
    node += para
    
    ul = nodes.bullet_list()
    para += ul
    
    for line in content:
        line = line.strip()
        if not line or line.startswith(':'): continue

        try:
            uri, name = resolve_name(line, state.inliner)
            title = name
            try:
                doc = models.Docstring.on_site.get(name=name)
                if doc.title:
                    title = doc.title
            except models.Docstring.DoesNotExist:
                pass
            entry = nodes.reference('', title, refuri=uri)
        except ValueError:
            entry = nodes.reference('', line, name=line,
                                    refname=':ref:`%s`' % line)

        ul += nodes.list_item('', nodes.paragraph('', '', entry))

    return [node]
Ejemplo n.º 26
0
    def _make_title_node(self, node, increment=True):
        """Generate a new title node for ``node``.

        ``node`` is a ``nextslide`` node. The title will use the node's
        parent's title, or the title specified as an argument.

        """

        parent_title_node = node.parent.next_node(nodes.title)
        nextslide_info = getattr(
            parent_title_node, 'nextslide_info',
            (parent_title_node.astext(), 1),
        )
        nextslide_info = (
            nextslide_info[0],
            nextslide_info[1] + 1,
        )

        if node.args:
            title_text = node.args[0]
        elif 'increment' in node.attributes:
            # autogenerating titles;
            title_text = '%s (%d)' % nextslide_info
        else:
            title_text = nextslide_info[0]

        new_title = nodes.title(
            '',
            title_text,
        )
        new_title.nextslide_info = nextslide_info
        return new_title
Ejemplo n.º 27
0
    def _build_program_options(self, parser, custom_content):
        """
        Build list of program options

        :param parser: pre-configured ArgumentParser instance
        :param custom_content: custom content for options
        :return: node forming program options
        """
        result = nodes.container()
        if self.ignore_option_groups:
            actions = parser._get_positional_actions() + parser._get_optional_actions()
            actions = [a for a in actions if a.help is not SUPPRESS]
            for action in actions:
                cc = [v for k, v in custom_content.items() if k in action.option_strings]
                result.append(self._build_option(parser, action, cc[0] if cc else None))
        else:
            for group in parser._action_groups:
                actions = [a for a in group._group_actions if a.help is not SUPPRESS]
                if actions:
                    title = nodes.title(text=group.title.capitalize())
                    options = nodes.container()
                    for action in actions:
                        cc = [v for k, v in custom_content.items() if k in action.option_strings]
                        options.append(self._build_option(parser, action, cc[0] if cc else None))
                    result.append(nodes.section('', title, options, ids=[group.title.lower()]))
        return result
Ejemplo n.º 28
0
 def apply(self):
     if self.document.form_processor.messages:
         messages = nodes.section()
         messages += nodes.title('','Form messages')
         messages += self.document.form_processor.messages
         self.document += messages
         self.document.form_processor.messages[:] = []
Ejemplo n.º 29
0
    def _construct_main_sections(self, parser):
        """
        Construct Synopsis, Description and Options sections

        :param parser: pre-configured ArgumentParser instance
        :return: list of section nodes
        """
        cc_sections, cc_options = self._get_custom_content()
        result = []
        for section in ['synopsis', 'description', 'options']:
            method = '_build_program_{}'.format(section)
            method = getattr(self, method)
            args = [parser]
            if section == 'options':
                args.append(cc_options)
            title = nodes.title(text=section.upper())
            content = method(*args)
            if section in cc_sections:
                cc = cc_sections[section]
                if cc['action'] == 'append':
                    content.extend(cc['content'].children)
                elif cc['action'] == 'prepend':
                    content[0:0] = cc['content'].children
                elif cc['action'] == 'replace':
                    content[:] = cc['content']
            else:
                # append empty paragraph to ensure separation from consecutive section
                content.append(nodes.paragraph(text=''))
            result.append(nodes.section('', title, content, ids=[section.lower()]))
        return result
Ejemplo n.º 30
0
Archivo: mcq.py Proyecto: JSterbi/cnp3
def html_add_content(app, doctree, docname):
	field_list = doctree.next_node(nodes.field_list)
	task_id = ''
	if field_list:
		for field in field_list.traverse(nodes.field):
			field_name = field.next_node(nodes.field_name).astext()
			if field_name == 'task_id':
				task_id = field.next_node(nodes.field_body).astext()
				field_list.parent.remove(field_list)
	builder = app.builder
	if not hasattr(builder, 'format') or builder.format != 'html':
		return
	h = hashlib.md5(str(doctree)).hexdigest()
	title = ''
	node = doctree
	for t in doctree.traverse(nodes.title):
		title = t.children[0].astext()
		node = t.parent
		break
	section = nodes.section(ids=["checker"], name=["checker"])
	section += nodes.title(text=translations[language]['verify_title'])
	text = u'<div id="results" style="display: none;"></div>'
	if app.config.mcq_inginious_url and task_id:
		text += '<input type="submit" value="' + translations[language]['verify'] + '" id="submit" />'
	section += nodes.raw(format='html', text=text)
	node += section
	js = nodes.raw(format='html')
	js += nodes.Text(u'\n<script type="text/javascript">var language = "' + unicode(language) + '";'
				u' var upload_url = "' + unicode(app.config.mcq_upload_url) + '";'
				u' var hash = "' + unicode(h) + '"; var title = "' + unicode(title) + '";'
				u' var html_title = "' + unicode(app.config.html_title) + '";')
	if app.config.mcq_inginious_url and task_id:
				js += nodes.Text(u' var task_id = "' + unicode(task_id) + '"; var inginious_url = "' + unicode(app.config.mcq_inginious_url) + '";')
	js += nodes.Text(u'</script>');
	doctree += js
Ejemplo n.º 31
0
 def create_title(self, text: str):
     # title nodes may only be inserted as children of section nodes
     return nodes.title(text=text)
Ejemplo n.º 32
0
def title(node):
    """
    A title node. It has no children
    """
    return nodes.title(node.first_child.literal, node.first_child.literal)
Ejemplo n.º 33
0
 def format_path(self, path_doc):
     container = n.section(ids=[n.make_id(path_doc["path"])], names=[])
     container += n.title(text=path_doc["path"])
     container.append(n.paragraph(text=path_doc["description"]))
     container.append(self.format_operation(path_doc["operations"]))
     return container
    def fill_node(self, node, env, tag, p, language_code, targetnode, sharepost):
        """
        Fill the node of an aggregated page.
        """
        # add a label
        suffix_label = self.suffix_label()
        container = nodes.container()
        tnl = [".. _{0}{1}:".format(tag, suffix_label), ""]
        content = StringList(tnl)
        self.state.nested_parse(content, self.content_offset, container)
        node += container

        # id section
        if env is not None:
            mid = int(env.new_serialno('indexblog-u-%s' % p["date"][:4])) + 1
        else:
            mid = -1

        # add title
        sids = "y{0}-{1}".format(p["date"][:4], mid)
        section = nodes.section(ids=[sids])
        section['year'] = p["date"][:4]
        section['blogmid'] = mid
        node += section
        textnodes, messages = self.state.inline_text(p["title"], self.lineno)
        section += nodes.title(p["title"], '', *textnodes)
        section += messages

        # add date and share buttons
        tnl = [":bigger:`::5:{0}`".format(p["date"])]
        if sharepost is not None:
            tnl.append(":sharenet:`{0}`".format(sharepost))
        tnl.append('')
        content = StringList(tnl)
        content = content + self.content

        # parse the content into sphinx directive,
        # it adds it to section
        container = nodes.container()
        # nested_parse_with_titles(self.state, content, paragraph)
        self.state.nested_parse(content, self.content_offset, container)
        section += container

        # final
        p['blogpost'] = node
        self.exe_class = p.copy()
        p["content"] = content
        node['classes'] += ["blogpost"]

        # target
        # self.state.add_target(p['title'], '', targetnode, lineno)

        # index (see site-packages/sphinx/directives/code.py, class Index)
        if self.__class__.add_index:
            # it adds an index
            # self.state.document.note_explicit_target(targetnode)
            indexnode = addnodes.index()
            indexnode['entries'] = ne = []
            indexnode['inline'] = False
            set_source_info(self, indexnode)
            for entry in set(p["keywords"] + p["categories"] + [p["date"]]):
                ne.extend(process_index_entry(entry, tag))  # targetid))
            ns = [indexnode, targetnode, node]
        else:
            ns = [targetnode, node]

        return ns
Ejemplo n.º 35
0
def visit_exercise(self, node):
    self.body.append(self.starttag(node, 'div', CLASS=('admonition exercise')))
    node.insert(0, nodes.title('exercise', 'Exercise'))
    self.set_first_last(node)
Ejemplo n.º 36
0
 def visit_admonition(self, node: Element, name: str = '') -> None:
     self.body.append(
         self.starttag(node, 'div', CLASS=('admonition ' + name)))
     if name:
         node.insert(0, nodes.title(name, admonitionlabels[name]))
     self.set_first_last(node)
Ejemplo n.º 37
0
 def visit_admonition(self, node, name=''):
     self.body.append(self.starttag(
         node, 'div', CLASS=('admonition ' + name)))
     if name and name != 'seealso':
         node.insert(0, nodes.title(name, admonitionlabels[name]))
     self.set_first_last(node)
Ejemplo n.º 38
0
class ErrorDirective(Directive):
    has_content = True
    final_argument_whitespace = True
    option_spec = {
        'instance': directives.unchanged_required,
        'example-data': directives.unchanged,
        'title': directives.unchanged,
    }

    MIMETYPES = [
        'application/json',
    ]

    def run(self):
        try:
            error_obj = self.get_error_object(self.options['instance'])
        except ErrorNotFound, e:
            return e.error_node

        # Add the class's file and this extension to the dependencies.
        self.state.document.settings.env.note_dependency(__file__)
        self.state.document.settings.env.note_dependency(
            sys.modules[error_obj.__module__].__file__)

        docname = 'webapi2.0-error-%s' % error_obj.code
        error_title = self.get_error_title(error_obj)

        targetnode = nodes.target('', '', ids=[docname], names=[docname])
        self.state.document.note_explicit_target(targetnode)
        main_section = nodes.section(ids=[docname])

        # Details section
        main_section += nodes.title(text=error_title)
        main_section += self.build_details_table(error_obj)

        # Example section
        examples_section = nodes.section(ids=['examples'])
        examples_section += nodes.title(text='Examples')
        extra_params = {}

        if 'example-data' in self.options:
            extra_params = json.loads(self.options['example-data'])

        has_examples = False

        for mimetype in self.MIMETYPES:
            headers, data = \
                fetch_response_data(WebAPIResponseError, mimetype,
                                    err=error_obj,
                                    extra_params=extra_params)
            example_node = build_example(headers, data, mimetype)

            if example_node:
                example_section = nodes.section(ids=['example_' + mimetype])
                examples_section += example_section

                example_section += nodes.title(text=mimetype)
                example_section += example_node
                has_examples = True

        if has_examples:
            main_section += examples_section

        return [targetnode, main_section]
Ejemplo n.º 39
0
    def _generate_nodes(self, name, command, parent=None, show_nested=False):
        """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
        """
        ctx = click.Context(command, info_name=name, parent=parent)

        # Title

        # We build this with plain old docutils nodes

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

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

        # Description

        # We parse this as reStructuredText, allowing users to embed rich
        # information in their help messages if they so choose.

        if ctx.command.help:
            for line in statemachine.string2lines(ctx.command.help,
                                                  tab_width=4,
                                                  convert_whitespace=True):
                result.append(line, source_name)

            result.append('', source_name)

        # Summary

        if isinstance(command, click.Command):
            summary = _format_command(ctx, show_nested)
        else:
            # TODO(stephenfin): Do we care to differentiate? Perhaps we
            # shouldn't show usage for groups?
            summary = _format_command(ctx, show_nested)

        for line in summary:
            result.append(line, source_name)

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

        # Commands

        if show_nested:
            commands = getattr(ctx.command, 'commands', {})
            for command_name, command_obj in sorted(commands.items()):
                section.extend(
                    self._generate_nodes(command_name, command_obj, ctx,
                                         show_nested))

        return [section]
Ejemplo n.º 40
0
 def visit_admonition(self, node, name=''):
     # type: (nodes.Element, str) -> None
     self.body.append(
         self.starttag(node, 'div', CLASS=('admonition ' + name)))
     if name:
         node.insert(0, nodes.title(name, admonitionlabels[name]))
Ejemplo n.º 41
0
def visit_gitusernote_html(self, node):
    # it is a simple div with a dedicated CSS class assigned
    self.body.append(
        self.starttag(node, 'div', CLASS=('admonition ' + 'gitusernote')))
    node.insert(0, nodes.title('first', 'Note for Git users'))
Ejemplo n.º 42
0
    def _render_service(self, service):
        service_id = "service-%d" % self.env.new_serialno('service')
        service_node = nodes.section(ids=[service_id])
        service_node += nodes.title(text='Service at %s' % service.path)

        if service.description is not None:
            service_node += rst2node(trim(service.description))

        for method, view, args in service.definitions:
            method_id = '%s-%s' % (service_id, method)
            method_node = nodes.section(ids=[method_id])
            method_node += nodes.title(text=method)

            if is_string(view):
                if 'klass' in args:
                    ob = args['klass']
                    view_ = getattr(ob, view.lower())
                    docstring = trim(view_.__doc__ or "") + '\n'
            else:
                docstring = trim(view.__doc__ or "") + '\n'

            if 'schema' in args:
                schema = args['schema']

                attrs_node = nodes.inline()
                for location in ('header', 'querystring', 'body'):
                    attributes = schema.get_attributes(location=location)
                    if attributes:
                        attrs_node += nodes.inline(text='values in the %s' %
                                                   location)
                        location_attrs = nodes.bullet_list()

                        for attr in attributes:
                            temp = nodes.list_item()
                            desc = "%s : " % attr.name

                            # Get attribute data-type
                            if hasattr(attr, 'type'):
                                attr_type = attr.type
                            elif hasattr(attr, 'typ'):
                                attr_type = attr.typ.__class__.__name__

                            desc += " %s, " % attr_type

                            if attr.required:
                                desc += "required "
                            else:
                                desc += "optional "

                            temp += nodes.inline(text=desc)
                            location_attrs += temp

                        attrs_node += location_attrs
                method_node += attrs_node

            for validator in args.get('validators', ()):
                if validator.__doc__ is not None:
                    docstring += trim(validator.__doc__)

            if 'accept' in args:
                accept = to_list(args['accept'])

                if callable(accept):
                    if accept.__doc__ is not None:
                        docstring += accept.__doc__.strip()
                else:
                    accept_node = nodes.strong(text='Accepted content types:')
                    node_accept_list = nodes.bullet_list()
                    accept_node += node_accept_list

                    for item in accept:
                        temp = nodes.list_item()
                        temp += nodes.inline(text=item)
                        node_accept_list += temp

                    method_node += accept_node

            node = rst2node(docstring)
            DocFieldTransformer(self).transform_all(node)
            if node is not None:
                method_node += node

            renderer = args['renderer']
            if renderer == 'simplejson':
                renderer = 'json'

            response = nodes.paragraph()

            response += nodes.strong(text='Response: %s' % renderer)
            method_node += response

            service_node += method_node

        return service_node
Ejemplo n.º 43
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)

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

        # Title

        item = 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, item)

        # Subcommands

        if not show_nested:
            return [item]

        commands = _filter_commands(ctx, commands)
        commands = self._sort_commands(command, commands)

        for help_section, subcommands in self._group_commands(
                command, commands):
            group_name = help_section.name

            if group_name == doc.UNSECTIONED:

                for subcommand in subcommands:
                    item.extend(
                        self._generate_nodes(subcommand.name, subcommand, ctx,
                                             show_nested))

                self.state.nested_parse(result, 0, item)
                continue

            group_item = nodes.section(
                "",
                nodes.title(text=group_name),
                ids=[nodes.make_id(group_name)],
                names=[nodes.fully_normalize_name(group_name)],
            )

            group_list = statemachine.ViewList()

            # pylint: disable=fixme
            # XXX This is supposed to add documentation lines to each group, but it doesn't seem to work.
            for line in help_section.doc.splitlines():
                group_list.append(line, group_name)

            for subcommand in subcommands:
                group_item.extend(
                    self._generate_nodes(subcommand.name, subcommand, ctx,
                                         show_nested))

            self.state.nested_parse(group_list, 0, group_item)

            item += group_item

        return [item]
Ejemplo n.º 44
0
def process_posts(app, doctree):
    """Process posts and map posted document names to post details in the
    environment."""

    env = app.builder.env
    if app.config.skip_pickling:
        env.topickle = lambda *args: env.warn(
            'index', 'Environment is not being pickled.')
    if not hasattr(env, 'ablog_posts'):
        env.ablog_posts = {}

    post_nodes = list(doctree.traverse(PostNode))
    if not post_nodes:
        return
    pdf = app.config['post_date_format']
    docname = env.docname

    # mark the post as 'orphan' so that
    #   "document isn't included in any toctree" warning is not issued
    app.env.metadata[docname]['orphan'] = True

    blog = Blog(app)
    auto_excerpt = blog.post_auto_excerpt
    multi_post = len(post_nodes) > 1 or blog.post_always_section
    for order, node in enumerate(post_nodes, start=1):
        # print node['excerpt']
        if node['excerpt'] is None:
            node['excerpt'] = auto_excerpt

        if multi_post:
            # section title, and first few paragraphs of the section of post
            # are used when there are more than 1 posts
            section = node
            while True:
                if isinstance(section, nodes.section):
                    break
                section = node.parent
        else:
            section = doctree

        # get updates here, in the section that post belongs to
        # Might there be orphan updates?
        update_nodes = list(section.traverse(UpdateNode))
        update_dates = []
        for un in update_nodes:
            try:
                update = datetime.strptime(un['date'], pdf)
            except ValueError:
                raise ValueError('invalid post update date in: ' + docname)

            un[0].replace_self(
                nodes.title(u'',
                            un[0][0].astext() + u' ' + update.strftime(pdf)))
            # for now, let updates look like note
            un['classes'] = ['note', 'update']

            update_dates.append(update)

        # Making sure that post has a title because all post titles
        # are needed when resolving post lists in documents
        title = node['title']
        if not title:
            for title in section.traverse(nodes.title):
                break
            # A problem with the following is that title may contain pending
            # references, e.g. :ref:`tag-tips`
            title = title.astext()

        # creating a summary here, before references are resolved
        excerpt = []
        if node.children:
            if node['exclude']:
                node.replace_self([])
            else:
                node.replace_self(node.children)
            for child in node.children:
                excerpt.append(child.deepcopy())
        elif node['excerpt']:
            count = 0
            for nod in section.traverse(nodes.paragraph):
                excerpt.append(nod.deepcopy())
                count += 1
                if count >= (node['excerpt'] or 0):
                    break
            node.replace_self([])
        else:
            node.replace_self([])
        nimg = node['image'] or blog.post_auto_image
        if nimg:
            for img, nod in enumerate(section.traverse(nodes.image), start=1):
                if img == nimg:
                    excerpt.append(nod.deepcopy())
                    break
        date = node['date']
        if date:
            try:
                date = datetime.strptime(date, pdf)
            except ValueError:
                raise ValueError('invalid post published date in: ' + docname)
        else:
            date = None

        #update = node['update']
        #if update:
        #    try:
        #        update = datetime.strptime(update, app.config['post_date_format'])
        #    except ValueError:
        #        raise ValueError('invalid post update date in: ' + docname)
        #else:
        #    update = date

        # if docname ends with `index` use folder name to reference the document
        # a potential problem here is that there may be files/folders with the
        #   same name, so issuing a warning when that's the case may be a good idea
        folder, label = os.path.split(docname)
        if label == 'index':
            folder, label = os.path.split(folder)
        if not label:
            label = slugify(title)

        post_name = docname
        section_name = ''

        if multi_post and section.parent is not doctree:
            section_name = section.attributes['ids'][0]
            post_name = docname + '#' + section_name
            label += '-' + section_name
        else:
            # create a reference for the post
            # if it is posting the document
            # ! this does not work for sections
            app.env.domains['std'].data['labels'][label] = (docname, label,
                                                            title)

        if section.parent is doctree:
            section_copy = section[0].deepcopy()
        else:
            section_copy = section.deepcopy()
        # multiple posting may result having post nodes
        for nn in section_copy.traverse(PostNode):
            if nn['exclude']:
                nn.replace_self([])
            else:
                nn.replace_self(node.children)

        postinfo = {
            'docname': docname,
            'section': section_name,
            'order': order,
            'date': date,
            'update': max(update_dates + [date]),
            'title': title,
            'excerpt': excerpt,
            'tags': node['tags'],
            'author': node['author'],
            'category': node['category'],
            'location': node['location'],
            'language': node['language'],
            'redirect': node['redirect'],
            'image': node['image'],
            'exclude': node['exclude'],
            'doctree': section_copy
        }

        if docname not in env.ablog_posts:
            env.ablog_posts[docname] = []
        env.ablog_posts[docname].append(postinfo)

        # instantiate catalogs and collections here
        #  so that references are created and no warnings are issued

        for key in ['tags', 'author', 'category', 'location', 'language']:
            catalog = blog.catalogs[key]
            for label in postinfo[key]:
                catalog[label]
        if postinfo['date']:
            blog.archive[postinfo['date'].year]
Ejemplo n.º 45
0
    def translate(self):
        visitor = PDFTranslator(self.document, self.builder)
        self.document.walkabout(visitor)
        lang = self.config.language or 'en'
        langmod = get_language_available(lang)[2]
        self.docutils_languages = {lang: langmod}

        # Generate Contents topic manually
        if self.use_toc:
            contents = nodes.topic(classes=['contents'])
            contents += nodes.title('')
            contents[0] += nodes.Text(langmod.labels['contents'])
            contents['ids'] = ['Contents']
            pending = nodes.topic()
            contents.append(pending)
            pending.details = {}
            self.document.insert(
                0, nodes.raw(text='SetPageCounter 1 arabic', format='pdf'))
            self.document.insert(
                0,
                nodes.raw(text='OddPageBreak %s' % self.page_template,
                          format='pdf'))
            self.document.insert(0, contents)
            self.document.insert(
                0, nodes.raw(text='SetPageCounter 1 lowerroman', format='pdf'))
            contTrans = PDFContents(self.document)
            contTrans.toc_depth = self.toc_depth
            contTrans.startnode = pending
            contTrans.apply()

        if self.use_coverpage:
            # Generate cover page

            # FIXME: duplicate from createpdf, refactor!
            # Add the Sphinx template paths
            def add_template_path(path):
                return os.path.join(self.srcdir, path)

            jinja_env = jinja2.Environment(
                loader=jinja2.FileSystemLoader([
                    self.srcdir,
                    os.path.expanduser('~/.rst2pdf'),
                    os.path.join(self.PATH, 'templates'),
                ] + list(map(add_template_path, self.config.templates_path))),
                autoescape=jinja2.select_autoescape(['html', 'xml']),
            )

            try:
                template = jinja_env.get_template(
                    self.config.pdf_cover_template)
            except jinja2.TemplateNotFound:
                log.error("Can't find cover template %s, using default" %
                          self.config.pdf_cover_template)
                template = jinja_env.get_template('sphinxcover.tmpl')

            # This is what's used in the python docs because
            # Latex does a manual linebreak. This sucks.
            authors = self.document.settings.author.split('\\')

            # Honour the "today" config setting
            if self.config.today:
                date = self.config.today
            else:
                date = time.strftime(self.config.today_fmt or _('%B %d, %Y'))

            # Feed data to the template, get restructured text.
            cover_text = template.render(
                title=self.document.settings.title
                or visitor.elements['title'],
                subtitle='%s %s' % (_('version'), self.config.version),
                authors=authors,
                date=date,
            )

            cover_tree = docutils.core.publish_doctree(cover_text)
            self.document.insert(0, cover_tree)

        sio = BytesIO()

        if self.invariant:
            createpdf.patch_PDFDate()
            createpdf.patch_digester()

        createpdf.RstToPdf(
            sphinx=True,
            stylesheets=self.stylesheets,
            language=self.__language,
            breaklevel=self.breaklevel,
            breakside=self.breakside,
            fit_mode=self.fitmode,
            font_path=self.fontpath,
            inline_footnotes=self.inline_footnotes,
            highlightlang=self.highlightlang,
            splittables=self.splittables,
            style_path=self.style_path,
            repeat_table_rows=self.repeat_table_rows,
            basedir=self.srcdir,
            def_dpi=self.default_dpi,
            real_footnotes=self.real_footnotes,
            numbered_links=self.use_numbered_links,
            background_fit_mode=self.fit_background_mode,
            baseurl=self.baseurl,
            section_header_depth=self.section_header_depth,
        ).createPdf(doctree=self.document,
                    output=sio,
                    compressed=self.compressed)
        self.output = sio.getvalue()
Ejemplo n.º 46
0
    def run(self):
        """
        Builds the mathdef text.
        """
        # sett = self.state.document.settings
        # language_code = sett.language_code
        lineno = self.lineno

        env = self.state.document.settings.env if hasattr(
            self.state.document.settings, "env") else None
        docname = None if env is None else env.docname
        if docname is not None:
            docname = docname.replace("\\", "/").split("/")[-1]
            legend = "{0}:{1}".format(docname, lineno)
        else:
            legend = ''

        if hasattr(env, "settings") and hasattr(env.settings,
                                                "mathdef_link_number"):
            number_format = env.settings.mathdef_link_number
        elif hasattr(self.state.document.settings, "mathdef_link_number"):
            number_format = self.state.document.settings.mathdef_link_number
        elif hasattr(env, "config") and hasattr(env.config,
                                                "mathdef_link_number"):
            number_format = env.config.mathdef_link_number
        else:
            raise ValueError(
                "mathdef_link_number is not defined in the configuration")

        if not self.options.get('class'):
            self.options['class'] = ['admonition-mathdef']

        # body
        (mathdef, ) = super(MathDef, self).run()
        if isinstance(mathdef, nodes.system_message):
            return [mathdef]

        # add a label
        lid = self.options.get('lid', self.options.get('label', None))
        if lid:
            container = nodes.container()
            tnl = [".. _{0}:".format(lid), ""]
            content = StringList(tnl)
            self.state.nested_parse(content, self.content_offset, container)
        else:
            container = None

        # mid
        mathtag = self.options.get('tag', '').strip()
        if len(mathtag) == 0:
            raise ValueError("tag is empty")
        if env is not None:
            mid = int(env.new_serialno('indexmathe-u-%s' % mathtag)) + 1
        else:
            mid = -1

        # id of the section
        first_letter = mathtag[0].upper()
        number = mid
        try:
            label_number = number_format.format(number=number,
                                                first_letter=first_letter)
        except ValueError as e:
            raise Exception("Unable to interpret format '{0}'.".format(
                number_format)) from e

        # title
        title = self.options.get('title', "").strip()
        if len(title) > 0:
            title = "{0} {1} : {2}".format(mathtag, label_number, title)
        else:
            raise ValueError("title is empty")

        # main node
        ttitle = title
        title = nodes.title(text=_(title))
        if container is not None:
            mathdef.insert(0, title)
            mathdef.insert(0, container)
        else:
            mathdef.insert(0, title)
        mathdef['mathtag'] = mathtag
        mathdef['mathmid'] = mid
        mathdef['mathtitle'] = ttitle
        set_source_info(self, mathdef)

        if env is not None:
            targetid = 'indexmathe-%s%s' % (
                mathtag, env.new_serialno('indexmathe%s' % mathtag))
            ids = [targetid]
            targetnode = nodes.target(legend, '', ids=ids[0])
            set_source_info(self, targetnode)
            try:
                self.state.add_target(targetid, '', targetnode, lineno)
            except Exception as e:
                raise Exception(
                    "Issue in\n  File '{0}', line {1}\ntid={2}\ntnode={3}".
                    format(None if env is None else env.docname, lineno,
                           targetid, targetnode)) from e

            # index node
            index = self.options.get('index', None)
            imposed = ",".join(a for a in [mathtag, ttitle] if a)
            if index is None or len(index.strip()) == 0:
                index = imposed
            else:
                index += "," + imposed
            if index is not None:
                indexnode = addnodes.index()
                indexnode['entries'] = ne = []
                indexnode['inline'] = False
                set_source_info(self, indexnode)
                for entry in index.split(","):
                    ne.extend(process_index_entry(entry, targetid))
            else:
                indexnode = None
        else:
            targetnode = None
            indexnode = None

        return [a for a in [indexnode, targetnode, mathdef] if a is not None]
Ejemplo n.º 47
0
def _create_section_with_title(section_id, title):
    node = nodes.section(ids=[_escape_id(section_id)])
    jobs_title = nodes.title(text=title)
    node.append(jobs_title)
    return node
Ejemplo n.º 48
0
 def run(self):
     node = mongodoc()
     title = 'See general MongoDB documentation'
     node += nodes.title(title, title)
     self.state.nested_parse(self.content, self.content_offset, node)
     return [node]
Ejemplo n.º 49
0
class ResourceDirective(Directive):
    has_content = True
    required_arguments = 0
    option_spec = {
        'classname': directives.unchanged_required,
        'is-list': directives.flag,
        'hide-links': directives.flag,
        'hide-examples': directives.flag,
    }

    item_http_methods = set(['GET', 'DELETE', 'PUT'])
    list_http_methods = set(['GET', 'POST'])

    type_mapping = {
        int: 'Integer',
        str: 'String',
        bool: 'Boolean',
        dict: 'Dictionary',
        file: 'Uploaded File',
    }

    def run(self):
        try:
            resource_class = self.get_resource_class(self.options['classname'])
        except ResourceNotFound, e:
            return e.error_node

        # Add the class's file and this extension to the dependencies.
        self.state.document.settings.env.note_dependency(__file__)
        self.state.document.settings.env.note_dependency(
            sys.modules[resource_class.__module__].__file__)

        resource = get_resource_from_class(resource_class)

        is_list = 'is-list' in self.options

        docname = 'webapi2.0-%s-resource' % \
            get_resource_docname(resource, is_list)
        resource_title = get_resource_title(resource, is_list)

        targetnode = nodes.target('', '', ids=[docname], names=[docname])
        self.state.document.note_explicit_target(targetnode)
        main_section = nodes.section(ids=[docname])

        # Details section
        main_section += nodes.title(text=resource_title)
        main_section += self.build_details_table(resource)

        # Fields section
        if (resource.fields and (not is_list or resource.singleton)):
            fields_section = nodes.section(ids=['fields'])
            main_section += fields_section

            fields_section += nodes.title(text='Fields')
            fields_section += self.build_fields_table(resource.fields)

        # Links section
        if 'hide-links' not in self.options:
            fields_section = nodes.section(ids=['links'])
            main_section += fields_section

            fields_section += nodes.title(text='Links')
            fields_section += self.build_links_table(resource)

        # HTTP method descriptions
        for http_method in self.get_http_methods(resource, is_list):
            method_section = nodes.section(ids=[http_method])
            main_section += method_section

            method_section += nodes.title(text='HTTP %s' % http_method)
            method_section += self.build_http_method_section(
                resource, http_method)

        if 'hide-examples' not in self.options:
            examples_section = nodes.section(ids=['examples'])
            examples_section += nodes.title(text='Examples')

            has_examples = False

            if is_list:
                allowed_mimetypes = resource.allowed_list_mimetypes
            else:
                allowed_mimetypes = resource.allowed_item_mimetypes

            for mimetype in allowed_mimetypes:
                example_node = build_example(
                    self.fetch_resource_data(resource, mimetype), mimetype)

                if example_node:
                    example_section = nodes.section(
                        ids=['example_' + mimetype])
                    examples_section += example_section

                    example_section += nodes.title(text=mimetype)
                    example_section += example_node
                    has_examples = True

            if has_examples:
                main_section += examples_section

        return [targetnode, main_section]
Ejemplo n.º 50
0
    def assemble_doctree(self, indexfile, toctree_only, appendices):
        self.docnames = set([indexfile] + appendices)
        self.info(darkgreen(indexfile) + " ", nonl=1)

        def process_tree(docname, tree):
            tree = tree.deepcopy()
            for toctreenode in tree.traverse(addnodes.toctree):
                newnodes = []
                includefiles = map(str, toctreenode['includefiles'])
                for includefile in includefiles:
                    try:
                        self.info(darkgreen(includefile) + " ", nonl=1)
                        subtree = process_tree(
                            includefile, self.env.get_doctree(includefile))
                        self.docnames.add(includefile)
                    except Exception:
                        self.warn(
                            'toctree contains ref to nonexisting '
                            'file %r' % includefile,
                            self.env.doc2path(docname))
                    else:
                        sof = addnodes.start_of_file(docname=includefile)
                        sof.children = subtree.children
                        newnodes.append(sof)
                toctreenode.parent.replace(toctreenode, newnodes)
            return tree

        tree = self.env.get_doctree(indexfile)
        tree['docname'] = indexfile
        if toctree_only:
            # extract toctree nodes from the tree and put them in a
            # fresh document
            new_tree = new_document('<latex output>')
            new_sect = nodes.section()
            new_sect += nodes.title(u'<Set title in conf.py>',
                                    u'<Set title in conf.py>')
            new_tree += new_sect
            for node in tree.traverse(addnodes.toctree):
                new_sect += node
            tree = new_tree
        largetree = process_tree(indexfile, tree)
        largetree['docname'] = indexfile
        for docname in appendices:
            appendix = self.env.get_doctree(docname)
            appendix['docname'] = docname
            largetree.append(appendix)
        self.info()
        self.info("resolving references...")
        self.env.resolve_references(largetree, indexfile, self)
        # resolve :ref:s to distant tex files -- we can't add a cross-reference,
        # but append the document name
        for pendingnode in largetree.traverse(addnodes.pending_xref):
            docname = pendingnode['refdocname']
            sectname = pendingnode['refsectname']
            newnodes = [nodes.emphasis(sectname, sectname)]
            for subdir, title in self.titles:
                if docname.startswith(subdir):
                    newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
                    newnodes.append(nodes.emphasis(title, title))
                    newnodes.append(nodes.Text(')', ')'))
                    break
            else:
                pass
            pendingnode.replace_self(newnodes)
        return largetree
Ejemplo n.º 51
0
    def run(self):
        filename = self.arguments[0]

        cwd = os.getcwd()
        os.chdir(TMPDIR)

        parts = []
        try:
            ff = AsdfFile()
            code = AsdfFile._open_impl(ff, filename, _get_yaml_content=True)
            code = '{0} {1}\n'.format(ASDF_MAGIC, version_string) + code.strip().decode('utf-8')
            literal = nodes.literal_block(code, code)
            literal['language'] = 'yaml'
            set_source_info(self, literal)
            parts.append(literal)

            with AsdfFile.open(filename) as ff:
                for i, block in enumerate(ff.blocks.internal_blocks):
                    data = codecs.encode(block.data.tostring(), 'hex')
                    if len(data) > 40:
                        data = data[:40] + '...'.encode()
                    allocated = block._allocated
                    size = block._size
                    data_size = block._data_size
                    flags = block._flags

                    if flags & BLOCK_FLAG_STREAMED:
                        allocated = size = data_size = 0

                    lines = []
                    lines.append('BLOCK {0}:'.format(i))

                    human_flags = []
                    for key, val in FLAGS.items():
                        if flags & key:
                            human_flags.append(val)
                    if len(human_flags):
                        lines.append('    flags: {0}'.format(' | '.join(human_flags)))
                    if block.compression:
                        lines.append('    compression: {0}'.format(block.compression))
                    lines.append('    allocated_size: {0}'.format(allocated))
                    lines.append('    used_size: {0}'.format(size))
                    lines.append('    data_size: {0}'.format(data_size))
                    lines.append('    data: {0}'.format(data))

                    code = '\n'.join(lines)

                    literal = nodes.literal_block(code, code)
                    literal['language'] = 'yaml'
                    set_source_info(self, literal)
                    parts.append(literal)

                internal_blocks = list(ff.blocks.internal_blocks)
                if (len(internal_blocks) and
                    internal_blocks[-1].array_storage != 'streamed'):
                    buff = io.BytesIO()
                    ff.blocks.write_block_index(buff, ff)
                    block_index = buff.getvalue()
                    literal = nodes.literal_block(block_index, block_index)
                    literal['language'] = 'yaml'
                    set_source_info(self, literal)
                    parts.append(literal)

        finally:
            os.chdir(cwd)

        result = nodes.admonition()
        textnodes, messages = self.state.inline_text(filename, self.lineno)
        title = nodes.title(filename, '', *textnodes)
        result += title
        result += parts
        return [result]
Ejemplo n.º 52
0
    def _generate_nodes(self,
                        name,
                        command,
                        parent,
                        nested,
                        commands=None,
                        semantic_group=False):
        """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 nested: The granularity of subcommand details.
        :param commands: Display only listed commands or skip the section if
            empty
        :param semantic_group: Display command as title and description for
            CommandCollection.
        :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()

        if semantic_group:
            lines = _format_description(ctx)
        else:
            lines = _format_command(ctx, nested, commands)

        for line in lines:
            LOG.debug(line)
            result.append(line, source_name)

        sphinx_nodes.nested_parse_with_titles(self.state, result, section)

        # Subcommands

        if nested == NESTED_FULL:
            if isinstance(command, click.CommandCollection):
                for source in command.sources:
                    section.extend(
                        self._generate_nodes(source.name,
                                             source,
                                             ctx,
                                             nested,
                                             semantic_group=True))
            else:
                commands = _filter_commands(ctx, commands)
                for command in commands:
                    parent = ctx if not semantic_group else ctx.parent
                    section.extend(
                        self._generate_nodes(command.name, command, parent,
                                             nested))

        return [section]
Ejemplo n.º 53
0
    def run(self):
        secid = [self.arguments[0].lower().replace(' ', '-')]
        section = nodes.section(ids=secid)
        section.document = self.state.document

        section += nodes.title(text=self.arguments[0])

        # parse the 'text' option into the section, as a paragraph.
        self.state.nested_parse(StringList([self.options['text']], parent=self), 0, section)

        node = self.create_progtable()
        section.children[-1] += node

        head = node.children[0].children[-2].children[0]
        body = node.children[0].children[-1]

        comps = collections.OrderedDict()
        cur = ""

        for line in self.content:
            # new list
            nl = re.match(r'^:(?P<component>.+):$', line)
            if nl is not None:
                if cur != "":
                    # finish up shrow
                    self.add_progbar(shrow, len([c for c in comps[cur] if c is True]), len(comps[cur]))

                cur = nl.groupdict()['component']

                if cur not in comps:
                    comps[cur] = []

                # shrow is the section header row
                shrow = self.create_headrow(cur, classes=['field-name'])
                body += shrow

                continue

            nl = re.match(r'^\s+- (?P<item>[^,]+),\s+(?P<value>(True|False))(, (?P<description>.+)$)?', line)
            if nl is not None:
                nl = nl.groupdict()
                comps[cur].append(True if nl['value'] == "True" else False)
                tr = nodes.row()
                tr += nodes.description('',
                                        nodes.inline(text="\u2713" if comps[cur][-1] else " "),
                                        classes=['field-name', 'progress-checkbox'])
                tr += nodes.description('',
                                        nodes.strong(text='{:s} '.format(nl['item'])),
                                        nodes.inline(text='{:s}'.format(nl['description'] if nl['description'] is not None else ' ')),
                                        classes=['field-value'])
                body += tr

        if self.content:
            # finish up the final hrow
            self.add_progbar(shrow, len([c for c in comps[cur] if c == True]), len(comps[cur]))


        # and fill in the end of mrow
        self.add_progbar(head, len([c for r in comps.values() for c in r if c == True]), len([c for r in comps.values() for c in r]))


        return [section]
Ejemplo n.º 54
0
 def _construct_manpage_specific_structure(self, parser_info):
     """
     Construct a typical man page consisting of the following elements:
         NAME (automatically generated, out of our control)
         SYNOPSIS
         DESCRIPTION
         OPTIONS
         FILES
         SEE ALSO
         BUGS
     """
     # SYNOPSIS section
     synopsis_section = nodes.section(
         '',
         nodes.title(text='Synopsis'),
         nodes.literal_block(text=parser_info["bare_usage"]),
         ids=['synopsis-section'])
     # DESCRIPTION section
     description_section = nodes.section(
         '',
         nodes.title(text='Description'),
         nodes.paragraph(text=parser_info.get(
             'description',
             parser_info.get('help', "undocumented").capitalize())),
         ids=['description-section'])
     nested_parse_with_titles(self.state, self.content, description_section)
     if parser_info.get('epilog'):
         # TODO: do whatever sphinx does to understand ReST inside
         # docstrings magically imported from other places. The nested
         # parse method invoked above seem to be able to do this but
         # I haven't found a way to do it for arbitrary text
         description_section += nodes.paragraph(text=parser_info['epilog'])
     # OPTIONS section
     options_section = nodes.section('',
                                     nodes.title(text='Options'),
                                     ids=['options-section'])
     if 'args' in parser_info:
         options_section += nodes.paragraph()
         options_section += nodes.subtitle(text='Positional arguments:')
         options_section += self._format_positional_arguments(parser_info)
     if 'options' in parser_info:
         options_section += nodes.paragraph()
         options_section += nodes.subtitle(text='Optional arguments:')
         options_section += self._format_optional_arguments(parser_info)
     items = [
         # NOTE: we cannot generate NAME ourselves. It is generated by
         # docutils.writers.manpage
         synopsis_section,
         description_section,
         # TODO: files
         # TODO: see also
         # TODO: bugs
     ]
     if len(options_section.children) > 1:
         items.append(options_section)
     if 'nosubcommands' not in self.options:
         # SUBCOMMANDS section (non-standard)
         subcommands_section = nodes.section(
             '',
             nodes.title(text='Sub-Commands'),
             ids=['subcommands-section'])
         if 'children' in parser_info:
             subcommands_section += self._format_subcommands(parser_info)
         if len(subcommands_section) > 1:
             items.append(subcommands_section)
     if os.getenv("INCLUDE_DEBUG_SECTION"):
         import json
         # DEBUG section (non-standard)
         debug_section = nodes.section(
             '',
             nodes.title(text="Argparse + Sphinx Debugging"),
             nodes.literal_block(text=json.dumps(parser_info, indent='  ')),
             ids=['debug-section'])
         items.append(debug_section)
     return items
Ejemplo n.º 55
0
    def create_title_node(self, traceable):
        title_content = self.create_title_content(traceable)
        title_node = nodes.title(traceable.tag, "", title_content)

        return [title_node]
Ejemplo n.º 56
0
 def create_section(self, title):
     section = nodes.section(ids=[title])
     section += nodes.title(title, title)
     return section
Ejemplo n.º 57
0
    def _build_grade_table(self, matrix, content):

        summarytitle = nodes.title(text="Backends -  Summary")
        summary = nodes.table()
        cols = len(list(six.iterkeys(matrix.backends)))
        cols += 2
        summarygroup = nodes.tgroup(cols=cols)
        summarybody = nodes.tbody()
        summaryhead = nodes.thead()

        for i in range(cols):
            summarygroup.append(nodes.colspec(colwidth=1))
        summarygroup.append(summaryhead)
        summarygroup.append(summarybody)
        summary.append(summarygroup)
        content.append(summarytitle)
        content.append(summary)

        header = nodes.row()
        blank = nodes.entry()
        blank.append(nodes.strong(text="Backend"))
        header.append(blank)

        blank = nodes.entry()
        blank.append(nodes.strong(text="Status"))
        header.append(blank)

        blank = nodes.entry()
        blank.append(nodes.strong(text="Type"))
        header.append(blank)

        blank = nodes.entry()
        blank.append(nodes.strong(text="In Tree"))
        header.append(blank)

        blank = nodes.entry()
        blank.append(nodes.strong(text="Notes"))
        header.append(blank)
        summaryhead.append(header)

        grades = matrix.grades
        impls = list(six.iterkeys(matrix.backends))
        impls.sort()
        for grade in grades:
            for backend in impls:
                if matrix.backends[backend].status == grade.key:
                    item = nodes.row()
                    namecol = nodes.entry()
                    namecol.append(
                        nodes.paragraph(text=matrix.backends[backend].title))
                    item.append(namecol)

                    statuscol = nodes.entry()
                    statuscol.append(nodes.paragraph(text=grade.title))
                    item.append(statuscol)

                    typecol = nodes.entry()
                    typecol.append(
                        nodes.paragraph(text=matrix.backends[backend].type))
                    item.append(typecol)

                    if bool(matrix.backends[backend].in_tree):
                        status = u"\u2714"
                    else:
                        status = u"\u2716"

                    intreecol = nodes.entry()
                    intreecol.append(nodes.paragraph(text=status))
                    item.append(intreecol)

                    notescol = nodes.entry()
                    notescol.append(
                        nodes.paragraph(text=matrix.backends[backend].notes))
                    item.append(notescol)

                    summarybody.append(item)

        return content
Ejemplo n.º 58
0
    def run(self):
        self.env = self.state.document.settings.env
        self.app = self.env.app

        # Make sure we have some content, which should be yaml that
        # defines some parameters.
        if not self.content:
            error = self.state_machine.reporter.error(
                'No parameters defined',
                nodes.literal_block(self.block_text, self.block_text),
                line=self.lineno)
            return [error]

        if not len(self.arguments) >= 2:
            error = self.state_machine.reporter.error(
                '%s' % self.arguments,
                nodes.literal_block(self.block_text, self.block_text),
                line=self.lineno)
            return [error]

        _, status_defs_file = self.env.relfn2path(self.arguments.pop())
        status_type = self.arguments.pop()

        self.status_defs = self._load_status_file(status_defs_file)

        # self.app.info("%s" % str(self.status_defs))

        if status_type not in self.status_types:
            error = self.state_machine.reporter.error(
                'Type %s is not one of %s' % (status_type, self.status_types),
                nodes.literal_block(self.block_text, self.block_text),
                line=self.lineno)
            return [error]

        self.yaml = self._load_codes()

        self.max_cols = len(self.headers)
        # TODO(sdague): it would be good to dynamically set column
        # widths (or basically make the colwidth thing go away
        # entirely)
        self.options['widths'] = [30, 70]
        self.col_widths = self.get_column_widths(self.max_cols)
        if isinstance(self.col_widths, tuple):
            # In docutils 0.13.1, get_column_widths returns a (widths,
            # colwidths) tuple, where widths is a string (i.e. 'auto').
            # See https://sourceforge.net/p/docutils/patches/120/.
            self.col_widths = self.col_widths[1]
        # Actually convert the yaml
        title, messages = self.make_title()
        # self.app.info("Title %s, messages %s" % (title, messages))
        table_node = self.build_table()
        self.add_name(table_node)

        title_block = nodes.title(
            text=status_type.capitalize())

        section = nodes.section(ids=title_block)
        section += title_block
        section += table_node

        return [section] + messages
Ejemplo n.º 59
0
class ResourceDirective(Directive):
    has_content = True
    required_arguments = 0
    option_spec = {
        'classname': directives.unchanged_required,
        'is-list': directives.flag,
        'hide-links': directives.flag,
        'hide-examples': directives.flag,
    }

    item_http_methods = set(['GET', 'DELETE', 'PUT'])
    list_http_methods = set(['GET', 'POST'])

    FILTERED_MIMETYPES = [
        'application/json',
        'application/xml',
    ]

    def run(self):
        try:
            resource_class = self.get_resource_class(self.options['classname'])
        except ResourceNotFound, e:
            return e.error_node

        # Add the class's file and this extension to the dependencies.
        env = self.state.document.settings.env
        env.note_dependency(__file__)
        env.note_dependency(sys.modules[resource_class.__module__].__file__)

        resource = get_resource_from_class(resource_class)

        is_list = 'is-list' in self.options

        docname = 'webapi2.0-%s-resource' % \
            get_resource_docname(env.app, resource, is_list)
        resource_title = get_resource_title(resource, is_list)

        targetnode = nodes.target('', '', ids=[docname], names=[docname])
        self.state.document.note_explicit_target(targetnode)
        main_section = nodes.section(ids=[docname])

        # Main section
        main_section += nodes.title(text=resource_title)

        for attr_name, text_fmt in (('added_in', 'Added in %s'),
                                    ('deprecated_in', 'Deprecated in %s'),
                                    ('removed_in', 'Removed in %s')):
            version = getattr(resource, attr_name, None)

            if not version:
                if is_list:
                    prefix = 'list_resource'
                else:
                    prefix = 'item_resource'

                version = getattr(resource, '%s_%s' % (prefix, attr_name),
                                  None)

            if version:
                paragraph = nodes.paragraph()
                paragraph += nodes.emphasis(text=text_fmt % version,
                                            classes=['resource-versioning'])

                main_section += paragraph

        main_section += parse_text(
            self, inspect.getdoc(resource),
            where='%s class docstring' % self.options['classname'])

        if getattr(resource, 'required_features', False):
            required_features = nodes.important()
            required_features += nodes.inline(
                text='Using this resource requires extra features to be '
                     'enabled on the server. See "Required Features" below.')
            main_section += required_features

        # Details section
        details_section = nodes.section(ids=['details'])
        main_section += details_section

        details_section += nodes.title(text='Details')
        details_section += self.build_details_table(resource)

        # Fields section
        if (resource.fields and
            (not is_list or resource.singleton)):
            fields_section = nodes.section(ids=['fields'])
            main_section += fields_section

            fields_section += nodes.title(text='Fields')
            fields_section += self.build_fields_table(resource.fields)

        # Links section
        if 'hide-links' not in self.options:
            fields_section = nodes.section(ids=['links'])
            main_section += fields_section

            fields_section += nodes.title(text='Links')
            fields_section += self.build_links_table(resource)

        # HTTP method descriptions
        for http_method in self.get_http_methods(resource, is_list):
            method_section = nodes.section(ids=[http_method])
            main_section += method_section

            method_section += nodes.title(text='HTTP %s' % http_method)
            method_section += self.build_http_method_section(resource,
                                                             http_method)

        if 'hide-examples' not in self.options:
            examples_section = nodes.section(ids=['examples'])
            examples_section += nodes.title(text='Examples')

            has_examples = False

            if is_list:
                mimetype_key = 'list'
            else:
                mimetype_key = 'item'

            for mimetype in resource.allowed_mimetypes:
                try:
                    mimetype = mimetype[mimetype_key]
                except KeyError:
                    continue

                if mimetype in self.FILTERED_MIMETYPES:
                    # Resources have more specific mimetypes. We want to
                    # filter out the general ones (like application/json)
                    # so we don't show redundant examples.
                    continue

                if mimetype.endswith('xml'):
                    # JSON is preferred. While we support XML, let's not
                    # continue to advertise it.
                    continue

                url, headers, data = \
                    self.fetch_resource_data(resource, mimetype)
                example_node = build_example(headers, data, mimetype)

                if example_node:
                    example_section = \
                        nodes.section(ids=['example_' + mimetype],
                                      classes=['examples', 'requests-example'])
                    examples_section += example_section

                    example_section += nodes.title(text=mimetype)

                    accept_mimetype = mimetype

                    if (mimetype.startswith('application/') and
                        mimetype.endswith('+json')):
                        # Instead of telling the user to ask for a specific
                        # mimetype on the request, show them that asking for
                        # application/json works fine.
                        accept_mimetype = 'application/json'

                    curl_text = (
                        '$ curl http://reviews.example.com%s -H "Accept: %s"'
                        % (url, accept_mimetype)
                    )
                    example_section += nodes.literal_block(
                        curl_text, curl_text, classes=['cmdline'])

                    example_section += nodes.literal_block(
                        headers, headers, classes=['http-headers'])
                    example_section += example_node
                    has_examples = True

            if has_examples:
                main_section += examples_section

        return [targetnode, main_section]
Ejemplo n.º 60
0
settings = frontend.OptionParser().get_default_values()
settings.xml_declaration = False
settings.embed_stylesheet = False
settings.stylesheet_path = False
settings.stylesheet = None
settings.initial_header_level = "1"
reporter = Reporter(source,
                    settings.report_level,
                    settings.halt_level,
                    stream=settings.warning_stream,
                    debug=settings.debug,
                    encoding=settings.error_encoding,
                    error_handler=settings.error_encoding_error_handler)
document = nodes.document(settings, reporter)

title = nodes.title(text="This is the title")
subtitle = nodes.subtitle(text=".. with a subtitle")

introduction = nodes.section()
start = nodes.paragraph(text="The introduction starts with this.")
introduction += start

background = nodes.section()
background += nodes.paragraph(
    text="This paragraph starts the second section, background.")

document += [title, subtitle, introduction, background]

#print str(document)

out = docutils.io.FileOutput()