#!/usr/bin/ruby USAGE = "Usage: footnotes.rb [options] -t, --target Sort footnotes by their position in target section instead of appearance in text. -T, --test Do a self test, using text appended to the script. -h, --help Show this message. " # Given an input and (optionally) output stream, this method does the actual # footnote sorting. def sort_footnotes(input, output=STDOUT) # initialize translation table footnote_counter = 0 old2new = Hash.new { |hash, key| hash[key] = (footnote_counter += 1) } # If we are to sort by the position in the target section, we need to scan # that section first, then rewind the stream and start processing. if $sort_by_target until input.readline =~ /^@footnote:/ do end input.each_line do |line| if line =~ /^\[(\d+)\]/ then old2new[$1] end end input.rewind end targets = [] # note: targets[0] remains empty (nil) input.each_line do |line| unless (line =~ /^@footnote:/) .. false output.puts line.gsub(/\[(\d+)\]/) { "[" + old2new[$1].to_s + "]" } else # we are within the target section if line =~ /^\[(\d+)\](.*)/ targets[old2new[$1]] = $2 else output.puts line end end end (1...targets.size).each { |nr| output.puts "[#{nr}]#{targets[nr]}" } end # handle command-line options, calling sort_footnotes to do the actual work if ARGV.delete("--help") || ARGV.delete("-h") puts USAGE; exit end $sort_by_target = ARGV.delete("--target") || ARGV.delete("-t") if ARGV.delete("--test") || ARGV.delete("-T") sort_footnotes StringIO.new(DATA.read) elsif ARGV[0] File.open(ARGV[0], "r") { |file| sort_footnotes file } else puts USAGE end __END__ A great brown fox [13] jumped off a pile of lorem ipsum [4], [7]. He met with a silver penguin [13], browsing the Linux Kernel Mailinglist [3]. They debated over the question whether to start a C-program with "main (int argc, char **argv)" or with "main (int argc, char *argv[])". Square brackets annoyed them [9999]. @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