Welcome, guest | Sign In | My Account | Store | Cart

This small recipe allows you to convert a reST text to HTML without creating a full HTML document but returning only a snippet that you can then put anywhere on a web page.

Python, 29 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from docutils import core
from docutils.writers.html4css1 import Writer,HTMLTranslator

class NoHeaderHTMLTranslator(HTMLTranslator):
    def __init__(self, document):
        HTMLTranslator.__init__(self,document)
        self.head_prefix = ['','','','','']
        self.body_prefix = []
        self.body_suffix = []
        self.stylesheet = []

_w = Writer()
_w.translator_class = NoHeaderHTMLTranslator

def reSTify(string):
    return core.publish_string(string,writer=_w)

if __name__ == '__main__':
    test = """
Test example of reST__ document.

__ http://docutils.sf.net/rst.html

- item 1
- item 2
- item 3

"""
    print reSTify(test)

The output of the script above is:<pre> <div class="document"><p>Test example of <a class="reference" href="http://docutils.sf.net/rst.html">reST</a> document.</p><ul class="simple"> <li>item 1</li><li>item 2</li><li>item 3</li></ul></div></pre>

This recipe is useful if you want to integrate the reST parsing tool in any other application or templating framework. Sometimes you just need some html markup to put in an already created html page. An example is posting to weblog services like http://www.blogger.com

reStructuredText is an easy-to-read, what-you-see-is-what-you-get plaintext markup syntax and parser system. It is useful for in-line program documentation (such as Python docstrings), for quickly creating simple web pages, and for standalone documents. reStructuredText is designed for extensibility for specific application domains. The reStructuredText parser is a component of Docutils.

reST can be found here: http://docutils.sf.net/rst.html

This code has been tested with the CVS version of reST.

6 comments

Keisuke URAGO 18 years, 7 months ago  # | flag

Is it version 0.2? I tried your tip. But not runned well. So I wrote corresponded to version 0.2 tip. See also below code.

-- begin code.

from docutils import core
from docutils.writers.html4css1 import Writer, HTMLTranslator
from docutils.readers.standalone import Reader
from docutils.parsers.rst import Parser

class NoHeaderHTMLTranslator(HTMLTranslator):
    def __init__(self, document):
        HTMLTranslator.__init__(self, document)
        self.head_prefix = ['','','','','']
        self.body_prefix = []
        self.body_suffix = []
        self.stylesheet = []

class Publisher(core.Publisher):
    def publish(self, data):
        self.set_options()
        self.options.stylesheet = ''
        self.options._destination = ''

        parser = Parser()
        reader = Reader(parser, None)
        writer = Writer()
        writer.translator_class = NoHeaderHTMLTranslator
        iodata = core.io.StringIO(self.options, source=data)
        xmldata = reader.read(iodata, parser, None)
        xmldata.options = self.options
        return writer.write(xmldata, iodata)

def reSTify(s):
    return Publisher().publish(s)

if __name__ == '__main__':
    test = """
Test example of reST__ document.

__ http://docutils.sf.net/rst.html

- item 1
- item 2
- item 3

"""
    print reSTify(test)

-- end of code.

So generate below HTML.

&lt;div class="document"&gt;
&lt;p&gt;Test example of &lt;a class="reference" href="http://docutils.sf.net/rst.html"&gt;reST&lt;/a&gt; document.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;item 1&lt;/li&gt;
&lt;li&gt;item 2&lt;/li&gt;
&lt;li&gt;item 3&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
Keisuke URAGO 18 years, 6 months ago  # | flag

Hmm, I had mistake. I had a mistake. It seems that I downloaded the older thing.

Keisuke URAGO 18 years, 6 months ago  # | flag

It corrects. It seems that that is not right although considered. Your tip will operate, if it is somewhat old CVS revision.

Ethan Fremen 18 years, 4 months ago  # | flag

Easier method for using ReST. A disadvantage of the method posted above is that it preserves the header while stripping it of context. Items that would be rendered as h1 in ReST also get rendered as title.

The function that finally writes out the page is the astext function. In the normal version, a bunch of lists are concatenated together, but we only care about the self.body list for our snippet. Thus we can avoid modifying any initialization steps and instead override the astext function, making our modification much simpler :

class NoHeaderHTMLTranslator(HTMLTranslator):
    def astext(self):
        return ''.join(self.body)

The rest of the recipe remains the same.

Rogier Steehouder 18 years, 2 months ago  # | flag

Controlling class. And if you add

def visit_document(self, node):
    self.body.append(self.starttag(node, 'div', CLASS='whatever'))

to the NoHeaderHTMLTranslator class, you can control the div class. "document" is a bit awkward if you only include snippets.

David Goodger 17 years, 7 months ago  # | flag

Official API now exists. There's now an official API (in CVS, as of version 0.3.2) that does this: docutils.core.publish_parts() (see the docstring for details). There's also a new module, docutils.examples, that exposes practical examples of Docutils client code, to be used as-is or as models for variations.

A development snapshot is always available here:

http://docutils.sf.net/docutils-snapshot.tgz