/[dtapublic]/pubs/books/ucbka/trunk/scripts/cp_script.tcl
ViewVC logotype

Annotation of /pubs/books/ucbka/trunk/scripts/cp_script.tcl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations) (download) (as text)
Thu Oct 6 03:15:02 2016 UTC (7 years, 9 months ago) by dashley
File MIME type: application/x-tcl
File size: 234647 byte(s)
Initial commit after migrating from CVS.
1 dashley 4 #----------------------------------------------------------------------------------------
2     #$Header: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/dtaipubs/esrgubka/scripts/cp_script.tcl,v 1.40 2009/08/14 03:38:57 dashley Exp $
3     #----------------------------------------------------------------------------------------
4     # Dave Ashley
5     # DAVEASHLEY@DAVEASHLEY.COM
6     # DTASHLEY@AOL.COM
7     #----------------------------------------------------------------------------------------
8     # Tcl script (using Tk extensions, so it must be run under Tk/Wish) to build and package
9     # both Dave Ashley's microcontroller software book, and the associated ESRG Tool set. This
10     # script is also included with the source code of either so that the script can be used
11     # by those who have purchased or otherwise obtained the LaTeX source for the book or the
12     # source for the ESRG Tool Set to do the build.
13     #----------------------------------------------------------------------------------------
14     #The version control information below is extracted by this Tcl script and incorporated
15     #into the back of the title page. This takes the place of the "main .TEX file" information
16     #that was there previously. Since the main files are now generated on the fly by the Tcl
17     #script, this is the logical replacement. Version control information is included so
18     #that if anything goes awry, the origin and what was being used can be tracked down.
19     #
20     #AUTOMATIC MARKER: BEGIN SCRIPT VERSION CONTROL INFORMATION
21     #$RCSfile: cp_script.tcl,v $
22     #$Source: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/dtaipubs/esrgubka/scripts/cp_script.tcl,v $
23     #$Revision: 1.40 $
24     #$Author: dashley $
25     #$Date: 2009/08/14 03:38:57 $
26     #AUTOMATIC MARKER: END SCRIPT VERSION CONTROL INFORMATION
27     #
28     #****************************************************************************************
29     #****************************************************************************************
30     #**** U T I L I T Y F U N C T I O N S ******************************************
31     #****************************************************************************************
32     #****************************************************************************************
33     # Exit procedure. Exits unconditionally. Clicked in response
34     # to the button marked EXIT.
35     #
36     proc exitProc { } { \
37     global buildlogfilehandle
38    
39     #Put the system date and time into the build log and on the console.
40     set buildendtimestamp [clock seconds]
41     set s0 [clock format $buildendtimestamp -format "Execution ending at: %A, %B %d, %Y; %I:%M:%S %p."]
42     outboth $s0
43     thickhlineboth
44     close $buildlogfilehandle
45     exit 0
46     }
47    
48     #-----------------------------------------------------------------------------
49     #Writes a contiguous group of a number of characters (or strings) to a stream,
50     #without a terminating newline.
51    
52     proc contiggrouptostream { thestream thechar howmany } {
53     for {set i 0} {$i < $howmany} {incr i} {
54     puts -nonewline $thestream $thechar
55     }
56    
57     return
58     }
59    
60     #----------------------------------------------------------------------------------------
61     #Copies (binary) from src to dest, destroying dest in advance.
62     proc destructive_binary_copy { src dest } {
63     #Delete dest, if it exists.
64     file delete $dest
65    
66     set srchandle [open $src "r"]
67     set dsthandle [open $dest "w"]
68    
69     fconfigure $srchandle -translation binary
70     fconfigure $dsthandle -translation binary
71    
72     fcopy $srchandle $dsthandle
73    
74     close $srchandle
75     close $dsthandle
76    
77     return
78     }
79    
80     #****************************************************************************************
81     #****************************************************************************************
82     #**** N U M B E R I N G F U N C T I O N S **************************************
83     #****************************************************************************************
84     #****************************************************************************************
85     # Each function here has to do with numbering parts, chapters, etc.
86     #
87     # Returns the lower-case string corresponding to a digit.
88     proc lower_case_number_string { arg } { \
89     switch -exact $arg {
90     "0" { return zero }
91     "1" { return one }
92     "2" { return two }
93     "3" { return three }
94     "4" { return four }
95     "5" { return five }
96     "6" { return six }
97     "7" { return seven }
98     "8" { return eight }
99     "9" { return nine }
100     default { return INTERNAL_FUNCTION_PAR_ERROR }
101     }
102     }
103    
104    
105     # Returns the upper-case string corresponding to the
106     # roman numerals of a decimal number. Algorithm is simple
107     # case because numbers won't get large enough to prevent
108     # enumeration.
109     proc upper_case_roman_numeral_string { arg } { \
110     switch -exact $arg {
111     "0" { return ZERO_NOT_SUPPORTED_ROMAN }
112     "1" { return I }
113     "2" { return II }
114     "3" { return III }
115     "4" { return IV }
116     "5" { return V }
117     "6" { return VI }
118     "7" { return VII }
119     "8" { return VIII }
120     "9" { return IX }
121     "10" { return X }
122     "11" { return XI }
123     "12" { return XII }
124     "13" { return XIII }
125     "14" { return XIV }
126     "15" { return XV }
127     "16" { return XVI }
128     "17" { return XVII }
129     "18" { return XVIII }
130     "19" { return XIX }
131     "20" { return XX }
132     "21" { return XXI }
133     "22" { return XXII }
134     "23" { return XXIII }
135     "24" { return XXIV }
136     "25" { return XXV }
137     "26" { return XXVI }
138     "27" { return XXVII }
139     "28" { return XXVIII }
140     "29" { return XXIX }
141     "30" { return XXX }
142     "31" { return XXXI }
143     "32" { return XXXII }
144     "33" { return XXXIII }
145     "34" { return XXXIV }
146     "35" { return XXXV }
147     "36" { return XXXVI }
148     "37" { return XXXVII }
149     "38" { return XXXVIII }
150     "39" { return XXXIX }
151     "40" { return XXXX }
152     "41" { return XXXXI }
153     "42" { return XXXXII }
154     "43" { return XXXXIII }
155     "44" { return XXXXIV }
156     "45" { return XXXXV }
157     "46" { return XXXXVI }
158     "47" { return XXXXVII }
159     "48" { return XXXXVIII }
160     "49" { return IL }
161     default { return INTERNAL_FUNCTION_PAR_ERROR }
162     }
163     }
164    
165     #****************************************************************************************
166     #****************************************************************************************
167     #**** T E X T M A N I P U L A T I O N F U N C T I O N S *********************
168     #****************************************************************************************
169     #****************************************************************************************
170     #
171     # Replaces all digits in a string with their textual strings. This is used to form
172     # commands whose names the LaTeX compiler will accept.
173     proc replace_digits_with_alphas { arg } { \
174     set result ""
175     set N [string length $arg]
176    
177     for {set i 0} {$i < $N} {incr i} { \
178     set c [string index $arg $i]
179    
180     if {[string first $c "0123456789"] == -1} { \
181     #Isn't a digit, just append.
182     append result $c
183     } \
184     else {
185     #Is a digit, must expand and append.
186     append result [lower_case_number_string $c]
187     }
188     }
189    
190     return $result
191     }
192    
193     #Replaces any spaces in a string with the HTML code %20. This is necessary to
194     #to achieve the proper HTML syntax when putting filenames in in come contexts.
195     #
196     proc replace_spaces_with_HTML_codes { tgt } { \
197     set tgt [string map {" " "%20"} $tgt]
198     return $tgt
199     }
200    
201    
202     #****************************************************************************************
203     #****************************************************************************************
204     #**** V E R S I O N C O N T R O L E X T R A C T I O N F U N C T I O N S **
205     #****************************************************************************************
206     #****************************************************************************************
207     #Extracts the version control information lines (marked automatically above) from this
208     #file and returns them as a string. The string includes all newline characters.
209    
210     proc extract_this_scripts_version_control_information { } { \
211     #Define the strings that we'll accept as beginning the
212     #block of version control information and the strings
213     #that we'll accept as terminating it.
214     set begin_string "AUTOMATIC MARKER: BEGIN SCRIPT VERSION CONTROL INFORMATION"
215     set end_string "AUTOMATIC MARKER: END SCRIPT VERSION CONTROL INFORMATION"
216    
217     #Initialize our return value to nothing so far.
218     set rv ""
219    
220     #Open the script for extraction.
221     set script_handle [open scripts/cp_script.tcl r]
222    
223     #Leaf through the file until we hit the end of file or else the beginning string.
224     set eof_found 0
225     set beginstring_found 0
226     while {!$eof_found && !$beginstring_found} { \
227     set current_line [gets $script_handle]
228     set beginstring_found_index [string first $begin_string $current_line]
229     set beginstring_found [expr $beginstring_found_index >= 0]
230     set eof_found [eof $script_handle]
231     }
232    
233     if {!$eof_found} { \
234     #If we're here, we got the begin string we were looking for. Copy over
235     #until the end string is encountered or until end of file.
236     set endstring_found 0
237     while {!$eof_found && !$endstring_found} { \
238     set current_line [gets $script_handle]
239    
240     #If the first character of the line is a Tcl comment delimieter (which it
241     #most likely is), trash it.
242     set current_line [string trimleft $current_line "#"]
243    
244     set endstring_found_index [string first $end_string $current_line]
245     set endstring_found [expr $endstring_found_index >= 0]
246     set eof_found [eof $script_handle]
247     if {!$endstring_found} { \
248     append rv $current_line "\n"
249     }
250     }
251     }
252    
253     #Close the script file.
254     close $script_handle
255    
256     #Return the extracted version control information.
257     return $rv
258     }
259    
260     #****************************************************************************************
261     #****************************************************************************************
262     #**** L O G G I N G F U N C T I O N S ******************************************
263     #****************************************************************************************
264     #****************************************************************************************
265     # Each function in this category is called as an aid in maintaing a log file and a
266     # console display which say exactly the same thing.
267     #----------------------------------------------------------------------------------------
268     #Writes a contiguous group of a number of characters to the standard output,
269     #plus to the build log file.
270    
271     proc contiggrouptoboth { thechar howmany } {
272     global buildlogfilehandle
273    
274     contiggrouptostream $buildlogfilehandle $thechar $howmany
275     contiggrouptostream stdout $thechar $howmany
276    
277     return
278     }
279    
280     #-----------------------------------------------------------------------------
281     #Writes a line of $loglinelength hyphens followed by a newline to only the
282     #console, but not the build log file.
283    
284     proc hlineconsole {} {
285     global loglinelength
286    
287     contiggrouptostream stdout - $loglinelength
288     puts ""
289    
290     return
291     }
292    
293     #-----------------------------------------------------------------------------
294     #Writes a line of $loglinelength hyphens followed by a newline to both the
295     #console and the build log file.
296    
297     proc hlineboth {} {
298     global loglinelength
299     global buildlogfilehandle
300    
301     contiggrouptoboth - $loglinelength
302     puts $buildlogfilehandle ""
303     puts ""
304    
305     return
306     }
307    
308     #-----------------------------------------------------------------------------
309     #Writes a line of $loglinelength "=" chars followed by a newline to only the
310     #console but not the build log file.
311    
312     proc thickhlineconsole {} {
313     global loglinelength
314    
315     contiggrouptostream stdout = $loglinelength
316     puts ""
317    
318     return
319     }
320    
321     #-----------------------------------------------------------------------------
322     #Writes a line of $loglinelength "=" chars followed by a newline to both the
323     #console and the build log file.
324    
325     proc thickhlineboth {} {
326     global loglinelength
327     global buildlogfilehandle
328    
329     contiggrouptoboth = $loglinelength
330     puts $buildlogfilehandle ""
331     puts ""
332    
333     return
334     }
335    
336     #-----------------------------------------------------------------------------
337     #Dumps output to both the console and the log file, with newline attached.
338     proc outboth { arg } {
339     global buildlogfilehandle
340    
341     puts $buildlogfilehandle $arg
342     puts $arg
343    
344     return
345     }
346    
347     #-----------------------------------------------------------------------------
348     #Dumps output to both the console and the log file, without newline attached.
349     proc outbothnonl { arg } {
350     global buildlogfilehandle
351    
352     puts -nonewline $buildlogfilehandle $arg
353     puts -nonewline $arg
354    
355     return
356     }
357    
358     #-----------------------------------------------------------------------------
359     #Prints a banner to the passed stream indicating success or failure of a build
360     #script. The two messages are "*OK*" and "FAIL". The failflag, if 0, means
361     #success, or if non-zero, means failure. The banner will be centered
362     #in the output. $nearpadchar and $farpadchar are the characters used to pad
363     #the centering near the banner letters and farther away. $nearfarmargin is
364     #the number of characters for which the near characters extend.
365     proc passfailbannertostream { thestream passfailflag nearpadchar farpadchar nearfarmargin} {
366    
367     global loglinelength
368    
369     set passbanner {
370     " OOOOO K K" \
371     "O O K K " \
372     "O O K K " \
373     "O O KK " \
374     "O O K K " \
375     "O O K K " \
376     "O O K K " \
377     "O O K K " \
378     " OOOOO K K" \
379     }
380     set failbanner {
381     "FFFFFFF AAA III L " \
382     "F A A I L " \
383     "F A A I L " \
384     "F A A I L " \
385     "FFFFFF AAAAAAA I L " \
386     "F A A I L " \
387     "F A A I L " \
388     "F A A I L " \
389     "F A A III LLLLLLL" \
390     }
391    
392     #First we need to calculate the number of chars on the left with which
393     #to pad the the result.
394    
395     if {$passfailflag != 0} {
396     #Fail
397     set banner $failbanner
398     } \
399     else {
400     #Pass
401     set banner $passbanner
402     }
403    
404     #Determine the width of the banner which applies.
405     set bannerwidth [string length [lindex $banner 0] ]
406    
407     #Calculate the size in chars to use for the far padding.
408     set farpadwidth [expr "($loglinelength - $bannerwidth - (2 * $nearfarmargin ) ) >> 1"]
409    
410     #If by poor choice of all values we ended up with a negative number, clip it to zero.
411     if {$farpadwidth < 0} {
412     set farpadwidth 0
413     }
414    
415     #Iterate to output the lines of the banner.
416     foreach curline $banner {
417     for {set i 0} {$i < $farpadwidth} {incr i} {
418     puts -nonewline $thestream $farpadchar
419     }
420    
421     for {set i 0} {$i < $nearfarmargin} {incr i} {
422     puts -nonewline $thestream $nearpadchar
423     }
424    
425     puts -nonewline $thestream $curline
426    
427     for {set i 0} {$i < $nearfarmargin} {incr i} {
428     puts -nonewline $thestream $nearpadchar
429     }
430    
431     for {set i 0} {$i < $farpadwidth} {incr i} {
432     puts -nonewline $thestream $farpadchar
433     }
434    
435     puts $thestream ""
436     }
437    
438     return
439     }
440    
441     #****************************************************************************************
442     #****************************************************************************************
443     #**** D A T A S T R U C T U R E U T I L I T Y F U N C T I O N S **********
444     #****************************************************************************************
445     #****************************************************************************************
446     # Each function in this category provides a function related to the data structures
447     # embedded in the script. Generally, errors are all fatal.
448     #----------------------------------------------------------------------------------------
449     # Indexes the volume list by the 4-letter tag. This is done for lookup speed.
450     proc IndexVolumeList { } { \
451     global bookVolumeList
452     global bookVolumeListStructSize
453     global bookVolumeListIndex
454    
455     outboth "Indexing volume list."
456    
457     set N [llength $bookVolumeList]
458    
459     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
460     set elem [lindex $bookVolumeList $i]
461    
462     set bookVolumeListIndex($elem) $i
463    
464     outboth " bookVolumeList($elem) = $i"
465     }
466    
467     hlineboth
468     }
469    
470     #----------------------------------------------------------------------------------------
471     # Indexes the chapter list by the 4-letter tag. This is done for lookup speed.
472     proc IndexChapterList { } { \
473     global chapterList
474     global chapterListStructSize
475     global chapterListIndex
476    
477     outboth "Indexing chapter list."
478    
479     set N [llength $chapterList]
480    
481     for {set i 0} {$i < $N} {incr i $chapterListStructSize} { \
482     set elem [lindex $chapterList $i]
483    
484     set chapterListIndex($elem) $i
485    
486     outboth " chapterList($elem) = $i"
487     }
488    
489     hlineboth
490     }
491    
492     #****************************************************************************************
493     #****************************************************************************************
494     #**** C H A P T E R T A B L E L O O K U P F U N C T I O N S **************
495     #****************************************************************************************
496     #****************************************************************************************
497     # Functions which look up chapter table information.
498     #----------------------------------------------------------------------------------------
499     #
500     # Returns the single-volume long title for a chapter. Input is the 4-character
501     # chapter tag. Chapter table must have been indexed in advance.
502     proc get_chap_long_single_volume_title { ctag } { \
503     global chapterList
504     global chapterListIndex
505    
506     set i $chapterListIndex($ctag)
507    
508     return [lindex $chapterList [expr $i + 1]]
509     }
510    
511     # Returns the single-volume short title for a chapter. Input is the 4-character
512     # chapter tag. Chapter table must have been indexed in advance.
513     proc get_chap_short_single_volume_title { ctag } { \
514     global chapterList
515     global chapterListIndex
516    
517     set i $chapterListIndex($ctag)
518    
519     return [lindex $chapterList [expr $i + 2]]
520     }
521    
522     #Mark an individual chapter (by tag) used.
523     proc mark_chapter_used { ctag } { \
524     global chapterList
525     global chapterListIndex
526    
527     #outboth "Inside chapter marking function, ctag is : $ctag"
528    
529     set i $chapterListIndex($ctag)
530    
531     set i [expr $i + 7]
532    
533     #outboth "Element selected for marking is : $i"
534    
535     #outboth "Current value is: [lindex $chapterList $i]"
536    
537     set chapterList [lreplace $chapterList $i $i 1]
538    
539     #outboth "New value is: [lindex $chapterList $i]"
540     }
541    
542    
543     #Inquire if a given chapter (by tag) has its used flag set.
544     #Result is "1" if used, "0" otherwise.
545     proc get_chap_used_flag { ctag } { \
546     global chapterList
547     global chapterListStructSize
548     global chapterListIndex
549    
550     set i $chapterListIndex($ctag)
551    
552     set i [expr $i + 7]
553    
554     return [lindex $chapterList $i]
555     }
556    
557    
558     #Marks each of the chapters as unused (resets all of the "used" flags to zero).
559     proc mark_all_chaps_unused { } { \
560     global chapterList
561     global chapterListStructSize
562    
563     set N [llength $chapterList]
564    
565     for {set i 0} {$i < $N} {incr i $chapterListStructSize} { \
566     set j [expr $i + 7]
567    
568     set chapterList [lreplace $chapterList $j $j 0]
569     }
570     }
571    
572     #****************************************************************************************
573     #****************************************************************************************
574     #**** V O L U M E T A B L E L O O K U P F U N C T I O N S ****************
575     #****************************************************************************************
576     #****************************************************************************************
577     # Functions which lookup volume table information.
578     #----------------------------------------------------------------------------------------
579     # Returns the part string associated with a volume record in the volume table.
580     # Input is the 4-character volume tag. Volume table must have been indexed in advance.
581     proc get_vol_part_title { vtag } { \
582     global bookVolumeList
583     global bookVolumeListIndex
584    
585     set i $bookVolumeListIndex($vtag)
586    
587     return [lindex $bookVolumeList [expr $i + 3]]
588     }
589    
590     # Returns the multiple-volume long title associated with a volume.
591     # Input is the 4-character volume tag. Volume table must have been indexed in advance.
592     proc get_multi_vol_long_title { vtag } { \
593     global bookVolumeList
594     global bookVolumeListIndex
595    
596     set i $bookVolumeListIndex($vtag)
597    
598     return [lindex $bookVolumeList [expr $i + 4]]
599     }
600    
601     #Marks each of the volumes as unused (resets all of the "used" flags to zero).
602     proc mark_all_volumes_unused { } { \
603     global bookVolumeList
604     global bookVolumeListStructSize
605    
606     set N [llength $bookVolumeList]
607    
608     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
609     set j [expr $i + 7]
610    
611     set bookVolumeList [lreplace $bookVolumeList $j $j 0]
612     }
613     }
614    
615     #Mark an individual volume (by tag) used.
616     proc mark_volume_used { vtag } { \
617     global bookVolumeList
618     global bookVolumeListIndex
619    
620     set i $bookVolumeListIndex($vtag)
621    
622     set i [expr $i + 7]
623    
624     set bookVolumeList [lreplace $bookVolumeList $i $i 1]
625     }
626    
627    
628     #Inquire if a given volume (by tag) has its used flag set.
629     #Result is "1" if used, "0" otherwise.
630     proc get_volume_used_flag { vtag } { \
631     global bookVolumeList
632     global bookVolumeListStructSize
633     global bookVolumeListIndex
634    
635     set i $bookVolumeListIndex($vtag)
636    
637     set i [expr $i + 7]
638    
639     return [lindex $bookVolumeList $i]
640     }
641    
642    
643     #****************************************************************************************
644     #****************************************************************************************
645     #**** L A T E X C O M P I L E F U N C T I O N S *****************************
646     #****************************************************************************************
647     #****************************************************************************************
648     # Each function in this category performs a function related to LaTeX compilation or
649     # indexing.
650     #----------------------------------------------------------------------------------------
651     # Performs the LaTeX compile of the passed filename, in the "root" directory of the book.
652     # Any errors will cause the script to terminate. It gets more attention that way, when
653     # an error kills the script.
654     #
655     proc LatexCompileFile { filename } { \
656     global execLatexCompiler
657     global errorCode
658    
659     #The error-handling strategy taken in this function is to terminate with a log file
660     #entry if the LaTeX compiler chokes. First of all, generally the LaTeX code is
661     #debugged in the 4AllTex GUI, so we shouldn't be compiling bad LaTeX code here.
662     #Second, this is a utility script, and not required to be graceful. Third,
663     #terminating the program will definitely get the user's attention, whereas any
664     #lesser approach might not.
665     outbothnonl "Using LaTeX to compile: $filename"
666     outboth .
667     hlineboth
668    
669     #The full path to the LaTeX compiler has already been calculated for us at
670     #script startup.
671    
672     #Delete existing intermediate files if they exist.
673     file delete tcl00out.txt
674     file delete tcl00err.txt
675    
676     #Open the intermediate files for writing.
677     set stdouthandle [open "tcl00out.txt" "w"]
678     set stderrhandle [open "tcl00err.txt" "w"]
679    
680     #Execute exec and suppress errors.
681     set catchreturncode 0
682     set catchreturncode [catch {exec -- $execLatexCompiler -progname=latex &latex $filename >@ $stdouthandle 2>@ $stderrhandle}]
683     set catcherrorcode $errorCode
684    
685     #Close both open files.
686     close $stderrhandle
687     close $stdouthandle
688    
689     if {$catchreturncode} {
690     outbothnonl "$execLatexCompiler generated errors (information follows): $catchreturncode $catcherrorcode"
691     outboth "."
692     outboth "The build must be aborted."
693     set compilefailed 1
694     hlineboth
695     } \
696     else {
697     outboth "$execLatexCompiler did not generate errors."
698     set compilefailed 0
699     hlineboth
700     }
701    
702     set stdouthandle [open "tcl00out.txt" "r"]
703     set stderrhandle [open "tcl00err.txt" "r"]
704     set stdoutoutput [read $stdouthandle]
705     set stderroutput [read $stderrhandle]
706     close $stdouthandle
707     close $stderrhandle
708    
709     #Delete existing intermediate files if they exist.
710     file delete tcl00out.txt
711     file delete tcl00err.txt
712    
713     outboth "Standard output stream from $execLatexCompiler invocation:"
714     hlineboth
715     outboth $stdoutoutput
716     hlineboth
717     outboth "Standard error stream from $execLatexCompiler invocation:"
718     hlineboth
719     outboth $stderroutput
720     hlineboth
721    
722     if {$compilefailed} { \
723     outboth "Compile has failed. Must abort script."
724     exitProc
725     }
726    
727     update
728     }
729    
730     #----------------------------------------------------------------------------------------
731     # Runs the MAKEINDEX program for a file located in the root directory of the book.
732     # File parameter passed is just the "base" file name.
733     #
734     proc MakeOrdinaryIndexFile { filename } { \
735     global execMakeindex
736     global errorCode
737    
738     #The error-handling strategy taken in this function is to terminate with a log file
739     #entry if the Makeindex utility chokes. First of all, generally the LaTeX code is
740     #debugged in the 4AllTex GUI, so we shouldn't be compiling bad LaTeX code here.
741     #Second, this is a utility script, and not required to be graceful. Third,
742     #terminating the program will definitely get the user's attention, whereas any
743     #lesser approach might not.
744     outbothnonl "Using MAKEINDEX to process: $filename"
745     outboth .
746     hlineboth
747    
748     #The full path to the MAKEINDEX utility has already been calculated for us at
749     #script startup.
750    
751     #Delete existing intermediate files if they exist.
752     file delete tcl00out.txt
753     file delete tcl00err.txt
754    
755     #Open the intermediate files for writing.
756     set stdouthandle [open "tcl00out.txt" "w"]
757     set stderrhandle [open "tcl00err.txt" "w"]
758    
759     #Execute exec and suppress errors.
760     set catchreturncode 0
761     set catchreturncode [catch {exec -- $execMakeindex $filename >@ $stdouthandle 2>@ $stderrhandle}]
762     set catcherrorcode $errorCode
763    
764     #Close both open files.
765     close $stderrhandle
766     close $stdouthandle
767    
768     if {$catchreturncode} {
769     outbothnonl "$execMakeindex generated errors (information follows): $catchreturncode $catcherrorcode"
770     outboth "."
771     outboth "The build must be aborted."
772     set compilefailed 1
773     hlineboth
774     } \
775     else {
776     outboth "$execMakeindex did not generate errors."
777     set compilefailed 0
778     hlineboth
779     }
780    
781     set stdouthandle [open "tcl00out.txt" "r"]
782     set stderrhandle [open "tcl00err.txt" "r"]
783     set stdoutoutput [read $stdouthandle]
784     set stderroutput [read $stderrhandle]
785     close $stdouthandle
786     close $stderrhandle
787    
788     #Delete existing intermediate files if they exist.
789     file delete tcl00out.txt
790     file delete tcl00err.txt
791    
792     outboth "Standard output stream from $execMakeindex invocation:"
793     hlineboth
794     outboth $stdoutoutput
795     hlineboth
796     outboth "Standard error stream from $execMakeindex invocation:"
797     hlineboth
798     outboth $stderroutput
799     hlineboth
800    
801     if {$compilefailed} { \
802     outboth "$execMakeindex has failed. Must abort script."
803     exitProc
804     }
805    
806     update
807     }
808    
809     #----------------------------------------------------------------------------------------
810     # Runs the DVIPS program to generate postscript output for a file located in the root
811     # directory of the book. File parameter passed is just the "base" file name.
812     #
813     proc RunDvipsToGenPsOutput { filename } { \
814     global execDvips
815     global errorCode
816     global pathUcBookA
817    
818     #The error-handling strategy taken in this function is to terminate with a log file
819     #entry if the DVIPS utility chokes. First of all, generally the LaTeX code is
820     #debugged in the 4AllTex GUI, so we shouldn't be compiling bad LaTeX code here.
821     #Second, this is a utility script, and not required to be graceful. Third,
822     #terminating the program will definitely get the user's attention, whereas any
823     #lesser approach might not.
824     outbothnonl "Using DVIPS to process: $filename"
825     outboth .
826     hlineboth
827    
828     #The full path to the DVIPS utility has already been calculated for us at
829     #script startup.
830    
831     #Delete existing intermediate files if they exist.
832     file delete tcl00out.txt
833     file delete tcl00err.txt
834    
835     #Open the intermediate files for writing.
836     set stdouthandle [open "tcl00out.txt" "w"]
837     set stderrhandle [open "tcl00err.txt" "w"]
838    
839     #Generate the full path names of interest. We need to convert the forward slashes
840     #in both names to backslashes because DVIPS accepts the file name and opens the file
841     #itself.
842     set dvips_input ""
843     append dvips_input $pathUcBookA / $filename .dvi
844     set dvips_input [string map {/ \\} $dvips_input]
845     set dvips_output ""
846     append dvips_output $pathUcBookA / $filename .ps
847     set dvips_output [string map {/ \\} $dvips_output]
848    
849     #outboth $dvips_input
850     #outboth $dvips_output
851    
852     #d:\4tex5.0\bin\win32\dvips.exe -P ljfive -o"c:\esrgubka\llr0.ps" "c:\esrgubka\llr0.dvi"
853    
854     #Execute exec and suppress errors.
855     set catchreturncode 0
856     set catchreturncode [catch {exec -- $execDvips -T 8.5in,11in -o$dvips_output $dvips_input >@ $stdouthandle 2>@ $stderrhandle}]
857     set catcherrorcode $errorCode
858    
859     #Close both open files.
860     close $stderrhandle
861     close $stdouthandle
862    
863     if {$catchreturncode} {
864     outbothnonl "$execDvips generated errors (information follows): $catchreturncode $catcherrorcode"
865     outboth "."
866     outboth "The build must be aborted."
867     set compilefailed 1
868     hlineboth
869     } \
870     else {
871     outboth "$execDvips did not generate errors."
872     set compilefailed 0
873     hlineboth
874     }
875    
876     set stdouthandle [open "tcl00out.txt" "r"]
877     set stderrhandle [open "tcl00err.txt" "r"]
878     set stdoutoutput [read $stdouthandle]
879     set stderroutput [read $stderrhandle]
880     close $stdouthandle
881     close $stderrhandle
882    
883     #Delete existing intermediate files if they exist.
884     file delete tcl00out.txt
885     file delete tcl00err.txt
886    
887     outboth "Standard output stream from $execDvips invocation:"
888     hlineboth
889     outboth $stdoutoutput
890     hlineboth
891     outboth "Standard error stream from $execDvips invocation:"
892     hlineboth
893     outboth $stderroutput
894     hlineboth
895    
896     if {$compilefailed} { \
897     outboth "$execDvips has failed. Must abort script."
898     exitProc
899     }
900    
901     update
902     }
903    
904     #----------------------------------------------------------------------------------------
905     # Modifies a PS file generated by DVIPS to be duplex. This is done in a very crude way,
906     # by inserting PostScript. It can probably be done more elegantly by using the configuration
907     # and startup files of DVIPS
908     #
909     proc ModifyPsToDuplex { filebasename } { \
910     global errorCode
911     global pathUcBookA
912    
913     outbothnonl "Modifying postscript to get duplex form of: $filebasename"
914     outboth .
915     update
916    
917     #Form the full path of both file names.
918     set mod_input ""
919     set mod_output ""
920     append mod_input $pathUcBookA / $filebasename .ps
921     append mod_output $pathUcBookA / $filebasename _duplex.ps
922    
923     set inhandle [open $mod_input "r"]
924     set outhandle [open $mod_output "w"]
925    
926     #Set larger buffers to speed the I/O operations.
927     fconfigure $inhandle -buffering full -buffersize 200000
928     fconfigure $outhandle -buffering full -buffersize 200000
929    
930     set oneshot 0
931    
932     while {! [eof $inhandle] } { \
933     set line [gets $inhandle]
934     puts $outhandle $line
935    
936     if { ! $oneshot } { \
937     if { [string match "*DVIPSSource*" $line] } { \
938     puts $outhandle "<< /Duplex true >> setpagedevice"
939     set oneshot 1
940     }
941     }
942     }
943    
944     #Close both open files.
945     close $inhandle
946     close $outhandle
947    
948     hlineboth
949    
950     update
951     }
952    
953    
954     #****************************************************************************************
955     #****************************************************************************************
956     #**** L A T E X S O U R C E F I L E G E N E R A T I O N ******************
957     #****************************************************************************************
958     #****************************************************************************************
959     #Outputs the file title line of a LaTeX book source file.
960     #
961     proc output_title_line { handle filename desc} { \
962     puts $handle "%[string toupper $filename]: $desc"
963     puts $handle "%"
964    
965     set preamble {
966     "%-----------------------------------------------------------------------------------" \
967     "%This is an automatically generated file and not version-controlled. This file is" \
968     "%generated by the script CP_SCRIPT.TCL." \
969     "%-----------------------------------------------------------------------------------" \
970     "%" \
971     }
972    
973     for {set i 0} {$i < [llength $preamble]} {incr i} { \
974     puts $handle [lindex $preamble $i]
975     }
976     }
977    
978     #Outputs the LaTeX document class and package includes.
979     #
980     proc output_doc_class_and_package_includes { handle } { \
981     set preamble {
982     "\\documentclass[letterpaper,10pt,titlepage]\{custbook\}" \
983     "%" \
984     "\\pagestyle\{headings\}" \
985     "%" \
986     "\\usepackage\{amsmath\}" \
987     "\\usepackage\{amsfonts\}" \
988     "\\usepackage\{amssymb\}" \
989     "\\usepackage[ansinew]\{inputenc\}" \
990     "\\usepackage[OT1]\{fontenc\}" \
991     "\\usepackage\{graphicx\}" \
992     "\\usepackage\{makeidx\}" \
993     "%" \
994     }
995    
996     for {set i 0} {$i < [llength $preamble]} {incr i} { \
997     puts $handle [lindex $preamble $i]
998     }
999     }
1000    
1001    
1002     #Outputs the final matter in both types of volumes. The "final matter" is the
1003     #stuff after the chapter includes up until but not including final
1004     #file annunciator.
1005     #
1006     proc output_tex_volume_final_matter { handle } { \
1007     set final_matter {
1008     "%Glossary Of Terms" \
1009     "\\cleardoublepage" \
1010     "\\addcontentsline\{toc\}\{chapter\}\{Glossary Of Terms\}" \
1011     "\\input\{c_glo0/c_glo0\}" \
1012     "%" \
1013     "%Glossary Of Mathematical Notation" \
1014     "\\cleardoublepage" \
1015     "\\addcontentsline\{toc\}\{chapter\}\{Glossary Of Mathematical Notation\}" \
1016     "\\input\{c_glo1/c_glo1\}" \
1017     "%" \
1018     "%Bibliography" \
1019     "\\cleardoublepage" \
1020     "\\addcontentsline\{toc\}\{chapter\}\{Bibliography\}" \
1021     "\\input\{volshare/workbibl\}" \
1022     "%" \
1023     "%Index Must Be Formed At This Directory Level" \
1024     "\\cleardoublepage" \
1025     "\\addcontentsline\{toc\}\{chapter\}\{Index\}" \
1026     "\\printindex" \
1027     "%" \
1028     "\\end\{document\}" \
1029     "%" \
1030     }
1031    
1032     for {set i 0} {$i < [llength $final_matter]} {incr i} { \
1033     puts $handle [lindex $final_matter $i]
1034     }
1035     }
1036    
1037    
1038     #Marks the end of a TEX volume file, for aesthetics.
1039     proc mark_end_of_tex_volume_files_for_aesthetics { handle filename } { \
1040     puts $handle "%End of file [string toupper $filename]."
1041     }
1042    
1043    
1044     #Output code to import the external document labels, used for cross-referencing
1045     #This is a bit tricky because don't want to include ourselves. This applies
1046     #to the multi-volume work only. For the single-volume work, all reference are
1047     #internal.
1048     proc output_external_document_symbol_imports { handle vtag } { \
1049     global bookVolumeList
1050     global bookVolumeListStructSize
1051    
1052     puts $handle "%External document symbol imports. These imports allow one volume"
1053     puts $handle "%to cross-reference to another, and create one large namespace for"
1054     puts $handle "%LaTeX symbols."
1055    
1056     set N [llength $bookVolumeList]
1057    
1058     #Iterate through the list. Everything gets output unless
1059     #it is our tag name.
1060     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
1061     if {[get_volume_used_flag [lindex $bookVolumeList $i]]} { \
1062     set iter_vtag [lindex $bookVolumeList $i]
1063     if {[string compare $iter_vtag $vtag]} { \
1064     set lineout \\externaldocument\{$iter_vtag\}
1065     puts $handle $lineout
1066     }
1067     }
1068     }
1069    
1070     puts $handle "%"
1071     }
1072    
1073     #Outputs the common things in a document, from the "\makeindex" command
1074     #through the "\begin{document}" command.
1075     #
1076     proc output_common_lines_through_begindoc { handle } { \
1077     set preamble {
1078     "%Embarrassingly, I've forgotten why \"makeindex\" is necessary ..." \
1079     "\\makeindex" \
1080     "%" \
1081     "%Shared mathematical definitions" \
1082     "\\input\{volshare/workmdef\}" \
1083     "%" \
1084     "%Hyphenation exceptions" \
1085     "\\input\{volshare/workhxcp\}" \
1086     "%" \
1087     "%New environments, etc." \
1088     "\\input\{volshare/worknenv\}" \
1089     "%" \
1090     "\\begin\{document\}" \
1091     "%" \
1092     "%Index \"see\" definitions" \
1093     "\\input\{volshare/workidxs\}" \
1094     "%" \
1095     }
1096    
1097     for {set i 0} {$i < [llength $preamble]} {incr i} { \
1098     puts $handle [lindex $preamble $i]
1099     }
1100     }
1101    
1102     #Outputs multi-volume volume and chapter definitions for a specific
1103     #volume.
1104     #
1105     #Inputs:
1106     # handle : File handle to write to.
1107     # vtag : Volume tag of the volume whose master file is being formed.
1108     # volnum : The ordinal number of the volume, as a decimal integer.
1109     # This is used to create ordinary numbers, roman numbers,
1110     # etc.
1111     #
1112     proc output_multi_volume_volume_and_chapter_definitions { handle vtag volnum } { \
1113     global bookVolumeList
1114     global bookVolumeListStructSize
1115     global mcl
1116    
1117     #Get the roman-numeral representation of the volume.
1118     set volnum_roman [upper_case_roman_numeral_string $volnum]
1119    
1120     #Get the long title of the volume.
1121     set vol_long_title [get_multi_vol_long_title $vtag]
1122    
1123     #Output the "current volume" LaTeX commands.
1124     puts $handle "%Constants for the current volume."
1125     puts $handle "\\newcommand\\curvolarabic\{$volnum\}"
1126     puts $handle "\\newcommand\\curvolroman\{$volnum_roman\}"
1127     puts $handle "\\newcommand\\curvoltitle\{$vol_long_title\}"
1128     puts $handle "\\newcommand\\curvoltitlepagesep\{: \}"
1129     puts $handle "\\newcommand\\curvoltitlepageprefix\{Volume \}"
1130     puts $handle "%"
1131    
1132     #Output definitions for all volumes. There is no need to exclude the
1133     #current volume, as this could just as well be cited in this framework.
1134     puts $handle "%Constants for all volumes."
1135     puts $handle "%"
1136     set temp_ordinal_volume_number 0
1137     set N [llength $bookVolumeList]
1138     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
1139     set cur_iter_volume [lindex $bookVolumeList $i]
1140    
1141     if {[get_volume_used_flag [lindex $bookVolumeList $i]]} { \
1142     incr temp_ordinal_volume_number
1143     puts $handle "%%%% [string toupper [lindex $bookVolumeList $i]]: Volume $temp_ordinal_volume_number: [get_multi_vol_long_title [lindex $bookVolumeList $i]] %%%%"
1144     puts $handle "\\newcommand\\v[replace_digits_with_alphas [lindex $bookVolumeList $i]]arabic\{$temp_ordinal_volume_number\}"
1145     puts $handle "\\newcommand\\v[replace_digits_with_alphas [lindex $bookVolumeList $i]]roman\{[upper_case_roman_numeral_string $temp_ordinal_volume_number]\}"
1146     puts $handle "\\newcommand\\v[replace_digits_with_alphas [lindex $bookVolumeList $i]]title\{[get_multi_vol_long_title [lindex $bookVolumeList $i]]\}"
1147     puts $handle "\\newcommand\\v[replace_digits_with_alphas [lindex $bookVolumeList $i]]citecomma\{[string toupper [lindex $bookVolumeList $i]], \}"
1148     puts $handle "\\newcommand\\v[replace_digits_with_alphas [lindex $bookVolumeList $i]]citehyphen\{[string toupper [lindex $bookVolumeList $i]]-\}"
1149     puts $handle "%"
1150    
1151     #Output definitions for all chapters which are enclosed by the current volume. This is a bit tricky
1152     #because must traverse the mcl table and pick out the right portion.
1153     set state 0
1154     #"state" is a state variable which keeps track of where we are parsing the mcl table.
1155     #State values are as follows:
1156     # 0 -- have not yet found the right volume.
1157     # 1 -- are in the midst of the right volume.
1158     # 2 -- are into subsequent volumes.
1159    
1160     set cur_vol ""
1161     set chapter_or_appendix ""
1162    
1163     for {set j 0} {$j < [llength $mcl]} {incr j 4} { \
1164     set rectype [lindex $mcl [expr $j + 0]]
1165     set par1 [lindex $mcl [expr $j + 1]]
1166     set par2 [lindex $mcl [expr $j + 2]]
1167     set par3 [lindex $mcl [expr $j + 3]]
1168    
1169     if {$state == 0} { \
1170     if {! [string compare $rectype v] || ! [string compare $rectype w]} { \
1171     #This is a volume record that has meaning for us. In either case,
1172     #the vtag comes from par1.
1173    
1174     #Have not yet encountered our volume of interest. If this is
1175     #it, record and change state.
1176     if {![string compare $cur_iter_volume $par1]} { \
1177     set cur_vol $par1
1178     set chapter_or_appendix "Chapter"
1179     set state 1
1180     }
1181     }
1182     } \
1183     elseif {$state == 1} { \
1184     #We are within the volume of interest. Looking for chapter records.
1185     if {! [string compare $rectype c] || ! [string compare $rectype e]} { \
1186     set cur_chap_lc $par1
1187     set cur_chap_uc [string toupper $cur_chap_lc]
1188     set cur_chap_idstring [replace_digits_with_alphas $cur_chap_lc]
1189     set cur_chap_short_title [get_chap_short_single_volume_title $cur_chap_lc]
1190     set cur_chap_long_title [get_chap_long_single_volume_title $cur_chap_lc]
1191     set cur_chap_vol_arabic $temp_ordinal_volume_number
1192     set cur_chap_vol_roman [upper_case_roman_numeral_string $temp_ordinal_volume_number]
1193     set cur_chap_vol_title [get_multi_vol_long_title [lindex $bookVolumeList $i]]
1194    
1195     puts $handle "%%%% Chapter C$cur_chap_uc: $cur_chap_long_title %%%%"
1196     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1197     puts $handle "volarabic\{$cur_chap_vol_arabic\}"
1198     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1199     puts $handle "volroman\{$cur_chap_vol_roman\}"
1200     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1201     puts $handle "voltitle\{$cur_chap_vol_title\}"
1202     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1203     puts $handle "shorttitle\{$cur_chap_short_title\}"
1204     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1205     puts $handle "title\{$cur_chap_long_title\}"
1206     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1207     puts $handle "longtitle\{$cur_chap_long_title\}"
1208    
1209     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1210    
1211     #For the cite, there are two cases to cover. If the chapter is in the
1212     #volume we're doing, the cite is the empty string. Otherwise, it
1213     #is the volume tag.
1214     if {![string compare $vtag $cur_iter_volume]} { \
1215     set cur_chap_xref_cite ""
1216     } \
1217     else {
1218     set cur_chap_xref_cite "[string toupper [lindex $bookVolumeList $i]]"
1219     }
1220    
1221     if {[string length $cur_chap_xref_cite]} { \
1222     puts $handle "xrefhyphen\{$cur_chap_xref_cite-\}"
1223     } \
1224     else {
1225     puts $handle "xrefhyphen\{\}"
1226     }
1227    
1228     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1229    
1230     if {[string length $cur_chap_xref_cite]} { \
1231     puts $handle "xrefcomma\{$cur_chap_xref_cite, \}"
1232     } \
1233     else {
1234     puts $handle "xrefcomma\{\}"
1235     }
1236    
1237     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1238     puts $handle "mcclass\{$chapter_or_appendix\}"
1239     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1240     puts $handle "ucclass\{[string toupper $chapter_or_appendix]\}"
1241     puts -nonewline $handle "\\newcommand\\c$cur_chap_idstring"
1242     puts $handle "lcclass\{[string tolower $chapter_or_appendix]\}"
1243     puts $handle "%"
1244     } \
1245     elseif {! [string compare $rectype y]} { \
1246     #This is the beginning of the appendix material for a multi-volume work.
1247     set chapter_or_appendix "Appendix"
1248     } \
1249     elseif {! [string compare $rectype v] || ! [string compare $rectype w]} { \
1250     set state 2
1251     }
1252     } \
1253     elseif {$state == 2} { \
1254     #Do nothing. We are in the parsing state where we have done the volume of interest
1255     #and can't do more.
1256     } \
1257     else {
1258     error "Bad state variable."
1259     }
1260     }
1261     }
1262     }
1263     }
1264    
1265    
1266     #Outputs the matter between the volume and chapter definitions and
1267     #the chapters.
1268     proc output_matter_between_chapter_defs_and_chapters { handle vtag script_vcinfo sv_or_mv} { \
1269     puts $handle "%Title page(s)"
1270     puts $handle "\\input\{volshare/workttla\}"
1271     puts $handle "%"
1272     puts $handle "\\vspace\{-0.45in\}"
1273     puts $handle "%"
1274     puts $handle "%Version control information for this script."
1275     puts $handle "\\noindent\\begin\{minipage\}\{\\textwidth\}"
1276     puts $handle "\\noindent\\rule\[-0.25in\]\{\\textwidth\}\{1pt\}"
1277     puts $handle "\\begin\{tiny\}"
1278     puts $handle "\\begin\{verbatim\}"
1279     puts -nonewline $handle $script_vcinfo
1280     puts $handle "\\end\{verbatim\}"
1281     puts $handle "\\end\{tiny\}"
1282     puts $handle "\\noindent\\rule\[0.25in\]\{\\textwidth\}\{1pt\}"
1283     puts $handle "\\end\{minipage\}"
1284     puts $handle "%"
1285     puts $handle "%Declare this as frontmatter, the front portion before the meat"
1286     puts $handle "%of the book."
1287     puts $handle "\\frontmatter\{\}"
1288     puts $handle "%"
1289     puts $handle "%Preface"
1290    
1291     copy_preface_to_stream $handle $sv_or_mv
1292    
1293     puts $handle "%"
1294     puts $handle "%Acknowledgements"
1295     puts $handle "\\input\{volshare/workacks\}"
1296     puts $handle "%"
1297     puts $handle "%Table of contents"
1298     puts $handle "\\tableofcontents"
1299     puts $handle "%"
1300     puts $handle "%List of tables"
1301     puts $handle "\\listoftables"
1302     puts $handle "%"
1303     puts $handle "%List of figures"
1304     puts $handle "\\listoffigures"
1305     puts $handle "%"
1306     puts $handle "%List of algorithms"
1307     puts $handle "\\listofalgorithms"
1308     puts $handle "%"
1309     puts $handle "%Everything after this is the main matter, the \"meat\""
1310     puts $handle "%of the book."
1311     puts $handle "\\mainmatter\{\}"
1312     puts $handle "%"
1313     }
1314    
1315     #Copies the contents of the preface to the master file being formed. To accomodate
1316     #single-volume versus multi-volume builds, the two tags "<sv>" and "<mv>", which
1317     #must occur starting in column 1, are supported. These two tags indicate that the
1318     #line goes only to the single-volume build or the multi-volume build files.
1319     #The paramter sv or mv must be "s" or "m" for single or multi.
1320     #
1321     proc copy_preface_to_stream { handle sv_or_mv } { \
1322     #Set the compare tag based on the input parameter.
1323     if {![string compare $sv_or_mv "s"]} { \
1324     set compare_tag "<sv>"
1325     } \
1326     elseif {![string compare $sv_or_mv "m"]} {
1327     set compare_tag "<mv>"
1328     } \
1329     else {
1330     error
1331     }
1332    
1333     #Open the preface for processing.
1334     set phandle [open volshare/workprfa.tex r]
1335    
1336     #For each line, just copy it in, discarding lines with the wrong tag.
1337     set eof_found 0
1338     while {!$eof_found} { \
1339     #Grab a line.
1340     set line_in [gets $phandle]
1341    
1342     #Set a boolean if it contains a tag of any sort. Remove the tag from the line.
1343     set tag ""
1344     set tag_found 0
1345     set sf_result_1 [string first "<" $line_in]
1346     set sf_result_2 [string first ">" $line_in]
1347     set sf_result_3 [string first $compare_tag $line_in]
1348     if {( $sf_result_1 == 0 ) && ( $sf_result_2 == 3 ) } { \
1349     set tag_found 1
1350     }
1351    
1352     if {$tag_found && ! ($sf_result_3 == 0)} { \
1353     #There was a tag, but it is not for us. Discard the line.
1354     } \
1355     elseif {$tag_found && ($sf_result_3 == 0)} {
1356     #The tag was found, and it is for us. Remove the tag from the line and
1357     #put the line to the output.
1358     set line_in [string range $line_in 4 end]
1359     puts $handle $line_in
1360     } \
1361     else {
1362     #There was no tag found. Just pass the line through.
1363     puts $handle $line_in
1364     }
1365    
1366     set eof_found [eof $phandle]
1367     }
1368    
1369     #Close the preface, we are done with it.
1370     close $phandle
1371     }
1372    
1373    
1374     #Outputs the chapter and appendix includes for one volume of a multi-volume work
1375     #
1376     proc output_multi_volume_chapter_and_appendix_includes { handle vtag } { \
1377     global mcl
1378    
1379     #Output definitions for all chapters which are enclosed by the current volume. This is a bit tricky
1380     #because must traverse the mcl table and pick out the right portion.
1381     set state 0
1382     #"state" is a state variable which keeps track of where we are parsing the mcl table.
1383     #State values are as follows:
1384     # 0 -- have not yet found the right volume.
1385     # 1 -- are in the midst of the right volume.
1386     # 2 -- are into subsequent volumes.
1387    
1388     for {set i 0} {$i < [llength $mcl]} {incr i 4} { \
1389     set rectype [lindex $mcl [expr $i + 0]]
1390     set par1 [lindex $mcl [expr $i + 1]]
1391     set par2 [lindex $mcl [expr $i + 2]]
1392     set par3 [lindex $mcl [expr $i + 3]]
1393    
1394     if {$state == 0} { \
1395     if {! [string compare $rectype v] || ! [string compare $rectype w]} { \
1396     #This is a volume record that has meaning for us. In either case,
1397     #the vtag comes from par1.
1398    
1399     #Have not yet encountered our volume of interest. If this is
1400     #it, record and change state.
1401     if {![string compare $vtag $par1]} { \
1402     set cur_vol $par1
1403     set chapter_or_appendix "Chapter"
1404     set state 1
1405     }
1406     }
1407     } \
1408     elseif {$state == 1} { \
1409     #We are within the volume of interest. Looking for chapter records.
1410     if {! [string compare $rectype c] || ! [string compare $rectype e]} { \
1411     set cur_chap_lc $par1
1412     set cur_chap_uc [string toupper $cur_chap_lc]
1413     set cur_chap_idstring [replace_digits_with_alphas $cur_chap_lc]
1414     set cur_chap_short_title [get_chap_short_single_volume_title $cur_chap_lc]
1415     set cur_chap_long_title [get_chap_long_single_volume_title $cur_chap_lc]
1416    
1417     puts $handle "%%%% $chapter_or_appendix C$cur_chap_uc: $cur_chap_long_title %%%%"
1418     puts $handle "\\input\{c_$cur_chap_lc/c_$cur_chap_lc\}"
1419     puts $handle "%"
1420     } \
1421     elseif {! [string compare $rectype y]} { \
1422     #This is the beginning of the appendix material for a multi-volume work.
1423     set chapter_or_appendix "Appendix"
1424     puts $handle "\\appendix"
1425     puts $handle "%"
1426     } \
1427     elseif {! [string compare $rectype v] || ! [string compare $rectype w]} { \
1428     set state 2
1429     }
1430     } \
1431     elseif {$state == 2} { \
1432     #Do nothing. We are in the parsing state where we have done the volume of interest
1433     #and can't do more.
1434     } \
1435     else {
1436     error "Bad state variable."
1437     }
1438     }
1439     }
1440    
1441    
1442     #Builds one volume of a multi-volume work, passed the volume tag and the volume
1443     #number. The volume number is an ordinal number, and is used for normal
1444     #and roman numerals and stuff.
1445     #
1446     proc createMultiVolumeWork { vtag volume_number script_vcinfo } { \
1447     #Form the filename, based on the input tag. All that is required is a .TEX
1448     #suffix.
1449     set filename $vtag
1450     append filename .tex
1451    
1452     #Open the file for writing.
1453     set handle [open $filename w]
1454    
1455     #Insert the title line.
1456     output_title_line $handle $filename "Volume of multi-volume work."
1457    
1458     #Insert the document class and package includes.
1459     output_doc_class_and_package_includes $handle
1460    
1461     #For the multi-volume only, use the "XR" package.
1462     puts $handle "%Must use \"xr\" package to import symbols from other volumes."
1463     puts $handle "\\usepackage\{xr\}"
1464     puts $handle "%"
1465    
1466     #Insert the external document symbol imports.
1467     output_external_document_symbol_imports $handle $vtag
1468    
1469     #Insert common lines through the begindoc.
1470     output_common_lines_through_begindoc $handle
1471    
1472     #Insert the volume and chapter definitions.
1473     output_multi_volume_volume_and_chapter_definitions $handle $vtag $volume_number
1474    
1475     #Insert the matter after the volume and chapter definitions but before
1476     #the chapters and appendices.
1477     output_matter_between_chapter_defs_and_chapters $handle $vtag $script_vcinfo m
1478    
1479     #Insert the chapter and appendix includes.
1480     output_multi_volume_chapter_and_appendix_includes $handle $vtag
1481    
1482     #Output the final matter.
1483     output_tex_volume_final_matter $handle
1484    
1485     #Output the final line of the file, with the file name, for aesthetics.
1486     mark_end_of_tex_volume_files_for_aesthetics $handle $filename
1487    
1488     #Close the file.
1489     close $handle
1490     }
1491    
1492     #
1493     # Builds the two single-volume works (the two source files SVF.TEX and SVD.TEX). These
1494     # are quite a bit simpler than the multi-volume generations.
1495     #
1496     proc createSingleVolumeWorks { script_vcinfo } { \
1497     global mcl
1498    
1499     #Define the preamble number 1 for both of the files. This is text up until the chapter
1500     #definitions.
1501     set preamble1 {
1502     "%Definitions For Chapter Citations" \
1503     "%--------------------------------------------------------------" \
1504     "%These definitions are created automatically by the Wish Script" \
1505     "%\"CP_SCRIPT.TCL\"." \
1506     "%--------------------------------------------------------------" \
1507     "%Note that for the single-volume works, there is no concept of" \
1508     "%the \"xref\" prefix, as everything is in the same volume." \
1509     "%That is why this prefix is set to the empty string in all" \
1510     "%cases." \
1511     "%--------------------------------------------------------------" \
1512     }
1513    
1514     #Define the matter between the chapter constants and the start of the version control information
1515     #for this script.
1516     set midamble1 {
1517     "\\newcommand\\curvoltitle\{\Full Edition (All Content)\}" \
1518     "\\newcommand\\curvolroman\{\}" \
1519     "\\newcommand\\curvoltitlepagesep\{\}" \
1520     "\\newcommand\\curvoltitlepageprefix\{\}" \
1521     "" \
1522     }
1523    
1524     #Define the matter between the main volume's version control information and the start of the chapter
1525     #includes.
1526     set midamble2 {
1527     "" \
1528     }
1529    
1530     #outboth "Generating single-volume work main TEX source files (SVF.TEX, SVD.TEX)."
1531     outboth "Generating single-volume work main TEX source file (SVF.TEX)."
1532    
1533     #Open the two files we want to write.
1534     set fhandle [open svf.tex w]
1535    
1536     #Output the title and descriptions for the files.
1537     output_title_line $fhandle SVF.TEX "Final Version Of Single-Volume Work"
1538    
1539     #Insert the document class and package includes.
1540     output_doc_class_and_package_includes $fhandle
1541    
1542     #Output common things through "begindoc"
1543     output_common_lines_through_begindoc $fhandle
1544    
1545     #Output the first preamble to the files.
1546     for {set i 0} {$i < [llength $preamble1]} {incr i} { \
1547     #puts $dhandle [lindex $preamble1 $i]
1548     puts $fhandle [lindex $preamble1 $i]
1549     }
1550    
1551     #Remembers whether the fundamental unit (the chapter) is a chapter or an
1552     #appendix. After the LaTeX "appendix" mark, everything gets numbered as
1553     #an appendix (A, B, C, etc.). This is included because if one Chapter or
1554     #Appendix needs to refer to another one symbolically (or to itself for that
1555     #matter) it needs to know if it is a chapter or appendix. This preserves
1556     #the ability to have something be an appendix in one compilation and a chapter
1557     #in another compilation.
1558     set chapter_or_appendix Chapter
1559    
1560     #Output the chapter citations for the files. The chapter citations are how one
1561     #chapter refers to another. For the "single-volume" works, there is no concept
1562     #of volume (there is only one), so the cites are just straight chapter cites.
1563     for {set i 0} {$i < [llength $mcl]} {incr i 4} { \
1564     set rectype [lindex $mcl $i]
1565    
1566     if {! [string compare $rectype d] || ! [string compare $rectype e]} { \
1567     #This is a chapter record that we need to be concerned with.
1568    
1569     #Get the chapter tag.
1570     set ctag [lindex $mcl [expr $i + 1]]
1571    
1572     #Output a header line to both files indicating which chapter.
1573     #puts -nonewline $dhandle %C
1574     puts -nonewline $fhandle %C
1575     set ucctag [string toupper $ctag]
1576     #puts -nonewline $dhandle $ucctag
1577     puts -nonewline $fhandle $ucctag
1578     #puts -nonewline $dhandle ": "
1579     puts -nonewline $fhandle ": "
1580     #puts $dhandle [get_chap_long_single_volume_title $ctag]
1581     puts $fhandle [get_chap_long_single_volume_title $ctag]
1582    
1583     #Output the data for the chapter, as LaTeX commands.
1584     set textag [replace_digits_with_alphas $ctag]
1585    
1586     #xref command. This is how one chapter refers to another (the
1587     #prefix). Set constant empty here, because no prefix required.
1588     set linebuf ""
1589     append linebuf \\newcommand \\ c $textag xrefhyphen \{ \}
1590     #puts $dhandle $linebuf
1591     puts $fhandle $linebuf
1592     set linebuf ""
1593     append linebuf \\newcommand \\ c $textag xrefcomma \{ \}
1594     #puts $dhandle $linebuf
1595     puts $fhandle $linebuf
1596    
1597     #Long title. This is normally used for the chapter unless there
1598     #are space constraints, such as would occur on page headers.
1599     set linebuf ""
1600     append linebuf \\newcommand \\ c $textag longtitle \{ [get_chap_long_single_volume_title $ctag] \}
1601     #puts $dhandle $linebuf
1602     puts $fhandle $linebuf
1603    
1604     #Title (same as long title).
1605     set linebuf ""
1606     append linebuf \\newcommand \\ c $textag title \{ [get_chap_long_single_volume_title $ctag] \}
1607     #puts $dhandle $linebuf
1608     puts $fhandle $linebuf
1609    
1610     #Short title. This is used in confined areas, such as on page headers.
1611     set linebuf ""
1612     append linebuf \\newcommand \\ c $textag shorttitle \{ [get_chap_short_single_volume_title $ctag] \}
1613     #puts $dhandle $linebuf
1614     puts $fhandle $linebuf
1615    
1616     #Fill in the "Class", whether this is a chapter or an appendix.
1617     set linebuf ""
1618     append linebuf \\newcommand \\ c $textag mcclass \{ $chapter_or_appendix \}
1619     puts $fhandle $linebuf
1620     set linebuf ""
1621     append linebuf \\newcommand \\ c $textag ucclass \{ [string toupper $chapter_or_appendix] \}
1622     puts $fhandle $linebuf
1623     set linebuf ""
1624     append linebuf \\newcommand \\ c $textag lcclass \{ [string tolower $chapter_or_appendix] \}
1625     puts $fhandle $linebuf
1626    
1627     #Put in a blank line for aesthetics
1628     #puts $dhandle ""
1629     puts $fhandle ""
1630     } \
1631     elseif {! [string compare $rectype z]} {
1632     #This tag indicates the location of the beginning of the appendices. We
1633     #need to switch from chapter to appendix.
1634     set chapter_or_appendix Appendix
1635     }
1636     }
1637    
1638     #Put in the "midamble" before the version control information.
1639     for {set i 0} {$i < [llength $midamble1]} {incr i} { \
1640     #puts $dhandle [lindex $midamble1 $i]
1641     puts $fhandle [lindex $midamble1 $i]
1642     }
1643    
1644     #Put in matter including title page and version control information.
1645     output_matter_between_chapter_defs_and_chapters $fhandle "" $script_vcinfo s
1646    
1647     #Put in the "midamble" until the chapter includes.
1648     for {set i 0} {$i < [llength $midamble2]} {incr i} { \
1649     #puts $dhandle [lindex $midamble2 $i]
1650     puts $fhandle [lindex $midamble2 $i]
1651     }
1652    
1653     #Put in the chapter includes. This will involve looping through the mcl table and
1654     #inserting things. There is a differentiation between draft chapters and non-draft
1655     #chapters.
1656     set chapter_or_appendix Chapter
1657     for {set i 0} {$i < [llength $mcl]} {incr i 4} { \
1658     set rectype [lindex $mcl $i]
1659    
1660     if {! [string compare $rectype d] || ! [string compare $rectype e]} { \
1661     #This is a chapter record that we need to be concerned with.
1662     #Can easily form the file name by a simple string concat with the
1663     #tag. For aesthetics, will also throw in the title.
1664     set ctag [lindex $mcl [expr $i + 1]]
1665     set ctitle [get_chap_long_single_volume_title $ctag]
1666    
1667     set line1 "%$chapter_or_appendix: $ctitle"
1668     set line2 ""
1669     append line2 \\input\{c_ $ctag /c_ $ctag \}
1670    
1671     #puts $dhandle $line1
1672     puts $fhandle $line1
1673     #puts $dhandle $line2
1674     puts $fhandle $line2
1675     #puts $dhandle ""
1676     puts $fhandle ""
1677     } \
1678     elseif {! [string compare $rectype p] || ! [string compare $rectype w]} {
1679     #This indicates that we need to spin a new part in the book. There are
1680     #two cases to consider. Either we yank the title from the volume information,
1681     #or else we yank the title from the par2 of the record. Set the title.
1682     set par1 [lindex $mcl [expr $i + 1]]
1683     set par2 [lindex $mcl [expr $i + 2]]
1684    
1685     if {[string length $par2]} { \
1686     set part_title $par2
1687     } \
1688     else {
1689     set part_title [get_vol_part_title $par1]
1690     }
1691    
1692     #We have the part title. Output the part record.
1693     set line1 "% New part: $part_title"
1694     set line2 "\\part\{$part_title\}"
1695     #puts $dhandle $line1
1696     puts $fhandle $line1
1697     #puts $dhandle $line2
1698     puts $fhandle $line2
1699     #puts $dhandle ""
1700     puts $fhandle ""
1701     } \
1702     elseif {! [string compare $rectype z]} {
1703     #This tag indicates the location of the beginning of the appendices. We
1704     #need to switch from chapter to appendix.
1705     set chapter_or_appendix Appendix
1706    
1707     #Also need to decorate the output files to reflect that we're going into
1708     #appendix mode.
1709     set appendix_mark {
1710     "%Mark the start of appendices. This causes numbering to be with letters" \
1711     "%instead of numbers." \
1712     "\\appendix" \
1713     "" \
1714     }
1715     for {set j 0} {$j < [llength $appendix_mark]} {incr j} { \
1716     #puts $dhandle [lindex $appendix_mark $j]
1717     puts $fhandle [lindex $appendix_mark $j]
1718     }
1719     }
1720     }
1721    
1722     #Now can put in the final matter.
1723     output_tex_volume_final_matter $fhandle
1724    
1725     #Mark the end of the files, for aesthetics.
1726     mark_end_of_tex_volume_files_for_aesthetics $fhandle svf.tex
1727    
1728     #Close the files.
1729     #close $dhandle
1730     close $fhandle
1731    
1732     hlineboth
1733     }
1734    
1735    
1736     #Write the preamble to the _README_.HTM file. This is everything up to the variable part that depends
1737     #on the parts and sections defined in the script.
1738     proc rebuildReadmeWritePreamble { fhandle } {
1739     set preamble {
1740     "<html>" \
1741     "" \
1742     "<head>" \
1743     "<title>README File:&nbsp; CD Accompanying &quot;A Practitioner's Guide ...&quot;</title>" \
1744     "</head>" \
1745     "" \
1746     "<body BACKGROUND=\"wbbkgnds/bkblue01.gif\" TEXT=\"\#000000\">" \
1747     "" \
1748     "<h1 ALIGN=\"center\">README File: CD Accompanying \"A Practitioner's Guide ...\"</h1>" \
1749     "" \
1750     "<hr>" \
1751     "" \
1752     "<p>This HTML file contains links to all of the files distributed with the book" \
1753     "&quot;A Practitioner's Guide To The Design And Development Of Small Microcontroller Software&quot;, and"\
1754     "explains what each of the files is.&nbsp; This file is automatically generated by the Wish script" \
1755     "SCRIPTS\\CP_SCRIPT.TCL.&nbsp; Note that some chapter titles" \
1756     "and other information in this HTML file may differ subtly from the book, because the Wish script" \
1757     "is aware of both long and short names for many titles -- the" \
1758     "long titles are used here, but the short titles may be used in some places in" \
1759     "the book.&nbsp; For LaTeX builds of the book,&nbsp; it is assumed that the" \
1760     "contents of this CD are present, with the subdirectory tree prserved, in the" \
1761     "directory C:\\ESRGUBKA, i.e. so that the full" \
1762     "path of this HTML file is C:\\ESRGUBKA\\_README_.HTM.&nbsp; All path names supplied" \
1763     "below are with respect to C:\\ESRGUBKA.</p>" \
1764     "" \
1765     "<hr>" \
1766     "" \
1767     }
1768    
1769     for {set i 0} {$i < [llength $preamble]} {incr i} { \
1770     puts $fhandle [lindex $preamble $i]
1771     }
1772     }
1773    
1774    
1775     #Write the "meat" to the file. This is the table and variable stuff.
1776     proc rebuildReadmeWriteMeat { fhandle } {
1777     global readme_build_list
1778    
1779     #For indentation, the code supplied by Microsoft Front page was used as a guide.
1780    
1781     #Write the start of the table.
1782     puts $fhandle "<table border=\"1\" width=\"100%\">"
1783    
1784     #Set state variables to remember if anything must be closed as we iterate.
1785     set tr_active 0
1786     #True if in a <tr> block.
1787     set td_active 0
1788     #True if in a <td> block.
1789     set ul_active 0
1790     #True if in a <ul> block.
1791     set li_active 0
1792     #True if in a <li> item.
1793    
1794     #Loop through the list, processing each record. Front Page HTML was used as a
1795     #guide.
1796     for {set i 0} {$i < [llength $readme_build_list]} {incr i} { \
1797     #Loop effort-savers.
1798     set cur_rec [lindex $readme_build_list $i]
1799     set cur_tag [string range $cur_rec 0 0]
1800     set cur_meat [string range $cur_rec 2 end]
1801    
1802     #puts $cur_rec
1803    
1804     #Split into cases, one for each possible tag.
1805     if {! [string compare -nocase $cur_tag F]} { \
1806     #If a <tr> block is not active, must start one.
1807     if {! $tr_active} { \
1808     puts $fhandle " <tr>"
1809     set tr_active 1
1810     }
1811     #If a <td> block is not active, must start one.
1812     if {! $td_active} { \
1813     puts $fhandle " <td width=\"100%\">"
1814     set td_active 1
1815     }
1816     #If a <ul> block is not active, must start one.
1817     if {! $ul_active} { \
1818     puts $fhandle " <ul>"
1819     set ul_active 1
1820     }
1821     #OK, can now write the filename and the associated markers. Will start
1822     #a list item in this endeavor, so must set this flag TRUE.
1823     #If a <li> block is active, must end it.
1824     if {$li_active} { \
1825     puts $fhandle " </li>"
1826     set li_active 0
1827     }
1828     set li_active 1
1829     puts $fhandle " <li><b><a href=\"" nonewline
1830     #When we stuff the file name in this context, need to change spaces to
1831     #the string "%20". The reasons for this are HTML syntax.
1832     puts $fhandle [replace_spaces_with_HTML_codes [string tolower $cur_meat]] nonewline
1833     puts $fhandle "\">" nonewline
1834     puts $fhandle [string toupper $cur_meat] nonewline
1835     puts $fhandle "</a>:</b>&nbsp; "
1836     } \
1837     elseif {! [string compare -nocase $cur_tag M]} { \
1838     #The first thing we need to do is close out any nested blocks that we are in.
1839     #If a <li> block is active, must end it.
1840     if {$li_active} { \
1841     puts $fhandle " </li>"
1842     set li_active 0
1843     }
1844     #If a <ul> block is active, must end it.
1845     if {$ul_active} { \
1846     puts $fhandle " </ul>"
1847     set ul_active 0
1848     }
1849     #If a <td> block is active, must end it.
1850     if {$td_active} { \
1851     puts $fhandle " </td>"
1852     set td_active 0
1853     }
1854     #If a <tr> block is active, must end it.
1855     if {$tr_active} { \
1856     puts $fhandle " </tr>"
1857     set tr_active 0
1858     }
1859    
1860     #Manually-generated header. Just stuff it in.
1861     puts $fhandle " <tr>"
1862     puts $fhandle " <td width=\"100%\"><b><font size=\"5\">" nonewline
1863     puts $fhandle "[string toupper $cur_meat]" nonewline
1864     puts $fhandle "</font></b></td>"
1865     puts $fhandle " </tr>"
1866     } \
1867     elseif {! [string compare -nocase $cur_tag C]} { \
1868     #If a <li> block is active, must end it.
1869     if {$li_active} { \
1870     puts $fhandle " </li>"
1871     set li_active 0
1872     }
1873     #If a <ul> block is active, must end it.
1874     if {$ul_active} { \
1875     puts $fhandle " </ul>"
1876     set ul_active 0
1877     }
1878     #If a <td> block is active, must end it.
1879     if {$td_active} { \
1880     puts $fhandle " </td>"
1881     set td_active 0
1882     }
1883     #If a <tr> block is active, must end it.
1884     if {$tr_active} { \
1885     puts $fhandle " </tr>"
1886     set tr_active 0
1887     }
1888    
1889     #This is one with a chapter tag. We need to look up the tag.
1890     set mc_ct [get_chap_long_single_volume_title $cur_meat]
1891     set uc_ct [string toupper $mc_ct]
1892     puts $fhandle " <tr>"
1893     puts $fhandle " <td width=\"100%\"><b><font size=\"5\">" nonewline
1894     puts $fhandle "CHAPTER " nonewline
1895     puts $fhandle [string toupper $cur_meat] nonewline
1896     puts $fhandle ":&nbsp; " nonewline
1897     puts $fhandle $uc_ct nonewline
1898     puts $fhandle "</font></b></td>"
1899     puts $fhandle " </tr>"
1900     } \
1901     elseif {! [string compare -nocase $cur_tag D]} { \
1902     #For descriptions, we just dump it in verbatim. There is no need to do any processing.
1903     puts $fhandle " " nonewline
1904     puts $fhandle $cur_meat
1905     } \
1906     else {
1907     error "Unexpected tag in readme_build_list."
1908     }
1909     }
1910    
1911     #Write the end of the table.
1912     puts $fhandle "</table>"
1913     puts $fhandle ""
1914     }
1915    
1916    
1917     #Write the postamble to the file. This is everything after the variable part.
1918     proc rebuildReadmeWritePostamble { fhandle } {
1919     #First, grab the time as seconds since a time mark unknown.
1920     set tref [clock seconds]
1921    
1922     #Convert the time obtained to date.
1923     set date [clock format $tref -format "%m/%d/%y"]
1924    
1925     #Convert the time obtained to hour and minute.
1926     set time [clock format $tref -format "%H:%M"]
1927    
1928     #This part has to be manually generated because of the date and time.
1929     puts $fhandle ""
1930     puts $fhandle "<hr>"
1931     puts $fhandle ""
1932     puts $fhandle "<p align=\"center\">This file automatically generated on " nonewline
1933     puts $fhandle $date nonewline
1934     puts $fhandle " at " nonewline
1935     puts $fhandle $time nonewline
1936     puts $fhandle " by "
1937     puts $fhandle "Wish script SCRIPTS\\CP_SCRIPT.TCL.</p>"
1938     puts $fhandle ""
1939     puts $fhandle "<hr noshade size=\"10\" color=\"\#000000\">"
1940     puts $fhandle "</body>"
1941     puts $fhandle "</html>"
1942     }
1943    
1944     #****************************************************************************************
1945     #****************************************************************************************
1946     #**** B U T T O N P R E S S F U N C T I O N S *******************************
1947     #****************************************************************************************
1948     #****************************************************************************************
1949     # Each of the functions in this category is called in response to a button on the main
1950     # graphical window being pressed.
1951     #----------------------------------------------------------------------------------------
1952     # Performs a full LaTeX compilation and indexing of all volumes. It isn't necessary to
1953     # subdivide this operation any further because the full build is rare enough that any
1954     # reasonable amount of time is OK. In the long term, it will be necessary to have the
1955     # tools build a full index spanning all volumes, but this isn't done yet.
1956     #
1957     proc fullLatexCompileAndIndexProc { } { \
1958     global bookVolumeList
1959     global bookVolumeListStructSize
1960     global pathUcBookA
1961     global execAcrobatDistiller
1962     global mcl
1963     global chapterList
1964     global chapterListStructSize
1965    
1966     outboth "BUTTON PRESS: Full LaTeX compile and index."
1967     hlineboth
1968    
1969     #As a first step, extract this script's version control information. This is used in
1970     #building the .TEX main files, to stamp them with the script's version control
1971     #information.
1972     set script_vcinfo [extract_this_scripts_version_control_information]
1973    
1974     #Set up the list of volumes and chapters to be processed. This involves scanning the mcl to see
1975     #what is used and what is not used, and setting flags accordingly. Volume "used" flags affect
1976     #how volumes are numbered and how they are cross-referenced. Chapter "used" flags are safely
1977     #ignored--it does no harm to include chapter cite information in the LaTeX output files--what will
1978     #happen is if the referenced chapter isn't included, the unresolvable references will be "pushed"
1979     #onto LaTeX.
1980    
1981     #Zero out all of the volume used flags.
1982     outbothnonl "Marking all volumes unused ... "
1983     mark_all_volumes_unused
1984     outboth "done."
1985    
1986     #Zero out all of the chapter used flags.
1987     outbothnonl "Marking all chapters unused ... "
1988     mark_all_chaps_unused
1989     outboth "done."
1990    
1991     #Iterate through the mcl list, figuring out which volumes and chapters are used. A "volume" is used
1992     #if it contains at least one chapter in the mcl list. A "chapter" is used if it appears either as
1993     #part of a volume or in the standalone work.
1994     outbothnonl "Scanning mcl list for used volumes and used chapters ... "
1995     set used_volumes 0
1996     set unused_volumes [expr [llength $bookVolumeList] / $bookVolumeListStructSize]
1997     set used_chapters 0
1998     set unused_chapters [expr [llength $chapterList] / $chapterListStructSize]
1999     set cur_vol ""
2000     set N [llength $mcl]
2001     #Iterate through the list, taking notes.
2002     for {set i 0} {$i < $N} {incr i 4} { \
2003     set mcl_rectype [lindex $mcl [expr $i + 0]]
2004     set mcl_par1 [lindex $mcl [expr $i + 1]]
2005     set mcl_par2 [lindex $mcl [expr $i + 2]]
2006     set mcl_par3 [lindex $mcl [expr $i + 3]]
2007    
2008     if {! [string compare $mcl_rectype v] || ! [string compare $mcl_rectype w]} \
2009     {
2010     #The v record type declares a new volume, and the w declares both a new volume and
2011     #a new part. Either of these record types mean that we've hit a new volume boundary.
2012     #Remember this.
2013     set cur_vol $mcl_par1
2014     } \
2015     elseif {! [string compare $mcl_rectype c] || ! [string compare $mcl_rectype e]} { \
2016     #Either of these declare a chapter in the current volume. Process.
2017     #Mark the chapter as used, and update chapter statistics.
2018     if {[get_chap_used_flag $mcl_par1]} { \
2019     #The chapter is already used. Don't want to count the chapter as used
2020     #again.
2021     } \
2022     else {
2023    
2024     #outboth "Marking $mcl_par1"
2025    
2026     #The chapter isn't yet marked used.
2027     mark_chapter_used $mcl_par1
2028     incr used_chapters
2029     incr unused_chapters -1
2030     }
2031     #Mark the volume used if it is used.
2032     if {[string length $cur_vol]} { \
2033     if {![get_volume_used_flag $cur_vol]} { \
2034     #Mark that volume (the nearest above enclosing one) as used.
2035     mark_volume_used $cur_vol
2036     incr used_volumes
2037     incr unused_volumes -1
2038     }
2039     }
2040     }
2041     }
2042    
2043     outboth "done."
2044    
2045     #Output statistics about what is used and not used. This is helpful for diagnosis.
2046     outbothnonl "Used chapters: $used_chapters Unused chapters: $unused_chapters"
2047     outboth .
2048     outboth "Enumeration of unused chapters (if any):"
2049     set N [llength $chapterList]
2050     #Iterate through the list, taking notes.
2051     for {set i 0} {$i < $N} {incr i $chapterListStructSize} { \
2052     #outboth "i: $i"
2053     if { ! [get_chap_used_flag [lindex $chapterList $i]]} { \
2054     outboth " [lindex $chapterList $i]"
2055     }
2056     }
2057    
2058     outbothnonl "Used volumes: $used_volumes Unused volumes: $unused_volumes"
2059     outboth .
2060     outboth "Enumeration of used volumes (if any):"
2061     set N [llength $bookVolumeList]
2062     #Iterate through the list, taking notes.
2063     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
2064     #outboth "i: $i"
2065     if {[get_volume_used_flag [lindex $bookVolumeList $i]]} { \
2066     outboth " [lindex $bookVolumeList $i]"
2067     }
2068     }
2069     outboth "Enumeration of unused volumes (if any):"
2070     set N [llength $bookVolumeList]
2071     #Iterate through the list, taking notes.
2072     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
2073     #outboth "i: $i"
2074     if { ! [get_volume_used_flag [lindex $bookVolumeList $i]]} { \
2075     outboth " [lindex $bookVolumeList $i]"
2076     }
2077     }
2078    
2079     #Delete all the output files. This guards against misunderstandings and accidents. In the deletion of output
2080     #files, whether volumes are used or not is not taken into account. The reason for this is neatness--if
2081     #the list of used volumes changes, it is helpful to get all of those files gone.
2082    
2083     #Delete the two single-volume files.
2084     set pathbase ""
2085     append pathbase $pathUcBookA / sv
2086     #set svlist {f.dvi f.ps f.pdf d.dvi d.ps d.pdf}
2087     set svlist {f.dvi f.ps f.pdf}
2088     set N [llength $svlist]
2089    
2090     #Iterate through, delete each single-volume file.
2091     for {set i 0} {$i < $N} {incr i} { \
2092     set target $pathbase
2093     append target [lindex $svlist $i]
2094    
2095     if {[file exists $target]} { \
2096     outbothnonl "Deleting $target"
2097     outboth .
2098     file delete $target
2099     } \
2100     else {
2101     outboth "Skipping $target : file does not exist."
2102     }
2103     }
2104    
2105     #Get number of elements in the list of volumes.
2106     set N [llength $bookVolumeList]
2107    
2108     #Iterate through, delete each file.
2109     for {set volnum 0} {$volnum < $N} {incr volnum $bookVolumeListStructSize} { \
2110     set voltag [lindex $bookVolumeList $volnum]
2111    
2112     set target ""
2113     append target $pathUcBookA / $voltag .dvi
2114    
2115     if {[file exists $target]} { \
2116     outbothnonl "Deleting $target"
2117     outboth .
2118     file delete $target
2119     } \
2120     else {
2121     outboth "Skipping $target : file does not exist."
2122     }
2123    
2124     set target ""
2125     append target $pathUcBookA / $voltag .ps
2126    
2127     if {[file exists $target]} { \
2128     outbothnonl "Deleting $target"
2129     outboth .
2130     file delete $target
2131     } \
2132     else {
2133     outboth "Skipping $target : file does not exist."
2134     }
2135    
2136     set target ""
2137     append target $pathUcBookA / $voltag .pdf
2138    
2139     if {[file exists $target]} { \
2140     outbothnonl "Deleting $target"
2141     outboth .
2142     file delete $target
2143     } \
2144     else {
2145     outboth "Skipping $target : file does not exist."
2146     }
2147    
2148     set target ""
2149     append target $pathUcBookA / $voltag .idx
2150    
2151     if {[file exists $target]} { \
2152     outbothnonl "Deleting $target"
2153     outboth .
2154     file delete $target
2155     } \
2156     else {
2157     outboth "Skipping $target : file does not exist."
2158     }
2159    
2160     set target ""
2161     append target $pathUcBookA / $voltag .ilg
2162    
2163     if {[file exists $target]} { \
2164     outbothnonl "Deleting $target"
2165     outboth .
2166     file delete $target
2167     } \
2168     else {
2169     outboth "Skipping $target : file does not exist."
2170     }
2171    
2172     set target ""
2173     append target $pathUcBookA / $voltag .ind
2174    
2175     if {[file exists $target]} { \
2176     outbothnonl "Deleting $target"
2177     outboth .
2178     file delete $target
2179     } \
2180     else {
2181     outboth "Skipping $target : file does not exist."
2182     }
2183    
2184     set target ""
2185     append target $pathUcBookA / $voltag .toc
2186    
2187     if {[file exists $target]} { \
2188     outbothnonl "Deleting $target"
2189     outboth .
2190     file delete $target
2191     } \
2192     else {
2193     outboth "Skipping $target : file does not exist."
2194     }
2195    
2196     set target ""
2197     append target $pathUcBookA / $voltag .aux
2198    
2199     if {[file exists $target]} { \
2200     outbothnonl "Deleting $target"
2201     outboth .
2202     file delete $target
2203     } \
2204     else {
2205     outboth "Skipping $target : file does not exist."
2206     }
2207    
2208     }
2209     hlineboth
2210    
2211     #Create the master files for the two single volume works (the draft and the final).
2212     createSingleVolumeWorks $script_vcinfo
2213    
2214     #Create the master files for the volumes. The volumes are automatically numbered,
2215     #based on those that are used, starting with 1.
2216     set volume_number 0
2217     set N [llength $bookVolumeList]
2218     #Iterate through, delete each file.
2219     for {set volnum 0} {$volnum < $N} {incr volnum $bookVolumeListStructSize} { \
2220     set voltag [lindex $bookVolumeList $volnum]
2221    
2222     if {[get_volume_used_flag $voltag]} { \
2223     incr volume_number
2224     createMultiVolumeWork $voltag $volume_number $script_vcinfo
2225     }
2226     }
2227    
2228     #Do four full rounds of LaTeX compiles and index builds. This is necessary
2229     #to resolve cross-dependencies and be sure no page numbering changes.
2230     for {set round 0} {$round < 4} {incr round} { \
2231     outbothnonl "LaTeX compile, Round "
2232     outbothnonl $round
2233     outboth .
2234     hlineboth
2235    
2236     #Do the single-volume works.
2237     #LatexCompileFile svd.tex
2238     #MakeOrdinaryIndexFile svd
2239     LatexCompileFile svf.tex
2240     MakeOrdinaryIndexFile svf
2241    
2242     #Get number of elements in the list of volumes. Compile only the used ones.
2243     set N [llength $bookVolumeList]
2244    
2245     #Iterate through, compile each file.
2246     for {set volnum 0} {$volnum < $N} {incr volnum $bookVolumeListStructSize} { \
2247     set voltag [lindex $bookVolumeList $volnum]
2248     if {[get_volume_used_flag $voltag]} { \
2249     outbothnonl "Latex compile: $voltag"
2250     outboth .
2251     hlineboth
2252    
2253     set fullfilename ""
2254     append fullfilename $voltag .tex
2255    
2256     LatexCompileFile $fullfilename
2257    
2258     MakeOrdinaryIndexFile $voltag
2259     }
2260     }
2261     update
2262     }
2263    
2264     #DVIPS the single-volume file.
2265     outbothnonl "DVIPS: svf"
2266     RunDvipsToGenPsOutput svf
2267    
2268     #Modify the postscript in the single volume file to
2269     #generate a duplex file.
2270     ModifyPsToDuplex svf
2271    
2272     #PDF the two single-volume file.
2273     set psfilepath ""
2274     append psfilepath $pathUcBookA / svf.ps
2275     exec $execAcrobatDistiller $psfilepath &
2276    
2277     #Get number of elements in the list of volumes.
2278     set N [llength $bookVolumeList]
2279    
2280     #Iterate through, DVIPS each file.
2281     for {set volnum 0} {$volnum < $N} {incr volnum $bookVolumeListStructSize} { \
2282     set voltag [lindex $bookVolumeList $volnum]
2283     if {[get_volume_used_flag $voltag]} { \
2284     outbothnonl "DVIPS: $voltag"
2285     outboth .
2286     hlineboth
2287    
2288     RunDvipsToGenPsOutput $voltag
2289     ModifyPsToDuplex $voltag
2290    
2291     set psfilepath ""
2292     append psfilepath $pathUcBookA / $voltag .ps
2293    
2294     #There is no barrier at this point to also running Distiller. Distiller gives us
2295     #no information back.
2296     exec $execAcrobatDistiller $psfilepath &
2297     }
2298     update
2299     }
2300    
2301     outboth "DONE: BUTTON PRESS: Full LaTeX compile and index."
2302     hlineboth
2303     update
2304     }
2305    
2306     #----------------------------------------------------------------------------------------
2307     # Rebuilds all the master files. This operation can be useful if one isn't using 4AllTex
2308     # but wants to build the automatically-generated files anyway, perhaps to use another
2309     # version of LaTeX.
2310     #
2311     proc masterFileRebuildProc { } { \
2312     global bookVolumeList
2313     global bookVolumeListStructSize
2314     global pathUcBookA
2315     global execAcrobatDistiller
2316     global mcl
2317     global chapterList
2318     global chapterListStructSize
2319    
2320     outboth "BUTTON PRESS: Rebuild single-volume and multi-volume master files."
2321     hlineboth
2322    
2323     #As a first step, extract this script's version control information. This is used in
2324     #building the .TEX main files, to stamp them with the script's version control
2325     #information.
2326     set script_vcinfo [extract_this_scripts_version_control_information]
2327    
2328     #Set up the list of volumes and chapters to be processed. This involves scanning the mcl to see
2329     #what is used and what is not used, and setting flags accordingly. Volume "used" flags affect
2330     #how volumes are numbered and how they are cross-referenced. Chapter "used" flags are safely
2331     #ignored--it does no harm to include chapter cite information in the LaTeX output files--what will
2332     #happen is if the referenced chapter isn't included, the unresolvable references will be "pushed"
2333     #onto LaTeX.
2334    
2335     #Zero out all of the volume used flags.
2336     outbothnonl "Marking all volumes unused ... "
2337     mark_all_volumes_unused
2338     outboth "done."
2339    
2340     #Zero out all of the chapter used flags.
2341     outbothnonl "Marking all chapters unused ... "
2342     mark_all_chaps_unused
2343     outboth "done."
2344    
2345     #Iterate through the mcl list, figuring out which volumes and chapters are used. A "volume" is used
2346     #if it contains at least one chapter in the mcl list. A "chapter" is used if it appears either as
2347     #part of a volume or in the standalone work.
2348     outbothnonl "Scanning mcl list for used volumes and used chapters ... "
2349     set used_volumes 0
2350     set unused_volumes [expr [llength $bookVolumeList] / $bookVolumeListStructSize]
2351     set used_chapters 0
2352     set unused_chapters [expr [llength $chapterList] / $chapterListStructSize]
2353     set cur_vol ""
2354     set N [llength $mcl]
2355     #Iterate through the list, taking notes.
2356     for {set i 0} {$i < $N} {incr i 4} { \
2357     set mcl_rectype [lindex $mcl [expr $i + 0]]
2358     set mcl_par1 [lindex $mcl [expr $i + 1]]
2359     set mcl_par2 [lindex $mcl [expr $i + 2]]
2360     set mcl_par3 [lindex $mcl [expr $i + 3]]
2361    
2362     if {! [string compare $mcl_rectype v] || ! [string compare $mcl_rectype w]} \
2363     {
2364     #The v record type declares a new volume, and the w declares both a new volume and
2365     #a new part. Either of these record types mean that we've hit a new volume boundary.
2366     #Remember this.
2367     set cur_vol $mcl_par1
2368     } \
2369     elseif {! [string compare $mcl_rectype c] || ! [string compare $mcl_rectype e]} { \
2370     #Either of these declare a chapter in the current volume. Process.
2371     #Mark the chapter as used, and update chapter statistics.
2372     if {[get_chap_used_flag $mcl_par1]} { \
2373     #The chapter is already used. Don't want to count the chapter as used
2374     #again.
2375     } \
2376     else {
2377    
2378     #outboth "Marking $mcl_par1"
2379    
2380     #The chapter isn't yet marked used.
2381     mark_chapter_used $mcl_par1
2382     incr used_chapters
2383     incr unused_chapters -1
2384     }
2385     #Mark the volume used if it is used.
2386     if {[string length $cur_vol]} { \
2387     if {![get_volume_used_flag $cur_vol]} { \
2388     #Mark that volume (the nearest above enclosing one) as used.
2389     mark_volume_used $cur_vol
2390     incr used_volumes
2391     incr unused_volumes -1
2392     }
2393     }
2394     }
2395     }
2396    
2397     outboth "done."
2398    
2399     #Output statistics about what is used and not used. This is helpful for diagnosis.
2400     outbothnonl "Used chapters: $used_chapters Unused chapters: $unused_chapters"
2401     outboth .
2402     outboth "Enumeration of unused chapters (if any):"
2403     set N [llength $chapterList]
2404     #Iterate through the list, taking notes.
2405     for {set i 0} {$i < $N} {incr i $chapterListStructSize} { \
2406     #outboth "i: $i"
2407     if { ! [get_chap_used_flag [lindex $chapterList $i]]} { \
2408     outboth " [lindex $chapterList $i]"
2409     }
2410     }
2411    
2412     outbothnonl "Used volumes: $used_volumes Unused volumes: $unused_volumes"
2413     outboth .
2414     outboth "Enumeration of used volumes (if any):"
2415     set N [llength $bookVolumeList]
2416     #Iterate through the list, taking notes.
2417     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
2418     #outboth "i: $i"
2419     if {[get_volume_used_flag [lindex $bookVolumeList $i]]} { \
2420     outboth " [lindex $bookVolumeList $i]"
2421     }
2422     }
2423     outboth "Enumeration of unused volumes (if any):"
2424     set N [llength $bookVolumeList]
2425     #Iterate through the list, taking notes.
2426     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
2427     #outboth "i: $i"
2428     if { ! [get_volume_used_flag [lindex $bookVolumeList $i]]} { \
2429     outboth " [lindex $bookVolumeList $i]"
2430     }
2431     }
2432    
2433     #Delete all the output files. This guards against misunderstandings and accidents. In the deletion of output
2434     #files, whether volumes are used or not is not taken into account. The reason for this is neatness--if
2435     #the list of used volumes changes, it is helpful to get all of those files gone.
2436    
2437     #Delete the two single-volume files.
2438     set pathbase ""
2439     append pathbase $pathUcBookA / sv
2440     #set svlist {f.dvi f.ps f.pdf d.dvi d.ps d.pdf}
2441     set svlist {f.dvi f.ps f.pdf}
2442     set N [llength $svlist]
2443    
2444     #Iterate through, delete each single-volume file.
2445     for {set i 0} {$i < $N} {incr i} { \
2446     set target $pathbase
2447     append target [lindex $svlist $i]
2448    
2449     if {[file exists $target]} { \
2450     outbothnonl "Deleting $target"
2451     outboth .
2452     file delete $target
2453     } \
2454     else {
2455     outboth "Skipping $target : file does not exist."
2456     }
2457     }
2458    
2459     #Get number of elements in the list of volumes.
2460     set N [llength $bookVolumeList]
2461    
2462     #Iterate through, delete each file.
2463     for {set volnum 0} {$volnum < $N} {incr volnum $bookVolumeListStructSize} { \
2464     set voltag [lindex $bookVolumeList $volnum]
2465    
2466     set target ""
2467     append target $pathUcBookA / $voltag .dvi
2468    
2469     if {[file exists $target]} { \
2470     outbothnonl "Deleting $target"
2471     outboth .
2472     file delete $target
2473     } \
2474     else {
2475     outboth "Skipping $target : file does not exist."
2476     }
2477    
2478     set target ""
2479     append target $pathUcBookA / $voltag .ps
2480    
2481     if {[file exists $target]} { \
2482     outbothnonl "Deleting $target"
2483     outboth .
2484     file delete $target
2485     } \
2486     else {
2487     outboth "Skipping $target : file does not exist."
2488     }
2489    
2490     set target ""
2491     append target $pathUcBookA / $voltag .pdf
2492    
2493     if {[file exists $target]} { \
2494     outbothnonl "Deleting $target"
2495     outboth .
2496     file delete $target
2497     } \
2498     else {
2499     outboth "Skipping $target : file does not exist."
2500     }
2501    
2502     set target ""
2503     append target $pathUcBookA / $voltag .idx
2504    
2505     if {[file exists $target]} { \
2506     outbothnonl "Deleting $target"
2507     outboth .
2508     file delete $target
2509     } \
2510     else {
2511     outboth "Skipping $target : file does not exist."
2512     }
2513    
2514     set target ""
2515     append target $pathUcBookA / $voltag .ilg
2516    
2517     if {[file exists $target]} { \
2518     outbothnonl "Deleting $target"
2519     outboth .
2520     file delete $target
2521     } \
2522     else {
2523     outboth "Skipping $target : file does not exist."
2524     }
2525    
2526     set target ""
2527     append target $pathUcBookA / $voltag .ind
2528    
2529     if {[file exists $target]} { \
2530     outbothnonl "Deleting $target"
2531     outboth .
2532     file delete $target
2533     } \
2534     else {
2535     outboth "Skipping $target : file does not exist."
2536     }
2537    
2538     set target ""
2539     append target $pathUcBookA / $voltag .toc
2540    
2541     if {[file exists $target]} { \
2542     outbothnonl "Deleting $target"
2543     outboth .
2544     file delete $target
2545     } \
2546     else {
2547     outboth "Skipping $target : file does not exist."
2548     }
2549    
2550     set target ""
2551     append target $pathUcBookA / $voltag .aux
2552    
2553     if {[file exists $target]} { \
2554     outbothnonl "Deleting $target"
2555     outboth .
2556     file delete $target
2557     } \
2558     else {
2559     outboth "Skipping $target : file does not exist."
2560     }
2561    
2562     }
2563     hlineboth
2564    
2565     #Create the master files for the two single volume works (the draft and the final).
2566     createSingleVolumeWorks $script_vcinfo
2567    
2568     #Create the master files for the volumes. The volumes are automatically numbered,
2569     #based on those that are used, starting with 1.
2570     set volume_number 0
2571     set N [llength $bookVolumeList]
2572     #Iterate through, delete each file.
2573     for {set volnum 0} {$volnum < $N} {incr volnum $bookVolumeListStructSize} { \
2574     set voltag [lindex $bookVolumeList $volnum]
2575    
2576     if {[get_volume_used_flag $voltag]} { \
2577     incr volume_number
2578     createMultiVolumeWork $voltag $volume_number $script_vcinfo
2579     }
2580     }
2581    
2582     outboth "DONE: Rebuild single-volume and multi-volume master files.."
2583     hlineboth
2584     update
2585     }
2586    
2587     #----------------------------------------------------------------------------------------
2588     # Rebuilds the _README_.HTM file for the book, using the list of files and descriptions
2589     # embedded in the script. Also identifies files which files and directories which should
2590     # be present but are not.
2591     #
2592     proc rebuildReadmeHtmForBookProc { } { \
2593     #Entry message.
2594     outboth "Rebuild README.HTM for book button clicked."
2595    
2596     #First, open the _README_.HTM file for writing. This will automatically empty the
2597     #file if it already exists.
2598     set fhandle [open _README_.HTM "w"]
2599    
2600     #Write the preamble to the file.
2601     rebuildReadmeWritePreamble $fhandle
2602    
2603     #Write the meat of the file.
2604     rebuildReadmeWriteMeat $fhandle
2605    
2606     #Write the postamble to the file.
2607     rebuildReadmeWritePostamble $fhandle
2608    
2609     #Close the file which was opened.
2610     close $fhandle
2611    
2612     #Termination message.
2613     outboth "DONE: BUTTON PRESS: Build of _README_.HTM."
2614     hlineboth
2615     }
2616    
2617     #----------------------------------------------------------------------------------------
2618     # Copies all of the book .PDF files to the places where they are needed (there may be
2619     # multiple locations for each file). This is a simple copy operation.
2620     #
2621     proc copyBookPdfsProc { } { \
2622    
2623     global bookVolumeList
2624     global bookVolumeListStructSize
2625     global readme_build_list
2626    
2627     set paths { \
2628     "c:/distribs/common/supmatls/books/embedded_control/dta_ucswbk_a" \
2629     "f:/wrootdta/proftopics/pubs_distributions_downloads/ucswbook01/outline_and_pdfs" \
2630     }
2631    
2632     outboth "BUTTON PRESS: Copy book .PDFs to other locations that must be"
2633     outboth " mirrored."
2634     hlineboth
2635    
2636     #These are the names of the two single-volume files.
2637     #set svlist {svf.pdf svd.pdf}
2638     set svlist {svf.pdf}
2639    
2640     foreach path $paths { \
2641     outbothnonl "Copying to "
2642     outboth $path
2643    
2644     #Iterate through, copy each single-volume file.
2645     set N [llength $svlist]
2646     for {set i 0} {$i < $N} {incr i} { \
2647     set source [lindex $svlist $i]
2648     set dest $path
2649     append dest / [lindex $svlist $i]
2650     if {[file exists $source]} { \
2651     outboth " Copying from: $source"
2652     outboth " to: $dest."
2653     file copy -force -- $source $dest
2654     } \
2655     else {
2656     outboth " Can't copy $source: does not exist."
2657     }
2658     update
2659     }
2660    
2661     #Get number of elements in the list of volumes.
2662     set N [llength $bookVolumeList]
2663    
2664     #Iterate through, copy each file.
2665     for {set i 0} {$i < $N} {incr i $bookVolumeListStructSize} { \
2666     set source [lindex $bookVolumeList $i]
2667     append source .pdf
2668     set dest $path
2669     append dest / [lindex $bookVolumeList $i] .pdf
2670     if {[file exists $source]} { \
2671     outboth " Copying from: $source"
2672     outboth " to: $dest."
2673     file copy -force -- $source $dest
2674     } \
2675     else {
2676     outboth " Can't copy $source: does not exist."
2677     }
2678     update
2679     }
2680     }
2681    
2682     hlineboth
2683    
2684     #The above just copies the .PDF files to a few needed locations. The portion below
2685     #performs a full directory copy (just of the files mentioned in the list which
2686     #defines the _README_.HTM file) to a set of target directories. The directories
2687     #themselves are wiped in advance.
2688     set fullcopypaths { \
2689     "f:/wrootdta/proftopics/pubs_distributions_downloads/ucswbook01/outline_and_pdfs" \
2690     "f:/ftproot/anonymous_user_common_area/books/ucswbka" \
2691     }
2692    
2693     foreach fullcopypath $fullcopypaths { \
2694     #Destroy the subdirectory and all subcomponents.
2695     outbothnonl "Destroying: "
2696     outboth $fullcopypath
2697     file delete -force $fullcopypath
2698    
2699     #Create the base directory. This will be at the same level as the directory
2700     #"c:/esrgubka" in the build on Dave Ashley's computer.
2701     file mkdir $fullcopypath
2702    
2703     #For each of the files in the list to build the _README_.HTM file, create the
2704     #directory in which the file exists, the copy the file.
2705     foreach cur_line $readme_build_list { \
2706     #Update the display so there is not an apparent freeze.
2707     update
2708    
2709     #Iteration timesavers.
2710     set cur_tag [string range $cur_line 0 0]
2711     set cur_meat [string range $cur_line 2 end]
2712    
2713     if {! [string compare -nocase $cur_tag "F"]} { \
2714    
2715     #puts $cur_tag
2716     #puts $cur_meat
2717    
2718     #Replace any backslashes in the string with forward slashes.
2719     set fname $cur_meat
2720     set fname [string map {"\\" "/"} $fname]
2721    
2722     #Concatenate the target directory with the file name to get the full name.
2723     set fullfname ""
2724     append fullfname $fullcopypath
2725     append fullfname "/"
2726     append fullfname $fname
2727    
2728     #Rip off the final path component to get the directory that must exist, and
2729     #create the required directory.
2730     set location [string last "/" $fullfname]
2731     if {$location >= 0} { \
2732     set dir_to_create [string range $fullfname 0 [expr $location - 1]]
2733     outbothnonl " Creating directory: "
2734     set dir_to_create [string tolower $dir_to_create]
2735     outboth $dir_to_create
2736     file mkdir $dir_to_create
2737     } \
2738     else {
2739     outboth "No directory to create."
2740     }
2741    
2742     #Convert everything to lower case. It looks more aesthetically pleasing
2743     #that way.
2744     set fname [string tolower $fname]
2745     set fullfname [string tolower $fullfname]
2746    
2747     #The directory that needs to exist definitely exists. Perform the copy.
2748     outbothnonl " Copying from: "
2749     outboth $fname
2750     outbothnonl " to: "
2751     outboth $fullfname
2752     file copy -force -- $fname $fullfname
2753     }
2754     }
2755     }
2756    
2757     hlineboth
2758     }
2759    
2760     #----------------------------------------------------------------------------------------
2761     # Removes known extraneous and disposable ESRG Tool Set files and directories.
2762     #
2763     proc removeESRGToolSetKnownExtraneousFilesAndDirectoriesProc { } { \
2764     outboth "ESRG Tool Set remove extraneous files and directories button clicked."
2765     hlineboth
2766     }
2767    
2768     #----------------------------------------------------------------------------------------
2769     # Identifies extraneous ESRG Tool Set files and directories, which are foreign but at the
2770     # same time not known to be deletable. It is safest to let the user look at these.
2771     #
2772     proc identifyESRGToolSetExtraneousFilesAndDirectoriesProc { } { \
2773     outboth "ESRG Tool Set identify extraneous files and directories button clicked."
2774     hlineboth
2775     }
2776    
2777     #----------------------------------------------------------------------------------------
2778     # Performs a full clean build of all executable versions of ESRGScripter. This consists
2779     # of:
2780     # o Deletion of all existing .OBJ and .EXE files to assure a clean build.
2781     # o Deletion of all other copy targets.
2782     # o A full clean build.
2783     # o A full re-copy to destinations for assembly.
2784     # o Generation of README.HTM files, watching for missing files.
2785     #
2786     proc fullBuildOfAllESRGToolSetExecutableVersionsProc { } { \
2787     outboth "ESRG Tool Set full build button clicked."
2788     hlineboth
2789     }
2790    
2791    
2792     #----------------------------------------------------------------------------------------
2793     #----------------------------------------------------------------------------------------
2794     #----------------------------------------------------------------------------------------
2795     # Main script.
2796    
2797     console show
2798     #We have to use this, or the console won't be created when running a script
2799     #directly on invocation.
2800    
2801     #----------------------------------------------------------------------------------------
2802     #----------------------------------------------------------------------------------------
2803     #------ C O N S T A N T S ----------------------------------------------------------__
2804     #----------------------------------------------------------------------------------------
2805     #----------------------------------------------------------------------------------------
2806     #***************************************************************************
2807     #Logging constants.
2808     set loglinelength 78
2809     #The length of a line in the log.
2810    
2811     set buildlogfilename cp_log.txt
2812     #The name of the log file which we'll use.
2813    
2814     #***************************************************************************
2815     #Directory path constants. These can be configured for a different machine
2816     #which might have a different drive name, etc.
2817     #
2818     #Path where Tex executables are located.
2819     set pathTexExecutables c:/texmf/miktex/bin
2820     #
2821     #Path where the the book source code is located. Everything is assumed in
2822     #a static arrangement below this directory.
2823     set pathUcBookA c:/e3ft_gpl01/dtaipubs/esrgubka
2824    
2825    
2826     #***************************************************************************
2827     #Executable path constants. There should be very little variation in these
2828     #from machine to machine. I've used 4AllTex (a distribution of LaTeX), but
2829     #my understanding is that all distributions of LaTeX are the same executable
2830     #names, etc.--usually just different GUI wrappers.
2831     #
2832     #File where the LaTeX compiler resides.
2833     set execLatexCompiler ""
2834     append execLatexCompiler $pathTexExecutables / latex.exe
2835    
2836     #File where the MAKEINDEX program resides.
2837     set execMakeindex ""
2838     append execMakeindex $pathTexExecutables / makeindex.exe
2839    
2840     #File where the DVIPS program resides.
2841     set execDvips ""
2842     append execDvips $pathTexExecutables / dvips.exe
2843    
2844     #Executable for Acrobat Distiller.
2845     set execAcrobatDistiller "c:/program files/adobe/acrobat 6.0/distillr/acrodist.exe"
2846    
2847    
2848     #***************************************************************************
2849     #Volumes of the book, with their long and short titles, in the
2850     #single-volume and multi-volume versions of the book, respectively.
2851     #Order is:
2852     # Single volume long name (used when longer description is required in
2853     # single volume build).
2854     # Single volume short name (used when shorter description is required in
2855     # single volume build).
2856     # Single volume part name (used to actually name the "Part" in the
2857     # single-volume compile). (May not be used.)
2858     # Multi-volume long name (used when longer description required).
2859     # Multi-volume short name (used when shorter description required).
2860     # Multi-volume cover name (the name which actually appears on the volume
2861     # cover).
2862     # Used flag (1 or 0), a scratch flag.
2863     #
2864     #Each of these is a LaTeX compilation unit. All
2865     #compilations and builds are based on this set of names. These should be
2866     #arranged in order of ascending volume numbers, not in alphabetical order.
2867     #This is to protect for the case of moving to the Tcl script generating
2868     #certain of the files automatically and numbering automatically.
2869     #
2870     #As of 08/27/01, this list contains many unused volumes that were deleted (and
2871     #turned into chapters). These will be kept around for a while, in case they
2872     #are added again in the future as the work grows.
2873     set bookVolumeList {
2874     con0 \
2875     "Concepts" \
2876     "Concepts" \
2877     "Concepts" \
2878     "Concepts" \
2879     "Concepts" \
2880     "Concepts" \
2881     "1" \
2882     mfr0 \
2883     "Mathematical Frameworks And Results" \
2884     "Mathematical Frameworks And Results" \
2885     "Mathematical Frameworks And Results" \
2886     "Mathematical Frameworks And Results" \
2887     "Mathematical Frameworks And Results" \
2888     "Mathematical Frameworks And Results" \
2889     "1" \
2890     csw0 \
2891     "Construction Of Embedded Software" \
2892     "Construction Of Embedded Software" \
2893     "Construction Of Embedded Software" \
2894     "Construction Of Embedded Software" \
2895     "Construction Of Embedded Software" \
2896     "Construction Of Embedded Software" \
2897     "1" \
2898     alg0 \
2899     "Embedded System Algorithms And Techniques" \
2900     "Embedded System Algorithms And Techniques" \
2901     "Embedded System Algorithms And Techniques" \
2902     "Embedded System Algorithms And Techniques" \
2903     "Embedded System Algorithms And Techniques" \
2904     "Embedded System Algorithms And Techniques" \
2905     "1" \
2906     pac0 \
2907     "Practical, Administrative, Incidental, And Miscellaneous Topics" \
2908     "Practical, Administrative, Incidental, And Miscellaneous Topics" \
2909     "Practical, Administrative, Incidental, And Miscellaneous Topics" \
2910     "Practical, Administrative, Incidental, And Miscellaneous Topics" \
2911     "Practical, Administrative, Incidental, And Miscellaneous Topics" \
2912     "Practical, Administrative, Incidental, And Miscellaneous Topics" \
2913     "1" \
2914     isk0 \
2915     "Insektengericht And Lessons Learned" \
2916     "Insektengericht And Lessons Learned" \
2917     "Insektengericht And Lessons Learned" \
2918     "Insektengericht And Lessons Learned" \
2919     "Insektengericht And Lessons Learned" \
2920     "Insektengericht And Lessons Learned" \
2921     "1" \
2922     ijt0 \
2923     "ESRG Workstation-Based Tool Set Reference Guide" \
2924     "ESRG Workstation-Based Tool Set Reference Guide" \
2925     "ESRG Workstation-Based Tool Set Reference Guide" \
2926     "ESRG Workstation-Based Tool Set Reference Guide" \
2927     "ESRG Workstation-Based Tool Set Reference Guide" \
2928     "ESRG Workstation-Based Tool Set Reference Guide" \
2929     "1" \
2930     ijv0 \
2931     "ESRG Server-Based Tool Set Reference Guide" \
2932     "ESRG Server-Based Tool Set Reference Guide" \
2933     "ESRG Server-Based Tool Set Reference Guide" \
2934     "ESRG Server-Based Tool Set Reference Guide" \
2935     "ESRG Server-Based Tool Set Reference Guide" \
2936     "ESRG Server-Based Tool Set Reference Guide" \
2937     "1" \
2938     sma0 \
2939     "Solutions Manual" \
2940     "Solutions Manual" \
2941     "Solutions Manual" \
2942     "Solutions Manual" \
2943     "Solutions Manual" \
2944     "Solutions Manual" \
2945     "1" \
2946     rta0 \
2947     "Real-Time Analysis" \
2948     "Real-Time Analysis" \
2949     "Real-Time Analysis" \
2950     "Real-Time Analysis" \
2951     "Real-Time Analysis" \
2952     "Real-Time Analysis" \
2953     "1" \
2954     scr0 \
2955     "Support Of Common Software Requirements And Design Scenarios"\
2956     "Support Of Common Software Requirements And Design Scenarios"\
2957     "Support Of Common Software Requirements And Design Scenarios"\
2958     "Support Of Common Software Requirements And Design Scenarios"\
2959     "Support Of Common Software Requirements And Design Scenarios"\
2960     "Support Of Common Software Requirements And Design Scenarios"\
2961     "1" \
2962     soc0 \
2963     "Support Of On-Chip Peripherals And Systems" \
2964     "Support Of On-Chip Peripherals And Systems" \
2965     "Support Of On-Chip Peripherals And Systems" \
2966     "Support Of On-Chip Peripherals And Systems" \
2967     "Support Of On-Chip Peripherals And Systems" \
2968     "Support Of On-Chip Peripherals And Systems" \
2969     "1" \
2970     sfc0 \
2971     "Support Of Off-Chip Peripherals And Systems" \
2972     "Support Of Off-Chip Peripherals And Systems" \
2973     "Support Of Off-Chip Peripherals And Systems" \
2974     "Support Of Off-Chip Peripherals And Systems" \
2975     "Support Of Off-Chip Peripherals And Systems" \
2976     "Support Of Off-Chip Peripherals And Systems" \
2977     "1" \
2978     caf0 \
2979     "Implementation Of Common Automotive Features" \
2980     "Implementation Of Common Automotive Features" \
2981     "Implementation Of Common Automotive Features" \
2982     "Implementation Of Common Automotive Features" \
2983     "Implementation Of Common Automotive Features" \
2984     "Implementation Of Common Automotive Features" \
2985     "1" \
2986     snw0 \
2987     "Support Of Networks And Communication Protocols" \
2988     "Support Of Networks And Communication Protocols" \
2989     "Support Of Networks And Communication Protocols" \
2990     "Support Of Networks And Communication Protocols" \
2991     "Support Of Networks And Communication Protocols" \
2992     "Support Of Networks And Communication Protocols" \
2993     "1" \
2994     nal0 \
2995     "Numerical Algorithms, Results, And Techniques" \
2996     "Numerical Algorithms, Results, And Techniques" \
2997     "Numerical Algorithms, Results, And Techniques" \
2998     "Numerical Algorithms, Results, And Techniques" \
2999     "Numerical Algorithms, Results, And Techniques" \
3000     "Numerical Algorithms, Results, And Techniques" \
3001     "1" \
3002     nna0 \
3003     "Non-Numerical Algorithms, Results, And Techniques" \
3004     "Non-Numerical Algorithms, Results, And Techniques" \
3005     "Non-Numerical Algorithms, Results, And Techniques" \
3006     "Non-Numerical Algorithms, Results, And Techniques" \
3007     "Non-Numerical Algorithms, Results, And Techniques" \
3008     "Non-Numerical Algorithms, Results, And Techniques" \
3009     "1" \
3010     sdm0 \
3011     "Software Design Methods" \
3012     "Software Design Methods" \
3013     "Software Design Methods" \
3014     "Software Design Methods" \
3015     "Software Design Methods" \
3016     "Software Design Methods" \
3017     "1" \
3018     cpc0 \
3019     "Microcontroller And CPU Core Usage Application Notes" \
3020     "Microcontroller And CPU Core Usage Application Notes" \
3021     "Microcontroller And CPU Core Usage Application Notes" \
3022     "Microcontroller And CPU Core Usage Application Notes" \
3023     "Microcontroller And CPU Core Usage Application Notes" \
3024     "Microcontroller And CPU Core Usage Application Notes" \
3025     "1" \
3026     sti0 \
3027     "Software Tool Descriptions And Information" \
3028     "Software Tool Descriptions And Information" \
3029     "Software Tool Descriptions And Information" \
3030     "Software Tool Descriptions And Information" \
3031     "Software Tool Descriptions And Information" \
3032     "Software Tool Descriptions And Information" \
3033     "1" \
3034     stn0 \
3035     "Software Tool Usage And Application Notes" \
3036     "Software Tool Usage And Application Notes" \
3037     "Software Tool Usage And Application Notes" \
3038     "Software Tool Usage And Application Notes" \
3039     "Software Tool Usage And Application Notes" \
3040     "Software Tool Usage And Application Notes" \
3041     "1" \
3042     hti0 \
3043     "Hardware Tool Descriptions And Information" \
3044     "Hardware Tool Descriptions And Information" \
3045     "Hardware Tool Descriptions And Information" \
3046     "Hardware Tool Descriptions And Information" \
3047     "Hardware Tool Descriptions And Information" \
3048     "Hardware Tool Descriptions And Information" \
3049     "1" \
3050     htn0 \
3051     "Hardware Tool Usage And Application Notes" \
3052     "Hardware Tool Usage And Application Notes" \
3053     "Hardware Tool Usage And Application Notes" \
3054     "Hardware Tool Usage And Application Notes" \
3055     "Hardware Tool Usage And Application Notes" \
3056     "Hardware Tool Usage And Application Notes" \
3057     "1" \
3058     hwd0 \
3059     "Hardware Design" \
3060     "Hardware Design" \
3061     "Hardware Design" \
3062     "Hardware Design" \
3063     "Hardware Design" \
3064     "Hardware Design" \
3065     "1" \
3066     pte0 \
3067     "Product Testing" \
3068     "Product Testing" \
3069     "Product Testing" \
3070     "Product Testing" \
3071     "Product Testing" \
3072     "Product Testing" \
3073     "1" \
3074     pas0 \
3075     "Product Manufacturing And Assembly" \
3076     "Product Manufacturing And Assembly" \
3077     "Product Manufacturing And Assembly" \
3078     "Product Manufacturing And Assembly" \
3079     "Product Manufacturing And Assembly" \
3080     "Product Manufacturing And Assembly" \
3081     "1" \
3082     pro0 \
3083     "Process, Administrative, And Personnel Issues" \
3084     "Process, Administrative, And Personnel Issues" \
3085     "Process, Administrative, And Personnel Issues" \
3086     "Process, Administrative, And Personnel Issues" \
3087     "Process, Administrative, And Personnel Issues" \
3088     "Process, Administrative, And Personnel Issues" \
3089     "1" \
3090     orq0 \
3091     "Open Research Questions" \
3092     "Open Research Questions" \
3093     "Open Research Questions" \
3094     "Open Research Questions" \
3095     "Open Research Questions" \
3096     "Open Research Questions" \
3097     "1" \
3098     llr0 \
3099     "Lessons Learned" \
3100     "Lessons Learned" \
3101     "Lessons Learned" \
3102     "Lessons Learned" \
3103     "Lessons Learned" \
3104     "Lessons Learned" \
3105     "1" \
3106     bpr0 \
3107     "Best Practices" \
3108     "Best Practices" \
3109     "Best Practices" \
3110     "Best Practices" \
3111     "Best Practices" \
3112     "Best Practices" \
3113     "1" \
3114     hpj0 \
3115     "Hardware Projects" \
3116     "Hardware Projects" \
3117     "Hardware Projects" \
3118     "Hardware Projects" \
3119     "Hardware Projects" \
3120     "Hardware Projects" \
3121     "1" \
3122     sca0 \
3123     "Software Case Studies" \
3124     "Software Case Studies" \
3125     "Software Case Studies" \
3126     "Software Case Studies" \
3127     "Software Case Studies" \
3128     "Software Case Studies" \
3129     "1" \
3130     hca0 \
3131     "Hardware Case Studies" \
3132     "Hardware Case Studies" \
3133     "Hardware Case Studies" \
3134     "Hardware Case Studies" \
3135     "Hardware Case Studies" \
3136     "Hardware Case Studies" \
3137     "1" \
3138     cdt0 \
3139     "Correspondence And Discussion Threads" \
3140     "Correspondence And Discussion Threads" \
3141     "Correspondence And Discussion Threads" \
3142     "Correspondence And Discussion Threads" \
3143     "Correspondence And Discussion Threads" \
3144     "Correspondence And Discussion Threads" \
3145     "1" \
3146     dtm0 \
3147     "Document Templates" \
3148     "Document Templates" \
3149     "Document Templates" \
3150     "Document Templates" \
3151     "Document Templates" \
3152     "Document Templates" \
3153     "1" \
3154     }
3155    
3156     set bookVolumeListStructSize 8
3157     #The numer of physical records per each logical record in the list above. This
3158     #minimizes tearup if things are added to what is above.
3159    
3160     set bookVolumeListIndex(NOT_USED) 0
3161     #Used to initialize the associative index array for the book volumes, so there are
3162     #no problems declaring it global to procs before it is first defined. This index
3163     #is associative by the 4-character volume code, and stores an integer which is the
3164     #base array index into the group of info for that volume name. This is done to
3165     #avoid repeated searches of the entire space. I would guess the Tcl hash function
3166     #is faster than a linear search.
3167    
3168     # The list of chapters in the entire work. They don't have to be in any particular
3169     # order (so I've arranged them alphabetically by tag). The fields are, in order:
3170     # a)The tag.
3171     # b)Single volume long name.
3172     # c)Single volume short name.
3173     # d)Multiple volume long name.
3174     # e)Multiple volume short name.
3175     # f)Single volume status ("D" or "F"). "D" indicates that chapter should be treated as a
3176     # draft chapter for the single volume work and only included in the draft version. "F" indicates
3177     # should be included in both draft and final versions.
3178     # g)Multi-volume status ("D" or "F"). See description immediately above, except
3179     # applies to multi-volume work.
3180     # h)"Used" flag ("Y" or "N"). This flag is set by the software as it runs to remember if a chapter
3181     # is referenced in the mcl or not. This is a scratch flag.
3182     #
3183     # As of 08/27/01, this list contains many unused chapters that were deleted. These will
3184     # be kept around for a while, in case they are added again in the future as the work grows.
3185     set chapterList {
3186     add0 \
3187     "Addition" \
3188     "Addition" \
3189     "Addition" \
3190     "Addition" \
3191     "F" \
3192     "F" \
3193     "0" \
3194     bal0 \
3195     "Boolean Algebra And Simplification Of Boolean Functions" \
3196     "Simplification Of Boolean Functions" \
3197     "Boolean Algebra And Simplification Of Boolean Functions" \
3198     "Simplification Of Boolean Functions" \
3199     "F" \
3200     "F" \
3201     "0" \
3202     bas0 \
3203     "Solutions: Boolean Algebra And Simplification Of Boolean Functions" \
3204     "Solutions: Boolean Algebra" \
3205     "Solutions: Boolean Algebra And Simplification Of Boolean Functions" \
3206     "Solutions: Boolean Algebra" \
3207     "F" \
3208     "F" \
3209     "0" \
3210     ber0 \
3211     "Build Environment Research Questions" \
3212     "Build Environment Research Questions" \
3213     "Build Environment Research Questions" \
3214     "Build Environment Research Questions" \
3215     "F" \
3216     "F" \
3217     "0" \
3218     bma0 \
3219     "Bad Management And Unpleasant Work Situations" \
3220     "Bad Management" \
3221     "Bad Management And Unpleasant Work Situations" \
3222     "Bad Management" \
3223     "F" \
3224     "F" \
3225     "0" \
3226     cch0 \
3227     "CRC, Checksum, And Hash Function Extensions" \
3228     "CRC, Checksum, And Hash Extensions" \
3229     "CRC, Checksum, And Hash Function Extensions" \
3230     "CRC, Checksum, And Hash Extensions" \
3231     "F" \
3232     "F" \
3233     "0" \
3234     cfr0 \
3235     "Continued Fractions And Related Topics" \
3236     "Continued Fractions And Related Topics" \
3237     "Continued Fractions And Related Topics" \
3238     "Continued Fractions And Related Topics" \
3239     "F" \
3240     "F" \
3241     "0" \
3242     cfs0 \
3243     "Solutions: Continued Fractions And Related Topics" \
3244     "Solutions: Continued Fractions" \
3245     "Solutions: Continued Fractions And Related Topics" \
3246     "Solutions: Continued Fractions" \
3247     "F" \
3248     "F" \
3249     "0" \
3250     cil0 \
3251     "Classical And Simple Integer Algorithms And Techniques" \
3252     "Simple Integer Algorithms" \
3253     "Classical And Simple Integer Algorithms And Techniques" \
3254     "Simple Integer Algorithms" \
3255     "F" \
3256     "F" \
3257     "0" \
3258     cis0 \
3259     "Solutions: Classical And Simple Integer Algorithms And Techniques" \
3260     "Solutions: Simple Integer Algorithms" \
3261     "Solutions: Classical And Simple Integer Algorithms And Techniques" \
3262     "Solutions: Simple Integer Algorithms" \
3263     "F" \
3264     "F" \
3265     "0" \
3266     css1 \
3267     "Canonical Server Setup" \
3268     "Canonical Server Setup" \
3269     "Canonical Server Setup" \
3270     "Canonical Server Setup" \
3271     "F" \
3272     "F" \
3273     "0" \
3274     cst0 \
3275     "Coding Standards" \
3276     "Coding Standards" \
3277     "Coding Standards" \
3278     "Coding Standards" \
3279     "F" \
3280     "F" \
3281     "0" \
3282     daa0 \
3283     "Decoration And Automatic Assembly" \
3284     "Decoration And Automatic Assembly" \
3285     "Decoration And Automatic Assembly" \
3286     "Decoration And Automatic Assembly" \
3287     "F" \
3288     "F" \
3289     "0" \
3290     dcm0 \
3291     "DOS Console-Mode Utilities" \
3292     "DOS Console-Mode Utilities" \
3293     "DOS Console-Mode Utilities" \
3294     "DOS Console-Mode Utilities" \
3295     "F" \
3296     "F" \
3297     "0" \
3298     div0 \
3299     "Division" \
3300     "Division" \
3301     "Division" \
3302     "Division" \
3303     "F" \
3304     "F" \
3305     "0" \
3306     dta0 \
3307     "Discrete-Time And Complex Integer Algorithms And Techniques" \
3308     "Complex Integer Algorithms" \
3309     "Discrete-Time And Complex Integer Algorithms And Techniques" \
3310     "Complex Integer Algorithms" \
3311     "F" \
3312     "F" \
3313     "0" \
3314     edc0 \
3315     "Error-Detecting And Error-Correcting Codes, With Microcontroller Applications" \
3316     "Error-Detecting And Correcting Codes" \
3317     "Error-Detecting And Error-Correcting Codes, With Microcontroller Applications" \
3318     "Error-Detecting And Correcting Codes" \
3319     "F" \
3320     "F" \
3321     "0" \
3322     eds0 \
3323     "Solutions: Error-Detecting And Error-Correcting Codes, With Microcontroller Applications" \
3324     "Solutions: Error-Detecting And Correcting Codes" \
3325     "Solutions: Error-Detecting And Error-Correcting Codes, With Microcontroller Applications" \
3326     "Solutions: Error-Detecting And Correcting Codes" \
3327     "F" \
3328     "F" \
3329     "0" \
3330     faq0 \
3331     "Frequently Asked Questions And Frequently Encountered Problems" \
3332     "FAQs And Common Problems" \
3333     "Frequently Asked Questions And Frequently Encountered Problems" \
3334     "FAQs And Common Problems" \
3335     "F" \
3336     "F" \
3337     "0" \
3338     frs0 \
3339     "Solutions: Farey Series And Related Topics" \
3340     "Solutions: Farey Series" \
3341     "Solutions: Farey Series And Related Topics" \
3342     "Solutions: Farey Series" \
3343     "F" \
3344     "F" \
3345     "0" \
3346     fry0 \
3347     "Farey Series And Related Topics" \
3348     "Farey Series And Related Topics" \
3349     "Farey Series And Related Topics" \
3350     "Farey Series And Related Topics" \
3351     "F" \
3352     "F" \
3353     "0" \
3354     fte0 \
3355     "File Transformation Extension" \
3356     "File Transformation Extension" \
3357     "File Transformation Extension" \
3358     "File Transformation Extension" \
3359     "F" \
3360     "F" \
3361     "0" \
3362     hgr0 \
3363     "The Holy Grail" \
3364     "The Holy Grail" \
3365     "The Holy Grail" \
3366     "The Holy Grail" \
3367     "F" \
3368     "F" \
3369     "0" \
3370     hrq0 \
3371     "Hardware Research Questions" \
3372     "Hardware Research Questions" \
3373     "Hardware Research Questions" \
3374     "Hardware Research Questions" \
3375     "F" \
3376     "F" \
3377     "0" \
3378     int0 \
3379     "Introduction To Small Microcontroller Work" \
3380     "Introduction To Small Microcontroller Work" \
3381     "Introduction To Small Microcontroller Work" \
3382     "Introduction To Small Microcontroller Work" \
3383     "F" \
3384     "F" \
3385     "0" \
3386     ird0 \
3387     "Interrupt-Related Software Defects" \
3388     "Interrupt-Related Software Defects" \
3389     "Interrupt-Related Software Defects" \
3390     "Interrupt-Related Software Defects" \
3391     "F" \
3392     "F" \
3393     "0" \
3394     isa1 \
3395     "Introduction and Server Architecture" \
3396     "Introduction and Server Architecture" \
3397     "Introduction and Server Architecture" \
3398     "Introduction and Server Architecture" \
3399     "F" \
3400     "F" \
3401     "0" \
3402     isk0 \
3403     "Insektengericht And Lessons Learned" \
3404     "Insektengericht And Lessons Learned" \
3405     "Insektengericht And Lessons Learned" \
3406     "Insektengericht And Lessons Learned" \
3407     "F" \
3408     "F" \
3409     "0" \
3410     lie0 \
3411     "Long Integer Extensions" \
3412     "Long Integer Extensions" \
3413     "Long Integer Extensions" \
3414     "Long Integer Extensions" \
3415     "F" \
3416     "F" \
3417     "0" \
3418     mpd0 \
3419     "Management Of Product Development Materials" \
3420     "Management Of Product Development Materials" \
3421     "Management Of Product Development Materials" \
3422     "Management Of Product Development Materials" \
3423     "F" \
3424     "F" \
3425     "0" \
3426     mtn0 \
3427     "Miscellaneous Topics From Mathematics And Number Theory" \
3428     "Miscellaneous Mathematical Topics" \
3429     "Miscellaneous Topics From Mathematics And Number Theory" \
3430     "Miscellaneous Mathematical Topics" \
3431     "F" \
3432     "F" \
3433     "0" \
3434     mul0 \
3435     "Multiplication" \
3436     "Multiplication" \
3437     "Multiplication" \
3438     "Multiplication" \
3439     "F" \
3440     "F" \
3441     "0" \
3442     nam0 \
3443     "Naming Conventions" \
3444     "Naming Conventions" \
3445     "Naming Conventions" \
3446     "Naming Conventions" \
3447     "F" \
3448     "F" \
3449     "0" \
3450     nnu0 \
3451     "Non-Numerical Algorithms And Techniques" \
3452     "Non-Numerical Algorithms And Techniques" \
3453     "Non-Numerical Algorithms And Techniques" \
3454     "Non-Numerical Algorithms And Techniques" \
3455     "F" \
3456     "F" \
3457     "0" \
3458     nth0 \
3459     "Number Theory Extensions" \
3460     "Number Theory Extensions" \
3461     "Number Theory Extensions" \
3462     "Number Theory Extensions" \
3463     "F" \
3464     "F" \
3465     "0" \
3466     orq0 \
3467     "Open Research Questions" \
3468     "Open Research Questions" \
3469     "Open Research Questions" \
3470     "Open Research Questions" \
3471     "F" \
3472     "F" \
3473     "0" \
3474     pbc0 \
3475     "Product Build- And Configuration-Related Software Defects" \
3476     "Build And Configuration Defects" \
3477     "Product Build- And Configuration-Related Software Defects" \
3478     "Build And Configuration Defects" \
3479     "F" \
3480     "F" \
3481     "0" \
3482     pco0 \
3483     "General Practical Construction Of Embedded Software" \
3484     "General Practical Construction Of Embedded Software" \
3485     "General Practical Construction Of Embedded Software" \
3486     "General Practical Construction Of Embedded Software" \
3487     "F" \
3488     "F" \
3489     "0" \
3490     pit0 \
3491     "Practical Interface And Test Circuits" \
3492     "Practical Interface And Test Circuits" \
3493     "Practical Interface And Test Circuits" \
3494     "Practical Interface And Test Circuits" \
3495     "F" \
3496     "F" \
3497     "0" \
3498     pri0 \
3499     "Integers, Prime Numbers, And Related Topics" \
3500     "Integers, Primes, And Related Topics" \
3501     "Integers, Prime Numbers, And Related Topics" \
3502     "Integers, Primes, And Related Topics" \
3503     "F" \
3504     "F" \
3505     "0" \
3506     prs0 \
3507     "Solutions: Integers, Prime Numbers, And Related Topics" \
3508     "Solutions: Integers, Primes, And Related Topics" \
3509     "Solutions: Integers, Prime Numbers, And Related Topics" \
3510     "Solutions: Integers, Primes, And Related Topics" \
3511     "F" \
3512     "F" \
3513     "0" \
3514     pxf0 \
3515     "Products Of Exceptional Functionality" \
3516     "Products Of Exceptional Functionality" \
3517     "Products Of Exceptional Functionality" \
3518     "Products Of Exceptional Functionality" \
3519     "F" \
3520     "F" \
3521     "0" \
3522     qua0 \
3523     "Quantization" \
3524     "Quantization" \
3525     "Quantization" \
3526     "Quantization" \
3527     "F" \
3528     "F" \
3529     "0" \
3530     rat0 \
3531     "Rational Approximation" \
3532     "Rational Approximation" \
3533     "Rational Approximation" \
3534     "Rational Approximation" \
3535     "F" \
3536     "F" \
3537     "0" \
3538     ras0 \
3539     "Solutions: Rational Approximation" \
3540     "Solutions: Rational Approximation" \
3541     "Solutions: Rational Approximation" \
3542     "Solutions: Rational Approximation" \
3543     "F" \
3544     "F" \
3545     "0" \
3546     rcs0 \
3547     "Ratiometric Conversion And Measurement Systems" \
3548     "Ratiometric Measurement Systems" \
3549     "Ratiometric Conversion And Measurement Systems" \
3550     "Ratiometric Measurement Systems" \
3551     "F" \
3552     "F" \
3553     "0" \
3554     rnd1 \
3555     "Random Number Generation Extensions" \
3556     "Random Number Generation Extensions" \
3557     "Random Number Generation Extensions" \
3558     "Random Number Generation Extensions" \
3559     "F" \
3560     "F" \
3561     "0" \
3562     rne0 \
3563     "Rational Number Extensions" \
3564     "Rational Number Extensions" \
3565     "Rational Number Extensions" \
3566     "Rational Number Extensions" \
3567     "F" \
3568     "F" \
3569     "0" \
3570     rta0 \
3571     "Real-Time Analysis" \
3572     "Real-Time Analysis" \
3573     "Real-Time Analysis" \
3574     "Real-Time Analysis" \
3575     "F" \
3576     "F" \
3577     "0" \
3578     sds0 \
3579     "Standard Directory Structures" \
3580     "Standard Directory Structures" \
3581     "Standard Directory Structures" \
3582     "Standard Directory Structures" \
3583     "F" \
3584     "F" \
3585     "0" \
3586     sfo0 \
3587     "Support Of Frequently-Occurring Requirements" \
3588     "Support Of Frequently-Occurring Requirements" \
3589     "Support Of Frequently-Occurring Requirements" \
3590     "Support Of Frequently-Occurring Requirements" \
3591     "F" \
3592     "F" \
3593     "0" \
3594     snc0 \
3595     "Support Of Communication Protocols And Networks" \
3596     "Support Of Communication Protocols And Networks" \
3597     "Support Of Communication Protocols And Networks" \
3598     "Support Of Communication Protocols And Networks" \
3599     "F" \
3600     "F" \
3601     "0" \
3602     soc0 \
3603     "Support Of On-Chip Peripherals And Subsystems" \
3604     "Support Of On-Chip Peripherals And Subsystems" \
3605     "Support Of On-Chip Peripherals And Subsystems" \
3606     "Support Of On-Chip Peripherals And Subsystems" \
3607     "F" \
3608     "F" \
3609     "0" \
3610     soc1 \
3611     "Support Of Off-Chip Peripherals And Subsystems" \
3612     "Off-Chip Peripherals And Subsystems" \
3613     "Support Of Off-Chip Peripherals And Subsystems" \
3614     "Off-Chip Peripherals And Subsystems" \
3615     "F" \
3616     "F" \
3617     "0" \
3618     sub0 \
3619     "Subtraction" \
3620     "Subtraction&q