summaryrefslogtreecommitdiff
path: root/fix-numbers.pl
diff options
context:
space:
mode:
Diffstat (limited to 'fix-numbers.pl')
-rwxr-xr-xfix-numbers.pl135
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;
+}
+
+