#!/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 <jak@jak-linux.org>:
 - 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:])
