-
Notifications
You must be signed in to change notification settings - Fork 69
/
fix-numbers.pl
executable file
·135 lines (113 loc) · 2.95 KB
/
fix-numbers.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/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;
}