Index: trac/wiki/api.py
===================================================================
--- trac/wiki/api.py	(revision 2737)
+++ trac/wiki/api.py	(working copy)
@@ -77,7 +77,19 @@
         The `label` is already HTML escaped, whereas the `target` is not.
         """
  
+class IWikiFormatExporter(Interface):
+    """ Represents an export format for Wiki pages. """
 
+    def get_export_formats():
+        """ Return an iterable over (format, description, content_type).
+
+        For example, the default "text/plain" exporter would yield
+        ('txt', 'Plain text', 'text/plain;charset=utf-8').
+        """
+
+    def export_page(format, req, page):
+        """ Export page in the given format. """
+
 class WikiSystem(Component):
     """Represents the wiki system."""
 
Index: trac/wiki/web_ui.py
===================================================================
--- trac/wiki/web_ui.py	(revision 2737)
+++ trac/wiki/web_ui.py	(working copy)
@@ -29,6 +29,7 @@
 from trac.versioncontrol.diff import get_diff_options, hdf_diff
 from trac.web.chrome import add_link, add_stylesheet, INavigationContributor
 from trac.web import IRequestHandler
+from trac.wiki.api import IWikiFormatExporter
 from trac.wiki.model import WikiPage
 from trac.wiki.formatter import wiki_to_html, wiki_to_oneliner
 
@@ -36,8 +37,10 @@
 class WikiModule(Component):
 
     implements(INavigationContributor, IPermissionRequestor, IRequestHandler,
-               ITimelineEventProvider, ISearchSource)
+               ITimelineEventProvider, ISearchSource, IWikiFormatExporter)
 
+    wiki_exporters = ExtensionPoint(IWikiFormatExporter)
+
     # INavigationContributor methods
 
     def get_active_navigation_item(self, req):
@@ -109,12 +112,17 @@
         elif action == 'history':
             self._render_history(req, db, page)
         else:
-            if req.args.get('format') == 'txt':
-                req.send_response(200)
-                req.send_header('Content-Type', 'text/plain;charset=utf-8')
-                req.end_headers()
-                req.write(page.text)
-                return
+            if req.args.has_key('format'):
+                required_format = req.args.get('format')
+                for exporter in self.wiki_exporters:
+                    for format, description, content_type in exporter.get_export_formats():
+                        if required_format == format:
+                            req.send_response(200)
+                            req.send_header('Content-Type', '%s' % content_type)
+                            req.end_headers()
+                            req.write(exporter.export_page(format, req, page))
+                            return
+                raise TracError('No IWikiFormatExporter for format "%s"' % required_format)
             self._render_view(req, db, page)
 
         req.hdf['wiki.action'] = action
@@ -357,8 +365,10 @@
             # Ask web spiders to not index old versions
             req.hdf['html.norobots'] = 1
 
-        txt_href = self.env.href.wiki(page.name, version=version, format='txt')
-        add_link(req, 'alternate', txt_href, 'Plain Text', 'text/plain')
+        for exporter in self.wiki_exporters:
+            for format, description, content_type in exporter.get_export_formats():
+                format_href = self.env.href.wiki(page.name, version=version, format=format)
+                add_link(req, 'alternate', format_href, description, content_type.split(';')[0])
 
         req.hdf['wiki'] = {'page_name': page.name, 'exists': page.exists,
                            'version': page.version, 'readonly': page.readonly}
@@ -405,3 +415,15 @@
                    '%s: %s' % (name, shorten_line(text)),
                    date, author,
                    shorten_result(text, query.split()))
+
+    # IWikiFormatExporter methods
+
+    def get_export_formats(self):
+        yield ('txt', 'Plain text', 'text/plain;charset=utf-8')
+        yield ('html', 'Raw HTML', 'text/html')
+
+    def export_page(self, format, req, page):
+        if format == 'txt':
+            return page.text
+        else:
+            return wiki_to_html(page.text, self.env, req, self.env.get_db_cnx())

