Commits

Julian Cowley  committed 7cad1e9

Rewrite of all patches to fit in new development model

After nine months, I finally bit the bullet and rewrote the patches for
the new development model that Radomir is using (hatta.py broken into
separate files). Some of the patches worked without changes as long as
the right file was used as the destination (instead of the old
hatta.py). Others patches, such as the xhtml one, had to be rewritten
from scratch.

  • Participants
  • Parent commits e3694e5

Comments (0)

Files changed (9)

File patches-julian-file-uri

 Add the "file:" URI scheme to wiki links and free text so that the
 URI is recognized as a URI, not as an internal wiki link.
 
-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -86,6 +86,8 @@
+diff --git a/hatta/parser.py b/hatta/parser.py
+--- a/hatta/parser.py
++++ b/hatta/parser.py
+@@ -23,6 +23,8 @@
      True
      >>> external_link('mailto:user@example.com')
      True
      >>> external_link('PageTitle')
      False
      >>> external_link(u'ąęśćUnicodePage')
-@@ -96,7 +98,8 @@
-     return (addr.startswith('http://')
-             or addr.startswith('https://')
-             or addr.startswith('ftp://')
--            or addr.startswith('mailto:'))
-+            or addr.startswith('mailto:')
-+            or addr.startswith('file:'))
- 
- def page_mime(title):
-     """
-@@ -847,7 +850,7 @@
-         "bold": (10, ur"[*][*]"),
-         "code": (20, ur"[{][{][{](?P<code_text>([^}]|[^}][}]|[^}][}][}])"
-                 ur"*[}]*)[}][}][}]"),
--        "free_link": (30, ur"""(http|https|ftp)://\S+[^\s.,:;!?()'"=+<>-]"""),
-+        "free_link": (30, ur"""(http|https|ftp|file)://\S+[^\s.,:;!?()'"=+<>-]"""),
-         "italic": (40 , ur"//"),
-         "link": (50, ur"\[\[(?P<link_target>([^|\]]|\][^|\]])+)"
-                 ur"(\|(?P<link_text>([^\]]|\][^\]])+))?\]\]"),

File patches-julian-menu-as-list

 From: Julian Cowley <julian@lava.net>
 Subject: Markup the menu as unordered list
 
-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -1716,7 +1716,8 @@
-         if self.wiki.logo_page in self.storage:
-             yield self.logo()
-         yield self.search_form()
--        yield html.div(u" ".join(self.menu()), class_="menu")
-+        yield html.div(html.ul("".join(html.li(s) for s in self.menu())),
-+                       class_="menu")
-         yield html.h1(html(special_title or self.title))
- 
-     def html_header(self, special_title, edit_url):
-@@ -1762,11 +1763,14 @@
-                 (_(u'Backlinks'), 'backlinks',
-                  self.get_url(self.title, self.wiki.backlinks))
-             ]
-+        yield u'<ul>'
-         for label, class_, url in footer_links:
-             if url:
--                yield werkzeug.xhtml.a(werkzeug.xhtml(label), href=url,
--                                      class_=class_)
-+                yield werkzeug.xhtml.li(werkzeug.xhtml.a(werkzeug.xhtml(label),
-+                                                         href=url,
-+                                                         class_=class_))
-                 yield u'\n'
-+        yield u'</ul>'
- 
-     def render_content(self, content, special_title=None):
-         """The main page template."""
-@@ -2397,6 +2401,9 @@
+diff --git a/hatta/data.py b/hatta/data.py
+--- a/hatta/data.py
++++ b/hatta/data.py
+@@ -94,6 +94,9 @@
  div.snippet { font-size: 80%; color: #888a85 }
- div.header div.menu { float: right; margin-top: 1.25em }
- div.header div.menu a.current { color: #000 }
-+div.header div.menu ul, div.footer ul { margin: 0; }
-+div.header div.menu li, div.footer li { display: inline;
+ div#hatta-header div#hatta-menu { float: right; margin-top: 1.25em }
+ div#hatta-header div#hatta-menu a.current { color: #000 }
++div#hatta-header div#hatta-menu ul, div#hatta-footer ul { margin: 0; }
++div#hatta-header div#hatta-menu li, div#hatta-footer li { display: inline;
 +    list-style-type: none; padding-left: 5px; }
  hr { background: transparent; border:none; height: 0;
       border-bottom: 1px solid #babdb6; clear: both }
  blockquote { border-left:.25em solid #ccc; padding-left:.5em; margin-left:0}
+diff --git a/hatta/templates/base.html b/hatta/templates/base.html
+--- a/hatta/templates/base.html
++++ b/hatta/templates/base.html
+@@ -45,9 +45,11 @@
+ 
+ {% block menu %}
+     <div id="hatta-menu">
+-    {% for part in page.menu() %}
+-        {{ part|safe }}
+-    {% endfor %}
++        <ul>
++        {% for part in page.menu() %}
++            <li>{{ part|safe }}</li>
++        {% endfor %}
++        </ul>
+     </div>
+ {% endblock %}
+ 
+diff --git a/hatta/templates/page.html b/hatta/templates/page.html
+--- a/hatta/templates/page.html
++++ b/hatta/templates/page.html
+@@ -4,12 +4,14 @@
+ {% block title %}{{ title }} - {{ wiki.site_name }}{% endblock %}
+ 
+ {% block footer %}
+-    {% if edit_url %}
+-        <a href="{{ edit_url }}"
+-           class="edit">{{ _('Edit') }}</a>
+-    {% endif %}
+-    <a href="{{ url(title, wiki.history) }}"
+-       class="hatta-history">{{ _('History') }}</a>
+-    <a href="{{ url(title, wiki.backlinks) }}"
+-       class="hatta-backlinks">{{ _('Backlinks') }}</a>
++    <ul>
++	{% if edit_url %}
++	    <li><a href="{{ edit_url }}"
++		   class="edit">{{ _('Edit') }}</a></li>
++	{% endif %}
++	<li><a href="{{ url(title, wiki.history) }}"
++	       class="hatta-history">{{ _('History') }}</a></li>
++	<li><a href="{{ url(title, wiki.backlinks) }}"
++	       class="hatta-backlinks">{{ _('Backlinks') }}</a></li>
++    </ul>
+ {% endblock %}
+diff --git a/hatta/templates/page_special.html b/hatta/templates/page_special.html
+--- a/hatta/templates/page_special.html
++++ b/hatta/templates/page_special.html
+@@ -6,8 +6,14 @@
+ {% block title %}{{ special_title }} - {{ wiki.site_name }}{% endblock %}
+ 
+ {% block footer %}
+-    <a href="{{ url(None, wiki.recent_changes) }}" class="changes">Changes</a>
+-    <a href="{{ url(None, wiki.all_pages) }}" class="index">Index</a>
+-    <a href="{{ url(None, wiki.orphaned) }}" class="orphaned">Orphaned</a>
+-    <a href="{{ url(None, wiki.wanted) }}" class="wanted">Wanted</a>
++    <ul>
++        <li><a href="{{ url(None, wiki.recent_changes) }}"
++               class="changes">Changes</a></li>
++        <li><a href="{{ url(None, wiki.all_pages) }}"
++               class="index">Index</a></li>
++        <li><a href="{{ url(None, wiki.orphaned) }}"
++               class="orphaned">Orphaned</a></li>
++        <li><a href="{{ url(None, wiki.wanted) }}"
++               class="wanted">Wanted</a></li>
++    </ul>
+ {% endblock %}

File patches-julian-music-handling

-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -846,6 +846,13 @@
+diff --git a/hatta/data.py b/hatta/data.py
+--- a/hatta/data.py
++++ b/hatta/data.py
+@@ -103,6 +103,7 @@
+ abbr.date {border:none}
+ dt {font-weight: bold; float: left; }
+ dd {font-style: italic; }
++span.music-symbol { font-family: Arial Unicode MS, Lucida Sans Unicode; }
+ @media print {
+  body {background:white;color:black;font-size:100%;font-family:serif;}
+  #hatta-search, #hatta-menu, #hatta-footer {display:none;}
+diff --git a/hatta/parser.py b/hatta/parser.py
+--- a/hatta/parser.py
++++ b/hatta/parser.py
+@@ -97,6 +97,13 @@
          r"''": "&rdquo;",
          r",,": "&bdquo;",
      }
      markup = {
          # "name": (priority, ur"pattern"),
          "bold": (10, ur"[*][*]"),
-@@ -865,6 +872,8 @@
-         "newline": (120, ur"\n"),
-         "punct": (130, ur'(^|\b|(?<=\s))(%s)((?=[\s.,:;!?)/&=+"\'—-])|\b|$)' %
+@@ -117,6 +124,8 @@
+         "punct": (130,
+                   ur'(^|\b|(?<=\s))(%s)((?=[\s.,:;!?)/&=+"\'—-])|\b|$)' %
                    ur"|".join(re.escape(k) for k in punct)),
 +        "music": (135, ur':::(?P<music_symbol>%s):::' %
 +                  ur"|".join(re.escape(k) for k in music)),
          "table": (140, ur"=?\|=?"),
          "text": (150, ur".+?"),
      }
-@@ -1036,6 +1045,11 @@
+@@ -290,6 +299,11 @@
      def _line_code(self, groups):
          return u'<code>%s</code>' % werkzeug.escape(groups["code_text"])
  
      def _line_free_link(self, groups):
          groups['link_target'] = groups['free_link']
          return self._line_link(groups)
-@@ -2600,6 +2614,7 @@
- abbr.date {border:none}
- dt {font-weight: bold; float: left; }
- dd {font-style: italic; }
-+span.music-symbol { font-family: Arial Unicode MS, Lucida Sans Unicode; }
- """
- 
-     def __init__(self, config):

File patches-julian-strip-table-cells

 From: Julian Cowley <julian@lava.net>
 Subject: Strip whitespace from table cells
 
-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -1149,6 +1149,7 @@
+diff --git a/hatta/parser.py b/hatta/parser.py
+--- a/hatta/parser.py
++++ b/hatta/parser.py
+@@ -403,6 +403,7 @@
              yield '<tr>'
              in_cell = False
              in_th = False
  
              for part in self.parse_line(table_row):
                  if part in ('=|', '|', '=|=', '|='):
-@@ -1162,6 +1163,9 @@
+@@ -416,6 +417,9 @@
                          in_th = True
                      else:
                          in_th = False
                  else:
                      if not in_cell:
                          if in_th:
-@@ -1169,6 +1173,13 @@
+@@ -423,6 +427,13 @@
                          else:
                              yield '<td>'
                          in_cell = True

File patches-julian-tbody

 From: Julian Cowley <julian@lava.net>
 Subject: Add support for TBODY in tables
 
-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -988,18 +988,28 @@
+diff --git a/hatta/parser.py b/hatta/parser.py
+--- a/hatta/parser.py
++++ b/hatta/parser.py
+@@ -378,18 +378,28 @@
      def _block_table(self, block):
          first_line = None
          in_head = False
              yield '<tr>'
              in_cell = False
              in_th = False
-@@ -1030,6 +1040,11 @@
+@@ -420,6 +430,11 @@
                  else:
                      yield '</td>'
              yield '</tr>'

File patches-julian-unicode-test

 From: Julian Cowley <julian@lava.net>
 Subject: Warn if Hatta is not running on a wide Python build
 
-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -2606,6 +2606,11 @@
+diff --git a/hatta/wiki.py b/hatta/wiki.py
+--- a/hatta/wiki.py
++++ b/hatta/wiki.py
+@@ -213,6 +213,11 @@
          if config.get_bool('show_version', False):
-             sys.stdout.write("Hatta %s\n" % __version__)
+             sys.stdout.write("Hatta %s\n" % hatta.__version__)
              sys.exit()
 +        try:
 +            unichr(0x10ffff)
 +            sys.stderr.write("See http://www.python.org/dev/peps/pep-0261/\n")
          self.dead = False
          self.config = config
-         self.language = config.get('language', None)
+ 

File patches-julian-unix-end-of-line

 From: Julian Cowley <julian@lava.net>
 Subject: Save files with Unix end-of-lines
 
-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -464,6 +464,8 @@
-         """Save text as specified page, encoded to charset."""
+diff --git a/hatta/storage.py b/hatta/storage.py
+--- a/hatta/storage.py
++++ b/hatta/storage.py
+@@ -278,7 +278,8 @@
  
          data = text.encode(self.charset)
-+        # Convert both CRLF (DOS/network) and CR (Mac) to LF (Unix)
-+        data = data.replace('\r\n', '\n').replace('\r', '\n')
+         if self.unix_eol:
+-            data = data.replace('\r\n', '\n')
++            # Convert both CRLF (DOS/network) and CR (Mac) to LF (Unix)
++            data = data.replace('\r\n', '\n').replace('\r', '\n')
          self.save_data(title, data, author, comment, parent)
  
      def page_text(self, title):

File patches-julian-xhtml

 From: Julian Cowley <julian@lava.net>
 Subject: XHTML compliance (incomplete)
 
-diff --git a/hatta.py b/hatta.py
---- a/hatta.py
-+++ b/hatta.py
-@@ -982,7 +982,7 @@
-         return groups["table"]
- 
-     def _line_linebreak(self, groups):
--        return u'<br>'
-+        return u'<br />'
- 
-     def _line_smiley(self, groups):
-         smiley = groups["smiley_face"]
-@@ -1076,7 +1076,7 @@
-     def _block_code(self, block):
-         for self.line_no, part in block:
-             inside = u"\n".join(self.lines_until(self.code_close_re))
--            yield werkzeug.html.pre(werkzeug.html(inside), class_="code",
-+            yield werkzeug.xhtml.pre(werkzeug.xhtml(inside), class_="code",
-                                     id="line_%d" % self.line_no)
- 
-     def _block_syntax(self, block):
-@@ -1087,8 +1087,8 @@
-                 return self.wiki_syntax(inside, syntax=syntax,
-                                         line_no=self.line_no)
-             else:
--                return [werkzeug.html.div(werkzeug.html.pre(
--                    werkzeug.html(inside), id="line_%d" % self.line_no),
-+                return [werkzeug.xhtml.div(werkzeug.xhtml.pre(
-+                    werkzeug.xhtml(inside), id="line_%d" % self.line_no),
-                     class_="highlight")]
- 
-     def _block_macro(self, block):
-@@ -1107,7 +1107,7 @@
-                 first_line = self.line_no
-             parts.append(part)
-         text = u"".join(self.parse_line(u"".join(parts)))
--        yield werkzeug.html.p(text, self.pop_to(""), id="line_%d" % first_line)
-+        yield werkzeug.xhtml.p(text, self.pop_to(""), id="line_%d" % first_line)
- 
-     def _block_indent(self, block):
-         parts = []
-@@ -1117,7 +1117,7 @@
-                 first_line = self.line_no
-             parts.append(part.rstrip())
-         text = u"\n".join(parts)
--        yield werkzeug.html.pre(werkzeug.html(text), id="line_%d" % first_line)
-+        yield werkzeug.xhtml.pre(werkzeug.xhtml(text), id="line_%d" % first_line)
- 
-     def _block_table(self, block):
-         first_line = None
-@@ -1171,7 +1171,7 @@
- 
-     def _block_rule(self, block):
-         for self.line_no, line in block:
--            yield werkzeug.html.hr()
-+            yield werkzeug.xhtml.hr()
- 
-     def _block_heading(self, block):
-         for self.line_no, line in block:
-@@ -1179,7 +1179,7 @@
-             self.headings[level-1] = self.headings.get(level-1, 0)+1
-             label = u"-".join(str(self.headings.get(i, 0))
-                               for i in range(level))
--            yield werkzeug.html.a(name="head-%s" % label)
-+            yield werkzeug.xhtml.a(name="head-%s" % label)
-             yield u'<h%d id="line_%d">%s</h%d>' % (level, self.line_no,
-                 werkzeug.escape(line.strip("= \t\n\r\v")), level)
- 
-@@ -1238,11 +1238,11 @@
-         for self.line_no, part in block:
-             yield u'<div class="conflict">'
-             local = u"\n".join(self.lines_until(self.conflict_sep_re))
--            yield werkzeug.html.pre(werkzeug.html(local),
-+            yield werkzeug.xhtml.pre(werkzeug.xhtml(local),
-                                     class_="local",
-                                     id="line_%d" % self.line_no)
-             other = u"\n".join(self.lines_until(self.conflict_close_re))
--            yield werkzeug.html.pre(werkzeug.html(other),
-+            yield werkzeug.xhtml.pre(werkzeug.xhtml(other),
-                                     class_="other",
-                                     id="line_%d" % self.line_no)
-             yield u'</div>'
-@@ -1745,7 +1745,7 @@
-         text = datetime.strftime('%Y-%m-%d %H:%M')
-         # We are going for YYYY-MM-DDTHH:MM:SSZ
-         title = datetime.strftime('%Y-%m-%dT%H:%M:%SZ')
--        html = werkzeug.html.abbr(text, class_="date", title=title)
-+        html = werkzeug.xhtml.abbr(text, class_="date", title=title)
-         return html
- 
- 
-@@ -1784,14 +1784,14 @@
-                 if addr not in self.storage:
-                     classes.append('nonexistent')
-         class_ = ' '.join(classes) or None
--        return werkzeug.html.a(image or text, href=href, class_=class_,
-+        return werkzeug.xhtml.a(image or text, href=href, class_=class_,
-                                title=addr+chunk)
- 
-     def wiki_image(self, addr, alt, class_='wiki', lineno=0):
+diff --git a/hatta/data.py b/hatta/data.py
+--- a/hatta/data.py
++++ b/hatta/data.py
+@@ -84,7 +84,7 @@
+     border: solid 1px #babdb6; }
+ .editor label { display:block; text-align: right }
+ .editor .upload { margin: 2em auto; text-align: center }
+-form#hatta-search input#hatta-search, .editor label input { font-size: 100%;
++form#hatta-search input, .editor label input { font-size: 100%;
+     border: solid 1px #babdb6; margin: 0.125em 0 }
+ .editor label.comment input  { width: 32em }
+ a#hatta-logo { float: left; display: block; margin: 0.25em }
+diff --git a/hatta/page.py b/hatta/page.py
+--- a/hatta/page.py
++++ b/hatta/page.py
+@@ -156,7 +156,7 @@
          """Create HTML for a wiki image."""
  
          addr = addr.strip()
 -        html = werkzeug.html
 +        html = werkzeug.xhtml
          chunk = ''
-         if external_link(addr):
+         if parser.external_link(addr):
              return html.img(src=werkzeug.url_fix(addr), class_="external",
-@@ -1811,14 +1811,14 @@
-             return html.a(html(alt), href=self.get_url(addr))
- 
-     def search_form(self):
--        html = werkzeug.html
-+        html = werkzeug.xhtml
-         return html.form(html.div(html.input(name="q", class_="search"),
-                 html.input(class_="button", type_="submit", value=_(u'Search')),
--            ), method="GET", class_="search",
-+            ), method="get", class_="search",
-             action=self.get_url(None, self.wiki.search))
- 
-     def logo(self):
--        html = werkzeug.html
-+        html = werkzeug.xhtml
-         img = html.img(alt=u"[%s]" % self.wiki.front_page,
-                        src=self.get_download_url(self.wiki.logo_page))
-         return html.a(img, class_='logo', href=self.get_url(self.wiki.front_page))
-@@ -1841,7 +1841,7 @@
-             yield self.wiki_link(link, label, class_=class_)
- 
-     def header(self, special_title):
--        html = werkzeug.html
-+        html = werkzeug.xhtml
-         if self.wiki.logo_page in self.storage:
-             yield self.logo()
-         yield self.search_form()
-@@ -1850,7 +1850,7 @@
- 
-     def html_header(self, special_title, edit_url):
-         e = lambda x: werkzeug.escape(x, quote=True)
--        h = werkzeug.html
-+        h = werkzeug.xhtml
-         yield h.title(u'%s - %s' % (e(special_title or self.title),
-                                     e(self.wiki.site_name)))
-         yield h.link(rel="stylesheet", type_="text/css",
-@@ -1892,7 +1892,7 @@
-             ]
-         for label, class_, url in footer_links:
-             if url:
--                yield werkzeug.html.a(werkzeug.html(label), href=url,
-+                yield werkzeug.xhtml.a(werkzeug.xhtml(label), href=url,
-                                       class_=class_)
-                 yield u'\n'
- 
-@@ -1908,9 +1908,11 @@
-                 pass
- 
-         yield u"""\
--<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
--"http://www.w3.org/TR/html4/strict.dtd">
--<html><head>\n"""
-+<?xml version="1.0" encoding="UTF-8"?>
-+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-+<head>\n"""
-         for part in self.html_header(special_title, edit_url):
-             yield part
-         yield u'\n</head><body><div class="header">\n'
-@@ -1930,22 +1932,22 @@
-     def pages_list(self, pages, message=None, link=None, _class=None):
-         """Generate the content of a page list page."""
- 
--        yield werkzeug.html.p(werkzeug.escape(message) % {'link': link})
-+        yield werkzeug.xhtml.p(werkzeug.escape(message) % {'link': link})
-         yield u'<ul class="%s">' % werkzeug.escape(_class or 'pagelist')
-         for title in pages:
--            yield werkzeug.html.li(self.wiki_link(title))
-+            yield werkzeug.xhtml.li(self.wiki_link(title))
-         yield u'</ul>'
- 
-     def history_list(self):
-         """Generate the content of the history page."""
- 
--        h = werkzeug.html
-+        h = werkzeug.xhtml
-         max_rev = -1;
-         title = self.title
-         link = self.wiki_link(title)
-         yield h.p(h(_(u'History of changes for %(link)s.')) % {'link': link})
-         url = self.request.get_url(title, self.wiki.undo, method='POST')
--        yield u'<form action="%s" method="POST"><ul class="history">' % url
-+        yield u'<form action="%s" method="post"><ul class="history">' % url
-         try:
-             self.wiki._check_lock(title)
-             read_only = False
-@@ -1970,7 +1972,7 @@
-                        h.i(self.wiki_link("~%s" % author, author)),
-                        h.div(h(comment), class_="comment"))
-         yield u'</ul>'
--        yield h.input(type_="hidden", name="parent", value=max_rev)
-+        yield h.div(h.input(type_="hidden", name="parent", value=max_rev))
-         yield u'</form>'
- 
- 
-@@ -1994,7 +1996,7 @@
+@@ -263,7 +263,7 @@
      def content_iter(self, lines):
          yield '<pre>'
          for line in lines:
          yield '</pre>'
  
      def plain_text(self):
-@@ -2031,14 +2033,14 @@
+@@ -302,7 +302,7 @@
              comment = _(u'created')
              rev = -1
-         except ForbiddenErr, e:
--            yield werkzeug.html.p(
--                werkzeug.html(_(unicode(e))))
-+            yield werkzeug.xhtml.p(
-+                werkzeug.xhtml(_(unicode(e))))
-             return
+         except error.ForbiddenErr, e:
+-            return werkzeug.html.p(werkzeug.html(_(unicode(e))))
++            return werkzeug.xhtml.p(werkzeug.xhtml(_(unicode(e))))
          if preview:
              lines = preview
              comment = self.request.form.get('comment', comment)
--        html = werkzeug.html
--        yield u'<form action="" method="POST" class="editor"><div>'
-+        html = werkzeug.xhtml
-+        yield u'<form action="" method="post" class="editor"><div>'
-         yield u'<textarea name="text" cols="80" rows="20" id="editortext">'
-         for line in lines:
-             yield werkzeug.escape(line)
-@@ -2126,7 +2128,7 @@
+@@ -378,7 +378,7 @@
          """Colorize the source code."""
  
          if pygments is None:
              return
  
          formatter = pygments.formatters.HtmlFormatter()
-@@ -2138,7 +2140,7 @@
+@@ -390,7 +390,7 @@
              yield 0, '<div class="highlight"><pre>'
              for lineno, line in source:
                  yield (lineno,
                                           formatter.line_no))
                  formatter.line_no += 1
              yield 0, '</pre></div>'
-@@ -2152,7 +2154,7 @@
+@@ -404,7 +404,7 @@
              else:
                  lexer = pygments.lexers.guess_lexer(text)
          except pygments.util.ClassNotFoundErr:
              return
          html = pygments.highlight(text, lexer, formatter)
          yield html
-@@ -2203,7 +2205,7 @@
+@@ -456,7 +456,7 @@
          else:
              url = '%s%s' % (math_url, werkzeug.url_quote(math))
          label = werkzeug.escape(math, quote=True)
  
      def dependencies(self):
          dependencies = WikiPage.dependencies(self)
-@@ -2239,7 +2241,7 @@
-         else:
-             comment = _(u'uploaded')
-             rev = -1
--        html = werkzeug.html
-+        html = werkzeug.xhtml
-         yield html.p(html(
-                 _(u"This is a binary file, it can't be edited on a wiki. "
-                   u"Please upload a new version instead.")))
-@@ -2253,7 +2255,7 @@
-             html.div(html.input(type_="submit", name="save", value=_(u'Save')),
-                      html.input(type_="submit", name="cancel",
-                                 value=_(u'Cancel')),
--            class_="buttons")), action="", method="POST", class_="editor",
-+            class_="buttons")), action="", method="post", class_="editor",
-                                 enctype="multipart/form-data")
- 
- class WikiPageImage(WikiPageFile):
-@@ -2264,7 +2266,7 @@
-     def view_content(self, lines=None):
-         if self.title not in self.storage:
-             raise NotFoundErr()
--        content = ['<img src="%s" alt="%s">'
-+        content = ['<img src="%s" alt="%s" />'
-                    % (self.request.get_url(self.title, self.wiki.render),
-                       werkzeug.escape(self.title))]
-         return content
-@@ -2310,7 +2312,7 @@
+@@ -539,7 +539,7 @@
                                                   for cell in row))
          except csv.Error, e:
              yield u'</table>'
 -            yield werkzeug.html.p(werkzeug.html(
 +            yield werkzeug.xhtml.p(werkzeug.xhtml(
-                 _(u'Error parsing CSV file %{file}s on line %{line}d: %{error}s')
-                 % {'file': html_title, 'line': reader.line_num, 'error': e}))
-         finally:
-@@ -2370,31 +2372,31 @@
+                 _(u'Error parsing CSV file %{file}s on'
+                   u'line %{line}d: %{error}s') %
+                 {'file': html_title, 'line': reader.line_num, 'error': e}))
+@@ -601,31 +601,31 @@
                      yield '<div id="line_%d">' % (line_no)
                      in_bug = True
                      if title:
                                  ''.join(last_lines)))
          if in_bug:
              yield '</div>'
-@@ -2713,14 +2715,14 @@
-     @URL('/+history/<title:title>/<int:rev>')
+diff --git a/hatta/parser.py b/hatta/parser.py
+--- a/hatta/parser.py
++++ b/hatta/parser.py
+@@ -332,7 +332,7 @@
+     def _block_code(self, block):
+         for self.line_no, part in block:
+             inside = u"\n".join(self.lines_until(self.code_close_re))
+-            yield werkzeug.html.pre(werkzeug.html(inside), class_="code",
++            yield werkzeug.xhtml.pre(werkzeug.xhtml(inside), class_="code",
+                                     id="line_%d" % self.line_no)
+ 
+     def _block_syntax(self, block):
+@@ -343,8 +343,8 @@
+                 return self.wiki_syntax(inside, syntax=syntax,
+                                         line_no=self.line_no)
+             else:
+-                return [werkzeug.html.div(werkzeug.html.pre(
+-                    werkzeug.html(inside), id="line_%d" % self.line_no),
++                return [werkzeug.xhtml.div(werkzeug.xhtml.pre(
++                    werkzeug.xhtml(inside), id="line_%d" % self.line_no),
+                     class_="highlight")]
+ 
+     def _block_macro(self, block):
+@@ -363,7 +363,7 @@
+                 first_line = self.line_no
+             parts.append(part)
+         text = u"".join(self.parse_line(u"".join(parts)))
+-        yield werkzeug.html.p(text, self.pop_to(""), id="line_%d" % first_line)
++        yield werkzeug.xhtml.p(text, self.pop_to(""), id="line_%d" % first_line)
+ 
+     def _block_indent(self, block):
+         parts = []
+@@ -373,7 +373,7 @@
+                 first_line = self.line_no
+             parts.append(part.rstrip())
+         text = u"\n".join(parts)
+-        yield werkzeug.html.pre(werkzeug.html(text), id="line_%d" % first_line)
++        yield werkzeug.xhtml.pre(werkzeug.xhtml(text), id="line_%d" % first_line)
+ 
+     def _block_table(self, block):
+         first_line = None
+@@ -427,7 +427,7 @@
+ 
+     def _block_rule(self, block):
+         for self.line_no, line in block:
+-            yield werkzeug.html.hr()
++            yield werkzeug.xhtml.hr()
+ 
+     def _block_heading(self, block):
+         for self.line_no, line in block:
+@@ -435,7 +435,7 @@
+             self.headings[level - 1] = self.headings.get(level - 1, 0) + 1
+             label = u"-".join(str(self.headings.get(i, 0))
+                               for i in range(level))
+-            yield werkzeug.html.a(name="head-%s" % label)
++            yield werkzeug.xhtml.a(name="head-%s" % label)
+             yield u'<h%d id="line_%d">%s</h%d>' % (level, self.line_no,
+                 werkzeug.escape(line.strip("= \t\n\r\v")), level)
+ 
+@@ -501,11 +501,11 @@
+         for self.line_no, part in block:
+             yield u'<div class="conflict">'
+             local = u"\n".join(self.lines_until(self.conflict_sep_re))
+-            yield werkzeug.html.pre(werkzeug.html(local),
++            yield werkzeug.xhtml.pre(werkzeug.xhtml(local),
+                                     class_="local",
+                                     id="line_%d" % self.line_no)
+             other = u"\n".join(self.lines_until(self.conflict_close_re))
+-            yield werkzeug.html.pre(werkzeug.html(other),
++            yield werkzeug.xhtml.pre(werkzeug.xhtml(other),
+                                     class_="other",
+                                     id="line_%d" % self.line_no)
+             yield u'</div>'
+diff --git a/hatta/templates/backlinks.html b/hatta/templates/backlinks.html
+--- a/hatta/templates/backlinks.html
++++ b/hatta/templates/backlinks.html
+@@ -1,6 +1,6 @@
+ {% extends 'page.html' %} 
+ 
+-{% block meta %}<meta name="robots" content="NOINDEX, NOFOLLOW">{% endblock %}
++{% block meta %}<meta name="robots" content="NOINDEX, NOFOLLOW" />{% endblock %}
+ 
+ {% block page_title %}
+     <h1>{{ _("Links to %(title)s", title=title) }}</h1>
+diff --git a/hatta/templates/base.html b/hatta/templates/base.html
+--- a/hatta/templates/base.html
++++ b/hatta/templates/base.html
+@@ -6,17 +6,17 @@
+ 
+ {% block links %}
+     <link rel="stylesheet" type="text/css"
+-          href="{{ url(None, wiki.style_css) }}">
++          href="{{ url(None, wiki.style_css) }}" />
+     <link rel="stylesheet" type="text/css"
+-          href="{{ url(None, wiki.pygments_css) }}">
++          href="{{ url(None, wiki.pygments_css) }}" />
+     <link rel="shortcut icon" type="image/x-icon"
+-          href="{{ url(None, wiki.favicon_ico) }}">
++          href="{{ url(None, wiki.favicon_ico) }}" />
+     <link rel="alternate" type="application/rss+xml"
+           title="{{ wiki.site_name }} (ATOM)"
+-          href="{{ url(None, wiki.atom) }}">
++          href="{{ url(None, wiki.atom) }}" />
+     {% if edit_url %}
+         <link rel="alternate" type="application/wiki"
+-              href="{{ edit_url }}">
++              href="{{ edit_url }}" />
+     {% endif %}
+ {% endblock %}
+ 
+@@ -36,11 +36,11 @@
+ {% endblock %}
+ 
+ {% block search %}
+-    <form action="{{ url(None, wiki.search) }}" id="hatta-search" method="GET"
++    <form action="{{ url(None, wiki.search) }}" id="hatta-search" method="get"
+       ><div><input
+-        id="hatta-search" name="q"><input
++        name="q" /><input
+         class="button" type="submit" value="Search"
+-    ></div></form>
++    /></div></form>
+ {% endblock %}
+ 
+ {% block menu %}
+diff --git a/hatta/templates/edit_file.html b/hatta/templates/edit_file.html
+--- a/hatta/templates/edit_file.html
++++ b/hatta/templates/edit_file.html
+@@ -7,18 +7,18 @@
+ {% block content %}
+     <p>{{ _("This is a binary file, it can't be edited on a wiki. "
+             "Please upload a new version instead.") }}</p>
+-    <form action="" method="POST" class="editor"
++    <form action="" method="post" class="editor"
+           enctype="multipart/form-data"><div>
+-        <div class="upload"><input type="file" name="data"></div>
++        <div class="upload"><input type="file" name="data" /></div>
+         <label class="comment">{{ _("Comment") }} <input
+-            name="comment" value="{{ comment }}"></label>
++            name="comment" value="{{ comment }}" /></label>
+         <label class="comment">{{ _("Author") }} <input
+-            name="author" value="{{ author }}"></label>
++            name="author" value="{{ author }}" /></label>
+         <div class="buttons">
+-            <input type="submit" name="save" value="{{ _("Save") }}">
+-            <input type="submit" name="cancel" value="{{ _("Cancel") }}">
++            <input type="submit" name="save" value="{{ _("Save") }}" />
++            <input type="submit" name="cancel" value="{{ _("Cancel") }}" />
+         </div>
+-        <input type="hidden" name="parent" value="{{ parent }}">
++        <input type="hidden" name="parent" value="{{ parent }}" />
+     </div></form>
+ {% endblock %}
+ 
+diff --git a/hatta/templates/edit_text.html b/hatta/templates/edit_text.html
+--- a/hatta/templates/edit_text.html
++++ b/hatta/templates/edit_text.html
+@@ -4,18 +4,18 @@
+ {% block title %}{{ _("Editing \"%(title)s\"", title=title) }}{% endblock %}
+ 
+ {% block content %}
+-    <form action="" method="POST" class="editor"><div>
++    <form action="" method="post" class="editor"><div>
+     <textarea name="text" cols="80" rows="20" id="edtortext"
+     >{% for line in lines %}{{ line }}{% endfor %}</textarea>
+-    <input type="hidden" name="parent" value="{{ parent }}">
++    <input type="hidden" name="parent" value="{{ parent }}" />
+     <label class="comment">{{ _("Comment") }} <input
+-        name="comment" value="{{ comment }}"></label>
++        name="comment" value="{{ comment }}" /></label>
+     <label class="comment">{{ _("Author") }} <input
+-        name="author" value="{{ author }}"></label>
++        name="author" value="{{ author }}" /></label>
+     <div class="buttons">
+-        <input type="submit" name="save" value="{{ _("Save") }}">
+-        <input type="submit" name="preview" value="{{ _("Preview") }}">
+-        <input type="submit" name="cancel" value="{{ _("Cancel") }}">
++        <input type="submit" name="save" value="{{ _("Save") }}" />
++        <input type="submit" name="preview" value="{{ _("Preview") }}" />
++        <input type="submit" name="cancel" value="{{ _("Cancel") }}" />
+     </div>
+     </div></form>
+     {% if preview %}
+diff --git a/hatta/templates/history.html b/hatta/templates/history.html
+--- a/hatta/templates/history.html
++++ b/hatta/templates/history.html
+@@ -1,6 +1,6 @@
+ {% extends 'page.html' %} 
+ 
+-{% block meta %}<meta name="robots" content="NOINDEX, NOFOLLOW">{% endblock %}
++{% block meta %}<meta name="robots" content="NOINDEX, NOFOLLOW" />{% endblock %}
+ 
+ {% block page_title %}
+     <h1>{{ _("History of %(title)s", title=title) }}</h1>
+@@ -9,19 +9,19 @@
+ 
+ {% block content %}
+     <p>{{ _("History of changes for %(link)s.", link=page.wiki_link(title)|safe) }}</p>
+-    <form action="{{ url(title, wiki.undo, method='POST') }}" method="POST">
++    <form action="{{ url(title, wiki.undo, method='POST') }}" method="post">
+         <ul id="hatta-history">
+             {% for date, date_url, rev, author, comment in history %}
+                 <li><a href="{{ date_url }}"
+                     >{{ date_html(date)|safe }}</a>
+                 {% if edit_url %}
+-                <input type="submit" name="{{ rev }}" value="{{ _('Undo') }}">
++                <input type="submit" name="{{ rev }}" value="{{ _('Undo') }}" />
+                 {% endif %}
+                 . . . .
+                 <i>{{ page.wiki_link('~%s' % author, author)|safe }}</i>
+                 <div class="hatta-comment">{{ comment }}</div></li>
+             {% endfor %}
+         </ul>
+-        <input type="hidden" name="parent" value="{{ parent_rev }}">
++        <div><input type="hidden" name="parent" value="{{ parent_rev }}" /></div>
+     </form>
+ {% endblock %}
+diff --git a/hatta/templates/layout.html b/hatta/templates/layout.html
+--- a/hatta/templates/layout.html
++++ b/hatta/templates/layout.html
+@@ -1,7 +1,9 @@
+-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+-"http://www.w3.org/TR/html4/strict.dtd"> 
+-<html><head>
+-<meta http-equiv="content-type" content="text/html;charset=utf-8">
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
++     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
++<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
++<head>
++<meta http-equiv="content-type" content="text/html;charset=utf-8" />
+ <title>{% block title %}{% endblock %}</title>
+     {% block links %}{% endblock %}
+     {% block meta %}{% endblock %}
+diff --git a/hatta/templates/page_special.html b/hatta/templates/page_special.html
+--- a/hatta/templates/page_special.html
++++ b/hatta/templates/page_special.html
+@@ -1,6 +1,6 @@
+ {% extends 'base.html' %}
+ 
+-{% block meta %}<meta name="robots" content="NOINDEX, NOFOLLOW">{% endblock %}
++{% block meta %}<meta name="robots" content="NOINDEX, NOFOLLOW" />{% endblock %}
+ 
+ {% block page_title %}<h1>{{ special_title }}</h1>{% endblock %}
+ {% block title %}{{ special_title }} - {{ wiki.site_name }}{% endblock %}
+diff --git a/hatta/wiki.py b/hatta/wiki.py
+--- a/hatta/wiki.py
++++ b/hatta/wiki.py
+@@ -372,14 +372,14 @@
      def revision(self, request, title, rev):
+         _ = self.gettext
          text = self.storage.revision_text(title, rev)
 -        link = werkzeug.html.a(werkzeug.html(title),
 +        link = werkzeug.xhtml.a(werkzeug.xhtml(title),
 +            werkzeug.xhtml.p(
 +                werkzeug.xhtml(
                      _(u'Content of revision %(rev)d of page %(title)s:'))
-                 % {'rev': rev, 'title': link }),
+                 % {'rev': rev, 'title': link}),
 -            werkzeug.html.pre(werkzeug.html(text)),
 +            werkzeug.xhtml.pre(werkzeug.xhtml(text)),
          ]
          special_title = _(u'Revision of "%(title)s"') % {'title': title}
          page = self.get_page(request, title)
-@@ -2752,7 +2754,7 @@
+@@ -413,7 +413,7 @@
              if text is not None:
                  lines = text.split('\n')
              else:
                      _(u'No preview for binaries.')))]
              return self.edit(request, title, preview=lines)
          elif request.form.get('save'):
-@@ -2986,7 +2988,7 @@
-         def changes_list(page):
-             """Generate the content of the recent changes page."""
- 
--            h = werkzeug.html
-+            h = werkzeug.xhtml
-             yield u'<ul>'
-             last = {}
-             lastrev = {}
-@@ -3034,13 +3036,13 @@
+@@ -701,13 +701,13 @@
          build = request.adapter.build
          from_url = build(self.revision, {'title': title, 'rev': from_rev})
          to_url = build(self.revision, {'title': title, 'rev': to_rev})
              u'Differences between revisions %(link1)s and %(link2)s '
              u'of page %(link)s.')) % links
          diff_content = getattr(page, 'diff_content', None)
-@@ -3049,7 +3051,7 @@
+@@ -716,7 +716,7 @@
              to_text = self.storage.revision_text(page.title, to_rev)
              content = page.diff_content(from_text, to_text, message)
          else:
 +            content = [werkzeug.xhtml.p(werkzeug.xhtml(
                  _(u"Diff not available for this kind of pages.")))]
          special_title = _(u'Diff for "%(title)s"') % {'title': title}
-         html = page.render_content(content, special_title)
-@@ -3091,7 +3093,7 @@
-         def wanted_pages_list(page):
-             """Generate the content of wanted pages page."""
- 
--            h = werkzeug.html
-+            h = werkzeug.xhtml
-             yield h.p(h(
-                 _(u"List of pages that are linked to, but don't exist yet.")))
-             yield u'<ol class="wanted">'
-@@ -3130,18 +3132,18 @@
+         html = page.template('page_special.html', content=content,
+@@ -795,18 +795,18 @@
              min_pos = max(position - 60, 0)
              max_pos = min(position + 60, len(text))
              snippet = werkzeug.escape(text[min_pos:max_pos])
 -            h = werkzeug.html
 +            h = werkzeug.xhtml
              self.storage.reopen()
-             self.index.update(self, request)
-             result = sorted(self.index.find(words), key=lambda x:-x[0])
+             self.index.update(self)
+             result = sorted(self.index.find(words), key=lambda x: -x[0])
 -            yield werkzeug.html.p(h(_(u'%d page(s) containing all words:')
 +            yield werkzeug.xhtml.p(h(_(u'%d page(s) containing all words:')
                                    % len(result)))