Summary

This is a Python implementation of John Gruber's [Markdown](http://daringfireball.net/projects/markdown/). The current version of python-markdown implements all Markdown syntax features and fully passes [Markdown Test Suite 1.0](http://six.pairlist.net/pipermail/markdown-discuss/2004-December/000909.html). It also supports footnotes (see [this thread](http://six.pairlist.net/pipermail/markdown-discuss/2005-August/001480.html)) and attributes (see [this thread](http://six.pairlist.net/pipermail/markdown-discuss/2005-August/001486.html)). If you find something missing, [submit a bug report](http://sourceforge.net/tracker/?func=add&group_id=153041&atid=790198) or send me an email (qaramazov-at-gmail.com). Better yet, send me a patch.

Installation and Usage

If you want to install the module into your python tree, get [setup.py](setup.py) and run "python setup.py install" from a directory where you put markdown.py. To use markdown.py by itself, run it as python markdown.py or python markdown.py To get footnotes, add a "-footnotes" option: python markdown.py -footnotes To use it as a module: import markdown html = markdown.markdown(your_text_string)

Extending

The functionality of the script can be extended without changing the code, by inserting additional pre-processors, post-processors or inline patterns into Markdown's pipeline. **Pre-processors** operate on lines of source text and are run in the beginning. It is sufficient to write a class with a run() method that takes a list of text lines as a parameter and returns the same or a new list. An instance of the preprocessor can then be inserted into the markdown pipeline. class SamplePreprocessor : def run(self, lines) : for i in range(len(lines)) : if lines[i].startswith(SOMETHING) : lines[i] = do_something(lines[i]) return lines md_instance.preprocessors.insert(SOME_INDEX, SamplePreprocessor()) **Post-processors** operate on a NanoDom tree and run at the very end. They need to implement a "run" method that takes a pointer to a NanoDom document. class SamplePostprocessor : def run(self, doc) : doc.documentElement.appendChild(doc.createElement("new")) md_instance.postprocessors.insert(SOME_INDEX, SamplePostprocessor()) Finally, **inline patterns** can be added. Each inline pattern includes a regular expression pattern and a method for turning a match object into a DOM fragment class MyCustomPattern (BasePattern) : def handleMatch(self, m, doc) : el = doc.createElement('custom') el.setAttribute('stuff', m.group(3)) return el new_pattern = MyCustomPattern(r'your regular expression here') md_instance.inlinePatterns.insert(SOME_INDEX, new_pattern) See the implementation of footnote support inside markdown.py for an example of using all three in combination to provide reasonably complex additional functionality. (I use a pre-processor to collect footnote definitions, an inline pattern to handle uses of footnotes inside the text and a post-processor to attach the HTML of the actual footnotes at the end of the document) Other extensions: * [Table-of-contents extension](extensions/markdown_with_toc.py) by Chris Clark (inserts a "title" element and a table of contents).

Credits

* The first version of this script was written by [Manfred Stienstra](http://www.dwerg.net/), who is responsible for about a quarter of the code. * Daniel Krech provided the setup.py script. * G. Clark Haynes submitted a patch for indented lists. * Tiago Cogumbreiro submitted an email autolink fix. * Sergej Chodarev submitted a patch for treatment of `
` tags. * Chris Clark submitted a patch to handle `` syntax and a reg ex for "smart" emphasis (ignoring underscores within a word). * Steward Midwinter wrote command-line parser and cleaned up comments. * Many other people helped by reporting bugs.

License

The code is dual-licensed under [GPL](http://www.gnu.org/copyleft/gpl.html) and [BSD License](http://www.opensource.org/licenses/bsd-license.php). Other licensing arrangements can be discussed.

Contact Info

Email qaramazov [at] gmail.com if you have any questions or spot any bugs. (Feel free to write in English, Russian, Portuguese or Spanish.) Or subscribe to [python-markdown-discuss](http://lists.sourceforge.net/lists/listinfo/python-markdown-discuss).

Change Log

*Feb. 28, 2006:* Clean-up and command-line handling by Stewart Midwinter. ([version 1.3](markdown-1.3.py)) *Feb. 24, 2006:* Fixed a bug with the last line of the list appearing again as a separate paragraph. Incorporated Chris Clark's "mailto" patch. Added support for `
` at the end of lines ending in two or more spaces. Fixed a crashing bug when using ImageReferencePattern. Added "hr" and "hr/" to BLOCK\_LEVEL\_ELEMENTS and changed `
` to `
`. (Thanks to Sergej Chodarev.) Added several utility methods to Nanodom. ([version 1.2](markdown-1.2.py)) *Nov. 30, 2005:* Fixed a bug with certain tabbed lines inside lists getting wrapped in `
`.  Made "\