#!/usr/bin/env python
"""USAGE: footnotes.py [-a] [--test] [< input.txt]
--test Self-test using text SAMPLE in script source
-a Number footnotes in order of appearance in text

Edited by Julian Andres Klode <[email protected]>:
- Remove nodups() and modify mkMap to ignore duplicate elements. nodups() was
  too slow because it used 'element in list' checks.
"""

SAMPLE = '''A great brown fox [13] jumped of a pile of lorem ipsum [4],
[7]. He met with a silver penguin, browsing the Linux Kernel
Mailinglist [3]. They debated whether to start a C-program with
"main (int argc, char **argv)" or with "main (int argc, char *argv[])".
Square brackets annoyed them [9999]. Multiple references exist [4].
@footnote:
[13] Al Fabetus: "On characters and animals", 1888, self published.
[4] Lorem Ipsum, <a href="http://link.org/Lorem_Ipsum">Web Link</a>
[9999] Annoying Link.
[7] B. Fox: "More on Blind Text".
[3] Linux Kernel Maintainers: LKML
'''
import sys, re

def mkMap(lst):
       ret = {}
       n = 1
       for ref in lst:
               if not ref in ret:
                       ret[ref] = "[%d]" % n
                       n+=1
       return ret


def asNum(line):
       try:
               key, _ = line[1:].split(']', 1)
               key = int(key)
       except:
               key = line or None # If line looks wrong, just return the raw line
       return key

def footnote(s, usebody=False):
       FOOTSPLIT = '\n@footnote:\n'
       body, foots = s.split(FOOTSPLIT)
       if usebody:
               mapping = mkMap(re.findall(r'\[\d+\]', body))
       else:
               mapping = mkMap(re.findall(r'\[\d+\]', foots))

       # Replace source->target footnote numbers
       def numsub(m):
               return mapping[m.group(1)]
       body = re.sub(r'(\[\d+\])', numsub , body)
       foots = re.sub(r'(\[\d+\])', numsub, foots)

       # May need to reorder target lines in foots
       if usebody:
               foots = '\n'.join(sorted(foots.splitlines(), key=asNum))
       return body + FOOTSPLIT + foots.strip()

if __name__ == '__main__':
       if '--test' in sys.argv[1:]:
               print footnote(SAMPLE, usebody='-a' in sys.argv[1:])
       else:
               print footnote(sys.stdin.read(), usebody='-a' in sys.argv[1:])