booker.pl 7.7 KB

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