#!/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 : - 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, Web Link [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:])