#!/usr/bin/ruby
# orders footnotes by first occurence
# Urs Meyer, ursmr [at] gmx.ch, September 2008

filename = ARGV[0] || "sample4.txt"

mapping = {}
newref = 0
lines = []

File.foreach(filename) { |line|
   if ($. == 1) .. line =~ /@footnote:/                # text body
       line.scan(/\[(\d+)\]/).flatten.each { |ref|
           mapping[ref] = (newref += 1) if mapping[ref].nil?
       }
       # print text body now as footnote mapping is known
       puts line.gsub(/\[(\d+)\]/) { "[#{mapping[$1]}]" }
   else                                                # footnote targets
       # collect targets sorted in an array
       line =~ /\[(\d+)\]/
       lines[mapping[$1]] = line.sub(/\[(\d+)\]/) { "[#{mapping[$1]}]" } unless $1.nil? || mapping[$1].nil?
   end
}

# print targets
lines.each { |line| puts line unless line.nil? }