changeset 1807:034cea31b7db

FootNote macro filters duplicates (patch by Johannes Berg)
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 24 Feb 2007 14:35:23 +0100
parents 7a113e54bee7
children e43e65d90f26
files MoinMoin/macro/FootNote.py docs/CHANGES
diffstat 2 files changed, 69 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/macro/FootNote.py	Sat Feb 24 14:19:15 2007 +0100
+++ b/MoinMoin/macro/FootNote.py	Sat Feb 24 14:35:23 2007 +0100
@@ -7,33 +7,55 @@
 
     @copyright: 2002 by Jürgen Hermann <jh@web.de>
                 2007 Reimar Bauer
+                2007 by Johannes Berg
     @license: GNU GPL, see COPYING for details.
 """
 
 import sha
+
 from MoinMoin import config, wikiutil
 from MoinMoin.parser.text_moin_wiki import Parser as WikiParser
 
 Dependencies = ["time"] # footnote macro cannot be cached
 
 def execute(macro, args):
+    request = macro.request
+    formatter = macro.formatter
+
     # create storage for footnotes
-    if not hasattr(macro.request, 'footnotes'):
-        macro.request.footnotes = []
+    if not hasattr(request, 'footnotes'):
+        request.footnotes = {}
+        request.footnote_ctr = 0
+        request.footnote_show_ctr = 0
 
     if not args:
-        return emit_footnotes(macro.request, macro.formatter)
+        return emit_footnotes(request, formatter)
     else:
-        # store footnote and emit number
-        idx = len(macro.request.footnotes)
-        fn_id = "-%s-%s" % (sha.new(args.encode(config.charset)).hexdigest(), idx)
-        macro.request.footnotes.append((args, fn_id))
+        # grab new footnote backref number
+        idx = request.footnote_ctr
+        request.footnote_ctr += 1
+
+        shahex = sha.new(args.encode(config.charset)).hexdigest()
+        backlink_id = "fndef-%s-%d" % (shahex, idx)
+        fwdlink_id = "fnref-%s" % shahex
+
+        if not args in request.footnotes:
+            showidx = request.footnote_show_ctr
+            request.footnote_show_ctr += 1
+            request.footnotes[args] = ([], fwdlink_id, showidx)
+        flist, dummy, showidx = request.footnotes[args]
+        request.footnotes[args] = (flist + [(backlink_id, idx)], fwdlink_id, showidx)
+
+        # do index -> text mapping in the same dict, that's fine because
+        # args is always a string and idx alwas a number.
+        request.footnotes[idx] = args
+
         return "%s%s%s%s%s" % (
-            macro.formatter.sup(1),
-            macro.formatter.anchorlink(1, 'fndef' + fn_id, id='fnref' + fn_id),
-            macro.formatter.text(str(idx+1)),
-            macro.formatter.anchorlink(0),
-            macro.formatter.sup(0),)
+            formatter.sup(1),
+            formatter.anchorlink(1, fwdlink_id, id=backlink_id),
+            formatter.text(str(showidx+1)),
+            formatter.anchorlink(0),
+            formatter.sup(0),)
 
     # nothing to do or emit
     return ''
@@ -48,18 +70,38 @@
 
         # Add footnotes list
         result.append(formatter.bullet_list(1))
-        for idx in range(len(request.footnotes)):
-            # Add item
-            result.append(formatter.listitem(1))
-            result.append(formatter.paragraph(1)) # see [1]
 
-            fn_id = request.footnotes[idx][1]
-            result.append(formatter.anchorlink(1, 'fnref' + fn_id,
-                                               id='fndef' + fn_id))
-            result.append(formatter.text(str(idx + 1)))
+        for ctr in range(request.footnote_ctr):
+            fn_txt = request.footnotes[ctr]
+            if not fn_txt in request.footnotes:
+                continue
+            this_txt_footnotes, fwdlink_id, showidx = request.footnotes[fn_txt]
+            # this text was handled
+            del request.footnotes[fn_txt]
+
+            result.append(formatter.listitem(1))
+            result.append(formatter.paragraph(1))
+            result.append(formatter.anchorlink(1, None, id=fwdlink_id))
             result.append(formatter.anchorlink(0))
+            result.append(formatter.text(str(showidx+1)))
             result.append(formatter.text(" "))
-            result.append(wikiutil.renderText(request, WikiParser, request.footnotes[idx][0]))
+            result.append(wikiutil.renderText(request, WikiParser, fn_txt))
+
+            items = []
+            subidx = 0
+            for backlink_id, idx in this_txt_footnotes:
+                # Add item
+                item = formatter.anchorlink(1, backlink_id)
+                item += formatter.text(str(subidx+1))
+                item += formatter.anchorlink(0)
+                items.append(item)
+                subidx += 1
+
+            result.append(formatter.text(" ("))
+            result.append(formatter.text(" ").join(items))
+            result.append(formatter.text(")"))
+
+            result.append(formatter.paragraph(0))
             result.append(formatter.listitem(0))
 
         result.append(formatter.bullet_list(0))
@@ -67,7 +109,9 @@
         # Finish div
         result.append(formatter.div(0))
 
-        request.footnotes = []
+        del request.footnotes
+        del request.footnote_ctr
+        del request.footnote_show_ctr
         return ''.join(result)
 
     return ''
--- a/docs/CHANGES	Sat Feb 24 14:19:15 2007 +0100
+++ b/docs/CHANGES	Sat Feb 24 14:35:23 2007 +0100
@@ -327,6 +327,9 @@
             add sistersites_force with sister sites we link to even if they do not
             have the page yet (will work only for moin as we don't know
             pagename>url transformation of other wikis)
+    * Make the FootNote macro filter duplicates and display a list of numbers
+      instead of a list of identical footnotes. Thanks to Johannes Berg for the
+      patch.
 
   Bugfixes:
     * on action "info" page, "revert" link will not be displayed for empty page