1#!/usr/bin/env python
2
3"""
4HTML Tidy Extension for Python-Markdown
5=======================================
6
7Runs [HTML Tidy][] on the output of Python-Markdown using the [uTidylib][]
8Python wrapper. Both libtidy and uTidylib must be installed on your system.
9
10Note than any Tidy [options][] can be passed in as extension configs. So,
11for example, to output HTML rather than XHTML, set ``output_xhtml=0``. To
12indent the output, set ``indent=auto`` and to have Tidy wrap the output in
13``<html>`` and ``<body>`` tags, set ``show_body_only=0``.
14
15[HTML Tidy]: http://tidy.sourceforge.net/
16[uTidylib]: http://utidylib.berlios.de/
17[options]: http://tidy.sourceforge.net/docs/quickref.html
18
19Copyright (c)2008 [Waylan Limberg](http://achinghead.com)
20
21License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
22
23Dependencies:
24* [Python2.3+](http://python.org)
25* [Markdown 2.0+](http://www.freewisdom.org/projects/python-markdown/)
26* [HTML Tidy](http://utidylib.berlios.de/)
27* [uTidylib](http://utidylib.berlios.de/)
28
29"""
30
31import markdown
32import tidy
33
34class TidyExtension(markdown.Extension):
35
36    def __init__(self, configs):
37        # Set defaults to match typical markdown behavior.
38        self.config = dict(output_xhtml=1,
39                           show_body_only=1,
40                          )
41        # Merge in user defined configs overriding any present if nessecary.
42        for c in configs:
43            self.config[c[0]] = c[1]
44
45    def extendMarkdown(self, md, md_globals):
46        # Save options to markdown instance
47        md.tidy_options = self.config
48        # Add TidyProcessor to postprocessors
49        md.postprocessors['tidy'] = TidyProcessor(md)
50
51
52class TidyProcessor(markdown.postprocessors.Postprocessor):
53
54    def run(self, text):
55        # Pass text to Tidy. As Tidy does not accept unicode we need to encode
56        # it and decode its return value.
57        return unicode(tidy.parseString(text.encode('utf-8'),
58                                        **self.markdown.tidy_options))
59
60
61def makeExtension(configs=None):
62    return TidyExtension(configs=configs)
63