1 | #!/bin/perl
|
---|
2 | #
|
---|
3 | #Used to prepare the book "tommath.src" for LaTeX by pre-processing it into a .tex file
|
---|
4 | #
|
---|
5 | #Essentially you write the "tommath.src" as normal LaTex except where you want code snippets you put
|
---|
6 | #
|
---|
7 | #EXAM,file
|
---|
8 | #
|
---|
9 | #This preprocessor will then open "file" and insert it as a verbatim copy.
|
---|
10 | #
|
---|
11 | #Tom St Denis
|
---|
12 |
|
---|
13 | #get graphics type
|
---|
14 | if (shift =~ /PDF/) {
|
---|
15 | $graph = "";
|
---|
16 | } else {
|
---|
17 | $graph = ".ps";
|
---|
18 | }
|
---|
19 |
|
---|
20 | open(IN,"<tommath.src") or die "Can't open source file";
|
---|
21 | open(OUT,">tommath.tex") or die "Can't open destination file";
|
---|
22 |
|
---|
23 | print "Scanning for sections\n";
|
---|
24 | $chapter = $section = $subsection = 0;
|
---|
25 | $x = 0;
|
---|
26 | while (<IN>) {
|
---|
27 | print ".";
|
---|
28 | if (!(++$x % 80)) { print "\n"; }
|
---|
29 | #update the headings
|
---|
30 | if (~($_ =~ /\*/)) {
|
---|
31 | if ($_ =~ /\\chapter{.+}/) {
|
---|
32 | ++$chapter;
|
---|
33 | $section = $subsection = 0;
|
---|
34 | } elsif ($_ =~ /\\section{.+}/) {
|
---|
35 | ++$section;
|
---|
36 | $subsection = 0;
|
---|
37 | } elsif ($_ =~ /\\subsection{.+}/) {
|
---|
38 | ++$subsection;
|
---|
39 | }
|
---|
40 | }
|
---|
41 |
|
---|
42 | if ($_ =~ m/MARK/) {
|
---|
43 | @m = split(",",$_);
|
---|
44 | chomp(@m[1]);
|
---|
45 | $index1{@m[1]} = $chapter;
|
---|
46 | $index2{@m[1]} = $section;
|
---|
47 | $index3{@m[1]} = $subsection;
|
---|
48 | }
|
---|
49 | }
|
---|
50 | close(IN);
|
---|
51 |
|
---|
52 | open(IN,"<tommath.src") or die "Can't open source file";
|
---|
53 | $readline = $wroteline = 0;
|
---|
54 | $srcline = 0;
|
---|
55 |
|
---|
56 | while (<IN>) {
|
---|
57 | ++$readline;
|
---|
58 | ++$srcline;
|
---|
59 |
|
---|
60 | if ($_ =~ m/MARK/) {
|
---|
61 | } elsif ($_ =~ m/EXAM/ || $_ =~ m/LIST/) {
|
---|
62 | if ($_ =~ m/EXAM/) {
|
---|
63 | $skipheader = 1;
|
---|
64 | } else {
|
---|
65 | $skipheader = 0;
|
---|
66 | }
|
---|
67 |
|
---|
68 | # EXAM,file
|
---|
69 | chomp($_);
|
---|
70 | @m = split(",",$_);
|
---|
71 | open(SRC,"<$m[1]") or die "Error:$srcline:Can't open source file $m[1]";
|
---|
72 |
|
---|
73 | print "$srcline:Inserting $m[1]:";
|
---|
74 |
|
---|
75 | $line = 0;
|
---|
76 | $tmp = $m[1];
|
---|
77 | $tmp =~ s/_/"\\_"/ge;
|
---|
78 | print OUT "\\vspace{+3mm}\\begin{small}\n\\hspace{-5.1mm}{\\bf File}: $tmp\n\\vspace{-3mm}\n\\begin{alltt}\n";
|
---|
79 | $wroteline += 5;
|
---|
80 |
|
---|
81 | if ($skipheader == 1) {
|
---|
82 | # scan till next end of comment, e.g. skip license
|
---|
83 | while (<SRC>) {
|
---|
84 | $text[$line++] = $_;
|
---|
85 | last if ($_ =~ /math\.libtomcrypt\.com/);
|
---|
86 | }
|
---|
87 | <SRC>;
|
---|
88 | }
|
---|
89 |
|
---|
90 | $inline = 0;
|
---|
91 | while (<SRC>) {
|
---|
92 | next if ($_ =~ /\$Source/);
|
---|
93 | next if ($_ =~ /\$Revision/);
|
---|
94 | next if ($_ =~ /\$Date/);
|
---|
95 | $text[$line++] = $_;
|
---|
96 | ++$inline;
|
---|
97 | chomp($_);
|
---|
98 | $_ =~ s/\t/" "/ge;
|
---|
99 | $_ =~ s/{/"^{"/ge;
|
---|
100 | $_ =~ s/}/"^}"/ge;
|
---|
101 | $_ =~ s/\\/'\symbol{92}'/ge;
|
---|
102 | $_ =~ s/\^/"\\"/ge;
|
---|
103 |
|
---|
104 | printf OUT ("%03d ", $line);
|
---|
105 | for ($x = 0; $x < length($_); $x++) {
|
---|
106 | print OUT chr(vec($_, $x, 8));
|
---|
107 | if ($x == 75) {
|
---|
108 | print OUT "\n ";
|
---|
109 | ++$wroteline;
|
---|
110 | }
|
---|
111 | }
|
---|
112 | print OUT "\n";
|
---|
113 | ++$wroteline;
|
---|
114 | }
|
---|
115 | $totlines = $line;
|
---|
116 | print OUT "\\end{alltt}\n\\end{small}\n";
|
---|
117 | close(SRC);
|
---|
118 | print "$inline lines\n";
|
---|
119 | $wroteline += 2;
|
---|
120 | } elsif ($_ =~ m/@\d+,.+@/) {
|
---|
121 | # line contains [number,text]
|
---|
122 | # e.g. @14,for (ix = 0)@
|
---|
123 | $txt = $_;
|
---|
124 | while ($txt =~ m/@\d+,.+@/) {
|
---|
125 | @m = split("@",$txt); # splits into text, one, two
|
---|
126 | @parms = split(",",$m[1]); # splits one,two into two elements
|
---|
127 |
|
---|
128 | # now search from $parms[0] down for $parms[1]
|
---|
129 | $found1 = 0;
|
---|
130 | $found2 = 0;
|
---|
131 | for ($i = $parms[0]; $i < $totlines && $found1 == 0; $i++) {
|
---|
132 | if ($text[$i] =~ m/\Q$parms[1]\E/) {
|
---|
133 | $foundline1 = $i + 1;
|
---|
134 | $found1 = 1;
|
---|
135 | }
|
---|
136 | }
|
---|
137 |
|
---|
138 | # now search backwards
|
---|
139 | for ($i = $parms[0] - 1; $i >= 0 && $found2 == 0; $i--) {
|
---|
140 | if ($text[$i] =~ m/\Q$parms[1]\E/) {
|
---|
141 | $foundline2 = $i + 1;
|
---|
142 | $found2 = 1;
|
---|
143 | }
|
---|
144 | }
|
---|
145 |
|
---|
146 | # now use the closest match or the first if tied
|
---|
147 | if ($found1 == 1 && $found2 == 0) {
|
---|
148 | $found = 1;
|
---|
149 | $foundline = $foundline1;
|
---|
150 | } elsif ($found1 == 0 && $found2 == 1) {
|
---|
151 | $found = 1;
|
---|
152 | $foundline = $foundline2;
|
---|
153 | } elsif ($found1 == 1 && $found2 == 1) {
|
---|
154 | $found = 1;
|
---|
155 | if (($foundline1 - $parms[0]) <= ($parms[0] - $foundline2)) {
|
---|
156 | $foundline = $foundline1;
|
---|
157 | } else {
|
---|
158 | $foundline = $foundline2;
|
---|
159 | }
|
---|
160 | } else {
|
---|
161 | $found = 0;
|
---|
162 | }
|
---|
163 |
|
---|
164 | # if found replace
|
---|
165 | if ($found == 1) {
|
---|
166 | $delta = $parms[0] - $foundline;
|
---|
167 | print "Found replacement tag for \"$parms[1]\" on line $srcline which refers to line $foundline (delta $delta)\n";
|
---|
168 | $_ =~ s/@\Q$m[1]\E@/$foundline/;
|
---|
169 | } else {
|
---|
170 | print "ERROR: The tag \"$parms[1]\" on line $srcline was not found in the most recently parsed source!\n";
|
---|
171 | }
|
---|
172 |
|
---|
173 | # remake the rest of the line
|
---|
174 | $cnt = @m;
|
---|
175 | $txt = "";
|
---|
176 | for ($i = 2; $i < $cnt; $i++) {
|
---|
177 | $txt = $txt . $m[$i] . "@";
|
---|
178 | }
|
---|
179 | }
|
---|
180 | print OUT $_;
|
---|
181 | ++$wroteline;
|
---|
182 | } elsif ($_ =~ /~.+~/) {
|
---|
183 | # line contains a ~text~ pair used to refer to indexing :-)
|
---|
184 | $txt = $_;
|
---|
185 | while ($txt =~ /~.+~/) {
|
---|
186 | @m = split("~", $txt);
|
---|
187 |
|
---|
188 | # word is the second position
|
---|
189 | $word = @m[1];
|
---|
190 | $a = $index1{$word};
|
---|
191 | $b = $index2{$word};
|
---|
192 | $c = $index3{$word};
|
---|
193 |
|
---|
194 | # if chapter (a) is zero it wasn't found
|
---|
195 | if ($a == 0) {
|
---|
196 | print "ERROR: the tag \"$word\" on line $srcline was not found previously marked.\n";
|
---|
197 | } else {
|
---|
198 | # format the tag as x, x.y or x.y.z depending on the values
|
---|
199 | $str = $a;
|
---|
200 | $str = $str . ".$b" if ($b != 0);
|
---|
201 | $str = $str . ".$c" if ($c != 0);
|
---|
202 |
|
---|
203 | if ($b == 0 && $c == 0) {
|
---|
204 | # its a chapter
|
---|
205 | if ($a <= 10) {
|
---|
206 | if ($a == 1) {
|
---|
207 | $str = "chapter one";
|
---|
208 | } elsif ($a == 2) {
|
---|
209 | $str = "chapter two";
|
---|
210 | } elsif ($a == 3) {
|
---|
211 | $str = "chapter three";
|
---|
212 | } elsif ($a == 4) {
|
---|
213 | $str = "chapter four";
|
---|
214 | } elsif ($a == 5) {
|
---|
215 | $str = "chapter five";
|
---|
216 | } elsif ($a == 6) {
|
---|
217 | $str = "chapter six";
|
---|
218 | } elsif ($a == 7) {
|
---|
219 | $str = "chapter seven";
|
---|
220 | } elsif ($a == 8) {
|
---|
221 | $str = "chapter eight";
|
---|
222 | } elsif ($a == 9) {
|
---|
223 | $str = "chapter nine";
|
---|
224 | } elsif ($a == 10) {
|
---|
225 | $str = "chapter ten";
|
---|
226 | }
|
---|
227 | } else {
|
---|
228 | $str = "chapter " . $str;
|
---|
229 | }
|
---|
230 | } else {
|
---|
231 | $str = "section " . $str if ($b != 0 && $c == 0);
|
---|
232 | $str = "sub-section " . $str if ($b != 0 && $c != 0);
|
---|
233 | }
|
---|
234 |
|
---|
235 | #substitute
|
---|
236 | $_ =~ s/~\Q$word\E~/$str/;
|
---|
237 |
|
---|
238 | print "Found replacement tag for marker \"$word\" on line $srcline which refers to $str\n";
|
---|
239 | }
|
---|
240 |
|
---|
241 | # remake rest of the line
|
---|
242 | $cnt = @m;
|
---|
243 | $txt = "";
|
---|
244 | for ($i = 2; $i < $cnt; $i++) {
|
---|
245 | $txt = $txt . $m[$i] . "~";
|
---|
246 | }
|
---|
247 | }
|
---|
248 | print OUT $_;
|
---|
249 | ++$wroteline;
|
---|
250 | } elsif ($_ =~ m/FIGU/) {
|
---|
251 | # FIGU,file,caption
|
---|
252 | chomp($_);
|
---|
253 | @m = split(",", $_);
|
---|
254 | print OUT "\\begin{center}\n\\begin{figure}[here]\n\\includegraphics{pics/$m[1]$graph}\n";
|
---|
255 | print OUT "\\caption{$m[2]}\n\\label{pic:$m[1]}\n\\end{figure}\n\\end{center}\n";
|
---|
256 | $wroteline += 4;
|
---|
257 | } else {
|
---|
258 | print OUT $_;
|
---|
259 | ++$wroteline;
|
---|
260 | }
|
---|
261 | }
|
---|
262 | print "Read $readline lines, wrote $wroteline lines\n";
|
---|
263 |
|
---|
264 | close (OUT);
|
---|
265 | close (IN);
|
---|