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