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); 266