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