ActiveState Code

Recipe 193890: Using reST (reStructuredText) to create HTML snippets


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
 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)

Discussion

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.

Comments

  1. 1. At 2:06 a.m. on 6 may 2003, Keisuke URAGO said:

    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;
    
  2. 2. At 6:08 p.m. on 10 may 2003, Keisuke URAGO said:

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

  3. 3. At 6:50 p.m. on 11 may 2003, Keisuke URAGO said:

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

  4. 4. At 10:20 p.m. on 25 jul 2003, Ethan Fremen said:

    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.

  5. 5. At 4:37 a.m. on 22 sep 2003, Rogier Steehouder said:

    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.

  6. 6. At 2:46 p.m. on 28 apr 2004, David Goodger said:

    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

Sign in to comment