Jason S
Jason S

Reputation: 189846

How to programmatically interpret reStructuredText into docutil nodes?

I'm writing custom roles/directives in Sphinx, and I need to insert a node in which I interpret a text string as reStructuredText. Is there a way to do this?

I found this source http://agateau.com/2015/docutils-snippets which says how to use docutils.nodes classes to construct a doctree fragment programmatically, e.g.

class BulletList(Directive):
    def run(self):
        fruits = ['Apples', 'Oranges', 'Bananas']

        lst = nodes.bullet_list()
        for fruit in fruits:
            item = nodes.list_item()
            lst += item
            item += nodes.paragraph(text=fruit)

        return [lst]

What I want to do is something like

:myrole:`this is *really* cool|trade|`

by doing this in conf.py:

def myrole(name, rawtext, text, lineno, inliner, options={}, content=[]):
    # somehow convert the "text" parameter into docutils nodes
    # by interpreting it as RST
    nodes = ???? what goes here ???
    return nodes, []

def setup(app):
    app.add_role('myrole', myrole)

Upvotes: 2

Views: 693

Answers (1)

Soren Bjornstad
Soren Bjornstad

Reputation: 1472

You want to use self.state.nested_parse in your directive's run() method:

Many directives will contain more markup that must be parsed. To do this, use one of the following APIs from the Directive.run() method:

self.state.nested_parse

sphinx.util.nodes.nested_parse_with_titles() – this allows titles in the parsed content.

Both APIs parse the content into a given node. They are used like this:

node = docutils.nodes.paragraph()
# either
nested_parse_with_titles(self.state, self.result, node)
# or
self.state.nested_parse(self.result, 0, node)

This question about creating input using a ViewList() may also be relevant.

I am not sure whether you can use this in a role. Obviously you won't be able to use the self. variant since roles are functions in any event.

Upvotes: 1

Related Questions