 macro/Include.py         |   11 +----------
 macro/TableOfContents.py |   12 ++----------
 parser/wiki.py           |   10 +---------
 wikiutil.py              |   19 +++++++++++++++++++
 4 files changed, 23 insertions(+), 29 deletions(-)
--- wikiutil.py.orig	Thu May 10 16:35:47 2007
+++ wikiutil.py	Thu May 10 18:44:33 2007
@@ -274,6 +274,25 @@
             newtext.append(part)
     return " ".join(newtext)
 
+def unique_heading_id(headings, text):
+    """ generate an ID for a heading that is unique to this request, human-readable and HTML-compliant
+    """
+    import unicodedata
+    # ID and NAME tokens must begin with a letter ([A-Za-z]) and may be
+    # followed by any number of letters, digits ([0-9]), hyphens ("-"),
+    # underscores ("_"), colons (":"), and periods (".").
+    # http://www.w3.org/TR/html4/types.html
+    pntt = re.sub('[^-A-Za-z0-9_:.]+', '-', unicodedata.normalize('NFKD', text).encode('ascii', 'ignore')).lower()
+    hid = "head-" + pntt # basic heading structure
+    # count the number of times this heading is found in this request
+    headings.setdefault(pntt, 0)
+    headings[pntt] += 1
+    # spcial case: if the text is strictly non-ascii, add a number anyways so it looks nicer
+    if headings[pntt] > 1 or pntt == "-":  
+        hid += '-%d' % (headings[pntt], ) # increment the heading id, to avoid duplicates
+    return re.sub('--+', '-', hid) # necessary because the last line might have added another duplicate -
+
+
 ########################################################################
 ### Storage
 ########################################################################
--- parser/wiki.py.orig	Sat Sep 16 18:21:52 2006
+++ parser/wiki.py	Thu May 10 18:42:59 2007
@@ -744,8 +744,6 @@
 
     def _heading_repl(self, word):
         """Handle section headings."""
-        import sha
-
         h = word.strip()
         level = 1
         while h[level:level+1] == '=':
@@ -756,15 +754,9 @@
         # TODO but it might still result in unpredictable results
         # when included the same page multiple times
         title_text = h[level:-level].strip()
-        pntt = self.formatter.page.page_name + title_text
-        self.titles.setdefault(pntt, 0)
-        self.titles[pntt] += 1
 
-        unique_id = ''
-        if self.titles[pntt] > 1:
-            unique_id = '-%d' % self.titles[pntt]
         result = self._closeP()
-        result += self.formatter.heading(1, depth, id="head-"+sha.new(pntt.encode(config.charset)).hexdigest()+unique_id)
+        result += self.formatter.heading(1, depth, id=wikiutil.unique_heading_id(self.request._page_headings, title_text))
                                      
         return (result + self.formatter.text(title_text) +
                 self.formatter.heading(0, depth))
--- macro/Include.py.orig	Wed Apr 18 14:56:22 2007
+++ macro/Include.py	Thu May 10 18:43:11 2007
@@ -190,21 +190,12 @@
                               macro.formatter.text(heading) +
                               macro.formatter.heading(0, level))
             else:
-                import sha
-                from MoinMoin import config
                 # this heading id might produce duplicate ids,
                 # if the same page is included multiple times
-                # Encode stuf we feed into sha module.
-                pntt = (inc_name + heading).encode(config.charset)
-                hid = "head-" + sha.new(pntt).hexdigest()
-                request._page_headings.setdefault(pntt, 0)
-                request._page_headings[pntt] += 1
-                if request._page_headings[pntt] > 1:
-                    hid += '-%d'%(request._page_headings[pntt],)
                 result.append(
                     #macro.formatter.heading(1, level, hid,
                     #    icons=edit_icon.replace('<img ', '<img align="right" ')) +
-                    macro.formatter.heading(1, level, id=hid) +
+                    macro.formatter.heading(1, level, id=wikiutil.unique_heading_id(request._page_headings, heading)) +
                     inc_page.link_to(request, heading, css_class="include-heading-link") +
                     macro.formatter.heading(0, level)
                 )
--- macro/TableOfContents.py.orig	Fri Nov 10 17:02:52 2006
+++ macro/TableOfContents.py	Thu May 10 18:43:32 2007
@@ -8,7 +8,7 @@
     @license: GNU GPL, see COPYING for details.
 """
 
-import re, sha
+import re
 from MoinMoin import config, wikiutil
 
 #Dependencies = ["page"]
@@ -125,9 +125,6 @@
         match = self.head_re.match(line)
         if not match: return
         title_text = match.group('htext').strip()
-        pntt = pagename + title_text
-        self.titles.setdefault(pntt, 0)
-        self.titles[pntt] += 1
 
         # Get new indent level
         newindent = len(match.group('hmarker'))
@@ -147,11 +144,6 @@
             self.result.append(self.macro.formatter.number_list(1))
             self.result.append(self.macro.formatter.listitem(1))
 
-        # Add the heading
-        unique_id = ''
-        if self.titles[pntt] > 1:
-            unique_id = '-%d' % (self.titles[pntt],)
-
         # close last listitem if same level
         if self.indent == newindent:
             self.result.append(self.macro.formatter.listitem(0))
@@ -159,7 +151,7 @@
         if self.indent >= newindent:
             self.result.append(self.macro.formatter.listitem(1))
         self.result.append(self.macro.formatter.anchorlink(1,
-            "head-" + sha.new(pntt.encode(config.charset)).hexdigest() + unique_id) +
+                           wikiutil.unique_heading_id(self.titles, title_text)) +
                            self.macro.formatter.text(title_text) +
                            self.macro.formatter.anchorlink(0))
 
