Discussion:
[Docutils-users] writing a directive to insert rst content into a document
Bernhard Leiner
2009-04-30 14:45:24 UTC
Permalink
Hello,

I'm trying to write a supposedly simple docutils "my_insert" directive
that is capable of inserting arbitrary rst content into a document.
Basically this directive should work as follows:

.. my_insert:: keyword

Inside the run() method of the "my_insert" directive, depending on the
"keyword", a function is called which returns some string in rst
format. The best thing I achieved so far is this version:


class My_Insert (Directive) :

required_arguments = 1

# table of functions to be used to get content, depending on the argument
func_d = { 'key_1' : function_1
}

def run (self):
rst_input = self.func_d[self.arguments[0]]()
node = nodes.literal_block (text = rst_input)
node['language'] = 'none'
return [node]


Note that this only includes the returned string inside a new
literal_block. I think I need something along this inside my run()
method to trigger parsing of the input:


def run (self):
rst_input = self.func_d[self.arguments[0]]()
node = nodes.Element ()
self.content = rst_input # XXX this does not work
self.state.nested_parse (self.content, self.content_offset, node)
return [node]


but unfortunately I'm not able to include the "rst_input" string into
self.content. The simple assignment as used above definitely does not
work.

Maybe I'm missing just a little bit, maybe my approach is not feasible
at all... I don't know

Thanks a lot in advance for any help!
--
Bernhard Leiner http://bernh.net
David Goodger
2009-04-30 15:06:56 UTC
Permalink
On Thu, Apr 30, 2009 at 10:45, Bernhard Leiner
Post by Bernhard Leiner
I'm trying to write a supposedly simple docutils "my_insert" directive
that is capable of inserting arbitrary rst content into a document.
.. my_insert:: keyword
Inside the run() method of the "my_insert" directive, depending on the
"keyword", a function is called which returns some string in rst
format.
...

It sounds like the "include" directive would serve your purposes. If
not, I suggest you take a look at the source for he "include"
directive, in docutils/parsers/rst/directives/misc.py. Most of its
"run" method is involved with opening the external file and selecting
the range of lines to include. The last 3 lines are relevant to your
case:

include_lines = statemachine.string2lines(include_text,
convert_whitespace=1)
self.state_machine.insert_input(include_lines, path)
return []

The 1st line converts the text into lines, as expected by the parser.
The 2nd line inserts these lines into the input, so they'll be parsed
normally. The 3rd line returns an empty list, which means nothing is
inserted into the document tree. The parsing will take care of that.
--
David Goodger <http://python.net/~goodger>
Bernhard Leiner
2009-04-30 16:23:39 UTC
Permalink
Post by David Goodger
It sounds like the "include" directive would serve your purposes. If
not, I suggest you take a look at the source for he "include"
directive, in docutils/parsers/rst/directives/misc.py. Most of its
"run" method is involved with opening the external file and selecting
the range of lines to include. The last 3 lines are relevant to your
           include_lines = statemachine.string2lines(include_text,
                                                     convert_whitespace=1)
           self.state_machine.insert_input(include_lines, path)
           return []
The 1st line converts the text into lines, as expected by the parser.
The 2nd line inserts these lines into the input, so they'll be parsed
normally. The 3rd line returns an empty list, which means nothing is
inserted into the document tree. The parsing will take care of that.
Thanks a lot, this is exactly what I was looking for.
--
Bernhard Leiner http://bernh.net
Loading...