#!/usr/bin/perl use strict; sub find_footnotes { my @text = @_; my @notes = (); my $found = 0; my $l; for ($l = 0; $l <= $#text; $l++) { if ($text[$l] =~ m/^FOOTNOTES:$/) { $found = 1; } next unless $found; if ($text[$l] =~ m/^\[[0-9]+\]\s/) { push @notes, $l; } } return @notes; }; sub find_sections { my @text = @_; my @sections = (); my $l; for ($l = 0; $l <= $#text - 1; $l++) { next unless (($text[$l + 1] =~ m/^=======*$/) or ($text[$l + 1] =~ m/^-------*$/)); next unless ($text[$l] =~ m/^(([0-9]+\.)+) /); push @sections, $l; } return @sections; }; sub get_section { my ($section, @prevpath) = @_; my @path = split(/\./, $section); #Possible cases: if ($#path > $#prevpath) { # Path deeper than parent: just add .1 my $diff = $#path - $#prevpath; @path = @prevpath; for (my $i = 0; $i < $diff; $i++) { push @path, 1; } } elsif ($#path == $#prevpath) { # Same level as parent @path = @prevpath; $path[$#path]++; } elsif ($#path < $#prevpath) { # Higher level than parent @path = @prevpath[0 .. $#path]; $path[$#path]++; } my $newsection = join('.', @path) . '.'; my $prev = join('.', @prevpath) . '.'; return ($newsection, @path); }; my @text = (); while (<>) { push @text, $_; } my @footnotes = find_footnotes(@text); my @sections = find_sections(@text); #Set new numbers for footnotes my %footnote_by_old_reference = (); my $f; for ($f = 0; $f <= $#footnotes; $f++) { my $l = $footnotes[$f]; die unless ($text[$l] =~ m/^\[([0-9]+)\]\s/); my $footnote = $1; my $newfootnote = $f + 1; die "duplicate footnote number $footnote" if defined($footnote_by_old_reference{$footnote}); $footnote_by_old_reference{$footnote} = $newfootnote; } #Find and fix references to footnotes my $l; for ($l = 0; $l <= $#text; $l++) { next unless $text[$l] =~ m/\[[0-9]+\]/; #premature optimization for my $old (keys(%footnote_by_old_reference)) { my $new = $footnote_by_old_reference{$old}; next if $new eq $old; $text[$l] =~ s/\[$old\]/[XYX$new]/g; } $text[$l] =~ s/\[XYX/[/go; } #Set new numbers for sections my %section_by_old_reference = (); my $s; my @path = (); for ($s = 0; $s <= $#sections; $s++) { my $l = $sections[$s]; die unless ($text[$l] =~ m/^(([0-9]+\.)+)/); my $section = $1; my ($newsection, @p) = get_section($section, @path); @path = @p; die "duplicate section number $section" if defined($section_by_old_reference{$section}); $section_by_old_reference{$section} = $newsection; } #Find and fix references to sections my $l; for ($l = 0; $l <= $#text; $l++) { next unless $text[$l] =~ m/^(([0-9]+\.)+)/; #premature optimization for my $old (keys(%section_by_old_reference)) { my $new = $section_by_old_reference{$old}; next if $new eq $old; my @p = split(/\./, $old); my $pattern = join("\\.", @p) . "\\."; my @s = split(/\./, $new); my $subst = join("XYX", @s) . "XYX"; $text[$l] =~ s/$pattern/$subst/g; } $text[$l] =~ s/XYX/./go; } for my $line (@text) { print $line; }