1#!/usr/bin/perl
2#
3#  $Id: protex,v 1.15 2004/06/03 23:49:46 eschwab Exp $
4#
5#BOP
6#
7# !ROUTINE: ProTeX v. 2.00 - Translates DAO Prologues to LaTeX
8#
9# !INTERFACE:
10#         protex [-hbACFS] ] [+-nlsxf] [src_file(s)]
11#
12# !DESCRIPTION:
13#         Perl filter to produce a \LaTeX compatible document
14#         from a DAO Fortran source code with standard Pro\TeX
15#         prologues. If source files are not specified it
16#         reads from stdin; output is always to stdout.
17#
18# \noindent
19# {\bf Command Line Switches:} \vspace{0.2cm}
20#
21# \begin{center}
22# \begin{tabular}{|c|l|} \hline \hline
23#   -h   & Help mode: list command line options   \\ \hline
24#   -b   & Bare mode, meaning no preamble, etc.  \\ \hline
25#   -i   & internal mode: omit prologues marked !BOPI  \\ \hline
26#   +/-n & New Page for each subsection (wastes paper) \\ \hline
27#   +/-l & Listing mode, default is prologues only \\ \hline
28#   +/-s & Shut-up mode, i.e., ignore any code from BOC to EOC \\ \hline
29#   +/-x & No LaTeX mode, i.e., put !DESCRIPTION: in verbatim mode \\ \hline
30#   +/-f & No source file info \\ \hline
31#   -A   & Ada code \\ \hline
32#   -C   & C++ code \\ \hline
33#   -F   & F90 code (default) \\ \hline
34#   -S   & Shell script \\ \hline \hline
35# \end{tabular}
36# \end{center}
37#
38# The options can appear in any order.  The options, -h and -b, affect
39# the input from all files listed on command-line input.  Each of the
40# remaining options effects only the input from the files listed after
41# the option and prior to any overriding option.  The plus sign
42# turns off the option.  For example, the command-line input,
43# \bv
44#      protex -bnS File1 -F File2.f +n File3.f
45# \ev
46# will cause the option, {\tt -n} to affect the input from the files,
47# {\tt File} and {\tt File2.f}, but not from {\tt File3.f}.  The
48# {\tt -S} option is implemented for {\tt File1} but is overridden by
49# the {\tt -F} for files {\tt File2.f} and {\tt File3.f}.
50#
51#
52# !SEE ALSO:
53#         For a more detailed description of ProTeX functionality,
54#         DAO Prologue and other conventions, consult:
55#
56#           Sawyer, W., and A. da Silva, 1997: ProTeX: A Sample
57#           Fortran 90 Source Code Documentation System.
58#           DAO Office Note 97-11
59#
60#
61# !REVISION HISTORY:
62#
63#  20Dec1995  da Silva  First experimental version
64#  10Nov1996  da Silva  First internal release (v1.01)
65#  28Jun1997  da Silva  Modified so that !DESCRIPTION can appear after
66#             !INTERFACE, and !INPUT PARAMETERS etc. changed to italics.
67#  02Jul1997  Sawyer    Added shut-up mode
68#  20Oct1997  Sawyer    Added support for shell scripts
69#  11Mar1998  Sawyer    Added: file name, date in header, C, script support
70#  05Aug1998  Sawyer    Fixed LPChang-bug-support-for-files-with-underscores
71#  10Oct1998  da Silva  Introduced -f option for removing source file info
72#                       from subsection, etc.  Added help (WS).
73#  06Dec1999  C. Redder Added LaTeX command "\label{sec:prologues}" just
74#                       after the beginning of the proglogue section.
75#  13Dec1999  C. Redder Increased flexbility in command-line
76#                       interface.  The options can appear in any
77#                       order which will allow the user to implement
78#                       options for select files.
79#  01Feb1999  C. Redder Added \usepackage commands to preamble of latex
80#                       document to include the packages amsmath, epsfig
81#                       and hangcaption.
82#  10May2000  C. Redder Revised LaTeX command "\label{sec:prologues}"
83#                       to "\label{app:ProLogues}"
84#  10/10/2002 da Silva  Introduced ARGUMENTS keyword, touch ups.
85#
86#  15Jan2003  R. Staufer  Modified table of contents to print only section headers - no descriptions
87#
88#  25Feb2003  R. Staufer  Added BOPI/EOPI and -i (internal) switch to provide the option of omitting prologue information from output files.
89#
90#EOP
91#----------------------------------------------------------------------------
92
93# Keep this if you don't know what it does...
94# -------------------------------------------
95###  $[ = 1;                 # set array base to 1 (removed to maintain Perl 5.30 compatibility)
96  $, = ' ';               # set output field separator
97  $\ = "\n";              # set output record separator
98
99# Set valid options lists
100# -----------------------
101  $GlobOptions = 'hb';    # Global options (i.e for all files)
102  $LangOptions = 'ACFS';  # Options for setting programming languages
103  $SwOptions   = 'flinsx'; # Options that can change for each input
104                          #   file
105  $RegOptions  = "$GlobOptions$LangOptions";
106                          # Scan for global options until first first
107                          #   file is processed.
108
109# Scan for global options
110# -----------------------
111  $NFiles = 0;
112Arg:
113  foreach $arg (@ARGV) {
114     $option = &CheckOpts ( $arg, $RegOptions, $SwOptions ) + 1;
115     if ( $option ) {
116        $rc = &GetOpts    ( $arg, $GlobOptions );
117         next Arg; }
118
119     else { $NFiles++;
120}#   end if
121}# end foreach
122
123# If all input arguments are options, then assume the
124# filename, "-", for the standard input
125# --------------------------------------------------
126  if ( $NFiles == 0 ) { push (@ARGV, "-"); }
127
128# Implement help option
129# ---------------------
130  if ( $opt_h ) {
131     &print_help();
132      exit();
133}#end if
134
135# Optional Prologue Keywords
136# --------------------------
137  @keys = ( "!INTERFACE:",
138            "!USES:",
139            "!PUBLIC TYPES:",
140            "!PRIVATE TYPES:",
141            "!PUBLIC MEMBER FUNCTIONS:",
142            "!PRIVATE MEMBER FUNCTIONS:",
143            "!PUBLIC DATA MEMBERS:",
144            "!PARAMETERS:",
145            "!ARGUMENTS:",
146            "!DEFINED PARAMETERS:",
147            "!INPUT PARAMETERS:",
148            "!INPUT/OUTPUT PARAMETERS:",
149            "!OUTPUT PARAMETERS:",
150            "!RETURN VALUE:",
151            "!REVISION HISTORY:",
152            "!BUGS:",
153            "!SEE ALSO:",
154            "!SYSTEM ROUTINES:",
155            "!FILES USED:",
156            "!REMARKS:",
157            "!TO DO:",
158            "!CALLING SEQUENCE:",
159            "!AUTHOR:",
160            "!CALLED FROM:",
161            "!LOCAL VARIABLES:" );
162
163# Initialize these for clarity
164# ----------------------------
165  $intro = 0;             # doing introduction?
166  $prologue = 0;          # doing prologue?
167  $first = 1;             # first prologue?
168  $source = 0;            # source code mode?
169  $verb = 0;              # verbatim mode?
170  $tpage = 0;             # title page?
171  $begdoc = 0;            # has \begin{document} been written?
172
173# Initial LaTeX stuff
174# -------------------
175  &print_notice();
176  &print_preamble();      # \documentclass, text dimensions, etc.
177  &print_macros();        # short-hand LaTeX macros
178
179# Main loop -- for each command-line argument
180# -------------------------------------------
181ARG:
182  foreach $arg (@ARGV) {
183
184#    Scan for non-global command-line options
185#    ----------------------------------------
186     $option = &CheckOpts ( $arg, $RegOptions, $SwOptions, "quiet" ) + 1;
187     if ( $option ) {
188        &GetOpts  ( $arg, $SwOptions   );
189        &SetOpt   ( $arg, $LangOptions );
190        next ARG;
191
192}#   end if
193
194#    Determine the type of code, set corresponding search strings
195#    ------------------------------------------------------------
196#    if ( $opt_F ) {            # FORTRAN
197        $comment_string = '!';  # -------
198        $boi_string = '!BOI';
199        $eoi_string = '!EOI';
200        $bop_string = '!BOP';
201        $eop_string = '!EOP';
202        $bopi_string = '!BOPI';
203        $eopi_string = '!EOPI';
204        $boc_string = '!BOC';
205        $eoc_string = '!EOC';
206        $boe_string = '!BOE';
207        $eoe_string = '!EOE';
208#}#   end if
209
210     if ( $opt_A ) {            # ADA
211        $comment_string = '--'; # ---
212        $boi_string = '--BOI';
213        $eoi_string = '--EOI';
214        $bop_string = '--BOP';
215        $eop_string = '--EOP';
216        $bopi_string = '--BOPI';
217        $eopi_string = '--EOPI';
218        $boc_string = '--BOC';
219        $eoc_string = '--EOC';
220        $boe_string = '--BOE';
221        $eoe_string = '--EOE';
222}#   end if
223
224     if ( $opt_C ) {
225        $comment_string = '//'; # C
226        $boi_string = '//BOI';  # -
227        $eoi_string = '//EOI';
228        $bop_string = '//BOP';
229        $eop_string = '//EOP';
230        $bopi_string = '//BOPI';
231        $eopi_string = '//EOPI';
232        $boc_string = '//BOC';
233        $eoc_string = '//EOC';
234        $boe_string = '//BOE';
235        $eoe_string = '//EOE';
236}#   end if
237
238     if ( $opt_S ) {            # Script
239        $comment_string = '#';  # ------
240        $boi_string = '#BOI';
241        $eoi_string = '#EOI';
242        $bop_string = '#BOP';
243        $eop_string = '#EOP';
244        $bopi_string = '#BOPI';
245	$eopi_string = '#EOPI';
246        $boc_string = '#BOC';
247        $eoc_string = '#EOC';
248        $boe_string = '#BOE';
249        $eoe_string = '#EOE';
250}#   end if
251
252#    Set file name parameters
253#    ------------------------
254     $InputFile           = $arg;
255     @all_path_components = split( /\//, $InputFile     );
256     $FileBaseName        = pop  ( @all_path_components );
257     $FileBaseName        =~ s/_/\\_/g;
258     if ( $InputFile eq "-" ) {$FileBaseName = "Standard Input";}
259
260#    Set date
261#    --------
262     $Date                = `date`;
263
264#    Open current file
265#    -----------------
266     open ( InputFile, "$InputFile" )
267          or print STDERR "Unable to open $InputFile: $!";
268
269#    Print page header
270#    -----------------
271#     printf "\n\\markboth{Left}{Source File: %s,  Date: %s}\n\n",
272#                               $FileBaseName,    $Date;
273
274LINE:
275#    Inner loop --- for processing each line of the input file
276#    ---------------------------------------------------------
277     while ( <InputFile> ) {
278        chop;     # strip record separator
279
280#       !PARAMETERS: really mean !ARGUMENTS:
281#       ------------------------------------
282#        s/!PARAMETERS:/!ARGUMENTS:/g;
283
284        @Fld = split(' ', $_, 9999);
285
286#       Straight quote
287#       --------------
288        if ($Fld[0] eq '!QUOTE:') {
289           for ($i = 1; $i <= $#Fld - 1; $i++) {
290               printf '%s ', $Fld[$i];
291}#         end for
292           print " ";
293           next LINE;
294}#      end if
295
296#       Handle optional Title Page and Introduction
297#       -------------------------------------------
298        if ($Fld[0] eq $boi_string) {
299           print ' ';
300           $intro = 1;
301           next LINE;
302}#      end if
303
304        if ($Fld[1] eq '!TITLE:') {
305           if ( $intro ) {
306              shift @Fld;
307              shift @Fld;
308              @title = @Fld;
309              $tpage = 1;
310              next LINE;
311}#         end if
312}#      end if
313
314        if ($Fld[1] eq '!AUTHORS:') {
315           if ( $intro ) {
316              shift @Fld;
317              shift @Fld;
318              @author = @Fld;
319              $tpage = 1;
320              next LINE;
321}#         end if
322}#      end if
323
324        if ($Fld[1] eq '!AFFILIATION:') {
325           if ( $intro ) {
326              shift @Fld;
327              shift @Fld;
328              @affiliation = @Fld;
329              $tpage = 1;
330              next LINE;
331}#         end if
332}#      end if
333
334        if ($Fld[1] eq '!DATE:') {
335           if ( $intro ) {
336              shift @Fld;
337              shift @Fld;
338              @date = @Fld;
339              $tpage = 1;
340              next LINE;
341}#         end if
342}#      end if
343
344        if ($Fld[1] eq '!INTRODUCTION:') {
345           if ( $intro ) {
346              &do_beg();
347              print ' ';
348              print '%..............................................';
349              shift @Fld;
350              shift @Fld;
351              print "\\section{@Fld}";
352              next LINE;
353}#         end if
354}#      end if
355
356
357#       End of introduction
358#       -------------------
359        if ($Fld[0] eq $eoi_string) {
360           print ' ';
361           print '%/////////////////////////////////////////////////////////////';
362           print "\\newpage";
363           $intro = 0;
364           next LINE;
365}#      end if
366
367#       Beginning of prologue
368#       ---------------------
369        if ($Fld[0] eq $bop_string) {
370           if ( $source ) { &do_eoc(); }
371           print ' ';
372           print '%/////////////////////////////////////////////////////////////';
373           &do_beg();
374           if ($first == 0) {
375              ### print "\\newpage";
376              print " ";
377              print "\\mbox{}\\hrulefill\\ ";
378              print " ";}
379           else {
380              unless($opt_b){print "\\section{Routine/Function Prologues} \\label{app:ProLogues}";}
381}#         end if
382
383           $first = 0;
384           $prologue = 1;
385           $verb = 0;
386           $source = 0;
387           &set_missing();   # no required keyword yet
388           next LINE;
389}#     end if
390
391#	Beginning of internal prologue
392#	------------------------------
393	if ($Fld[0] eq $bopi_string) {
394	   if ($opt_i) {$prologue = 0;}
395           else {
396              if ($source) { &do_eoc(); }
397              print ' ';
398              print '%/////////////////////////////////////////////////////////////';
399              &do_beg();
400              if ($first ==0) {
401                 ### print "\\newpage";
402                 print " ";
403                 print "\\mbox{}\\hrulefill\\";
404                 print " ";}
405              else {
406                 unless($opt_b){print "\\section{Routine/Function Prologues} \\label{app:ProLogues}";}
407}#            endif
408              $first = 0;
409              $prologue = 1;
410              $verb = 0;
411              $source = 0;
412              &set_missing();    # no required keyword yet
413              next LINE;
414           }#   endelse
415        }#    endif
416
417#       A new subroutine/function
418#       -------------------------
419        if ($Fld[1] eq '!ROUTINE:' ) {
420           if ($prologue) {
421              shift @Fld;
422              shift @Fld;
423              $_ = join(' ', @Fld);
424              $name_is = $_;
425              s/_/\\_/g;                         # Replace "_" with "\_"
426              if ( $opt_n && $not_first ) { printf "\\newpage\n"; }
427              unless ($opt_f) {printf "\\subsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;}
428              else            {printf "\\subsection{%s }\n\n", $_;}
429              $have_name = 1;
430              $not_first = 1;
431              next LINE;
432}#         end if
433}#      end if
434
435#       A new Module
436#       ------------
437        if ($Fld[1] eq '!MODULE:' ) {
438           if ($prologue) {
439              shift @Fld;
440              shift @Fld;
441              $_ = join(' ', @Fld);
442              $name_is = $_;
443              s/_/\\_/g;                         # Replace "_" with "\_"
444              if ( $opt_n && $not_first ) { printf "\\newpage\n"; }
445              unless($opt_f) {printf "\\subsection{Fortran:  Module Interface %s (Source File: %s)}\n\n", $_, $FileBaseName;}
446              else           {printf "\\subsection{Fortran:  Module Interface %s }\n\n", $_;}
447              $have_name = 1;
448              $have_intf = 1;  # fake it, it does not need one.
449              $not_first = 1;
450              next LINE;
451}#         end if
452}#      end if
453
454#       A new include file
455#       ------------------
456        if ($Fld[1] eq '!INCLUDE:' ) {
457           if ($prologue) {
458              shift @Fld;
459              shift @Fld;
460              $_ = join(' ', @Fld);
461              $name_is = $_;
462              s/_/\\_/g;                         # Replace "_" with "\_"
463              if ( $opt_n && $not_first ) { printf "\\newpage\n"; }
464              unless($opt_f) {printf "\\subsection{Include File %s (Source File: %s)}\n\n", $_, $FileBaseName;}
465              else           {printf "\\subsection{Include File %s }\n\n", $_;}
466              $have_name = 1;
467              $have_intf = 1;  # fake it, it does not need one.
468              $not_first = 1;
469              next LINE;
470}#         end if
471}#      end if
472
473#       A new INTERNAL subroutine/function
474#       ----------------------------------
475        if ($Fld[1] eq '!IROUTINE:') {            # Internal routine
476           if ($prologue) {
477              shift @Fld;
478              shift @Fld;
479              $_ = join(' ', @Fld);
480              $name_is = $_;
481              s/_/\\_/g;                        # Replace "_" with "\_"
482	      @words = split " ", $_;
483              printf "\\subsection [$words[1]] {$_}\n\n";
484              $have_name = 1;
485              next LINE;
486}#         end if
487}#      end if
488
489#       A new CLASS
490#       ------------
491        if ($Fld[1] eq '!CLASS:' ) {
492           if ($prologue) {
493              shift @Fld;
494              shift @Fld;
495              $_ = join(' ', @Fld);
496              $name_is = $_;
497              s/_/\\_/g;                         # Replace "_" with "\_"
498              if ( $opt_n && $not_first ) { printf "\\newpage\n"; }
499              unless($opt_f) {printf "\\subsection{C++:  Class Interface %s (Source File: %s)}\n\n", $_, $FileBaseName;}
500              else           {printf "\\subsection{C++:  Class Interface %s }\n\n", $_;}
501              $have_name = 1;
502              $have_intf = 1;  # fake it, it does not need one.
503              $not_first = 1;
504              next LINE;
505}#         end if
506}#      end if
507
508#       A new Method
509#       -------------------------
510        if ($Fld[1] eq '!METHOD:' ) {
511           if ($prologue) {
512              shift @Fld;
513              shift @Fld;
514              $_ = join(' ', @Fld);
515              $name_is = $_;
516              s/_/\\_/g;                         # Replace "_" with "\_"
517              if ( $opt_n && $not_first ) { printf "\\newpage\n"; }
518              unless ($opt_f) {printf "\\subsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;}
519              else            {printf "\\subsection{%s }\n\n", $_;}
520              $have_name = 1;
521              $not_first = 1;
522              next LINE;
523}#         end if
524}#      end if
525
526#       A new function
527#       -------------------------
528        if ($Fld[1] eq '!FUNCTION:' ) {
529           if ($prologue) {
530              shift @Fld;
531              shift @Fld;
532              $_ = join(' ', @Fld);
533              $name_is = $_;
534              s/_/\\_/g;                         # Replace "_" with "\_"
535              if ( $opt_n && $not_first ) { printf "\\newpage\n"; }
536              unless ($opt_f) {printf "\\subsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;}
537              else            {printf "\\subsection{%s }\n\n", $_;}
538              $have_name = 1;
539              $not_first = 1;
540              next LINE;
541}#         end if
542}#      end if
543
544#       Description: what follows will be regular LaTeX (no verbatim)
545#       -------------------------------------------------------------
546        if (/!DESCRIPTION:/) {
547           if ($prologue) {
548              if ($verb) {
549                 printf "\\end{verbatim}";
550                 printf "\n{\\sf DESCRIPTION:\\\\ }\n\n";
551                 $verb = 0; }
552              else {                          # probably never occurs
553}#            end if
554              if ($opt_x) {
555                 printf "\\begin{verbatim} ";
556                 $verb = 1;
557                 $first_verb = 1; }
558              else {
559                 for ($i = 2; $i <= $#Fld - 1; $i++) {
560                    printf '%s ', $Fld[$i];
561}#               end for
562}#            end if
563              ### print " ";
564              $have_desc = 1;
565              next LINE;
566}#         end if
567}#      end if
568
569#       Handle optional keywords (these will appear as verbatim)
570#       --------------------------------------------------------
571        if ($prologue) {
572KEY:       foreach $key ( @keys ) {
573              if ( /$key/ ) {
574                 if ($verb) {
575                    printf "\\end{verbatim}";
576                    $verb = 0; }
577                 else {
578                    printf "\n\\bigskip";
579}#               end if
580                 $k = sprintf('%s', $key);
581                 $ln = length($k);
582                 ###printf "\\subsection*{%s}\n", substr($k, 2, $ln - 1);
583                 ###printf "{\\Large \\em %s}\n", ucfirst lc substr($k, 2, $ln - 1);
584                 $_ = $key;
585                if( /USES/ || /INPUT/ || /OUTPUT/ || /PARAMETERS/ ||
586                    /VALUE/  || /ARGUMENTS/ ) {
587                    printf "{\\em %s}\n", substr($k, 1, $ln - 1); } # italics
588                 else {
589                    printf "{\\sf %s}\n", substr($k, 1, $ln - 1); # san serif
590}#               end if
591
592                 printf "\\begin{verbatim} ";
593                 $verb = 1;
594                 $first_verb = 1;
595                 if ( $key eq "!INTERFACE:" )        { $have_intf = 1; }
596                 if ( $key eq "!CALLING SEQUENCE:" ) { $have_intf = 1; }
597                 if ( $key eq "!REVISION HISTORY:" ) { $have_hist = 1; }
598                 next LINE;
599}#            end if
600}#         end foreach
601}#      end if
602
603#       End of prologue
604#       ---------------
605        if ($Fld[0] eq $eop_string) {
606           if ($verb) {
607              print "\\end{verbatim}";
608              $verb = 0;
609}#         end if
610           $prologue = 0;
611#           &check_if_all_there(); # check if all required keywords are there.
612           if ( $opt_l ) {
613              $Fld[0] = $boc_string;}
614           else { next LINE; }
615}#      end if
616
617        unless ( $opt_s ) {
618
619#       End of Internal Prologue
620#	------------------------
621
622	if ($Fld[0] eq $eopi_string) {
623           if ($verb) {
624              print "\\end{verbatim}";
625              $verb = 0;
626}#         endif
627           $prologue = 0;
628#          &check_if_all_there(); # check if all required keywords are there.
629           if ($opt_l) {
630              $Fld[0] = $boc_string;}
631           else { next LINE; }
632}#       endif
633
634#
635#          Beginning of source code section
636#          --------------------------------
637           if ($Fld[0] eq $boc_string) {
638              print ' ';
639              print '%/////////////////////////////////////////////////////////////';
640              $first = 0;
641              $prologue = 0;
642              $source = 1;
643              ### printf "\\subsection*{CONTENTS:}\n\n", $Fld[3];
644              ###printf "{\\sf CONTENTS:}";
645              printf "\n \\begin{verbatim}\n";
646              $verb = 1;
647              next LINE;
648}#         end if
649
650#          End of source code
651#          ------------------
652           if ($Fld[0] eq $eoc_string) {
653              &do_eoc();
654              $prologue = 0;
655              next LINE;
656}#         end if
657
658#          Beginning of example prologue
659#          -----------------------------
660           if ($Fld[0] eq $boe_string) {
661              if ( $source ) { &do_eoc(); }
662              print ' ';
663              print '%/////////////////////////////////////////////////////////////';
664              $first = 0;
665              $prologue = 1;
666              $verb = 0;
667              $source = 0;
668              next LINE;
669}#        end if
670
671#       End of example prologue
672#       -----------------------
673        if ($Fld[0] eq $eoe_string) {
674           if ($verb) {
675              print "\\end{verbatim}";
676              $verb = 0;
677}#         end if
678           $prologue = 0;
679           if ( $opt_l ) {
680              $Fld[0] = $boc_string;}
681           else { next LINE; }
682}#      end if
683
684}#      end unless
685
686#   Prologue or Introduction, print regular line (except for !)
687#   -----------------------------------------------------------
688    if ($prologue||$intro) {
689        if ( $verb && $#Fld == 0 && ( $Fld[0] eq $comment_string ) ) {
690           next LINE;                # to eliminate excessive blanks
691}#      end if
692        if ( $Fld[1] eq "\\ev" ) {   # special handling
693           $_ = $comment_string . " \\end{verbatim}";
694}#      end if
695        s/^$comment_string/ /;       # replace comment string with blank
696#       $line = sprintf('%s', $_);   # not necessary -- comment str is absent
697#       $ln = length($line);         # not necessary -- comment str is absent
698        unless ( $first_verb ) { printf "\n "; }
699        printf '%s', $_;
700#       printf '%s', substr($line, 1, $ln - 1);     # comment str is absent
701        $first_verb = 0;
702        next LINE;
703}#  end if
704
705#   Source code: print the full line
706#   --------------------------------
707    if ($source) {
708        print $_;
709        next LINE;
710}#  end if
711
712}#   end inner loop for processing each line of the input file
713 #   ---------------------------------------------------------
714
715}# end main loop for each command-line argument
716 # --------------------------------------------
717  print $_;
718  if ( $source ) { &do_eoc(); }
719  print '%...............................................................';
720
721  # see comment above where these are originally set.
722  #print "\\setlength{\\parskip}{\\oldparskip}";
723  #print "\\setlength{\\parindent}{\\oldparindent}";
724  #print "\\setlength{\\baselineskip}{\\oldbaselineskip}";
725
726  unless ( $opt_b ) {
727     print "\\end{document}";
728}#end unless
729
730
731#----------------------------------------------------------------------
732
733  sub CheckOpts
734#    Checks options against a given list.  Outputs error message
735#    for any invalid option.
736#
737#    Usage:
738#       $rc = &CheckOpts ( options, valid_reg_options,
739#                                   valid_sw_options,
740#                                   quiet_mode )
741#
742#       character: options - options to be checked. (e.g. -df+x)  The
743#                            list must begin with a positive or
744#                            negative sign.  If no sign appears at the
745#                            beginning or by itself, then the argument
746#                            is not recognized as a list of options.
747#       character: valid_reg_options - list of valid regular options.
748#                            (i.e. options that are associated only
749#                            eith negative sign.)
750#       character: valid_sw_options - list of valid switch options.
751#                            (i.e. options that can be associated with
752#                            either a positive or negative sign.
753#       logical:   quiet mode (optional) If true then print no error
754#                            messages.
755#       integer:   rc      - return code
756#                            = -1 if the arguement, options, is
757#                               not recognized as a list of options
758#                            =  0 if all options are valid.
759#                            >  0 for the number of invalid options.
760#
761{    local($options,
762           $valid_reg_options,
763           $valid_sw_options,
764           $quiet_mode ) = @_;
765
766     if ( $options eq "+" ||
767          $options eq "-" ) {return -1}
768
769     local(@Options) = split( / */, $options );
770     if ( $Options[ $[ ] ne "-" &&
771          $Options[ $[ ] ne "+" ) {return -1;}
772
773     local($option, $option_sign, $valid_list, $pos);
774     local($errs)    = 0;
775     foreach $option ( @Options ) {
776        if ( $option eq "-" ||
777             $option eq "+" ) {$option_sign = $option;}
778        else {
779           if ( $option_sign eq "-" )
780              { $valid_list = $valid_reg_options
781                            . $valid_sw_options; }
782           else
783              { $valid_list = $valid_sw_options; }
784           $pos = index ($valid_list,$option);
785           if ( $pos < $[ &&
786                $quiet_mode ) {
787              $errs++;
788              print STDERR "Invalid option: $option_sign$option \n";
789
790}#         end if
791}#      end if
792}#   end foreach
793     return $errs;
794
795}#end sub GetOpts
796
797  sub GetOpts
798#    Gets options.  If an option is valid,  then opt_[option] is
799#    set to 0 or 1 as a side effect if the option is preceeded by
800#    a positive or negative sign.
801#
802#    Usage:
803#       $rc = &GetOpts ( options, valid_options )
804#
805#       character: options - options to be checked. (e.g. -df+x)  The
806#                            list must begin with a positive or
807#                            negative sign.  If no sign appears at the
808#                            beginning or by itself, then the argument
809#                            is not recognized as a list of options.
810#       character: valid_options - list of valid options (e.g. dfhx)
811#       integer:   rc      - return code
812#                            = -1 if the arguement, options, is
813#                               not recognized as a list of options.
814#                            =  0 otherwise
815#
816{    local($options,$valid_options) = @_;
817
818     if ( $options eq "+" ||
819          $options eq "-" ) {return -1}
820
821     local(@Options)       = split( / */, $options );
822     if ( $Options[ $[ ] ne "-" &&
823          $Options[ $[ ] ne "+" ) {return -1;}
824
825     local($option, $option_sign);
826
827     foreach $option ( @Options ) {
828
829        if ( $option eq "-" ||
830             $option eq "+" ) {
831           $option_sign = $option; }
832
833        else {
834
835           if ( index ($valid_options,$option) >= $[ ) {
836              if ( $option_sign eq "-" ) {${"opt_$option"} = 1;}
837              if ( $option_sign eq "+" ) {${"opt_$option"} = 0;};
838
839}#         end if
840}#      end if
841}#   end foreach
842
843     return 0;
844}#end sub GetOpts
845
846  sub SetOpt
847#    Sets option flags.  For the last input option that is in a
848#    list, the flag opt_[option] is set to 1 as a side effect.
849#    For all other options in the list, opt_[option] is set to 0.
850#
851#    Usage:
852#       $rc = &SetOpt ( options, valid_options )
853#
854#       character: options - options to be checked. (e.g. -df+x)  The
855#                            list must begin with a positive or
856#                            negative sign.  If no sign appears at the
857#                            beginning or by itself, then the argument
858#                            is not recognized as a list of options.
859#       character: valid_options - list of valid options (e.g. def )
860#       integer:   rc      - return code
861#                            = -1 if the arguement, options, is
862#                               not recognized as a list of options.
863#                            =  0 otherwise
864#       Note: For the examples provided for the input arguments,
865#             $opt_d = 0, $opt_e = 0, and $opt_f = 1, since the
866#             input option, -f, was the last in the argument,
867#             option.
868#
869{    local($options,$valid_options) = @_;
870
871     if ( $options eq "+" ||
872          $options eq "-" ) {return -1}
873
874     local(@Options)       = split( / */, $options       );
875     local(@ValidOptions)  = split( / */, $valid_options );
876     if ( $Options[ $[ ] ne "-" &&
877          $Options[ $[ ] ne "+" ) {return -1;}
878
879     local($option, $option_sign);
880
881     foreach $option ( @Options ) {
882        if ( $option ne "-" &&
883             $option ne "+" ) {
884
885           if ( index ($valid_options,$option) >= $[ ) {
886              foreach $valid_option (@ValidOptions ) {
887                 ${"opt_$valid_option"} = 0;
888
889}#            end foreach
890              ${"opt_$option"} = 1;
891}#         end if
892}#      end if
893}#   end foreach
894
895  return 0;
896}#end sub SetOpt
897
898sub print_help {
899
900    print "Usage:     protex [-hbACFS] [+-nlsxf] [src_file(s)]";
901    print " ";
902    print " Options:";
903    print "     -h   Help mode: list command line options";
904    print "     -b   Bare mode, meaning no preamble, etc.";
905    print "     +-n  New Page for each subsection (wastes paper)";
906    print "     +-l  Listing mode, default is prologues only";
907    print "     +-s  Shut-up mode, i.e., ignore any code from BOC to EOC";
908    print "     +-x  No LaTeX mode, i.e., put !DESCRIPTION: in verbatim mode";
909    print "     +-f  No source file info";
910    print "     -A   Ada code";
911    print "     -C   C++ code";
912    print "     -F   F90 code";
913    print "     -S   Shell script";
914    print " ";
915    print "  The options can appear in any order.  The options, -h and -b,";
916    print "  affect the input from all files listed on command-line input.";
917    print "  Each of the remaining options effects only the input from the";
918    print "  files listed after the option and prior to any overriding";
919    print "  option.  The plus sign turns off the option.";
920}# end sub print_help
921
922sub print_notice {
923
924    print "%                **** IMPORTANT NOTICE *****" ;
925    print "% This LaTeX file has been automatically produced by ProTeX v. 1.1";
926    print "% Any changes made to this file will likely be lost next time";
927    print "% this file is regenerated from its source. Send questions ";
928    print "% to Arlindo da Silva, dasilva\@gsfc.nasa.gov";
929    print " ";
930
931}# sub print_notice
932
933sub print_preamble {
934
935  unless ( $opt_b ) {
936    print "%------------------------ PREAMBLE --------------------------";
937    print "\\documentclass[a4paper,11pt]{article}";
938    print "\\usepackage{amsmath}";
939    print "\\usepackage{amssymb}";
940    print "\\usepackage{epsfig}";
941    print "\\usepackage{tabularx}";
942    print "\\usepackage{color}";
943    print "\\usepackage[linkbordercolor={0 0 1}]{hyperref}";
944    print "\\textheight     9in";
945    print "\\topmargin      0pt";
946    print "\\headsep        1cm";
947    print "\\headheight     0pt";
948    print "\\textwidth      6in";
949    print "\\oddsidemargin  0in";
950    print "\\evensidemargin 0in";
951    print "\\marginparpush  0pt";
952    print "\\pagestyle{plain}";
953    print "\\markboth{}{}";
954    print "%-------------------------------------------------------------";
955}#  end unless
956
957    # in your main document before you include any protex-generated files
958    # for the first time, if you define these three variables as length
959    # settings (like this:)
960    #   \newlength{\oldparskip}
961    #   \newlength{\oldparindent}
962    #   \newlength{\oldbaselineskip}
963    # then 1) comment in all the lines below, and 2) find the 3 reset lines
964    # further down and comment in them as well.
965    # then protex will override the paragraph and skip settings during
966    # the source sections, but will restore the original document settings
967    # at the end.   if someone can figure out how to check to see if a
968    # latex variable exists, and do a conditional section, we could make
969    # this fully self-contained.
970    # nsc feb 2003
971
972    #print "\\setlength{\\oldparskip}{\\parskip}";
973    print "\\setlength{\\parskip}{0pt}";
974    #print "\\setlength{\\oldparindent}{\\parindent}";
975    print "\\setlength{\\parindent}{0pt}";
976    #print "\\setlength{\\oldbaselineskip}{\\baselineskip}";
977    print "\\setlength{\\baselineskip}{11pt}";
978
979}# end sub print_preamble
980
981sub print_macros {
982
983    print " ";
984    print "%--------------------- SHORT-HAND MACROS ----------------------";
985    print "\\def\\bv{\\begin{verbatim}}";
986    print "\\def\\ev\{\\end\{verbatim}}";
987    print "\\def\\be{\\begin{equation}}";
988    print "\\def\\ee{\\end{equation}}";
989    print "\\def\\bea{\\begin{eqnarray}}";
990    print "\\def\\eea{\\end{eqnarray}}";
991    print "\\def\\bi{\\begin{itemize}}";
992    print "\\def\\ei{\\end{itemize}}";
993    print "\\def\\bn{\\begin{enumerate}}";
994    print "\\def\\en{\\end{enumerate}}";
995    print "\\def\\bd{\\begin{description}}";
996    print "\\def\\ed{\\end{description}}";
997    print "\\def\\({\\left (}";
998    print "\\def\\){\\right )}";
999    print "\\def\\[{\\left [}";
1000    print "\\def\\]{\\right ]}";
1001    print "\\def\\<{\\left  \\langle}";
1002    print "\\def\\>{\\right \\rangle}";
1003    print "\\def\\cI{{\\cal I}}";
1004    print "\\def\\diag{\\mathop{\\rm diag}}";
1005    print "\\def\\tr{\\mathop{\\rm tr}}";
1006    print "%-------------------------------------------------------------";
1007    print " ";
1008    print "%------------------------ Elk commands -----------------------";
1009    print "\\newcommand{\\block}[2]{";
1010    print "\\color{blue}\\subsection{\\tt #1}\\color{black}";
1011    print "\\begin{tabularx}{\\textwidth}[h]{|l|X|c|c|}";
1012    print "\\hline";
1013    print "#2 \\\\";
1014    print "\\hline";
1015    print "\\end{tabularx}\\vskip 0.25cm";
1016    print "}";
1017    print "%-------------------------------------------------------------";
1018
1019}# end sub print_macros
1020
1021sub do_beg {
1022    unless ( $opt_b ) {
1023    if ( $begdoc == 0 ) {
1024        if ( $tpage ) {
1025            print "\\title{@title}";
1026            print "\\author{@author\\\\ {\\em @affiliation}}";
1027            print "\\date{@date}";
1028        }
1029        print "\\begin{document}";
1030        if ( $tpage ) {
1031            print "\\pagecolor[rgb]{1,0.95,0.85}";
1032            print "\\fcolorbox{black}{white}{\\fbox{";
1033            print "\\begin{minipage}[t]{\\linewidth}";
1034            print "\\maketitle";
1035            print "\\end{minipage}}}";
1036            print "\\thispagestyle{empty}";
1037            print "\\newpage";
1038            print "\\pagecolor{white}";
1039        }
1040        print "\\tableofcontents";
1041        print "\\newpage";
1042        $begdoc = 1;
1043     }
1044  }
1045}# end sub do_beg
1046
1047sub do_eoc {
1048        print ' ';
1049        if ($verb) {
1050            print "\\end{verbatim}";
1051            $verb = 0;
1052        }
1053        $source = 0;
1054}# end sub do_eoc
1055
1056sub set_missing {
1057
1058  $have_name = 0;      # have routine name?
1059  $have_desc = 0;      # have description?
1060  $have_intf = 0;      # have interface?
1061  $have_hist = 0;      # have revision history?
1062  $name_is = "UNKNOWN";
1063
1064}# end sub set_missing
1065
1066
1067sub check_if_all_there {
1068
1069$have_name ||
1070die "ProTeX: invalid prologue, missing !ROUTINE: or !IROUTINE: in <$name_is>";
1071
1072$have_desc ||
1073die "ProTeX: invalid prologue, missing !DESCRIPTION: in <$name_is>";
1074
1075$have_intf ||
1076die "ProTeX: invalid prologue, missing !INTERFACE: in <$name_is>";
1077
1078$have_hist ||
1079 die "ProTeX: invalid prologue, missing !REVISION HISTORY: in <$name_is>";
1080
1081}# end sub check_if_all_there
1082