#!/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:])