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