1
|
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 ($_ =~ /tommath\.h/); |
|
86 } |
|
87 } |
|
88 |
|
89 $inline = 0; |
|
90 while (<SRC>) { |
|
91 $text[$line++] = $_; |
|
92 ++$inline; |
|
93 chomp($_); |
|
94 $_ =~ s/\t/" "/ge; |
|
95 $_ =~ s/{/"^{"/ge; |
|
96 $_ =~ s/}/"^}"/ge; |
|
97 $_ =~ s/\\/'\symbol{92}'/ge; |
|
98 $_ =~ s/\^/"\\"/ge; |
|
99 |
|
100 printf OUT ("%03d ", $line); |
|
101 for ($x = 0; $x < length($_); $x++) { |
|
102 print OUT chr(vec($_, $x, 8)); |
|
103 if ($x == 75) { |
|
104 print OUT "\n "; |
|
105 ++$wroteline; |
|
106 } |
|
107 } |
|
108 print OUT "\n"; |
|
109 ++$wroteline; |
|
110 } |
|
111 $totlines = $line; |
|
112 print OUT "\\end{alltt}\n\\end{small}\n"; |
|
113 close(SRC); |
|
114 print "$inline lines\n"; |
|
115 $wroteline += 2; |
|
116 } elsif ($_ =~ m/@\d+,.+@/) { |
|
117 # line contains [number,text] |
|
118 # e.g. @14,for (ix = 0)@ |
|
119 $txt = $_; |
|
120 while ($txt =~ m/@\d+,.+@/) { |
|
121 @m = split("@",$txt); # splits into text, one, two |
|
122 @parms = split(",",$m[1]); # splits one,two into two elements |
|
123 |
|
124 # now search from $parms[0] down for $parms[1] |
|
125 $found1 = 0; |
|
126 $found2 = 0; |
|
127 for ($i = $parms[0]; $i < $totlines && $found1 == 0; $i++) { |
|
128 if ($text[$i] =~ m/\Q$parms[1]\E/) { |
|
129 $foundline1 = $i + 1; |
|
130 $found1 = 1; |
|
131 } |
|
132 } |
|
133 |
|
134 # now search backwards |
|
135 for ($i = $parms[0] - 1; $i >= 0 && $found2 == 0; $i--) { |
|
136 if ($text[$i] =~ m/\Q$parms[1]\E/) { |
|
137 $foundline2 = $i + 1; |
|
138 $found2 = 1; |
|
139 } |
|
140 } |
|
141 |
|
142 # now use the closest match or the first if tied |
|
143 if ($found1 == 1 && $found2 == 0) { |
|
144 $found = 1; |
|
145 $foundline = $foundline1; |
|
146 } elsif ($found1 == 0 && $found2 == 1) { |
|
147 $found = 1; |
|
148 $foundline = $foundline2; |
|
149 } elsif ($found1 == 1 && $found2 == 1) { |
|
150 $found = 1; |
|
151 if (($foundline1 - $parms[0]) <= ($parms[0] - $foundline2)) { |
|
152 $foundline = $foundline1; |
|
153 } else { |
|
154 $foundline = $foundline2; |
|
155 } |
|
156 } else { |
|
157 $found = 0; |
|
158 } |
|
159 |
|
160 # if found replace |
|
161 if ($found == 1) { |
|
162 $delta = $parms[0] - $foundline; |
|
163 print "Found replacement tag for \"$parms[1]\" on line $srcline which refers to line $foundline (delta $delta)\n"; |
|
164 $_ =~ s/@\Q$m[1]\E@/$foundline/; |
|
165 } else { |
|
166 print "ERROR: The tag \"$parms[1]\" on line $srcline was not found in the most recently parsed source!\n"; |
|
167 } |
|
168 |
|
169 # remake the rest of the line |
|
170 $cnt = @m; |
|
171 $txt = ""; |
|
172 for ($i = 2; $i < $cnt; $i++) { |
|
173 $txt = $txt . $m[$i] . "@"; |
|
174 } |
|
175 } |
|
176 print OUT $_; |
|
177 ++$wroteline; |
|
178 } elsif ($_ =~ /~.+~/) { |
|
179 # line contains a ~text~ pair used to refer to indexing :-) |
|
180 $txt = $_; |
|
181 while ($txt =~ /~.+~/) { |
|
182 @m = split("~", $txt); |
|
183 |
|
184 # word is the second position |
|
185 $word = @m[1]; |
|
186 $a = $index1{$word}; |
|
187 $b = $index2{$word}; |
|
188 $c = $index3{$word}; |
|
189 |
|
190 # if chapter (a) is zero it wasn't found |
|
191 if ($a == 0) { |
|
192 print "ERROR: the tag \"$word\" on line $srcline was not found previously marked.\n"; |
|
193 } else { |
|
194 # format the tag as x, x.y or x.y.z depending on the values |
|
195 $str = $a; |
|
196 $str = $str . ".$b" if ($b != 0); |
|
197 $str = $str . ".$c" if ($c != 0); |
|
198 |
|
199 if ($b == 0 && $c == 0) { |
|
200 # its a chapter |
|
201 if ($a <= 10) { |
|
202 if ($a == 1) { |
|
203 $str = "chapter one"; |
|
204 } elsif ($a == 2) { |
|
205 $str = "chapter two"; |
|
206 } elsif ($a == 3) { |
|
207 $str = "chapter three"; |
|
208 } elsif ($a == 4) { |
|
209 $str = "chapter four"; |
|
210 } elsif ($a == 5) { |
|
211 $str = "chapter five"; |
|
212 } elsif ($a == 6) { |
|
213 $str = "chapter six"; |
|
214 } elsif ($a == 7) { |
|
215 $str = "chapter seven"; |
|
216 } elsif ($a == 8) { |
|
217 $str = "chapter eight"; |
|
218 } elsif ($a == 9) { |
|
219 $str = "chapter nine"; |
|
220 } elsif ($a == 2) { |
|
221 $str = "chapter ten"; |
|
222 } |
|
223 } else { |
|
224 $str = "chapter " . $str; |
|
225 } |
|
226 } else { |
|
227 $str = "section " . $str if ($b != 0 && $c == 0); |
|
228 $str = "sub-section " . $str if ($b != 0 && $c != 0); |
|
229 } |
|
230 |
|
231 #substitute |
|
232 $_ =~ s/~\Q$word\E~/$str/; |
|
233 |
|
234 print "Found replacement tag for marker \"$word\" on line $srcline which refers to $str\n"; |
|
235 } |
|
236 |
|
237 # remake rest of the line |
|
238 $cnt = @m; |
|
239 $txt = ""; |
|
240 for ($i = 2; $i < $cnt; $i++) { |
|
241 $txt = $txt . $m[$i] . "~"; |
|
242 } |
|
243 } |
|
244 print OUT $_; |
|
245 ++$wroteline; |
|
246 } elsif ($_ =~ m/FIGU/) { |
|
247 # FIGU,file,caption |
|
248 chomp($_); |
|
249 @m = split(",", $_); |
|
250 print OUT "\\begin{center}\n\\begin{figure}[here]\n\\includegraphics{pics/$m[1]$graph}\n"; |
|
251 print OUT "\\caption{$m[2]}\n\\label{pic:$m[1]}\n\\end{figure}\n\\end{center}\n"; |
|
252 $wroteline += 4; |
|
253 } else { |
|
254 print OUT $_; |
|
255 ++$wroteline; |
|
256 } |
|
257 } |
|
258 print "Read $readline lines, wrote $wroteline lines\n"; |
|
259 |
|
260 close (OUT); |
|
261 close (IN); |