diff options
Diffstat (limited to 'fix-numbers.pl')
-rwxr-xr-x | fix-numbers.pl | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/fix-numbers.pl b/fix-numbers.pl new file mode 100755 index 0000000..2170856 --- /dev/null +++ b/fix-numbers.pl @@ -0,0 +1,135 @@ +#!/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; +} + + |