An Introduction to ReStructuredText

17 May 2008

Writing text

There are many ways to markup plain text. There is SGML and its off-shoot HTML. Later came XML, a replacement for SGML, a general-purpose way of making markup languages, one of which is XHTML, which is what you are using to view this page now.

There is also LaTeX, which is a markup used for typesetting in various contexts, especially in academic fields where complex mathematical equations are used.

With all these formats, the marked up document is plain text, and then rendered into its final form, that form may be paper, or it may be a browser window. The downside to these formats is that the marked up plain text document is ugly - full of random angle brackets and letters and words entered into the text that you are trying to read. While after using HTML for a decade I can more or less block it out, the plain text form is far less readable because of the markup.

Enter reStructuredText

reStructuredText is a markup language that does things differently. It uses more natural looking markup with a focus on readability so reStructuredText can be easily read and shared in its plain text form. You can then automatically processes the document into XML (called Docutils XML), and from there it can go into XHTML, LaTeX, OpenDocument, Docbook, or any other format that you can get to from XML. So readable, yet maps to XML in a well thought out way.

If you are going to abbreviate reStructuredText, then use 'rst', don't use 'rest' because that gets confusing with Representational State Transfer, a completely different thing altogether.

I have jumped in the deep-end and I am using reStructuredText to write my posts in this new version of the site, and it is an optional markup format for people leaving their opinions in the discussion/comments section (you don't need to use it to leave a comment).

While I have just got into it, reStructuredText has been around for several years, and has been most prominently used for creating Python documentation, however, it is a general purpose and extensible markup language that can be used in many different contexts.

Some people use it to create text for the web or for standalone documents. It can also be used wherever you might have made a one-off markup format, such as on a web forum, wiki or comments section.

reStructuredText everywhere

The reference implementation of a reStructuredText parser is called Docutils which is written in Python (but this can be used from many languages). Docutils is very easy to use in your application to process reStructuredText.

If you do not have docutils on your system already then it is available from all Linux/BSD package managers. For Windows, follow the installation-instructions.

There are also third-party parsers in Perl, Java, Haskell and probably more that I have not heard of. There are also plugins for text editors and plugins for lots of web frameworks, content management systems and web log software.

As explained in the last post, Django comes with reStructuredText support (bindings to docutils) out of the box. Lastly, there are also lots of cute reStructuredText website generators that allow you generate a website from a set of reStructuredText files. For example, Michael's rest2web, Sphinx,which is used to create the new Python 2.6/Python 3000 documentation, and Damien Baty's Soho.

Very quick reStructuredText (permalink to markup)

Okay, enough blab, lets get into it. There is very comprehensive set of markup available, but I will just cover a few basic ones that are always useful.

There is no need for paragraph tags or linebreak tags; to make a paragraph, you just make a paragraph, to break a line you just break a line.

To mark something with emphasis (i.e. italic), you use a star around the word or pharse: *emphasised text* becomes emphasised text.

Two stars are for strong emphasis (i.e. bold). Like so:

Hyperlinks

To make a hyperlink, you just start the text with http:// . So http://commandline.org.uk/ becomes: http://commandline.org.uk/

If you want to do a named hyperlink, then you need two parts. First, you put an underscore after the name, for example Zeth_ will become Zeth

Then you need a target to go with that name. You specify the target with two dots, a space and an underscore:

.. _Zeth: http://commandline.org.uk/

The line with the target can go anywhere in the document. For example, some people put the target line straight after the paragraph that has the name in. However, in a long document, it is often tidier to put all the targets at the end.

Lists

To make an unordered list (i.e. a bullet list), just start the line with a star, plus or hyphen, for example:

* Green eggs
* Ham

Becomes:

  • Green eggs
  • Ham

For a numerated list, just start the line with the number and a dot, for example:

1. Green eggs
2. Ham

Becomes:

  1. Green eggs
  2. Ham

I could go on, but I think you get the idea. By default, the core of reStructuredText is broadly feature equivalent to HTML. However, reStructuredText is very flexible and allows you to go beyond that core, as we shall look at next.

Directives

To markup a piece of more advanced functionality, you use a 'directive'. Directives are where reStructuredText shines over similar markup languages. Directives are extensions to the main markup, some directives are included by default (analogous to a standard library), others can be added by yourself or from getting them from the web or wherever. I will give an example of a standard directive, then an example of a third-party directive.

A directive has four parts. First you have some markup declaring the directive itself (two dots), second comes the directive name, third is some markup that says here is the content (two colons), lastly there is the content.

Two dots, the name, two colons, the content.

.. name :: content

So to display an image, you use the image directive.

You write two dots, a space, the word "image", two colons and then the URL:

.. image:: \http://commandline.org.uk/images/whokilledtux.png

Becomes:

http://commandline.org.uk/images/whokilledtux.png

To share source code, firstly you start with the source code directive, this is two dots, the directive name (source code), followed by two dots; secondly, we have the name of the language the source code is in. Then we leave a blank line, then we write the source code indented (preferably with four spaces ;-)

So for example:

.. sourcecode:: python

    import os
    for i in os.uname():
        print i

Will become:

import os
for i in os.uname():
    print i

Here is the list of supported languages on this site.

There you go, if you made it this far then you can use ReStructuredText, give it a go! You can start by leaving a comment in ReStructuredText format!

1 dbr says...

Hm.. ReStructuredText is very similar to markdown it would seem. A few things like the syntax for URL's is different ( _blah:http://google.com compared to (http://google.com)[blah] ), but it seems a very similar concept..

A help link next to the preview comment button, that shows a pop-up window/unhides a DIV containing a summary of R'S'T syntax would be useful..

Erm, just got an server error and full traceback when I tried to post this comment containing: http://thisbrokeyourcomments.pastecode.com/?show=m253f0917 Also, it may be a good idea to disable the debug traceback thingy

Posted at 10:23 p.m. on May 17, 2008


2 Zeth says...

Hi dbr. thanks for your comment.

Yeah there are at least three of these languages competing (reStructuredText, markdown, Textile), probably lots of others too. I suppose the main differences between reStructuredText and markdown are that markdown has a far cooler name, and that markdown seems to process directly to XHTML, whereas reStructuredText goes to docutils XML and then to whatever you want. Both valid approaches.

However, if there is something in your target format (e.g. ODF) that cannot be expressed in XHTML then you might lose it by going via XHTML. I don't really know enough about the markdown and its parser to see what it does about directives and so on.

The help link is a really good idea. I will add that when everything works.

The "debug traceback thingy" comes on and off depending on whether I am tenting something out. If you see it then it means I am working on the site at that moment.

As for your specific traceback, you seem to have found a bug in upstream Django! I have submitted the bug to them, and will think about it more to see what I can do.

Posted at 11:13 a.m. on May 18, 2008


3 The Dude says...

  1. Green Eggs
  2. Ham
  3. things

Posted at 5:08 p.m. on June 24, 2008


4 Kurushiyama says...

XML is no replacement for SGML, it's a subset.

Posted at 4:54 p.m. on June 30, 2008


5 Flo says...

If not her first title disabled?

test :

Editor with non-fixed police is awful to do titles in reST !!

list

  • a
  • aa
  • b
  • bb
  • aaa

Posted at 7:40 a.m. on October 16, 2008


6 loxs says...

Hello, Are you sure about the sourcecode directive, because I didn't manage to make it work. And it doesn't work with the online renderers too.

Posted at 2:58 p.m. on November 9, 2008


7 Zeth says...

Hi Ioxs,

I said above "I will give an example of a standard directive, then an example of a third-party directive", so the image directive is the example of a standard directive and the sourcecode directive is the example of a third-party directive.

If you want that directive on your own site, you need to get the Python module called pygments, see http://pygments.org/ for more information.

Posted at 5:30 p.m. on November 11, 2008


8 brokol says...

I discovered rST about a week ago, and decided to use it for notes/manuals/todo/etc. But I'd like to go even further and set up small server for this purpose. Is there a wiki engine/platform/application that would utilise rST as it's markup language?

Posted at 9:53 a.m. on March 16, 2009


9 gutes Qualitätscasino says...

The paragraph is the most basic block in a reST document. Paragraphs are simply chunks of text separated by one or more blank lines. As in Python, indentation is significant in reST, so all lines of the same paragraph must be left-aligned to the same level of indentation.

Posted at 1:45 p.m. on July 3, 2009


10 Fred says...

  • point 1

Posted at 3:05 a.m. on November 2, 2009


What do you have to say?

Show Editing Help

About

Hello, my name is Zeth, I'll be your host here.

Command Line Warriors is about taking control of your own technology, it looks at our experiences of computing; especially using GNU/Linux, the Python programming language, the command-line and issues such as techno-ethics, best practices and whatever is cool now. If you take control of your technology then you are a Warrior too!

This site is your site too which means that you can contribute and get involved. You can leave comments using the facility provided. For me, the comments and discussions are by far the best part of the site. So please do have your say!

Latest Discussions

Zeth

November 29, 2009
Hi Jordan, yes that URL is gone now. I have a new contact form on this site.
Python CGI contact forms

Jordan

November 29, 2009
Zeth attention! Your form, http://zeth.me.uk/contact/, is not working The explorer says connecting ..but nothing happens Sorry for my poor English: I am Spanish Regards
Python CGI contact forms

Jordan

November 26, 2009
Sorry: tell me , not tellme (I'm spaniard) And http://zeth.me.uk/contact/ don't work
You got the touch, you got the power

David Jones

November 25, 2009
Your mad skillz are too l33t! for me. I specifically switched to Google Reader so that I could show people what blogs I read. But I couldn't work out how ...
How to find the fashionable blogs quickly

Brian R. Hickey

November 20, 2009
Symantec picked it up too.
How to bring down Internet Explorer with six words

Zeth

November 17, 2009
Thanks djm, I am the moose here. Christian, assuming one actually does Internationalise the countries, it should still work I guess, as the gettext stuff will happen before the list ...
Countries in Django

Phillip Temple

November 17, 2009
Good start, but: a) wouldn't I want None back rather than 'ZZ'? b) why not add a 'shortcut' boolean, then prepend flagged fields (plus usual '-----' separator) to the actual ...
Countries in Django

djm

November 17, 2009
Am I being a moose or did you mean: from whatever.countries import CountryField instead of from whatever.countries import CharField ? Good post though, cheers.
Countries in Django

Christian Joergensen

November 17, 2009
Wouldn't the ordering get messed up after i18n?
Countries in Django

Steve - Electronic Cigarettes Fan

November 17, 2009
Very well done. Is your blog just you writing? Nicely done, Steven.
Blogger vs Wordpress

vetetix

November 15, 2009
Sorry to bother you nearly two years after you wrote this blog article, but I can't manage to find how to modify an existing field. I am trying to change ...
Three Useful Python Bindings - ClamAV, Apt and Evolution

Manju

November 4, 2009
I am transferring some files using psftp to other device's FAT partition. But the filestamp of the file being transferred is modified to that of FAT device, after the transfer. ...
PuTTY Series: Using PSFTP

iki

November 2, 2009
or simpler: socket.gethostbyname_ex(socket.gethostname())[2]
How to find out your IP address in Python

iki

November 2, 2009
local_ip = set([ i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None) if i[0] == 2 ])
How to find out your IP address in Python

Fred

November 2, 2009
testing rst ------------- - point 1
An Introduction to ReStructuredText

Ano

October 27, 2009
"You simply found the license of the StumbleUpon Toolbar for Internet Explorer." That's possible. I've got some more interesting information to add. Firstly, go to this page: https://addons.mozilla.org/en-US/firefox/addon/138 - this ...
Are your Firefox extensions proprietary software?

Ken

October 21, 2009
Stumbled in here at lunch. This is the best find of the week. Thanks.
Three classic command line tips

Jim

October 19, 2009
Thanks for the rtsp:// post - that's something that has been bugging me for a while!
Three classic command line tips

Zeth

October 18, 2009
Thanks for the comments guys. Great to see the all the gang are still here!
Three classic command line tips

Bubba

October 18, 2009
Is there any way psftp can return the true transfer rates oberved during the actual transfer?
PuTTY Series: Using PSFTP