Index: trac/attachment.py
===================================================================
--- trac/attachment.py	(revision 3821)
+++ trac/attachment.py	(working copy)
@@ -34,7 +34,6 @@
 from trac.web import HTTPBadRequest, IRequestHandler
 from trac.web.chrome import add_link, add_stylesheet, INavigationContributor
 from trac.wiki.api import IWikiSyntaxProvider
-from trac.wiki.formatter import wiki_to_html, wiki_to_oneliner
 
 
 class InvalidAttachment(TracError):
@@ -254,29 +253,6 @@
         return fd
 
 
-# Templating utilities
-
-def attachments_data(env, req, db, parent_type, parent_id):
-    return [attachment_data(env, req, db, attachment) for attachment
-            in Attachment.select(env, parent_type, parent_id, db)]
-    
-def attachment_data(env, req, db, attachment):
-    # FIXME: pretty close to the attachment itself... so pass directly
-    # the attachment
-    if not db:
-        db = env.get_db_cnx()
-    description = wiki_to_oneliner(attachment.description, env, db)
-    return {
-        'filename': attachment.filename,
-        'description': Markup(description.strip()),
-        'author': attachment.author,
-        'ipnr': attachment.ipnr,
-        'size': attachment.size,
-        'date': attachment.time,
-        'href': attachment.href(req)
-    }
-
-
 class AttachmentModule(Component):
 
     implements(IEnvironmentSetupParticipant, IRequestHandler,
@@ -363,8 +339,8 @@
                 data = {
                     'mode': 'list',
                     'parent': parent_data(parent_type, last_segment),
-                    'attachments': attachments_data(self.env, req, None,
-                                                    parent_type, last_segment),
+                    'attachments': Attachment.select(self.env,
+                                                     parent_type, last_segment)
                     }
                 return 'attachment.html', data, None
             if not last_segment:
@@ -426,15 +402,7 @@
                 self.get_history(start, stop, type):
             title = html(html.EM(os.path.basename(filename)),
                          ' attached to ', display(id))
-            if format == 'rss':
-                descr = wiki_to_html(descr or '--', self.env, req, db,
-                                     absurls=True)
-                href = req.abs_href
-            else:
-                descr = wiki_to_oneliner(descr, self.env, db, shorten=True)
-                title += Markup(' by %s', author)
-                href = req.href
-            yield('attachment', href.attachment(type, id, filename), title,
+            yield('attachment', req.href.attachment(type, id, filename), title,
                   time, author, descr)
 
     # Internal methods
@@ -533,14 +501,8 @@
 
         req.check_modified(attachment.time)
 
-        # Render HTML view
-        att_data = attachment_data(self.env, req, None, attachment)
-        # Override the 'oneliner'
-        att_data['description'] = wiki_to_html(attachment.description,
-                                               self.env, req)
-        
         data = {'mode': 'view', 'title': attachment.title,
-                'attachment': att_data}
+                'attachment': attachment}
     
         perm_map = {'ticket': 'TICKET_ADMIN', 'wiki': 'WIKI_DELETE'}
         if req.perm.has_permission(perm_map[attachment.parent_type]):
Index: trac/ticket/web_ui.py
===================================================================
--- trac/ticket/web_ui.py	(revision 3821)
+++ trac/ticket/web_ui.py	(working copy)
@@ -19,7 +19,7 @@
 from StringIO import StringIO
 import time
 
-from trac.attachment import attachments_data, Attachment, AttachmentModule
+from trac.attachment import Attachment, AttachmentModule
 from trac.config import BoolOption, Option
 from trac.core import *
 from trac.ticket import Milestone, Ticket, TicketSystem, ITicketManipulator
@@ -31,8 +31,8 @@
 from trac.web import IRequestHandler
 from trac.web.chrome import add_link, add_stylesheet, INavigationContributor, \
                             Chrome
-from trac.wiki import wiki_to_html, wiki_to_oneliner
 from trac.mimeview.api import Mimeview, IContentConverter
+from trac.wiki import wiki_to_html, wiki_to_oneliner
 
 
 class InvalidTicket(TracError):
@@ -107,10 +107,6 @@
         ticket.values['reporter'] = get_reporter_id(req, 'reporter')
         data['ticket'] = ticket
 
-        if 'description' in ticket.values:
-            description = wiki_to_html(ticket['description'], self.env, req, db)
-            data['preview'] = description
-
         field_names = [field['name'] for field in ticket.fields
                        if not field.get('custom')]
         if 'owner' in field_names:
@@ -265,8 +261,7 @@
                 comment = req.args.get('comment')
                 if comment:
                     data['comment'] = comment
-                    # Wiki format a preview of comment
-                    data['preview'] = wiki_to_html(comment, self.env, req, db)
+                    data['preview'] = True
         else:
             data['reassign_owner'] = req.authname
             # Store a timestamp in order to detect "mid air collisions"
@@ -445,9 +440,6 @@
             change_summary = {}
             # wikify comment
             if 'comment' in change:
-                comment = change['comment']
-                change['comment'] = unicode(wiki_to_html(
-                    comment, self.env, req, db, absurls=True))
                 change_summary['added'] = ['comment']
             for field, values in change['fields'].iteritems():
                 if field == 'description':
@@ -462,12 +454,7 @@
             change['title'] = '; '.join(['%s %s' % (', '.join(v), k) for k, v \
                                          in change_summary.iteritems()])
 
-        data = {
-            'id': ticket.id,
-            'description': wiki_to_html(ticket['description'], self.env, req,
-                                        db, absurls=True),
-            'changes': changes,
-            }
+        data = {'ticket': ticket, 'changes': changes}
         
         template = Chrome(self.env).load_template('ticket.rss', req, data)
         return template.generate(**data).render('xml'), 'application/rss+xml'
@@ -558,8 +545,6 @@
             data['fields'].append(field)
 
         data['reporter_id'] = reporter_id
-        data['description'] = wiki_to_html(ticket['description'], self.env, req,
-                                           db)
 
         # FIXME: get rid of this once datetime branch is merged
         data['opened'] = ticket.time_created
@@ -587,7 +572,6 @@
             comment = ''
             if 'comment' in change:
                 comment = change['comment']
-                change['comment'] = wiki_to_html(comment, self.env, req, db)
             if change['permanent']:
                 cnum = change['cnum']
                 # keep track of replies threading
@@ -611,8 +595,8 @@
 
         # -- Ticket Attachments
 
-        data['attachments'] = attachments_data(self.env, req, db, 'ticket',
-                                               ticket.id)
+        data['attachments'] = Attachment.select(self.env, 'ticket', ticket.id,
+                                                db)
         if req.perm.has_permission('TICKET_APPEND'):
             data['attach_href'] = req.href.attachment('ticket', ticket.id)
 
Index: trac/ticket/report.py
===================================================================
--- trac/ticket/report.py	(revision 3821)
+++ trac/ticket/report.py	(working copy)
@@ -27,7 +27,7 @@
 from trac.util.html import html
 from trac.web.api import IRequestHandler, RequestDone
 from trac.web.chrome import add_link, add_stylesheet, INavigationContributor
-from trac.wiki import wiki_to_html, IWikiSyntaxProvider, Formatter
+from trac.wiki import IWikiSyntaxProvider, Formatter
 
 
 class ReportModule(Component):
@@ -232,12 +232,8 @@
             title = '{%i} %s' % (id, title)
         
         data = {'action': 'view', 'title': title,
-                'report':
-                {'id': id, 'title': title,
-                 'description': wiki_to_html(description, self.env, req, db,
-                                             absurls=(format == 'rss')),
-                 'can': perms}}
-
+                'report': {'id': id, 'title': title,
+                           'description': description, 'can': perms}}
         try:
             cols, results = self.execute_report(req, db, id, sql, args)
         except Exception, e:
@@ -318,10 +314,7 @@
                         row['id'] = value
                     # Special casing based on column name
                     col = col.strip('_')
-                    if col == 'description':
-                        cell['parsed'] = wiki_to_html(value, self.env, req, db,
-                                                      absurls=(format == 'rss'))
-                    elif col == 'reporter':
+                    if col == 'reporter':
                         if '@' in value:
                             cell['author'] = value
                         elif value in email_map:
Index: trac/ticket/roadmap.py
===================================================================
--- trac/ticket/roadmap.py	(revision 3821)
+++ trac/ticket/roadmap.py	(working copy)
@@ -29,7 +29,7 @@
 from trac.Timeline import ITimelineEventProvider
 from trac.web import IRequestHandler
 from trac.web.chrome import add_link, add_stylesheet, INavigationContributor
-from trac.wiki import wiki_to_html, wiki_to_oneliner, IWikiSyntaxProvider
+from trac.wiki import IWikiSyntaxProvider
 
 
 def get_tickets_for_milestone(env, db, milestone, field='component'):
@@ -87,14 +87,14 @@
     }
 
 def milestone_to_hdf(env, db, req, milestone):
+    ### FIXME: should use the Milestone object directly
     safe_name = None
     if milestone.exists:
         safe_name = milestone.name.replace('/', '%2F')
     hdf = {'name': milestone.name, 'exists': milestone.exists,
            'href': req.href.milestone(safe_name)}
     if milestone.description:
-        hdf['description_source'] = milestone.description
-        hdf['description'] = wiki_to_html(milestone.description, env, req, db)
+        hdf['description'] = milestone.description
     if milestone.due:
         hdf['due'] = milestone.due
         hdf['due_date'] = format_date(milestone.due)
@@ -317,15 +317,7 @@
                            (start, stop,))
             for completed, name, description in cursor:
                 title = Markup('Milestone <em>%s</em> completed', name)
-                if format == 'rss':
-                    href = req.abs_href.milestone(name)
-                    message = wiki_to_html(description, self.env, req, db,
-                                           absurls=True)
-                else:
-                    href = req.href.milestone(name)
-                    message = wiki_to_oneliner(description, self.env, db,
-                                               shorten=True)
-                yield 'milestone', href, title, completed, None, message or '--'
+                yield 'milestone', href, title, completed, None, description
 
     # IRequestHandler methods
 
Index: trac/ticket/query.py
===================================================================
--- trac/ticket/query.py	(revision 3821)
+++ trac/ticket/query.py	(working copy)
@@ -29,7 +29,6 @@
 from trac.web.chrome import add_link, add_script, add_stylesheet, \
                             INavigationContributor, Chrome
 from trac.wiki.api import IWikiSyntaxProvider, parse_args
-from trac.wiki.formatter import wiki_to_html, wiki_to_oneliner
 from trac.wiki.macros import WikiMacroBase # TODO: should be moved in .api
 from trac.mimeview.api import Mimeview, IContentConverter
 
@@ -405,13 +404,7 @@
                     groups.setdefault(value, []).append(ticket)
                     if not groupsequence or groupsequence[-1] != value:
                         groupsequence.append(value)
-                if field == 'time':
-                    ticket[field] = value
-                elif field == 'description':
-                    ticket[field] = \
-                                  wiki_to_html(value or '', self.env, req, db)
-                else:
-                    ticket[field] = value
+                ticket[field] = value
         groupsequence = [(value, groups[value]) for value in groupsequence]
 
         return {'query': self,
@@ -639,10 +632,6 @@
         for result in results:
             if result['reporter'].find('@') == -1:
                 result['reporter'] = ''
-            if result['description']:
-                result['description'] = wiki_to_html(result['description'],
-                                                     self.env, req, db,
-                                                     absurls=True)
         query_href = req.abs_href.query(group=query.group,
                                         groupdesc=query.groupdesc and 1 or None,
                                         verbose=query.verbose and 1 or None,
Index: trac/versioncontrol/web_ui/util.py
===================================================================
--- trac/versioncontrol/web_ui/util.py	(revision 3821)
+++ trac/versioncontrol/web_ui/util.py	(working copy)
@@ -24,7 +24,6 @@
 from trac.util.html import escape, html, Markup
 from trac.util.text import shorten_line
 from trac.versioncontrol.api import NoSuchNode, NoSuchChangeset
-from trac.wiki import wiki_to_html, wiki_to_oneliner
 
 __all__ = ['get_changes', 'get_path_links', 'get_path_rev_line',
            'get_existing_node', 'render_node_property']
@@ -41,33 +40,24 @@
 
         wiki_format = env.config['changeset'].getbool('wiki_format_messages')
         message = changeset.message or '--'
-        absurls = (format == 'rss')
-        if wiki_format:
-            shortlog = wiki_to_oneliner(message, env, db,
-                                        shorten=True, absurls=absurls)
-        else:
+        if not wiki_format:
             shortlog = Markup.escape(shorten_line(message))
+        else:
+            shortlog = message
 
         if full:
-            if wiki_format:
-                message = wiki_to_html(message, env, req, db,
-                                       absurls=absurls, escape_newlines=True)
-            else:
+            if not wiki_format:
                 message = html.PRE(message)
         else:
             message = shortlog
 
-        if format == 'rss':
-            if isinstance(shortlog, Markup):
-                shortlog = u' '.join(shortlog.striptags().splitlines())
-            message = unicode(message)
-
         changes[rev] = {
             'date_seconds': changeset.date,
             'date': format_datetime(changeset.date),
             'age': pretty_timedelta(changeset.date),
             'author': changeset.author or 'anonymous',
-            'message': message, 'shortlog': shortlog,
+            'message': message,
+            'shortlog': shortlog,
         }
     return changes
 
Index: trac/versioncontrol/web_ui/changeset.py
===================================================================
--- trac/versioncontrol/web_ui/changeset.py	(revision 3821)
+++ trac/versioncontrol/web_ui/changeset.py	(working copy)
@@ -39,8 +39,7 @@
 from trac.versioncontrol.web_ui.util import render_node_property
 from trac.web import IRequestHandler, RequestDone
 from trac.web.chrome import INavigationContributor, add_link, add_stylesheet
-from trac.wiki import wiki_to_html, wiki_to_oneliner, IWikiSyntaxProvider, \
-                      Formatter
+from trac.wiki import IWikiSyntaxProvider, Formatter
 
 
 class ChangesetModule(Component):
@@ -202,10 +201,7 @@
         if chgset:
             chgset = repos.get_changeset(new)
             message = chgset.message or '--'
-            if self.wiki_format_messages:
-                message = wiki_to_html(message, self.env, req,
-                                              escape_newlines=True)
-            else:
+            if not self.wiki_format_messages:
                 message = html.PRE(message)
             req.check_modified(chgset.date, [
                 style, ''.join(options), repos.name,
@@ -293,10 +289,9 @@
             title = _changeset_title(rev)
             properties = []
             for name, value, wikiflag, htmlclass in chgset.get_properties():
-                if wikiflag:
-                    value = wiki_to_html(value or '', self.env, req)
                 properties.append({'name': name, 'value': value,
-                                   'htmlclass': htmlclass})
+                                   'htmlclass': htmlclass,
+                                   'wiki_formatting': wikiflag})
 
             data['changeset'] = {
                 'revision': chgset.rev,
@@ -619,19 +614,13 @@
             repos = self.env.get_repository(req.authname)
             for chgset in repos.get_changesets(start, stop):
                 message = chgset.message or '--'
-                if wiki_format:
-                    shortlog = wiki_to_oneliner(message, self.env, db,
-                                                shorten=True)
-                else:
+                if not wiki_format:
                     shortlog = shorten_line(message)
 
                 if format == 'rss':
                     title = Markup('Changeset [%s]: %s', chgset.rev, shortlog)
                     href = req.abs_href.changeset(chgset.rev)
-                    if wiki_format:
-                        message = wiki_to_html(message, self.env, req, db,
-                                               absurls=True)
-                    else:
+                    if not wiki_format:
                         message = html.PRE(message)
                 else:
                     title = Markup('Changeset <em>[%s]</em> by %s', chgset.rev,
@@ -639,14 +628,13 @@
                     href = req.href.changeset(chgset.rev)
 
                     if wiki_format:
+                        # FIXME:
                         if self.timeline_long_messages:
-                            message = wiki_to_html(message, self.env, req, db,
-                                                   absurls=True)
-                        else:
-                            message = wiki_to_oneliner(message, self.env, db,
-                                                       shorten=True)
+                            pass
+                        # FIXME: should set the shorten flag on the event,
+                        #        see timeline.html
                     else:
-                        message = shortlog
+                        message = Markup.escape(shortlog)
 
                 if show_files and req.perm.has_permission('BROWSER_VIEW'):
                     files = []
Index: trac/versioncontrol/web_ui/browser.py
===================================================================
--- trac/versioncontrol/web_ui/browser.py	(revision 3821)
+++ trac/versioncontrol/web_ui/browser.py	(working copy)
@@ -27,11 +27,11 @@
 from trac.util import sorted, embedded_numbers
 from trac.util.datefmt import http_date
 from trac.util.html import escape, html, Markup
-from trac.web import IRequestHandler, RequestDone
-from trac.web.chrome import add_link, add_stylesheet, INavigationContributor
-from trac.wiki import wiki_to_html, IWikiSyntaxProvider
 from trac.versioncontrol.api import NoSuchChangeset
 from trac.versioncontrol.web_ui.util import *
+from trac.web.api import IRequestHandler, RequestDone
+from trac.web.chrome import add_link, add_stylesheet, INavigationContributor
+from trac.wiki.api import IWikiSyntaxProvider
 
 
 CHUNK_SIZE = 4096
@@ -204,10 +204,7 @@
             changeset = repos.get_changeset(node.rev)
 
             message = changeset.message or '--'
-            if self.config['changeset'].getbool('wiki_format_messages'):
-                message = wiki_to_html(message, self.env, req,
-                                       escape_newlines=True)
-            else:
+            if not self.config['changeset'].getbool('wiki_format_messages'):
                 message = html.PRE(message)
 
             # add ''Plain Text'' alternate link if needed
Index: trac/About.py
===================================================================
--- trac/About.py	(revision 3821)
+++ trac/About.py	(working copy)
@@ -95,10 +95,9 @@
 
     def _render_plugins(self, req):
         try:
-            from trac.wiki.formatter import wiki_to_html
             import inspect
             def getdoc(obj):
-                return wiki_to_html(inspect.getdoc(obj), self.env, req)
+                return inspect.getdoc(obj)
         except:
             def getdoc(obj):
                 return obj.__doc__
@@ -112,7 +111,7 @@
                 continue
             plugin = {'name': component.__name__}
             if component.__doc__:
-                plugin['description'] = Markup(getdoc(component))
+                plugin['description'] = getdoc(component)
 
             module = sys.modules[component.__module__]
             plugin['module'] = module.__name__
@@ -128,7 +127,7 @@
                                'interface': xtnpt.interface.__name__,
                                'module': xtnpt.interface.__module__})
                 if xtnpt.interface.__doc__:
-                    xtnpts[-1]['description'] = Markup(getdoc(xtnpt.interface))
+                    xtnpts[-1]['description'] = getdoc(xtnpt.interface)
                 extensions = []
                 for extension in ComponentMeta._registry.get(xtnpt.interface, []):
                     if self.env.is_component_enabled(extension):
Index: trac/wiki/web_ui.py
===================================================================
--- trac/wiki/web_ui.py	(revision 3821)
+++ trac/wiki/web_ui.py	(working copy)
@@ -20,7 +20,7 @@
 import re
 import StringIO
 
-from trac.attachment import attachments_data, Attachment, AttachmentModule
+from trac.attachment import Attachment, AttachmentModule
 from trac.core import *
 from trac.perm import IPermissionRequestor
 from trac.Search import ISearchSource, search_to_sql, shorten_result
@@ -33,7 +33,6 @@
 from trac.web import HTTPNotFound, IRequestHandler
 from trac.wiki.api import IWikiPageManipulator, WikiSystem
 from trac.wiki.model import WikiPage
-from trac.wiki.formatter import wiki_to_html, wiki_to_oneliner
 from trac.mimeview.api import Mimeview, IContentConverter
 
 
@@ -243,7 +242,7 @@
             if version == new_version:
                 date = t
                 author = a or 'anonymous'
-                comment = wiki_to_html(c or '--', self.env, req, db)
+                comment = c
                 ipnr = i or ''
             else:
                 if version < new_version:
@@ -335,11 +334,6 @@
             'edit_rows': editrows,
             'scroll_bar_pos': req.args.get('scroll_bar_pos', '')
         })
-        if action == 'preview':
-            data.update({
-            'page_html': wiki_to_html(page.text, self.env, req, db),
-            'comment_html': wiki_to_oneliner(comment, self.env, db)
-            })
         return 'wiki_edit.html', data, None
 
     def _render_history(self, req, db, page):
@@ -361,7 +355,7 @@
                 'version': version,
                 'date': date,
                 'author': author,
-                'comment': wiki_to_oneliner(comment or '', self.env, db),
+                'comment': comment,
                 'ipnr': ipnr
             })
         data['history'] = history
@@ -384,27 +378,21 @@
         if page.name == 'WikiStart':
             data['title'] = ''
 
-        page_html = comment_html = attach_href = ''
+        attach_href = ''
         latest_page = WikiPage(self.env, page.name)
 
-        if page.exists:
-            page_html = wiki_to_html(page.text, self.env, req, db)
-            if version:
-                comment_html = wiki_to_oneliner(page.comment or '--',
-                                                self.env, db)
-        else:
+        if not page.exists:
             if not req.perm.has_permission('WIKI_CREATE'):
                 raise HTTPNotFound('Page %s not found', page.name)
-            page_html = html.P('Describe "%s" here' % data['page_name'])
+            page.text = 'Describe "`%s`" here' % data['page_name']
 
         # Show attachments
-        attachments = attachments_data(self.env, req, db, 'wiki', page.name)
+        attachments = Attachment.select(self.env, 'wiki', page.name, db)
         if req.perm.has_permission('WIKI_MODIFY'):
             attach_href = req.href.attachment('wiki', page.name)
 
         data.update({'action': 'view',
-                     'page_html': page_html,
-                     'comment_html': comment_html,
+                     'version': version,
                      'latest_version': latest_page.version,
                      'attachments': attachments,
                      'attach_href': attach_href,
@@ -432,17 +420,11 @@
             for t,name,comment,author,version in cursor:
                 title = Markup('<em>%s</em> edited by %s',
                                wiki.format_page_name(name), author)
-                diff_link = html.A('diff', href=href.wiki(name, action='diff',
-                                                          version=version))
-                if format == 'rss':
-                    comment = wiki_to_html(comment or '--', self.env, req, db,
-                                           absurls=True)
-                else:
-                    comment = wiki_to_oneliner(comment, self.env, db,
-                                               shorten=True)
                 if version > 1:
-                    comment = html(comment, ' (', diff_link, ')')
-                yield 'wiki', href.wiki(name), title, t, author, comment
+                    link = href.wiki(name, action='diff', version=version)
+                else:
+                    link = href.wiki(name)
+                yield 'wiki', link, title, t, author, comment
 
             # Attachments
             def display(id):
Index: trac/wiki/tests/formatter.py
===================================================================
--- trac/wiki/tests/formatter.py	(revision 3821)
+++ trac/wiki/tests/formatter.py	(working copy)
@@ -129,7 +129,7 @@
 
 class OneLinerTestCase(WikiTestCase):
     def formatter(self):
-        return OneLinerFormatter(self.env) # TODO: self.req
+        return OneLinerFormatter(self.env, self.req)
 
 
 def suite(data=None, setup=None, file=__file__):
Index: trac/wiki/formatter.py
===================================================================
--- trac/wiki/formatter.py	(revision 3821)
+++ trac/wiki/formatter.py	(working copy)
@@ -861,8 +861,8 @@
     """
     flavor = 'oneliner'
 
-    def __init__(self, env, absurls=False, db=None):
-        Formatter.__init__(self, env, None, absurls, db)
+    def __init__(self, env, req, absurls=False, db=None):
+        Formatter.__init__(self, env, req, absurls, db)
 
     # Override a few formatters to disable some wiki syntax in "oneliner"-mode
     def _list_formatter(self, match, fullmatch): return match
@@ -1009,7 +1009,7 @@
     if not wikitext:
         return Markup()
     out = StringIO()
-    OneLinerFormatter(env, absurls, db).format(wikitext, out, shorten)
+    OneLinerFormatter(env, None, absurls, db).format(wikitext, out, shorten)
     return Markup(out.getvalue())
 
 def wiki_to_outline(wikitext, env, db=None,
Index: trac/web/chrome.py
===================================================================
--- trac/web/chrome.py	(revision 3821)
+++ trac/web/chrome.py	(working copy)
@@ -17,9 +17,10 @@
 import __builtin__
 import os
 import re
+from StringIO import StringIO
 
 from genshi import Markup
-from genshi.builder import tag
+from genshi.builder import tag, Fragment
 from genshi.output import DocType
 from genshi.template import TemplateLoader, MarkupTemplate, TextTemplate
 
@@ -32,7 +33,8 @@
                               format_time, http_date
 from trac.web.api import IRequestHandler, HTTPNotFound
 from trac.web.href import Href
-from trac.wiki import IWikiSyntaxProvider
+from trac.wiki.api import IWikiSyntaxProvider
+from trac.wiki.formatter import Formatter, OneLinerFormatter
 
 def add_link(req, rel, href, title=None, mimetype=None, classname=None):
     """Add a link to the HDF data set that will be inserted as <link> element in
@@ -419,7 +421,30 @@
         data['format_date'] = format_date
         data['format_time'] = format_time
         data['http_date'] = http_date
-        
+
+        def wiki_to_html(text, absurls=False, escape_newlines=False):
+            if not text:
+                return Markup()
+            if isinstance(text, (Fragment, Markup)):
+                return text
+            out = StringIO()
+            Formatter(self.env, req, absurls).format(text, out,
+                                                     escape_newlines)
+            return Markup(out.getvalue())
+            
+        def wiki_to_oneliner(text, absurls=False, shorten=False):
+            if not text:
+                return Markup()
+            if isinstance(text, (Fragment, Markup)):
+                return text
+            out = StringIO()
+            OneLinerFormatter(self.env, req, absurls).format(text, out,
+                                                             shorten)
+            return Markup(out.getvalue())
+
+        data['wiki_to_html'] = wiki_to_html
+        data['wiki_to_oneliner'] = wiki_to_oneliner
+
         ## debugging tools
         from pprint import pformat
         data['pprint'] = pformat
Index: templates/ticket_view.html
===================================================================
--- templates/ticket_view.html	(revision 3821)
+++ templates/ticket_view.html	(working copy)
@@ -69,7 +69,7 @@
                   (last modified by ${description_author})
                 </span>
               </h3>
-              ${description}
+              ${wiki_to_html(ticket.description)}
             </div>
           </form>
         </div>
@@ -122,7 +122,7 @@
                     </py:choose>
                   </li>
                 </ul>
-                <div py:if="change.comment" class="comment">${change.comment}</div>
+                <div py:if="change.comment" class="comment">${wiki_to_html(change.comment)}</div>
               </div>
             </form>
           </div>
@@ -149,7 +149,7 @@
             </fieldset>
             <fieldset py:if="preview" id="preview">
               <legend>Comment Preview</legend>
-              ${preview}
+              ${wiki_to_html(comment)}
             </fieldset>
           </div>
 
Index: templates/report.rss
===================================================================
--- templates/report.rss	(revision 3821)
+++ templates/report.rss	(working copy)
@@ -28,7 +28,7 @@
               <title>#$row.id: $cell.value</title>
             </py:when>
             <py:when test="col == 'description'">
-              <description>unicode($cell.parsed)</description>
+              <description>${unicode(wiki_to_html($cell.value, absurls=True))}</description>
             </py:when>
           </py:choose>
         </py:with>
Index: templates/browser.html
===================================================================
--- templates/browser.html	(revision 3821)
+++ templates/browser.html	(working copy)
@@ -78,7 +78,7 @@
                                  in trac.versioncontrol.web_ui.util.get_changes -->
                     <td class="change">
                       <span class="author">$change.author:</span>
-                      <span class="change">$change.message</span>
+                      <span class="change">${wiki_to_oneliner(change.message)}</span>
                     </td>
                   </tr>
                 </py:with>
@@ -95,7 +95,7 @@
             </th>
           </tr>
           <tr py:if="file">
-            <td class="message">$file.message</td>
+            <td class="message">${wiki_to_html(file.message)}</td>
           </tr>
           <tr py:if="props">
             <td colspan="2">
Index: templates/macros.html
===================================================================
--- templates/macros.html	(revision 3821)
+++ templates/macros.html	(working copy)
@@ -22,7 +22,7 @@
   -      'selector'  is a boolean variable
   -      'name       is the name of the option
   -      'text'      is the displayed text, defaults to 'name'
-  -      'id'        optional id for the checkbox, if different from 'name' 
+  -      'id'        optional id for the checkbox, if different from 'name'
   -->
   <py:def function="checkbox(selector, name, text=None, id=None)">
     <py:with vars="id = id or name">
@@ -43,7 +43,7 @@
   <py:def function="radiobuttons(selector, name, buttons)">
     <label py:for="button in buttons"
            py:with="value = button[0]; text = button[1] or button[0]; default = button[3]">
-      <input type="radio" id="$value" name="$name" value="$value" 
+      <input type="radio" id="$value" name="$name" value="$value"
         checked="${selector == value or (default and selector not in values) and 'checked' or None}" />
       $text
     </label>
@@ -57,8 +57,8 @@
   -
   -      We take care to not insert any extra space.
   -->
-  
-  <py:def function="plural(cnt,noun,keepzero=False)"><py:if 
+
+  <py:def function="plural(cnt,noun,keepzero=False)"><py:if
       test="cnt != 0 or keepzero"
       >${cnt == 1 and ('1 '+noun) or '%d %ss' % (cnt, noun)}</py:if></py:def>
 
@@ -69,7 +69,7 @@
   <py:def function="sizeinfo(size)"><span title="$size bytes">${
       pretty_size(size)
   }</span></py:def>
-    
+
   <!--!  Display how many time elapsed since the given date.
   -
   -      Typically used in sentences like "changed ${dateinfo(date)} ago"
@@ -79,7 +79,7 @@
   <py:def function="dateinfo(date)"><span title="${format_datetime(date)}">${
       pretty_timedelta(date)
   }</span></py:def>
-    
+
   <!--!  Display a sequence of path components.
   -
   -      Each component is a link to the corresponding location in the browser.
@@ -87,7 +87,7 @@
   <py:def function="browser_path_links(path_links)">
     <py:for each="idx, part in enumerate(path_links)">
       <py:with vars="first = idx == 0; last = idx == len(path_links) - 1">
-        <a class="${first and 'first' or None}" 
+        <a class="${first and 'first' or None}"
           title="${first and 'Go to root directory' or 'View ' + part.name}"
           href="$part.href">$part.name</a>
         <py:if test="not last"><span class="sep">/</span></py:if>
@@ -105,7 +105,7 @@
   -->
   <py:def function="changeset_navigation(change, others=[])">
     <li class="first" py:choose="">
-      <py:when test="chrome.links.prev"> 
+      <py:when test="chrome.links.prev">
         &larr; <a class="prev" py:attrs="chrome.links.prev[0]">Previous $change</a>
       </py:when>
       <py:otherwise>
@@ -115,7 +115,7 @@
     <li py:for="label, url in others"><a href="$url">$label</a></li>
     <li class="last" py:choose="">
       <py:when test="chrome.links.next">
-        <a class="next" py:attrs="chrome.links.next[0]">Next $change</a> &rarr; 
+        <a class="next" py:attrs="chrome.links.next[0]">Next $change</a> &rarr;
       </py:when>
       <py:otherwise>
         <span class="missing">Next $change &rarr;</span>
@@ -167,7 +167,7 @@
           Try <a href="$preview.raw_href">downloading</a> the file instead.
         </py:when>
         <py:when test="not preview.rendered">
-          <strong>HTML preview not available</strong>. 
+          <strong>HTML preview not available</strong>.
           To view, <a href="$preview.raw_href">download</a> the file.
         </py:when>
       </py:choose>
@@ -182,9 +182,9 @@
   -->
   <py:def function="list_of_attachments(attachments, attach_href, compact=False)">
     <py:def function="show_one_attachment(attachment)">
-      <a href="$attachment.href" title="View attachment">$attachment.filename</a>
-        (${sizeinfo(attachment.size)}) - added by <em>$attachment.author</em> 
-        ${dateinfo(attachment.date)} ago.
+      <a href="${attachment.href(req)}" title="View attachment">$attachment.filename</a>
+        (${sizeinfo(attachment.size)}) - added by <em>$attachment.author</em>
+        ${dateinfo(attachment.time)} ago.
     </py:def>
     <py:choose test="">
       <py:when test="compact and attachments">
@@ -192,7 +192,7 @@
         <ul>
           <li py:for="attachment in attachments">
             ${show_one_attachment(attachment)}
-            <q py:if="compact and attachment.description">$attachment.description</q>
+            <q py:if="compact and attachment.description">${wiki_to_oneliner(attachment.description)}</q>
           </li>
         </ul>
       </py:when>
@@ -202,7 +202,7 @@
           <dl py:if="attachments" class="attachments">
             <py:for each="attachment in attachments">
               <dt>${show_one_attachment(attachment)}</dt>
-              <dd py:if="attachment.description">$attachment.description</dd>
+              <dd py:if="attachment.description">${wiki_to_oneliner(attachment.description)}</dd>
             </py:for>
           </dl>
           <form py:if="attach_href" method="get" action="$attach_href">
Index: templates/wiki_history.html
===================================================================
--- templates/wiki_history.html	(revision 3821)
+++ templates/wiki_history.html	(working copy)
@@ -47,7 +47,7 @@
               </td>
               <td class="date">${format_datetime(item.date)}</td>
               <td class="author" title="IP-Address: $item.ipnr">$item.author</td>
-              <td class="comment">$item.comment</td>
+              <td class="comment">${wiki_to_oneliner(item.comment, shorten=True)}</td>
             </tr>
           </tbody>
         </table>
Index: templates/milestone_view.html
===================================================================
--- templates/milestone_view.html	(revision 3821)
+++ templates/milestone_view.html	(working copy)
@@ -87,7 +87,7 @@
         </fieldset>
       </form>
 
-      <div class="description">${milestone.description}</div>
+      <div class="description">${wiki_to_html(milestone.description)}</div>
 
       <div py:if="perm.has_permission('MILESTONE_MODIFY') or perm.has_permission('MILESTONE_DELETE')" class="buttons">
         <form py:if="perm.has_permission('MILESTONE_MODIFY')" method="get" action="">
Index: templates/ticket_new.html
===================================================================
--- templates/ticket_new.html	(revision 3821)
+++ templates/ticket_new.html	(working copy)
@@ -8,7 +8,7 @@
  <head>
   <title>New Ticket</title>
   <script type="text/javascript">
-   addEvent(window, 'load', function() { document.getElementById('summary').focus()}); 
+   addEvent(window, 'load', function() { document.getElementById('summary').focus()});
   </script>
  </head>
 
@@ -34,11 +34,11 @@
     <div class="field">
      <label for="description">Full description (you may use <a tabindex="42"
             href="${href.wiki('WikiFormatting')}">WikiFormatting</a> here):</label><br />
-     <textarea id="description" name="description" class="wikitext" rows="10"
-               cols="78">${ticket.description}</textarea>
-     <fieldset py:if="preview" id="preview">
+     <textarea id="description" name="description" class="wikitext" rows="10" cols="78">
+${ticket.description}</textarea>
+     <fieldset py:if="ticket.description" id="preview">
       <legend>Description Preview</legend>
-      ${preview}
+      ${wiki_to_html(ticket.description)}
      </fieldset>
     </div>
 
@@ -85,7 +85,7 @@
 
     </fieldset>
 
-    
+
     <p py:if="can_attach">
      <label>
       <input type="checkbox" name="attachment" checked="${attachment or None}" />
@@ -99,7 +99,7 @@
     </div>
 
    </form>
-   
+
    <script type="text/javascript" src="${chrome.htdocs_location}js/wikitoolbar.js"></script>
 
    <div id="help">
Index: templates/revisionlog.html
===================================================================
--- templates/revisionlog.html	(revision 3821)
+++ templates/revisionlog.html	(working copy)
@@ -116,11 +116,11 @@
                   </td>
                   <td class="date">$change.date</td>
                   <td class="author">$change.author</td>
-                  <td class="summary">${not verbose and change.message or ''}</td>
+                  <td class="summary">${not verbose and wiki_to_oneliner(change.message, shorten=True) or ''}</td>
                 </tr>
 
                 <tr py:if="verbose">
-                  <td class="summary" colspan="7">$change.message</td>
+                  <td class="summary" colspan="7">${wiki_to_html(change.message)}</td>
                 </tr>
               </py:with>
             </py:for>
Index: templates/revisionlog.rss
===================================================================
--- templates/revisionlog.rss	(revision 3821)
+++ templates/revisionlog.rss	(working copy)
@@ -16,10 +16,10 @@
     <item py:for="item in items" py:with="change = changes[item.rev]">
       <author py:if="change.author">$change.author</author>
       <pubDate>${format_datetime(change.date_seconds)}</pubDate> <!--! FIXME: use 'change.date' later on -->
-      <title>Revision $item.rev: $change.shortlog</title>
+      <title>Revision $item.rev: ${u' '.join(change.shortlog.striptags().splitlines())})</title>
       <link>${abs_href.changeset(rev, path)}</link>
       <guid isPermaLink="false">${abs_href.changeset(item.rev, item.path)}</guid>
-      <description>$change.message</description>
+      <description>${unicode(wiki_to_html(change.message, absurls=True))}</description>
       <category>Log</category>
     </item>
 
Index: templates/report_view.html
===================================================================
--- templates/report_view.html	(revision 3821)
+++ templates/report_view.html	(working copy)
@@ -5,7 +5,7 @@
     <span py:if="numrows and report.id != -1" class="numrows">($numrows matches)</span>
   </h1>
 
-  <div py:if="report.description" id="description">$report.description</div>
+  <div py:if="report.description" id="description">${wiki_to_html(report.description)}</div>
 
   <div py:if="report.id != -1 and (report.can.create or report.can.modify or report.can.delete)" class="buttons">
     <form py:if="report.can.modify" action="" method="get">
@@ -108,7 +108,7 @@
 
                     <py:when test="col == 'description'">
                       <py:def function="cellclass"></py:def>
-                      <py:def function="content">$cell.parsed</py:def>
+                      <py:def function="content">${wiki_to_html(cell.value)}</py:def>
                     </py:when>
 
                     <py:otherwise>
Index: templates/timeline.html
===================================================================
--- templates/timeline.html	(revision 3821)
+++ templates/timeline.html	(working copy)
@@ -36,10 +36,12 @@
         <h2>$day:</h2>
         <dl>
           <py:for each="event in events">
-            <dt class="${event.kind}"><a href="${event.href}">
-              <span class="time">${event.time}</span> ${event.title}
-            </a></dt>
-            <dd class="${event.kind}">${event.message}</dd>
+            <dt class="${event.kind}">
+              <a href="${event.href}"><span class="time">${event.time}</span> ${event.title}</a>
+            </dt>
+            <dd class="${event.kind}" py:with="shorten = event.shorten_message is None and True or event.shorten_message">
+              ${wiki_to_oneliner(event.message, shorten)}
+            </dd>
           </py:for>
         </dl>
       </py:for>
Index: templates/wiki_edit.html
===================================================================
--- templates/wiki_edit.html	(revision 3821)
+++ templates/wiki_edit.html	(working copy)
@@ -33,12 +33,12 @@
           <table id="info" summary="Revision info">
             <tbody>
               <tr><th scope="col">Preview of future version ${page.version+1} (modified by $author)</th></tr>
-              <tr><td class="message">$comment_html</td></tr>
+              <tr><td class="message">${wiki_to_html(comment)}</td></tr>
             </tbody>
           </table>
           <fieldset id="preview">
             <legend>Preview (<a href="#edit">skip</a>)</legend>
-            <div class="wikipage">$page_html</div>
+            <div class="wikipage">${wiki_to_html(page.text)}</div>
           </fieldset>
         </py:when>
         <py:when test="'collision'">
@@ -63,8 +63,7 @@
             </select>
           </div>
           <p><textarea id="text" class="wikitext" name="text" cols="80" rows="$edit_rows">
-$page.text
-            </textarea>
+$page.text</textarea>
           </p>
           <script type="text/javascript">
             var scrollBarPos = document.getElementById("scroll_bar_pos");
Index: templates/timeline.rss
===================================================================
--- templates/timeline.rss	(revision 3821)
+++ templates/timeline.rss	(working copy)
@@ -17,9 +17,9 @@
    <title>${event.title}</title>
    <author py:if="event.author">${event.author}</author>
    <pubDate>${event.date}</pubDate>
-   <link>${event.href}</link>
-   <guid isPermaLink="false">${event.href}/${event.dateuid}</guid>
-   <description>${event.message}</description>
+   <link>${abs_href()}/${event.href}</link>
+   <guid isPermaLink="false">${abs_href()}/${event.href}/${event.dateuid}</guid>
+   <description>${unicode(wiki_to_html(event.message, absurls=True))}</description>
   </item>
 
  </channel>
Index: templates/about.html
===================================================================
--- templates/about.html	(revision 3821)
+++ templates/about.html	(working copy)
@@ -69,14 +69,14 @@
               </tr>
               <tr py:if="plugin.description">
                 <th class="description" scope="row">Description</th>
-                <td class="description">${plugin.description}</td>
+                <td class="description">${wiki_to_html(plugin.description)}</td>
               </tr>
               <tr py:for="idx,extension_point in enumerate(plugin.extension_points)">
                 <th py:if="idx == 0" class="xtnpts"
                   rowspan="${len(plugin.extension_points)}">
                   Extension points:
                 </th>
-                <td class="xtnpts">        
+                <td class="xtnpts">
                   <code>${extension_point.module}.${extension_point.interface}</code>
                   <div py:if="extension_point.extensions" py:strip="">
                     (${len(extension_point.extensions)} extensions)
@@ -86,7 +86,7 @@
                       </li>
                     </ul>
                   </div>
-                  <div class="description">${extension_point.description}</div>
+                  <div class="description">${wiki_to_html(extension_point.description)}</div>
                 </td>
               </tr>
             </table>
@@ -102,20 +102,20 @@
         </a>
         <h1>About Trac ${trac.version}</h1>
         <p>Trac is a web-based software project management and bug/issue
-          tracking system emphasizing ease of use and low ceremony. 
-          It provides an integrated Wiki, an interface to version control 
+          tracking system emphasizing ease of use and low ceremony.
+          It provides an integrated Wiki, an interface to version control
           systems, and a number convenient ways to stay on top of events
           and changes within a project.
         </p>
         <p>Trac is distributed under the modified BSD License.<br />
-          The complete text of the license can be found 
+          The complete text of the license can be found
           <a href="http://trac.edgewall.org/wiki/TracLicense">online</a>
           as well as in the <tt>COPYING</tt> file included in the distribution.</p>
         <a href="http://www.python.org/" style="border: none; float: right">
           <img style="display: block" src="${chrome.htdocs_location}python.png"
             alt="python powered" width="140" height="56" />
         </a>
-        <p>Please visit the Trac open source project: 
+        <p>Please visit the Trac open source project:
           <a href="http://trac.edgewall.org/">http://trac.edgewall.org/</a></p>
         <p>Copyright &copy; 2003-2006
           <a href="http://www.edgewall.org/">Edgewall Software</a></p>
Index: templates/roadmap.html
===================================================================
--- templates/roadmap.html	(revision 3821)
+++ templates/roadmap.html	(working copy)
@@ -16,7 +16,7 @@
 
     <div id="content" class="roadmap">
       <h1>Roadmap</h1>
-      
+
       <form id="prefs" method="get" action="">
         <div>
           <input type="checkbox" id="showall" name="show" value="all"
@@ -62,7 +62,7 @@
             </py:if>
           </div>
 
-          <div class="description">${milestone.description}</div>
+          <div class="description">${wiki_to_html(milestone.description)}</div>
 
         </li>
       </ul>
Index: templates/ticket.rss
===================================================================
--- templates/ticket.rss	(revision 3821)
+++ templates/ticket.rss	(working copy)
@@ -4,7 +4,7 @@
 
     <title>${project.name}: Ticket $title</title>
     <link>${abs_href.ticket(id)}</link>
-    <description>${unicode(description)}</description>
+    <description>${unicode(wiki_to_html(ticket.description, absurls=True))}</description>
     <language>en-us</language>
     <image py:if="chrome.logo.src">
       <title>$project.name</title>
@@ -18,12 +18,12 @@
       <pubDate>${http_date(change.date)}</pubDate>
       <title>$change.title</title>
       <link>${abs_href.ticket(id)}<py:if test="change.cnum">#comment:$change.cnum</py:if></link>
-      <guid isPermaLink="false">${abs_href.ticket(id)}<py:if test="change.cnum">#comment:$change.cnum</py:if></guid>
+      <guid isPermaLink="false">${abs_href.ticket(id)}<py:if test="change.cnum">#comment:$change.cnum</py:if></guid     >
       <description>
         <py:if test="change.fields">
           &lt;ul&gt;
           <py:for each="field, value in change.fields.iteritems()">
-            &lt;li&gt;&lt;strong&gt;$field&lt;/strong&gt; 
+            &lt;li&gt;&lt;strong&gt;$field&lt;/strong&gt;
             <py:choose>
               <py:when test="not value.old">
                 set to &lt;em&gt;$value.new&lt;/em&gt;
@@ -39,7 +39,7 @@
           </py:for>
           &lt;/ul&gt;
         </py:if>
-        $change.comment
+        ${unicode(wiki_to_html(change.comment, absurls=True))}
       </description>
       <category>Ticket</category>
     </item>
Index: templates/attachment.html
===================================================================
--- templates/attachment.html	(revision 3821)
+++ templates/attachment.html	(working copy)
@@ -77,12 +77,12 @@
           <tbody>
             <tr>
               <th scope="col">
-                File $attachment.filename, ${sizeinfo(attachment.size)} 
-                (added by $attachment.author,  ${dateinfo(attachment.date)} ago)
+                File $attachment.filename, ${sizeinfo(attachment.size)}
+                (added by $attachment.author,  ${dateinfo(attachment.time)} ago)
               </th>
             </tr>
             <tr>
-              <td class="message">$attachment.description</td>
+              <td class="message">${wiki_to_html(attachment.description)}</td>
             </tr>
           </tbody>
         </table>
Index: templates/wiki_diff.html
===================================================================
--- templates/wiki_diff.html	(revision 3821)
+++ templates/wiki_diff.html	(working copy)
@@ -52,7 +52,7 @@
         <dt class="property message">Comment:</dt>
         <dd class="message" py:choose="">
           <em py:when="multi" class="multi">(multiple changes)</em>
-          <py:otherwise>$comment</py:otherwise>
+          <py:otherwise>${wiki_to_html(comment)}</py:otherwise>
         </dd>
       </dl>
       <div class="diff">
Index: templates/wiki_view.html
===================================================================
--- templates/wiki_view.html	(revision 3821)
+++ templates/wiki_view.html	(working copy)
@@ -20,24 +20,24 @@
         <li><a href="${href.wiki('RecentChanges')}">Index by Date</a></li>
         <li class="last">
           <a href="${req.href.wiki(page.name, action='diff', version=page.version)}">Last Change</a>
-        </li> 
+        </li>
       </ul>
       <hr />
     </div>
 
     <div id="content" class="wiki">
-      
-      <py:if test="comment_html">
+
+      <py:if test="version">
         <table id="info" summary="Revision info">
           <tbody>
             <tr><th scope="col">Version $page.version (modified by $page.author, ${dateinfo(page.time)} ago)</th></tr>
-            <tr><td class="message">$comment_html</td></tr>
+            <tr><td class="message">${wiki_to_html(comment or '--')}</td></tr>
           </tbody>
         </table>
       </py:if>
 
       <div class="wikipage">
-        <div id="searchable">$page_html</div>
+        <div id="searchable">${wiki_to_html(page.text)}</div>
       </div>
 
       ${list_of_attachments(attachments, attach_href, compact=True)}
Index: templates/changeset.html
===================================================================
--- templates/changeset.html	(revision 3821)
+++ templates/changeset.html	(working copy)
@@ -105,7 +105,7 @@
           <dd class="$prop.htmlclass">$prop.value</dd>
           </span>
           <dt class="property message">Message:</dt>
-          <dd class="message" id="searchable">${changeset.message or '&nbsp;'}</dd>
+          <dd class="message" id="searchable">${wiki_to_html(changeset.message)}</dd>
         </py:if>
         <dt class="property files">${filter(None, changes) and 'Files:' or '(No files)'}</dt>
         <dd class="files">
Index: templates/milestone_edit.html
===================================================================
--- templates/milestone_edit.html	(revision 3821)
+++ templates/milestone_edit.html	(working copy)
@@ -13,7 +13,7 @@
     <link rel="stylesheet" type="text/css"
           href="${chrome.htdocs_location}css/roadmap.css" />
     <script type="text/javascript">
-      addEvent(window, 'load', function() { document.getElementById('name').focus()}); 
+      addEvent(window, 'load', function() { document.getElementById('name').focus()});
     </script>
   </head>
 
@@ -82,7 +82,7 @@
             <label for="description">Description (you may use <a tabindex="42"
                    href="${href.wiki('WikiFormatting')}">WikiFormatting</a> here):</label>
             <p><textarea id="description" name="description" class="wikitext" rows="10" cols="78">
-${milestone.description_source}</textarea></p>
+${milestone.description}</textarea></p>
           </fieldset>
         </div>
         <div class="buttons" py:choose="milestone.exists">
Index: templates/query_div.html
===================================================================
--- templates/query_div.html	(revision 3821)
+++ templates/query_div.html	(working copy)
@@ -56,7 +56,7 @@
             <td colspan="${len(headers)}">
               <p class="meta">Reported by <strong>$result.reporter</strong>,
                 ${dateinfo(result.time)} ago${result.description and ':' or ''}</p>
-              <p py:if="result.description">$result.description</p>
+              <py:if test="result.description">${wiki_to_html(result.description)}</py:if>
             </td>
           </tr>
 
Index: templates/query.rss
===================================================================
--- templates/query.rss	(revision 3821)
+++ templates/query.rss	(working copy)
@@ -17,7 +17,7 @@
       <title>#$result.id: $result.summary</title>
       <pubDate py:if="result.time">${http_date(result.time)}</pubDate>
       <author py:if="result.reporter">$result.reporter</author>
-      <description>${unicode(result.description)}</description>
+      <description>${unicode(wiki_to_html(result.description, absurls=True))}</description>
       <category>Results</category>
       <comments>$href#changelog</comments>
     </item>
