"""Collates and generates foot-notes. Call the macro with the foot-note content as the only argument: {{{ [[FootNote(This is a footnote)]] }}} Foot-notes are numbered by the order in which they appear. To create a reference to an existing foot-note, pass the footnote number as argument to the macro: {{{ [[FootNote(1)]] }}} In addition, identical foot-notes are coalesced into one entry. The following will generate one footnote entry with two references: {{{ Some text[[FootNote(A footnote)]] and some more text [[FootNote(A footnote)]]. }}} A list of footnotes generated by one or more of the above commands is produced by calling the macro without arguments: {{{ [[FootNote]] }}} Once a set of footnotes has been displayed, a complete new set of footnotes can be created. This allows multiple sets of footnotes per page. """ from StringIO import StringIO from trac.util import escape from trac.wiki import wiki_to_oneliner def unescape(text): """Un-escapes &, <, > and \"""" if not text: return '' return unicode(text).replace('&', '&') \ .replace('<', '<') \ .replace('>', '>') \ .replace('"', '"') def execute(hdf, args, env): if not hasattr(hdf, 'footnotes'): hdf.footnotes = [] hdf.footnote_set = 1 # Display and clear footnotes... if not args: out = StringIO() out.write('
\n'); out.write('
\n'); out.write('
    \n') for i, v in enumerate(hdf.footnotes): id = "%i.%i" % (hdf.footnote_set, i + 1) out.write('
  1. %i. %s
  2. \n' % (id, id, i + 1, wiki_to_oneliner(unescape(v), env))) out.write('
\n') out.write('
\n'); hdf.footnotes = [] hdf.footnote_set += 1 return out.getvalue() else: id = len(hdf.footnotes) + 1 try: id = int(args) except ValueError: existing = None for index, note in enumerate(hdf.footnotes): if args == note: existing = note id = index + 1 break if not existing: hdf.footnotes.append(args) full_id = "%i.%i" % (hdf.footnote_set, id) return '%i' % (args[:16] + u"...", full_id, full_id, id)